From 67f5adcdf7c46dee252186f8097a6c04b5ef5042 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:11:56 +0800 Subject: [PATCH 01/25] chore: scaffold extension mvp workspace --- apps/extension/node_modules/.bin/rimraf | 17 ++ apps/extension/node_modules/.bin/rimraf.CMD | 12 + apps/extension/node_modules/.bin/rimraf.ps1 | 41 +++ .../@data-recipe/recipe-core/package.json | 12 + .../@data-recipe/recipe-core/src/index.ts | 111 ++++++++ .../@data-recipe/recipe-core/tsconfig.json | 10 + .../@data-recipe/detector/package.json | 15 ++ .../@data-recipe/detector/src/index.ts | 215 +++++++++++++++ .../@data-recipe/detector/tsconfig.json | 10 + .../@data-recipe/recipe-core/package.json | 12 + .../@data-recipe/recipe-core/src/index.ts | 111 ++++++++ .../@data-recipe/recipe-core/tsconfig.json | 10 + apps/extension/node_modules/rimraf/LICENSE.md | 55 ++++ apps/extension/node_modules/rimraf/README.md | 255 ++++++++++++++++++ .../rimraf/dist/commonjs/default-tmp.d.ts | 3 + .../rimraf/dist/commonjs/default-tmp.d.ts.map | 1 + .../rimraf/dist/commonjs/default-tmp.js | 58 ++++ .../rimraf/dist/commonjs/default-tmp.js.map | 1 + .../rimraf/dist/commonjs/error.d.ts | 6 + .../rimraf/dist/commonjs/error.d.ts.map | 1 + .../rimraf/dist/commonjs/error.js | 10 + .../rimraf/dist/commonjs/error.js.map | 1 + .../rimraf/dist/commonjs/fix-eperm.d.ts | 3 + .../rimraf/dist/commonjs/fix-eperm.d.ts.map | 1 + .../rimraf/dist/commonjs/fix-eperm.js | 38 +++ .../rimraf/dist/commonjs/fix-eperm.js.map | 1 + .../node_modules/rimraf/dist/commonjs/fs.d.ts | 16 ++ .../rimraf/dist/commonjs/fs.d.ts.map | 1 + .../node_modules/rimraf/dist/commonjs/fs.js | 33 +++ .../rimraf/dist/commonjs/fs.js.map | 1 + .../rimraf/dist/commonjs/ignore-enoent.d.ts | 3 + .../dist/commonjs/ignore-enoent.d.ts.map | 1 + .../rimraf/dist/commonjs/ignore-enoent.js | 24 ++ .../rimraf/dist/commonjs/ignore-enoent.js.map | 1 + .../rimraf/dist/commonjs/index.d.ts | 50 ++++ .../rimraf/dist/commonjs/index.d.ts.map | 1 + .../rimraf/dist/commonjs/index.js | 84 ++++++ .../rimraf/dist/commonjs/index.js.map | 1 + .../rimraf/dist/commonjs/opt-arg.d.ts | 34 +++ .../rimraf/dist/commonjs/opt-arg.d.ts.map | 1 + .../rimraf/dist/commonjs/opt-arg.js | 54 ++++ .../rimraf/dist/commonjs/opt-arg.js.map | 1 + .../rimraf/dist/commonjs/package.json | 3 + .../rimraf/dist/commonjs/path-arg.d.ts | 4 + .../rimraf/dist/commonjs/path-arg.d.ts.map | 1 + .../rimraf/dist/commonjs/path-arg.js | 49 ++++ .../rimraf/dist/commonjs/path-arg.js.map | 1 + .../dist/commonjs/readdir-or-error.d.ts | 3 + .../dist/commonjs/readdir-or-error.d.ts.map | 1 + .../rimraf/dist/commonjs/readdir-or-error.js | 19 ++ .../dist/commonjs/readdir-or-error.js.map | 1 + .../rimraf/dist/commonjs/retry-busy.d.ts | 8 + .../rimraf/dist/commonjs/retry-busy.d.ts.map | 1 + .../rimraf/dist/commonjs/retry-busy.js | 65 +++++ .../rimraf/dist/commonjs/retry-busy.js.map | 1 + .../rimraf/dist/commonjs/rimraf-manual.d.ts | 3 + .../dist/commonjs/rimraf-manual.d.ts.map | 1 + .../rimraf/dist/commonjs/rimraf-manual.js | 8 + .../rimraf/dist/commonjs/rimraf-manual.js.map | 1 + .../dist/commonjs/rimraf-move-remove.d.ts | 4 + .../dist/commonjs/rimraf-move-remove.d.ts.map | 1 + .../dist/commonjs/rimraf-move-remove.js | 138 ++++++++++ .../dist/commonjs/rimraf-move-remove.js.map | 1 + .../rimraf/dist/commonjs/rimraf-native.d.ts | 4 + .../dist/commonjs/rimraf-native.d.ts.map | 1 + .../rimraf/dist/commonjs/rimraf-native.js | 24 ++ .../rimraf/dist/commonjs/rimraf-native.js.map | 1 + .../rimraf/dist/commonjs/rimraf-posix.d.ts | 4 + .../dist/commonjs/rimraf-posix.d.ts.map | 1 + .../rimraf/dist/commonjs/rimraf-posix.js | 102 +++++++ .../rimraf/dist/commonjs/rimraf-posix.js.map | 1 + .../rimraf/dist/commonjs/rimraf-windows.d.ts | 4 + .../dist/commonjs/rimraf-windows.d.ts.map | 1 + .../rimraf/dist/commonjs/rimraf-windows.js | 159 +++++++++++ .../dist/commonjs/rimraf-windows.js.map | 1 + .../rimraf/dist/commonjs/use-native.d.ts | 4 + .../rimraf/dist/commonjs/use-native.d.ts.map | 1 + .../rimraf/dist/commonjs/use-native.js | 18 ++ .../rimraf/dist/commonjs/use-native.js.map | 1 + .../node_modules/rimraf/dist/esm/bin.d.mts | 3 + .../rimraf/dist/esm/bin.d.mts.map | 1 + .../node_modules/rimraf/dist/esm/bin.mjs | 250 +++++++++++++++++ .../node_modules/rimraf/dist/esm/bin.mjs.map | 1 + .../rimraf/dist/esm/default-tmp.d.ts | 3 + .../rimraf/dist/esm/default-tmp.d.ts.map | 1 + .../rimraf/dist/esm/default-tmp.js | 55 ++++ .../rimraf/dist/esm/default-tmp.js.map | 1 + .../node_modules/rimraf/dist/esm/error.d.ts | 6 + .../rimraf/dist/esm/error.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/error.js | 5 + .../node_modules/rimraf/dist/esm/error.js.map | 1 + .../rimraf/dist/esm/fix-eperm.d.ts | 3 + .../rimraf/dist/esm/fix-eperm.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/fix-eperm.js | 33 +++ .../rimraf/dist/esm/fix-eperm.js.map | 1 + .../node_modules/rimraf/dist/esm/fs.d.ts | 16 ++ .../node_modules/rimraf/dist/esm/fs.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/fs.js | 18 ++ .../node_modules/rimraf/dist/esm/fs.js.map | 1 + .../rimraf/dist/esm/ignore-enoent.d.ts | 3 + .../rimraf/dist/esm/ignore-enoent.d.ts.map | 1 + .../rimraf/dist/esm/ignore-enoent.js | 19 ++ .../rimraf/dist/esm/ignore-enoent.js.map | 1 + .../node_modules/rimraf/dist/esm/index.d.ts | 50 ++++ .../rimraf/dist/esm/index.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/index.js | 76 ++++++ .../node_modules/rimraf/dist/esm/index.js.map | 1 + .../node_modules/rimraf/dist/esm/opt-arg.d.ts | 34 +++ .../rimraf/dist/esm/opt-arg.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/opt-arg.js | 47 ++++ .../rimraf/dist/esm/opt-arg.js.map | 1 + .../node_modules/rimraf/dist/esm/package.json | 3 + .../rimraf/dist/esm/path-arg.d.ts | 4 + .../rimraf/dist/esm/path-arg.d.ts.map | 1 + .../node_modules/rimraf/dist/esm/path-arg.js | 47 ++++ .../rimraf/dist/esm/path-arg.js.map | 1 + .../rimraf/dist/esm/readdir-or-error.d.ts | 3 + .../rimraf/dist/esm/readdir-or-error.d.ts.map | 1 + .../rimraf/dist/esm/readdir-or-error.js | 14 + .../rimraf/dist/esm/readdir-or-error.js.map | 1 + .../rimraf/dist/esm/retry-busy.d.ts | 8 + .../rimraf/dist/esm/retry-busy.d.ts.map | 1 + .../rimraf/dist/esm/retry-busy.js | 60 +++++ .../rimraf/dist/esm/retry-busy.js.map | 1 + .../rimraf/dist/esm/rimraf-manual.d.ts | 3 + .../rimraf/dist/esm/rimraf-manual.d.ts.map | 1 + .../rimraf/dist/esm/rimraf-manual.js | 5 + .../rimraf/dist/esm/rimraf-manual.js.map | 1 + .../rimraf/dist/esm/rimraf-move-remove.d.ts | 4 + .../dist/esm/rimraf-move-remove.d.ts.map | 1 + .../rimraf/dist/esm/rimraf-move-remove.js | 133 +++++++++ .../rimraf/dist/esm/rimraf-move-remove.js.map | 1 + .../rimraf/dist/esm/rimraf-native.d.ts | 4 + .../rimraf/dist/esm/rimraf-native.d.ts.map | 1 + .../rimraf/dist/esm/rimraf-native.js | 19 ++ .../rimraf/dist/esm/rimraf-native.js.map | 1 + .../rimraf/dist/esm/rimraf-posix.d.ts | 4 + .../rimraf/dist/esm/rimraf-posix.d.ts.map | 1 + .../rimraf/dist/esm/rimraf-posix.js | 97 +++++++ .../rimraf/dist/esm/rimraf-posix.js.map | 1 + .../rimraf/dist/esm/rimraf-windows.d.ts | 4 + .../rimraf/dist/esm/rimraf-windows.d.ts.map | 1 + .../rimraf/dist/esm/rimraf-windows.js | 154 +++++++++++ .../rimraf/dist/esm/rimraf-windows.js.map | 1 + .../rimraf/dist/esm/use-native.d.ts | 4 + .../rimraf/dist/esm/use-native.d.ts.map | 1 + .../rimraf/dist/esm/use-native.js | 15 ++ .../rimraf/dist/esm/use-native.js.map | 1 + .../rimraf/node_modules/.bin/rimraf | 17 ++ .../rimraf/node_modules/.bin/rimraf.CMD | 12 + .../rimraf/node_modules/.bin/rimraf.ps1 | 41 +++ .../node_modules/rimraf/package.json | 77 ++++++ apps/extension/package.json | 19 ++ apps/extension/public/manifest.json | 30 +++ apps/extension/public/sidepanel.css | 223 +++++++++++++++ apps/extension/public/sidepanel.html | 43 +++ apps/extension/scripts/copy-assets.mjs | 10 + apps/extension/src/background.ts | 124 +++++++++ apps/extension/src/content.ts | 59 ++++ apps/extension/src/messages.ts | 38 +++ apps/extension/src/page-hook.ts | 203 ++++++++++++++ apps/extension/src/sidepanel.ts | 211 +++++++++++++++ apps/extension/tsconfig.json | 8 + docs/test-page.html | 86 ++++++ package.json | 18 ++ .../@data-recipe/recipe-core/package.json | 12 + .../@data-recipe/recipe-core/src/index.ts | 111 ++++++++ .../@data-recipe/recipe-core/tsconfig.json | 10 + packages/detector/package.json | 15 ++ packages/detector/src/index.ts | 215 +++++++++++++++ packages/detector/tsconfig.json | 10 + packages/recipe-core/package.json | 12 + packages/recipe-core/src/index.ts | 111 ++++++++ packages/recipe-core/tsconfig.json | 10 + .../@data-recipe/recipe-core/package.json | 12 + .../@data-recipe/recipe-core/src/index.ts | 111 ++++++++ .../@data-recipe/recipe-core/tsconfig.json | 10 + packages/recipe-runner/package.json | 15 ++ packages/recipe-runner/src/index.ts | 6 + packages/recipe-runner/tsconfig.json | 10 + pnpm-workspace.yaml | 3 + tsconfig.base.json | 14 + 182 files changed, 5103 insertions(+) create mode 100644 apps/extension/node_modules/.bin/rimraf create mode 100644 apps/extension/node_modules/.bin/rimraf.CMD create mode 100644 apps/extension/node_modules/.bin/rimraf.ps1 create mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json create mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts create mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json create mode 100644 apps/extension/node_modules/@data-recipe/detector/package.json create mode 100644 apps/extension/node_modules/@data-recipe/detector/src/index.ts create mode 100644 apps/extension/node_modules/@data-recipe/detector/tsconfig.json create mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/package.json create mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts create mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json create mode 100644 apps/extension/node_modules/rimraf/LICENSE.md create mode 100644 apps/extension/node_modules/rimraf/README.md create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/package.json create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.js create mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.d.mts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.mjs create mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/package.json create mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts create mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map create mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.js create mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.js.map create mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf create mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD create mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 create mode 100644 apps/extension/node_modules/rimraf/package.json create mode 100644 apps/extension/package.json create mode 100644 apps/extension/public/manifest.json create mode 100644 apps/extension/public/sidepanel.css create mode 100644 apps/extension/public/sidepanel.html create mode 100644 apps/extension/scripts/copy-assets.mjs create mode 100644 apps/extension/src/background.ts create mode 100644 apps/extension/src/content.ts create mode 100644 apps/extension/src/messages.ts create mode 100644 apps/extension/src/page-hook.ts create mode 100644 apps/extension/src/sidepanel.ts create mode 100644 apps/extension/tsconfig.json create mode 100644 docs/test-page.html create mode 100644 package.json create mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/package.json create mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts create mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json create mode 100644 packages/detector/package.json create mode 100644 packages/detector/src/index.ts create mode 100644 packages/detector/tsconfig.json create mode 100644 packages/recipe-core/package.json create mode 100644 packages/recipe-core/src/index.ts create mode 100644 packages/recipe-core/tsconfig.json create mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json create mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts create mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json create mode 100644 packages/recipe-runner/package.json create mode 100644 packages/recipe-runner/src/index.ts create mode 100644 packages/recipe-runner/tsconfig.json create mode 100644 pnpm-workspace.yaml create mode 100644 tsconfig.base.json diff --git a/apps/extension/node_modules/.bin/rimraf b/apps/extension/node_modules/.bin/rimraf new file mode 100644 index 0000000..b19312d --- /dev/null +++ b/apps/extension/node_modules/.bin/rimraf @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../rimraf/dist/esm/bin.mjs" "$@" +else + exec node "$basedir/../rimraf/dist/esm/bin.mjs" "$@" +fi diff --git a/apps/extension/node_modules/.bin/rimraf.CMD b/apps/extension/node_modules/.bin/rimraf.CMD new file mode 100644 index 0000000..6c04d44 --- /dev/null +++ b/apps/extension/node_modules/.bin/rimraf.CMD @@ -0,0 +1,12 @@ +@SETLOCAL +@IF NOT DEFINED NODE_PATH ( + @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" +) ELSE ( + @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules;%NODE_PATH%" +) +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\rimraf\dist\esm\bin.mjs" %* +) ELSE ( + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\rimraf\dist\esm\bin.mjs" %* +) diff --git a/apps/extension/node_modules/.bin/rimraf.ps1 b/apps/extension/node_modules/.bin/rimraf.ps1 new file mode 100644 index 0000000..e5e1227 --- /dev/null +++ b/apps/extension/node_modules/.bin/rimraf.ps1 @@ -0,0 +1,41 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +$pathsep=":" +$env_node_path=$env:NODE_PATH +$new_node_path="D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" + $pathsep=";" +} else { + $new_node_path="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" +} +if ([string]::IsNullOrEmpty($env_node_path)) { + $env:NODE_PATH=$new_node_path +} else { + $env:NODE_PATH="$new_node_path$pathsep$env_node_path" +} + +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args + } else { + & "$basedir/node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args + } else { + & "node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} +$env:NODE_PATH=$env_node_path +exit $ret diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json new file mode 100644 index 0000000..e4538ee --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@data-recipe/recipe-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + } +} diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts new file mode 100644 index 0000000..7cdb195 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts @@ -0,0 +1,111 @@ +export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; + +export type JsonObject = Record; + +export interface DataRecipe { + name: string; + displayName: string; + source: DataRecipeSource; + request: DataRecipeRequest; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: DataRecipeField[]; +} + +export interface DataRecipeSource { + type: "web_api"; + pageUrl: string; + apiUrl: string; + method: HttpMethod; +} + +export interface DataRecipeRequest { + query: JsonObject; + body: unknown; +} + +export interface DataRecipeResponse { + type: "list" | "object" | "unknown"; + listPath: string; + totalPath: string; +} + +export interface DataRecipePagination { + type: "page_number" | "cursor" | "unknown"; + pageParam: string; + pageSizeParam: string; + totalPath: string; +} + +export interface DataRecipeField { + name: string; + path: string; + type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + sample?: unknown; +} + +export interface CreateRecipeInput { + pageUrl: string; + apiUrl: string; + method: HttpMethod; + query: JsonObject; + body: unknown; + responseType: DataRecipeResponse["type"]; + listPath: string; + totalPath: string; + fields: DataRecipeField[]; +} + +export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { + const name = buildRecipeName(input.apiUrl); + + return { + name, + displayName: "数据来源", + source: { + type: "web_api", + pageUrl: input.pageUrl, + apiUrl: input.apiUrl, + method: input.method + }, + request: { + query: input.query, + body: input.body ?? {} + }, + response: { + type: input.responseType, + listPath: input.listPath, + totalPath: input.totalPath + }, + pagination: { + type: "page_number", + pageParam: "", + pageSizeParam: "", + totalPath: input.totalPath + }, + fields: input.fields + }; +} + +function buildRecipeName(apiUrl: string): string { + try { + const url = new URL(apiUrl); + const pathPart = url.pathname + .split("/") + .filter(Boolean) + .slice(-2) + .join("_"); + return normalizeName(pathPart || url.hostname); + } catch { + return normalizeName(apiUrl || "data_source"); + } +} + +function normalizeName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_+|_+$/g, ""); + + return normalized || "data_source"; +} diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/apps/extension/node_modules/@data-recipe/detector/package.json b/apps/extension/node_modules/@data-recipe/detector/package.json new file mode 100644 index 0000000..e7a9ca2 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/package.json @@ -0,0 +1,15 @@ +{ + "name": "@data-recipe/detector", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@data-recipe/recipe-core": "workspace:*" + } +} diff --git a/apps/extension/node_modules/@data-recipe/detector/src/index.ts b/apps/extension/node_modules/@data-recipe/detector/src/index.ts new file mode 100644 index 0000000..00145a3 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/src/index.ts @@ -0,0 +1,215 @@ +import { + createDataRecipeDraft, + type DataRecipe, + type DataRecipeField, + type JsonObject +} from "@data-recipe/recipe-core"; + +export interface CapturedRequest { + id: string; + pageUrl: string; + url: string; + method: string; + status: number; + requestBody: unknown; + query: JsonObject; + responseBody: unknown; + responsePreview: string; + capturedAt: number; + transport: "fetch" | "xhr"; +} + +export interface ResponseDetection { + isJson: boolean; + looksLikeList: boolean; + hasArray: boolean; + arrayPaths: string[]; + listPath: string; + totalPath: string; + keywordPaths: string[]; + fields: DataRecipeField[]; +} + +const TOTAL_KEYS = new Set(["total", "count", "totalCount", "total_count", "recordCount", "record_count"]); +const LIST_KEYS = new Set(["records", "list", "items", "rows", "data", "result"]); +const PAGE_KEYS = new Set(["page", "pageNo", "pageNum", "page_number", "current", "currentPage", "pageSize"]); + +export function parseQueryFromUrl(urlValue: string): JsonObject { + try { + const url = new URL(urlValue); + const query: JsonObject = {}; + url.searchParams.forEach((value, key) => { + if (query[key] === undefined) { + query[key] = value; + } else if (Array.isArray(query[key])) { + (query[key] as string[]).push(value); + } else { + query[key] = [query[key], value]; + } + }); + return query; + } catch { + return {}; + } +} + +export function tryParseJson(text: string): unknown { + if (!text.trim()) { + return null; + } + + try { + return JSON.parse(text); + } catch { + return text; + } +} + +export function summarizeResponse(responseBody: unknown): ResponseDetection { + const isJson = responseBody !== null && typeof responseBody === "object"; + const arrayPaths: string[] = []; + const keywordPaths: string[] = []; + const totalPaths: string[] = []; + + if (isJson) { + walk(responseBody, "$", (path, value, key) => { + if (Array.isArray(value)) { + arrayPaths.push(path); + } + + if (key && (TOTAL_KEYS.has(key) || LIST_KEYS.has(key) || PAGE_KEYS.has(key))) { + keywordPaths.push(path); + } + + if (key && TOTAL_KEYS.has(key) && typeof value !== "object") { + totalPaths.push(path); + } + }); + } + + const listPath = pickListPath(responseBody, arrayPaths); + const fields = inferFieldsAtPath(responseBody, listPath); + + return { + isJson, + looksLikeList: arrayPaths.length > 0 && fields.length > 0, + hasArray: arrayPaths.length > 0, + arrayPaths, + listPath, + totalPath: totalPaths[0] ?? "", + keywordPaths, + fields + }; +} + +export function buildRecipeFromCapture(capture: CapturedRequest): DataRecipe { + const detection = summarizeResponse(capture.responseBody); + + return createDataRecipeDraft({ + pageUrl: capture.pageUrl, + apiUrl: capture.url, + method: capture.method, + query: capture.query, + body: capture.requestBody ?? {}, + responseType: detection.looksLikeList ? "list" : detection.isJson ? "object" : "unknown", + listPath: detection.listPath, + totalPath: detection.totalPath, + fields: detection.fields + }); +} + +export function formatPreview(value: unknown, maxLength = 1800): string { + const text = typeof value === "string" ? value : JSON.stringify(value, null, 2); + + if (!text) { + return ""; + } + + return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; +} + +function pickListPath(responseBody: unknown, arrayPaths: string[]): string { + if (arrayPaths.length === 0) { + return ""; + } + + const preferred = arrayPaths.find((path) => { + const key = path.split(".").at(-1) ?? ""; + return LIST_KEYS.has(key); + }); + + return preferred ?? arrayPaths[0] ?? ""; +} + +function inferFieldsAtPath(responseBody: unknown, listPath: string): DataRecipeField[] { + const target = getByPath(responseBody, listPath); + const sample = Array.isArray(target) ? target.find((item) => item && typeof item === "object") : null; + + if (!sample || typeof sample !== "object" || Array.isArray(sample)) { + return []; + } + + return Object.entries(sample).map(([key, value]) => ({ + name: key, + path: `${listPath}.${key}`, + type: inferJsonType(value), + sample: simplifySample(value) + })); +} + +function getByPath(value: unknown, path: string): unknown { + if (!path || path === "$") { + return value; + } + + return path + .replace(/^\$\./, "") + .split(".") + .filter(Boolean) + .reduce((current, part) => { + if (current && typeof current === "object" && part in current) { + return (current as Record)[part]; + } + return undefined; + }, value); +} + +function walk(value: unknown, path: string, visit: (path: string, value: unknown, key?: string) => void): void { + visit(path, value, path.split(".").at(-1)); + + if (!value || typeof value !== "object") { + return; + } + + if (Array.isArray(value)) { + value.slice(0, 3).forEach((item, index) => walk(item, `${path}[${index}]`, visit)); + return; + } + + Object.entries(value).forEach(([key, child]) => { + const childPath = path === "$" ? `$.${key}` : `${path}.${key}`; + walk(child, childPath, visit); + }); +} + +function inferJsonType(value: unknown): DataRecipeField["type"] { + if (value === null) return "null"; + if (Array.isArray(value)) return "array"; + if (typeof value === "string") return "string"; + if (typeof value === "number") return "number"; + if (typeof value === "boolean") return "boolean"; + if (typeof value === "object") return "object"; + return "unknown"; +} + +function simplifySample(value: unknown): unknown { + if (Array.isArray(value)) { + return value.slice(0, 2); + } + + if (value && typeof value === "object") { + return Object.fromEntries(Object.entries(value).slice(0, 5)); + } + + return value; +} diff --git a/apps/extension/node_modules/@data-recipe/detector/tsconfig.json b/apps/extension/node_modules/@data-recipe/detector/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/detector/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/package.json b/apps/extension/node_modules/@data-recipe/recipe-core/package.json new file mode 100644 index 0000000..e4538ee --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/recipe-core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@data-recipe/recipe-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + } +} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts b/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts new file mode 100644 index 0000000..7cdb195 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts @@ -0,0 +1,111 @@ +export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; + +export type JsonObject = Record; + +export interface DataRecipe { + name: string; + displayName: string; + source: DataRecipeSource; + request: DataRecipeRequest; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: DataRecipeField[]; +} + +export interface DataRecipeSource { + type: "web_api"; + pageUrl: string; + apiUrl: string; + method: HttpMethod; +} + +export interface DataRecipeRequest { + query: JsonObject; + body: unknown; +} + +export interface DataRecipeResponse { + type: "list" | "object" | "unknown"; + listPath: string; + totalPath: string; +} + +export interface DataRecipePagination { + type: "page_number" | "cursor" | "unknown"; + pageParam: string; + pageSizeParam: string; + totalPath: string; +} + +export interface DataRecipeField { + name: string; + path: string; + type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + sample?: unknown; +} + +export interface CreateRecipeInput { + pageUrl: string; + apiUrl: string; + method: HttpMethod; + query: JsonObject; + body: unknown; + responseType: DataRecipeResponse["type"]; + listPath: string; + totalPath: string; + fields: DataRecipeField[]; +} + +export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { + const name = buildRecipeName(input.apiUrl); + + return { + name, + displayName: "数据来源", + source: { + type: "web_api", + pageUrl: input.pageUrl, + apiUrl: input.apiUrl, + method: input.method + }, + request: { + query: input.query, + body: input.body ?? {} + }, + response: { + type: input.responseType, + listPath: input.listPath, + totalPath: input.totalPath + }, + pagination: { + type: "page_number", + pageParam: "", + pageSizeParam: "", + totalPath: input.totalPath + }, + fields: input.fields + }; +} + +function buildRecipeName(apiUrl: string): string { + try { + const url = new URL(apiUrl); + const pathPart = url.pathname + .split("/") + .filter(Boolean) + .slice(-2) + .join("_"); + return normalizeName(pathPart || url.hostname); + } catch { + return normalizeName(apiUrl || "data_source"); + } +} + +function normalizeName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_+|_+$/g, ""); + + return normalized || "data_source"; +} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json b/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/apps/extension/node_modules/rimraf/LICENSE.md b/apps/extension/node_modules/rimraf/LICENSE.md new file mode 100644 index 0000000..c5402b9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/apps/extension/node_modules/rimraf/README.md b/apps/extension/node_modules/rimraf/README.md new file mode 100644 index 0000000..2e53476 --- /dev/null +++ b/apps/extension/node_modules/rimraf/README.md @@ -0,0 +1,255 @@ +The [UNIX command]() `rm -rf` for node +in a cross-platform implementation. + +Install with `npm install rimraf`. + +> [!CAUTION] +> +> ## Please Be Safe, this tool deletes and moves stuff, by design +> +> The _intended purpose_ of this tool is to remove files and +> directories from the filesystem, aggressively and recursively +> removing all items that it can find under a given target. +> +> It goes without saying that you _must not pass untrusted input +> to this function or CLI tool_, just as you would not to the +> `rm(1)` command or the `unlink(2)` function. It is very +> challenging to guarantee that _any_ user input will be safe to +> remove recursively in this way. +> +> Furthermore, note that if you allow untrusted parties to +> provide arguments to the `rimraf` command line tool, they may +> also specify the `--tmp=` folder used by the +> `--impl=move-remove` strategy, which can move files to an +> arbitrary place on disk. +> +> Because the intended purpose of this tool is the permanent +> destruction of filesystem entries, any security reports that +> rely on untrusted input being passed to the function or command +> line tool will be rejected. +> +> **It is your responsibility as a user to never pass untrusted +> user input to this module, or your system can be destroyed or +> compromised.** + +## Major Changes + +### v5 to v6 + +- Require node `20` or `>=22` +- Add `--version` to CLI + +### v4 to v5 + +- There is no default export anymore. Import the functions directly + using, e.g., `import { rimrafSync } from 'rimraf'`. + +### v3 to v4 + +- The function returns a `Promise` instead of taking a callback. +- Globbing requires the `--glob` CLI option or `glob` option property + to be set. (Removed in 4.0 and 4.1, opt-in support added in 4.2.) +- Functions take arrays of paths, as well as a single path. +- Native implementation used by default when available, except on + Windows, where this implementation is faster and more reliable. +- New implementation on Windows, falling back to "move then + remove" strategy when exponential backoff for `EBUSY` fails to + resolve the situation. +- Simplified implementation on POSIX, since the Windows + affordances are not necessary there. +- As of 4.3, return/resolve value is boolean instead of undefined. + +## API + +Hybrid module, load either with `import` or `require()`. + +```js +// 'rimraf' export is the one you probably want, but other +// strategies exported as well. +import { rimraf, rimrafSync, native, nativeSync } from 'rimraf' +// or +const { rimraf, rimrafSync, native, nativeSync } = require('rimraf') +``` + +All removal functions return a boolean indicating that all +entries were successfully removed. + +The only case in which this will not return `true` is if +something was omitted from the removal via a `filter` option. + +### `rimraf(f, [opts]) -> Promise` + +This first parameter is a path or array of paths. The second +argument is an options object. + +Options: + +- `preserveRoot`: If set to boolean `false`, then allow the + recursive removal of the root directory. Otherwise, this is + not allowed. +- `tmp`: Windows only. Temp folder to place files and + folders for the "move then remove" fallback. Must be on the + same physical device as the path being deleted. Defaults to + `os.tmpdir()` when that is on the same drive letter as the path + being deleted, or `${drive}:\temp` if present, or `${drive}:\` + if not. +- `maxRetries`: Windows and Native only. Maximum number of + retry attempts in case of `EBUSY`, `EMFILE`, and `ENFILE` + errors. Default `10` for Windows implementation, `0` for Native + implementation. +- `backoff`: Windows only. Rate of exponential backoff for async + removal in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. + Should be a number greater than 1. Default `1.2` +- `maxBackoff`: Windows only. Maximum total backoff time in ms to + attempt asynchronous retries in case of `EBUSY`, `EMFILE`, and + `ENFILE` errors. Default `200`. With the default `1.2` backoff + rate, this results in 14 retries, with the final retry being + delayed 33ms. +- `retryDelay`: Native only. Time to wait between retries, using + linear backoff. Default `100`. +- `signal` Pass in an AbortSignal to cancel the directory + removal. This is useful when removing large folder structures, + if you'd like to limit the time spent. + + Using a `signal` option prevents the use of Node's built-in + `fs.rm` because that implementation does not support abort + signals. + +- `glob` Boolean flag to treat path as glob pattern, or an object + specifying [`glob` options](https://github.com/isaacs/node-glob). +- `filter` Method that returns a boolean indicating whether that + path should be deleted. With async `rimraf` methods, this may + return a Promise that resolves to a boolean. (Since Promises + are truthy, returning a Promise from a sync filter is the same + as just not filtering anything.) + + The first argument to the filter is the path string. The + second argument is either a `Dirent` or `Stats` object for that + path. (The first path explored will be a `Stats`, the rest + will be `Dirent`.) + + If a filter method is provided, it will _only_ remove entries + if the filter returns (or resolves to) a truthy value. Omitting + a directory will still allow its children to be removed, unless + they are also filtered out, but any parents of a filtered entry + will not be removed, since the directory will not be empty in + that case. + + Using a filter method prevents the use of Node's built-in + `fs.rm` because that implementation does not support filtering. + +Any other options are provided to the native Node.js `fs.rm` implementation +when that is used. + +This will attempt to choose the best implementation, based on the Node.js +version and `process.platform`. To force a specific implementation, use +one of the other functions provided. + +### `rimraf.sync(f, [opts])`
`rimraf.rimrafSync(f, [opts])` + +Synchronous form of `rimraf()` + +Note that, unlike many file system operations, the synchronous form will +typically be significantly _slower_ than the async form, because recursive +deletion is extremely parallelizable. + +### `rimraf.native(f, [opts])` + +Uses the built-in `fs.rm` implementation that Node.js provides. This is +used by default on Node.js versions greater than or equal to `14.14.0`. + +### `rimraf.native.sync(f, [opts])`
`rimraf.nativeSync(f, [opts])` + +Synchronous form of `rimraf.native` + +### `rimraf.manual(f, [opts])` + +Use the JavaScript implementation appropriate for your operating system. + +### `rimraf.manual.sync(f, [opts])`
`rimraf.manualSync(f, opts)` + +Synchronous form of `rimraf.manual()` + +### `rimraf.windows(f, [opts])` + +JavaScript implementation of file removal appropriate for Windows +platforms. Works around `unlink` and `rmdir` not being atomic +operations, and `EPERM` when deleting files with certain +permission modes. + +First deletes all non-directory files within the tree, and then +removes all directories, which should ideally be empty by that +time. When an `ENOTEMPTY` is raised in the second pass, falls +back to the `rimraf.moveRemove` strategy as needed. + +### `rimraf.windows.sync(path, [opts])`
`rimraf.windowsSync(path, [opts])` + +Synchronous form of `rimraf.windows()` + +### `rimraf.moveRemove(path, [opts])` + +Moves all files and folders to the parent directory of `path` +with a temporary filename prior to attempting to remove them. + +Note that, in cases where the operation fails, this _may_ leave +files lying around in the parent directory with names like +`.file-basename.txt.0.123412341`. Until the Windows kernel +provides a way to perform atomic `unlink` and `rmdir` operations, +this is, unfortunately, unavoidable. + +To move files to a different temporary directory other than the +parent, provide `opts.tmp`. Note that this _must_ be on the same +physical device as the folder being deleted, or else the +operation will fail. + +This is the slowest strategy, but most reliable on Windows +platforms. Used as a last-ditch fallback by `rimraf.windows()`. + +### `rimraf.moveRemove.sync(path, [opts])`
`rimraf.moveRemoveSync(path, [opts])` + +Synchronous form of `rimraf.moveRemove()` + +### Command Line Interface + +``` +rimraf version 6.0.1 + +Usage: rimraf [ ...] +Deletes all files and folders at "path", recursively. + +Options: + -- Treat all subsequent arguments as paths + -h --help Display this usage info + --version Display version + --preserve-root Do not remove '/' recursively (default) + --no-preserve-root Do not treat '/' specially + -G --no-glob Treat arguments as literal paths, not globs (default) + -g --glob Treat arguments as glob patterns + -v --verbose Be verbose when deleting files, showing them as + they are removed. Not compatible with --impl=native + -V --no-verbose Be silent when deleting files, showing nothing as + they are removed (default) + -i --interactive Ask for confirmation before deleting anything + Not compatible with --impl=native + -I --no-interactive Do not ask for confirmation before deleting + + --impl= Specify the implementation to use: + rimraf: choose the best option (default) + native: the built-in implementation in Node.js + manual: the platform-specific JS implementation + posix: the Posix JS implementation + windows: the Windows JS implementation (falls back to + move-remove on ENOTEMPTY) + move-remove: a slow reliable Windows fallback + +Implementation-specific options: + --tmp= Temp file folder for 'move-remove' implementation + --max-retries= maxRetries for 'native' and 'windows' implementations + --retry-delay= retryDelay for 'native' implementation, default 100 + --backoff= Exponential backoff factor for retries (default: 1.2) +``` + +## mkdirp + +If you need to _create_ a directory recursively, check out +[mkdirp](https://github.com/isaacs/node-mkdirp). diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts new file mode 100644 index 0000000..a68e925 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts @@ -0,0 +1,3 @@ +export declare const defaultTmp: (path: string) => Promise; +export declare const defaultTmpSync: (path: string) => string; +//# sourceMappingURL=default-tmp.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map new file mode 100644 index 0000000..e3200d4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"default-tmp.d.ts","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAiEA,eAAO,MAAM,UAAU,SApCc,MAAM,oBAqCuB,CAAA;AAClE,eAAO,MAAM,cAAc,SAtBQ,MAAM,WAuBiC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js new file mode 100644 index 0000000..8061980 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultTmpSync = exports.defaultTmp = void 0; +// The default temporary folder location for use in the windows algorithm. +// It's TEMPting to use dirname(path), since that's guaranteed to be on the +// same device. However, this means that: +// rimraf(path).then(() => rimraf(dirname(path))) +// will often fail with EBUSY, because the parent dir contains +// marked-for-deletion directory entries (which do not show up in readdir). +// The approach here is to use os.tmpdir() if it's on the same drive letter, +// or resolve(path, '\\temp') if it exists, or the root of the drive if not. +// On Posix (not that you'd be likely to use the windows algorithm there), +// it uses os.tmpdir() always. +const os_1 = require("os"); +const path_1 = require("path"); +const fs_js_1 = require("./fs.js"); +const { stat } = fs_js_1.promises; +const isDirSync = (path) => { + try { + return (0, fs_js_1.statSync)(path).isDirectory(); + } + catch { + return false; + } +}; +const isDir = (path) => stat(path).then(st => st.isDirectory(), () => false); +const win32DefaultTmp = async (path) => { + const { root } = (0, path_1.parse)(path); + const tmp = (0, os_1.tmpdir)(); + const { root: tmpRoot } = (0, path_1.parse)(tmp); + if (root.toLowerCase() === tmpRoot.toLowerCase()) { + return tmp; + } + const driveTmp = (0, path_1.resolve)(root, '/temp'); + if (await isDir(driveTmp)) { + return driveTmp; + } + return root; +}; +const win32DefaultTmpSync = (path) => { + const { root } = (0, path_1.parse)(path); + const tmp = (0, os_1.tmpdir)(); + const { root: tmpRoot } = (0, path_1.parse)(tmp); + if (root.toLowerCase() === tmpRoot.toLowerCase()) { + return tmp; + } + const driveTmp = (0, path_1.resolve)(root, '/temp'); + if (isDirSync(driveTmp)) { + return driveTmp; + } + return root; +}; +// eslint-disable-next-line @typescript-eslint/require-await +const posixDefaultTmp = async () => (0, os_1.tmpdir)(); +const posixDefaultTmpSync = () => (0, os_1.tmpdir)(); +exports.defaultTmp = process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp; +exports.defaultTmpSync = process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync; +//# sourceMappingURL=default-tmp.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map new file mode 100644 index 0000000..5681ff8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map @@ -0,0 +1 @@ +{"version":3,"file":"default-tmp.js","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0CAA0C;AAC1C,iDAAiD;AACjD,8DAA8D;AAC9D,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,8BAA8B;AAC9B,2BAA2B;AAC3B,+BAAqC;AACrC,mCAA4C;AAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAQ,CAAA;AAEzB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,OAAO,IAAA,gBAAQ,EAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACb,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EACtB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAA;AAEH,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,IAAA,WAAM,GAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAA,YAAK,EAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,IAAA,WAAM,GAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAA,YAAK,EAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC,IAAA,WAAM,GAAE,CAAA;AAC5C,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,IAAA,WAAM,GAAE,CAAA;AAE7B,QAAA,UAAU,GACrB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAA;AACrD,QAAA,cAAc,GACzB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAA","sourcesContent":["// The default temporary folder location for use in the windows algorithm.\n// It's TEMPting to use dirname(path), since that's guaranteed to be on the\n// same device. However, this means that:\n// rimraf(path).then(() => rimraf(dirname(path)))\n// will often fail with EBUSY, because the parent dir contains\n// marked-for-deletion directory entries (which do not show up in readdir).\n// The approach here is to use os.tmpdir() if it's on the same drive letter,\n// or resolve(path, '\\\\temp') if it exists, or the root of the drive if not.\n// On Posix (not that you'd be likely to use the windows algorithm there),\n// it uses os.tmpdir() always.\nimport { tmpdir } from 'os'\nimport { parse, resolve } from 'path'\nimport { promises, statSync } from './fs.js'\nconst { stat } = promises\n\nconst isDirSync = (path: string) => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n\nconst isDir = (path: string) =>\n stat(path).then(\n st => st.isDirectory(),\n () => false,\n )\n\nconst win32DefaultTmp = async (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (await isDir(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\nconst win32DefaultTmpSync = (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (isDirSync(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await\nconst posixDefaultTmp = async () => tmpdir()\nconst posixDefaultTmpSync = () => tmpdir()\n\nexport const defaultTmp =\n process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp\nexport const defaultTmpSync =\n process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts new file mode 100644 index 0000000..5ba53c8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts @@ -0,0 +1,6 @@ +export declare const isFsError: (o: unknown) => o is NodeJS.ErrnoException & { + code: string; + path: string; +}; +export declare const errorCode: (er: unknown) => unknown; +//# sourceMappingURL=error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map new file mode 100644 index 0000000..6671be4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,GACpB,GAAG,OAAO,KACT,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACkD,CAAA;AAEhE,eAAO,MAAM,SAAS,GAAI,IAAI,OAAO,YACmB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.js b/apps/extension/node_modules/rimraf/dist/commonjs/error.js new file mode 100644 index 0000000..3a96451 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/error.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.errorCode = exports.isFsError = void 0; +const isRecord = (o) => !!o && typeof o === 'object'; +const hasString = (o, key) => key in o && typeof o[key] === 'string'; +const isFsError = (o) => isRecord(o) && hasString(o, 'code') && hasString(o, 'path'); +exports.isFsError = isFsError; +const errorCode = (er) => isRecord(er) && hasString(er, 'code') ? er.code : null; +exports.errorCode = errorCode; +//# sourceMappingURL=error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map new file mode 100644 index 0000000..4b7ee21 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAC5D,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAA;AAE9B,MAAM,SAAS,GAAG,CAAC,CAA0B,EAAE,GAAW,EAAE,EAAE,CAC5D,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAA;AAEjC,MAAM,SAAS,GAAG,CACvB,CAAU,EAIV,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AALnD,QAAA,SAAS,aAK0C;AAEzD,MAAM,SAAS,GAAG,CAAC,EAAW,EAAE,EAAE,CACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AAD3C,QAAA,SAAS,aACkC","sourcesContent":["const isRecord = (o: unknown): o is Record =>\n !!o && typeof o === 'object'\n\nconst hasString = (o: Record, key: string) =>\n key in o && typeof o[key] === 'string'\n\nexport const isFsError = (\n o: unknown,\n): o is NodeJS.ErrnoException & {\n code: string\n path: string\n} => isRecord(o) && hasString(o, 'code') && hasString(o, 'path')\n\nexport const errorCode = (er: unknown) =>\n isRecord(er) && hasString(er, 'code') ? er.code : null\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts new file mode 100644 index 0000000..4b329ef --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts @@ -0,0 +1,3 @@ +export declare const fixEPERM: (fn: (path: string) => Promise) => (path: string) => Promise; +export declare const fixEPERMSync: (fn: (path: string) => unknown) => (path: string) => void; +//# sourceMappingURL=fix-eperm.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map new file mode 100644 index 0000000..498e950 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fix-eperm.d.ts","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,GAClB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAChC,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBjC,CAAA;AAEH,eAAO,MAAM,YAAY,GACtB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,MAC7B,MAAM,MAAM,KAAG,IAYf,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js new file mode 100644 index 0000000..1a60f8d --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fixEPERMSync = exports.fixEPERM = void 0; +const error_js_1 = require("./error.js"); +const fs_js_1 = require("./fs.js"); +const ignore_enoent_js_1 = require("./ignore-enoent.js"); +const { chmod } = fs_js_1.promises; +const fixEPERM = (fn) => async (path) => { + try { + return void (await (0, ignore_enoent_js_1.ignoreENOENT)(fn(path))); + } + catch (er) { + if ((0, error_js_1.errorCode)(er) === 'EPERM') { + if (!(await (0, ignore_enoent_js_1.ignoreENOENT)(chmod(path, 0o666).then(() => true), er))) { + return; + } + return void (await fn(path)); + } + throw er; + } +}; +exports.fixEPERM = fixEPERM; +const fixEPERMSync = (fn) => (path) => { + try { + return void (0, ignore_enoent_js_1.ignoreENOENTSync)(() => fn(path)); + } + catch (er) { + if ((0, error_js_1.errorCode)(er) === 'EPERM') { + if (!(0, ignore_enoent_js_1.ignoreENOENTSync)(() => ((0, fs_js_1.chmodSync)(path, 0o666), true), er)) { + return; + } + return void fn(path); + } + throw er; + } +}; +exports.fixEPERMSync = fixEPERMSync; +//# sourceMappingURL=fix-eperm.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map new file mode 100644 index 0000000..17a4e56 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fix-eperm.js","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,mCAA6C;AAC7C,yDAAmE;AACnE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAQ,CAAA;AAEnB,MAAM,QAAQ,GACnB,CAAC,EAAsC,EAAE,EAAE,CAC3C,KAAK,EAAE,IAAY,EAAiB,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,IAAA,+BAAY,EAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IACE,CAAC,CAAC,MAAM,IAAA,+BAAY,EAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACnC,EAAE,CACH,CAAC,EACF,CAAC;gBACD,OAAM;YACR,CAAC;YACD,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9B,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAnBU,QAAA,QAAQ,YAmBlB;AAEI,MAAM,YAAY,GACvB,CAAC,EAA6B,EAAE,EAAE,CAClC,CAAC,IAAY,EAAQ,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,KAAK,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,CAAC,IAAA,iBAAS,EAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAdU,QAAA,YAAY,gBActB","sourcesContent":["import { errorCode } from './error.js'\nimport { chmodSync, promises } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nconst { chmod } = promises\n\nexport const fixEPERM =\n (fn: (path: string) => Promise) =>\n async (path: string): Promise => {\n try {\n return void (await ignoreENOENT(fn(path)))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (\n !(await ignoreENOENT(\n chmod(path, 0o666).then(() => true),\n er,\n ))\n ) {\n return\n }\n return void (await fn(path))\n }\n throw er\n }\n }\n\nexport const fixEPERMSync =\n (fn: (path: string) => unknown) =>\n (path: string): void => {\n try {\n return void ignoreENOENTSync(() => fn(path))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) {\n return\n }\n return void fn(path)\n }\n throw er\n }\n }\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts new file mode 100644 index 0000000..4e6fbab --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts @@ -0,0 +1,16 @@ +import fs, { Dirent } from 'fs'; +import fsPromises from 'fs/promises'; +export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; +export declare const readdirSync: (path: fs.PathLike) => Dirent[]; +export declare const promises: { + chmod: typeof fsPromises.chmod; + mkdir: typeof fsPromises.mkdir; + readdir: (path: fs.PathLike) => Promise[]>; + rename: typeof fsPromises.rename; + rm: typeof fsPromises.rm; + rmdir: typeof fsPromises.rmdir; + stat: typeof fsPromises.stat; + lstat: typeof fsPromises.lstat; + unlink: typeof fsPromises.unlink; +}; +//# sourceMappingURL=fs.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map new file mode 100644 index 0000000..ed3c8db --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAyB,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAKpC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,QAAQ,KAAG,MAAM,EACf,CAAA;AAEvC,eAAO,MAAM,QAAQ;;;oBAGH,EAAE,CAAC,QAAQ;;;;;;;CAQ5B,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js new file mode 100644 index 0000000..3736587 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js @@ -0,0 +1,33 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.promises = exports.readdirSync = exports.unlinkSync = exports.lstatSync = exports.statSync = exports.rmSync = exports.rmdirSync = exports.renameSync = exports.mkdirSync = exports.chmodSync = void 0; +const fs_1 = require("fs"); +const promises_1 = __importDefault(require("fs/promises")); +// sync ones just take the sync version from node +// readdir forces withFileTypes: true +var fs_2 = require("fs"); +Object.defineProperty(exports, "chmodSync", { enumerable: true, get: function () { return fs_2.chmodSync; } }); +Object.defineProperty(exports, "mkdirSync", { enumerable: true, get: function () { return fs_2.mkdirSync; } }); +Object.defineProperty(exports, "renameSync", { enumerable: true, get: function () { return fs_2.renameSync; } }); +Object.defineProperty(exports, "rmdirSync", { enumerable: true, get: function () { return fs_2.rmdirSync; } }); +Object.defineProperty(exports, "rmSync", { enumerable: true, get: function () { return fs_2.rmSync; } }); +Object.defineProperty(exports, "statSync", { enumerable: true, get: function () { return fs_2.statSync; } }); +Object.defineProperty(exports, "lstatSync", { enumerable: true, get: function () { return fs_2.lstatSync; } }); +Object.defineProperty(exports, "unlinkSync", { enumerable: true, get: function () { return fs_2.unlinkSync; } }); +const readdirSync = (path) => (0, fs_1.readdirSync)(path, { withFileTypes: true }); +exports.readdirSync = readdirSync; +exports.promises = { + chmod: promises_1.default.chmod, + mkdir: promises_1.default.mkdir, + readdir: (path) => promises_1.default.readdir(path, { withFileTypes: true }), + rename: promises_1.default.rename, + rm: promises_1.default.rm, + rmdir: promises_1.default.rmdir, + stat: promises_1.default.stat, + lstat: promises_1.default.lstat, + unlink: promises_1.default.unlink, +}; +//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map new file mode 100644 index 0000000..1cc3b0f --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAsD;AACtD,2DAAoC;AAEpC,iDAAiD;AACjD,qCAAqC;AAErC,yBASW;AART,+FAAA,SAAS,OAAA;AACT,+FAAA,SAAS,OAAA;AACT,gGAAA,UAAU,OAAA;AACV,+FAAA,SAAS,OAAA;AACT,4FAAA,MAAM,OAAA;AACN,8FAAA,QAAQ,OAAA;AACR,+FAAA,SAAS,OAAA;AACT,gGAAA,UAAU,OAAA;AAGL,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAY,EAAE,CACzD,IAAA,gBAAM,EAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;AAD1B,QAAA,WAAW,eACe;AAE1B,QAAA,QAAQ,GAAG;IACtB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,OAAO,EAAE,CAAC,IAAiB,EAAE,EAAE,CAC7B,kBAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,EAAE,kBAAU,CAAC,MAAM;IACzB,EAAE,EAAE,kBAAU,CAAC,EAAE;IACjB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,IAAI,EAAE,kBAAU,CAAC,IAAI;IACrB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,MAAM,EAAE,kBAAU,CAAC,MAAM;CAC1B,CAAA","sourcesContent":["import fs, { Dirent, readdirSync as rdSync } from 'fs'\nimport fsPromises from 'fs/promises'\n\n// sync ones just take the sync version from node\n// readdir forces withFileTypes: true\n\nexport {\n chmodSync,\n mkdirSync,\n renameSync,\n rmdirSync,\n rmSync,\n statSync,\n lstatSync,\n unlinkSync,\n} from 'fs'\n\nexport const readdirSync = (path: fs.PathLike): Dirent[] =>\n rdSync(path, { withFileTypes: true })\n\nexport const promises = {\n chmod: fsPromises.chmod,\n mkdir: fsPromises.mkdir,\n readdir: (path: fs.PathLike) =>\n fsPromises.readdir(path, { withFileTypes: true }),\n rename: fsPromises.rename,\n rm: fsPromises.rm,\n rmdir: fsPromises.rmdir,\n stat: fsPromises.stat,\n lstat: fsPromises.lstat,\n unlink: fsPromises.unlink,\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts new file mode 100644 index 0000000..e56d721 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts @@ -0,0 +1,3 @@ +export declare const ignoreENOENT: (p: Promise, rethrow?: unknown) => Promise; +export declare const ignoreENOENTSync: (fn: () => T, rethrow?: unknown) => T | undefined; +//# sourceMappingURL=ignore-enoent.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map new file mode 100644 index 0000000..14097fc --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ignore-enoent.d.ts","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,GAAU,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,OAAO,sBAMlE,CAAA;AAEJ,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,UAAU,OAAO,kBASjE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js new file mode 100644 index 0000000..f37c380 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ignoreENOENTSync = exports.ignoreENOENT = void 0; +const error_js_1 = require("./error.js"); +const ignoreENOENT = async (p, rethrow) => p.catch(er => { + if ((0, error_js_1.errorCode)(er) === 'ENOENT') { + return; + } + throw rethrow ?? er; +}); +exports.ignoreENOENT = ignoreENOENT; +const ignoreENOENTSync = (fn, rethrow) => { + try { + return fn(); + } + catch (er) { + if ((0, error_js_1.errorCode)(er) === 'ENOENT') { + return; + } + throw rethrow ?? er; + } +}; +exports.ignoreENOENTSync = ignoreENOENTSync; +//# sourceMappingURL=ignore-enoent.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map new file mode 100644 index 0000000..8877bde --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ignore-enoent.js","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAE/B,MAAM,YAAY,GAAG,KAAK,EAAK,CAAa,EAAE,OAAiB,EAAE,EAAE,CACxE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;IACX,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAM;IACR,CAAC;IACD,MAAM,OAAO,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA;AANS,QAAA,YAAY,gBAMrB;AAEG,MAAM,gBAAgB,GAAG,CAAI,EAAW,EAAE,OAAiB,EAAE,EAAE;IACpE,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,OAAO,IAAI,EAAE,CAAA;IACrB,CAAC;AACH,CAAC,CAAA;AATY,QAAA,gBAAgB,oBAS5B","sourcesContent":["import { errorCode } from './error.js'\n\nexport const ignoreENOENT = async (p: Promise, rethrow?: unknown) =>\n p.catch(er => {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n })\n\nexport const ignoreENOENTSync = (fn: () => T, rethrow?: unknown) => {\n try {\n return fn()\n } catch (er) {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts new file mode 100644 index 0000000..9ec4a12 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts @@ -0,0 +1,50 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './opt-arg.js'; +export { assertRimrafOptions, isRimrafOptions, type RimrafAsyncOptions, type RimrafOptions, type RimrafSyncOptions, } from './opt-arg.js'; +export declare const nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const rimraf: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + rimraf: (path: string | string[], opt?: RimrafAsyncOptions) => Promise; + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map new file mode 100644 index 0000000..e69bc3c --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.js b/apps/extension/node_modules/rimraf/dist/commonjs/index.js new file mode 100644 index 0000000..be36db6 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/index.js @@ -0,0 +1,84 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimraf = exports.sync = exports.rimrafSync = exports.moveRemove = exports.moveRemoveSync = exports.posix = exports.posixSync = exports.windows = exports.windowsSync = exports.manual = exports.manualSync = exports.native = exports.nativeSync = exports.isRimrafOptions = exports.assertRimrafOptions = void 0; +const glob_1 = require("glob"); +const opt_arg_js_1 = require("./opt-arg.js"); +const path_arg_js_1 = __importDefault(require("./path-arg.js")); +const rimraf_manual_js_1 = require("./rimraf-manual.js"); +const rimraf_move_remove_js_1 = require("./rimraf-move-remove.js"); +const rimraf_native_js_1 = require("./rimraf-native.js"); +const rimraf_posix_js_1 = require("./rimraf-posix.js"); +const rimraf_windows_js_1 = require("./rimraf-windows.js"); +const use_native_js_1 = require("./use-native.js"); +var opt_arg_js_2 = require("./opt-arg.js"); +Object.defineProperty(exports, "assertRimrafOptions", { enumerable: true, get: function () { return opt_arg_js_2.assertRimrafOptions; } }); +Object.defineProperty(exports, "isRimrafOptions", { enumerable: true, get: function () { return opt_arg_js_2.isRimrafOptions; } }); +const wrap = (fn) => async (path, opt) => { + const options = (0, opt_arg_js_1.optArg)(opt); + if (options.glob) { + path = await (0, glob_1.glob)(path, options.glob); + } + if (Array.isArray(path)) { + return !!(await Promise.all(path.map(p => fn((0, path_arg_js_1.default)(p, options), options)))).reduce((a, b) => a && b, true); + } + else { + return !!(await fn((0, path_arg_js_1.default)(path, options), options)); + } +}; +const wrapSync = (fn) => (path, opt) => { + const options = (0, opt_arg_js_1.optArgSync)(opt); + if (options.glob) { + path = (0, glob_1.globSync)(path, options.glob); + } + if (Array.isArray(path)) { + return !!path + .map(p => fn((0, path_arg_js_1.default)(p, options), options)) + .reduce((a, b) => a && b, true); + } + else { + return !!fn((0, path_arg_js_1.default)(path, options), options); + } +}; +exports.nativeSync = wrapSync(rimraf_native_js_1.rimrafNativeSync); +exports.native = Object.assign(wrap(rimraf_native_js_1.rimrafNative), { + sync: exports.nativeSync, +}); +exports.manualSync = wrapSync(rimraf_manual_js_1.rimrafManualSync); +exports.manual = Object.assign(wrap(rimraf_manual_js_1.rimrafManual), { + sync: exports.manualSync, +}); +exports.windowsSync = wrapSync(rimraf_windows_js_1.rimrafWindowsSync); +exports.windows = Object.assign(wrap(rimraf_windows_js_1.rimrafWindows), { + sync: exports.windowsSync, +}); +exports.posixSync = wrapSync(rimraf_posix_js_1.rimrafPosixSync); +exports.posix = Object.assign(wrap(rimraf_posix_js_1.rimrafPosix), { sync: exports.posixSync }); +exports.moveRemoveSync = wrapSync(rimraf_move_remove_js_1.rimrafMoveRemoveSync); +exports.moveRemove = Object.assign(wrap(rimraf_move_remove_js_1.rimrafMoveRemove), { + sync: exports.moveRemoveSync, +}); +exports.rimrafSync = wrapSync((path, opt) => (0, use_native_js_1.useNativeSync)(opt) ? + (0, rimraf_native_js_1.rimrafNativeSync)(path, opt) + : (0, rimraf_manual_js_1.rimrafManualSync)(path, opt)); +exports.sync = exports.rimrafSync; +const rimraf_ = wrap((path, opt) => (0, use_native_js_1.useNative)(opt) ? (0, rimraf_native_js_1.rimrafNative)(path, opt) : (0, rimraf_manual_js_1.rimrafManual)(path, opt)); +exports.rimraf = Object.assign(rimraf_, { + rimraf: rimraf_, + sync: exports.rimrafSync, + rimrafSync: exports.rimrafSync, + manual: exports.manual, + manualSync: exports.manualSync, + native: exports.native, + nativeSync: exports.nativeSync, + posix: exports.posix, + posixSync: exports.posixSync, + windows: exports.windows, + windowsSync: exports.windowsSync, + moveRemove: exports.moveRemove, + moveRemoveSync: exports.moveRemoveSync, +}); +exports.rimraf.rimraf = exports.rimraf; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map new file mode 100644 index 0000000..6624e13 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { glob, globSync } from 'glob'\nimport {\n optArg,\n optArgSync,\n RimrafAsyncOptions,\n RimrafSyncOptions,\n} from './opt-arg.js'\nimport pathArg from './path-arg.js'\nimport { rimrafManual, rimrafManualSync } from './rimraf-manual.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { rimrafNative, rimrafNativeSync } from './rimraf-native.js'\nimport { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\nimport { useNative, useNativeSync } from './use-native.js'\n\nexport {\n assertRimrafOptions,\n isRimrafOptions,\n type RimrafAsyncOptions,\n type RimrafOptions,\n type RimrafSyncOptions,\n} from './opt-arg.js'\n\nconst wrap =\n (fn: (p: string, o: RimrafAsyncOptions) => Promise) =>\n async (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ): Promise => {\n const options = optArg(opt)\n if (options.glob) {\n path = await glob(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!(\n await Promise.all(path.map(p => fn(pathArg(p, options), options)))\n ).reduce((a, b) => a && b, true)\n } else {\n return !!(await fn(pathArg(path, options), options))\n }\n }\n\nconst wrapSync =\n (fn: (p: string, o: RimrafSyncOptions) => boolean) =>\n (path: string | string[], opt?: RimrafSyncOptions): boolean => {\n const options = optArgSync(opt)\n if (options.glob) {\n path = globSync(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!path\n .map(p => fn(pathArg(p, options), options))\n .reduce((a, b) => a && b, true)\n } else {\n return !!fn(pathArg(path, options), options)\n }\n }\n\nexport const nativeSync = wrapSync(rimrafNativeSync)\nexport const native = Object.assign(wrap(rimrafNative), {\n sync: nativeSync,\n})\n\nexport const manualSync = wrapSync(rimrafManualSync)\nexport const manual = Object.assign(wrap(rimrafManual), {\n sync: manualSync,\n})\n\nexport const windowsSync = wrapSync(rimrafWindowsSync)\nexport const windows = Object.assign(wrap(rimrafWindows), {\n sync: windowsSync,\n})\n\nexport const posixSync = wrapSync(rimrafPosixSync)\nexport const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync })\n\nexport const moveRemoveSync = wrapSync(rimrafMoveRemoveSync)\nexport const moveRemove = Object.assign(wrap(rimrafMoveRemove), {\n sync: moveRemoveSync,\n})\n\nexport const rimrafSync = wrapSync((path, opt) =>\n useNativeSync(opt) ?\n rimrafNativeSync(path, opt)\n : rimrafManualSync(path, opt),\n)\nexport const sync = rimrafSync\n\nconst rimraf_ = wrap((path, opt) =>\n useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt),\n)\nexport const rimraf = Object.assign(rimraf_, {\n rimraf: rimraf_,\n sync: rimrafSync,\n rimrafSync: rimrafSync,\n manual,\n manualSync,\n native,\n nativeSync,\n posix,\n posixSync,\n windows,\n windowsSync,\n moveRemove,\n moveRemoveSync,\n})\nrimraf.rimraf = rimraf\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts new file mode 100644 index 0000000..c869d4a --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts @@ -0,0 +1,34 @@ +import { Dirent, Stats } from 'fs'; +import { GlobOptions } from 'glob'; +export declare const isRimrafOptions: (o: any) => o is RimrafOptions; +export declare const assertRimrafOptions: (o: any) => void; +export interface RimrafAsyncOptions { + preserveRoot?: boolean; + tmp?: string; + maxRetries?: number; + retryDelay?: number; + backoff?: number; + maxBackoff?: number; + signal?: AbortSignal; + glob?: boolean | GlobOptions; + filter?: ((path: string, ent: Dirent | Stats) => boolean) | ((path: string, ent: Dirent | Stats) => Promise); +} +export interface RimrafSyncOptions extends RimrafAsyncOptions { + filter?: (path: string, ent: Dirent | Stats) => boolean; +} +export type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions; +export declare const optArg: (opt?: RimrafAsyncOptions) => (RimrafAsyncOptions & { + glob: GlobOptions & { + withFileTypes: false; + }; +}) | (RimrafAsyncOptions & { + glob: undefined; +}); +export declare const optArgSync: (opt?: RimrafSyncOptions) => (RimrafSyncOptions & { + glob: GlobOptions & { + withFileTypes: false; + }; +}) | (RimrafSyncOptions & { + glob: undefined; +}); +//# sourceMappingURL=opt-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map new file mode 100644 index 0000000..93e1f92 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"opt-arg.d.ts","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAKlC,eAAO,MAAM,eAAe,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,aAWX,CAAA;AAEnC,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAM7C,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;IAC5B,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,GAChD,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAA;CACxD;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAqClE,eAAO,MAAM,MAAM,GAAI,MAAK,kBAAuB;UA/BvC,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA6B0C,CAAA;AACpE,eAAO,MAAM,UAAU,GAAI,MAAK,iBAAsB;UAhC1C,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA8B6C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js new file mode 100644 index 0000000..70538b5 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.optArgSync = exports.optArg = exports.assertRimrafOptions = exports.isRimrafOptions = void 0; +const typeOrUndef = (val, t) => typeof val === 'undefined' || typeof val === t; +const isRimrafOptions = (o) => !!o && + typeof o === 'object' && + typeOrUndef(o.preserveRoot, 'boolean') && + typeOrUndef(o.tmp, 'string') && + typeOrUndef(o.maxRetries, 'number') && + typeOrUndef(o.retryDelay, 'number') && + typeOrUndef(o.backoff, 'number') && + typeOrUndef(o.maxBackoff, 'number') && + (typeOrUndef(o.glob, 'boolean') || + (o.glob && typeof o.glob === 'object')) && + typeOrUndef(o.filter, 'function'); +exports.isRimrafOptions = isRimrafOptions; +const assertRimrafOptions = (o) => { + if (!(0, exports.isRimrafOptions)(o)) { + throw new Error('invalid rimraf options'); + } +}; +exports.assertRimrafOptions = assertRimrafOptions; +const optArgT = (opt) => { + (0, exports.assertRimrafOptions)(opt); + const { glob, ...options } = opt; + if (!glob) { + return options; + } + const globOpt = glob === true ? + opt.signal ? + { signal: opt.signal } + : {} + : opt.signal ? + { + signal: opt.signal, + ...glob, + } + : glob; + return { + ...options, + glob: { + ...globOpt, + // always get absolute paths from glob, to ensure + // that we are referencing the correct thing. + absolute: true, + withFileTypes: false, + }, + }; +}; +const optArg = (opt = {}) => optArgT(opt); +exports.optArg = optArg; +const optArgSync = (opt = {}) => optArgT(opt); +exports.optArgSync = optArgSync; +//# sourceMappingURL=opt-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map new file mode 100644 index 0000000..9d97431 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map @@ -0,0 +1 @@ +{"version":3,"file":"opt-arg.js","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":";;;AAGA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,CAAS,EAAE,EAAE,CAC1C,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,KAAK,CAAC,CAAA;AAEzC,MAAM,eAAe,GAAG,CAAC,CAAM,EAAsB,EAAE,CAC5D,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,QAAQ;IACrB,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC;IACtC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IAC5B,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC;QAC7B,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAXtB,QAAA,eAAe,mBAWO;AAE5B,MAAM,mBAAmB,GAAqB,CACnD,CAAM,EACsB,EAAE;IAC9B,IAAI,CAAC,IAAA,uBAAe,EAAC,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC,CAAA;AANY,QAAA,mBAAmB,uBAM/B;AAsBD,MAAM,OAAO,GAAG,CACd,GAAM,EAKsB,EAAE;IAC9B,IAAA,2BAAmB,EAAC,GAAG,CAAC,CAAA;IACxB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAA;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,OAAkC,CAAA;IAC3C,CAAC;IACD,MAAM,OAAO,GACX,IAAI,KAAK,IAAI,CAAC,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,CAAC;YACV,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACxB,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACZ;gBACE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,IAAI;aACR;YACH,CAAC,CAAC,IAAI,CAAA;IACR,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE;YACJ,GAAG,OAAO;YACV,iDAAiD;YACjD,6CAA6C;YAC7C,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,KAAK;SACrB;KACsD,CAAA;AAC3D,CAAC,CAAA;AAEM,MAAM,MAAM,GAAG,CAAC,MAA0B,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAAvD,QAAA,MAAM,UAAiD;AAC7D,MAAM,UAAU,GAAG,CAAC,MAAyB,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAA1D,QAAA,UAAU,cAAgD","sourcesContent":["import { Dirent, Stats } from 'fs'\nimport { GlobOptions } from 'glob'\n\nconst typeOrUndef = (val: any, t: string) =>\n typeof val === 'undefined' || typeof val === t\n\nexport const isRimrafOptions = (o: any): o is RimrafOptions =>\n !!o &&\n typeof o === 'object' &&\n typeOrUndef(o.preserveRoot, 'boolean') &&\n typeOrUndef(o.tmp, 'string') &&\n typeOrUndef(o.maxRetries, 'number') &&\n typeOrUndef(o.retryDelay, 'number') &&\n typeOrUndef(o.backoff, 'number') &&\n typeOrUndef(o.maxBackoff, 'number') &&\n (typeOrUndef(o.glob, 'boolean') ||\n (o.glob && typeof o.glob === 'object')) &&\n typeOrUndef(o.filter, 'function')\n\nexport const assertRimrafOptions: (o: any) => void = (\n o: any,\n): asserts o is RimrafOptions => {\n if (!isRimrafOptions(o)) {\n throw new Error('invalid rimraf options')\n }\n}\n\nexport interface RimrafAsyncOptions {\n preserveRoot?: boolean\n tmp?: string\n maxRetries?: number\n retryDelay?: number\n backoff?: number\n maxBackoff?: number\n signal?: AbortSignal\n glob?: boolean | GlobOptions\n filter?:\n | ((path: string, ent: Dirent | Stats) => boolean)\n | ((path: string, ent: Dirent | Stats) => Promise)\n}\n\nexport interface RimrafSyncOptions extends RimrafAsyncOptions {\n filter?: (path: string, ent: Dirent | Stats) => boolean\n}\n\nexport type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions\n\nconst optArgT = (\n opt: T,\n):\n | (T & {\n glob: GlobOptions & { withFileTypes: false }\n })\n | (T & { glob: undefined }) => {\n assertRimrafOptions(opt)\n const { glob, ...options } = opt\n if (!glob) {\n return options as T & { glob: undefined }\n }\n const globOpt =\n glob === true ?\n opt.signal ?\n { signal: opt.signal }\n : {}\n : opt.signal ?\n {\n signal: opt.signal,\n ...glob,\n }\n : glob\n return {\n ...options,\n glob: {\n ...globOpt,\n // always get absolute paths from glob, to ensure\n // that we are referencing the correct thing.\n absolute: true,\n withFileTypes: false,\n },\n } as T & { glob: GlobOptions & { withFileTypes: false } }\n}\n\nexport const optArg = (opt: RimrafAsyncOptions = {}) => optArgT(opt)\nexport const optArgSync = (opt: RimrafSyncOptions = {}) => optArgT(opt)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/package.json b/apps/extension/node_modules/rimraf/dist/commonjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts new file mode 100644 index 0000000..c0b7e7c --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions } from './index.js'; +declare const pathArg: (path: string, opt?: RimrafAsyncOptions) => string; +export default pathArg; +//# sourceMappingURL=path-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map new file mode 100644 index 0000000..2112460 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"path-arg.d.ts","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,QAAA,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,MAAK,kBAAuB,WAkD1D,CAAA;AAED,eAAe,OAAO,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js new file mode 100644 index 0000000..981cd7d --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = require("path"); +const util_1 = require("util"); +const pathArg = (path, opt = {}) => { + const type = typeof path; + if (type !== 'string') { + const ctor = path && type === 'object' && path.constructor; + const received = ctor && ctor.name ? `an instance of ${ctor.name}` + : type === 'object' ? (0, util_1.inspect)(path) + : `type ${type} ${path}`; + const msg = 'The "path" argument must be of type string. ' + + `Received ${received}`; + throw Object.assign(new TypeError(msg), { + path, + code: 'ERR_INVALID_ARG_TYPE', + }); + } + if (/\0/.test(path)) { + // simulate same failure that node raises + const msg = 'path must be a string without null bytes'; + throw Object.assign(new TypeError(msg), { + path, + code: 'ERR_INVALID_ARG_VALUE', + }); + } + path = (0, path_1.resolve)(path); + const { root } = (0, path_1.parse)(path); + if (path === root && opt.preserveRoot !== false) { + const msg = 'refusing to remove root directory without preserveRoot:false'; + throw Object.assign(new Error(msg), { + path, + code: 'ERR_PRESERVE_ROOT', + }); + } + if (process.platform === 'win32') { + const badWinChars = /[*|"<>?:]/; + const { root } = (0, path_1.parse)(path); + if (badWinChars.test(path.substring(root.length))) { + throw Object.assign(new Error('Illegal characters in path.'), { + path, + code: 'EINVAL', + }); + } + } + return path; +}; +exports.default = pathArg; +//# sourceMappingURL=path-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map new file mode 100644 index 0000000..a41add7 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map @@ -0,0 +1 @@ +{"version":3,"file":"path-arg.js","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":";;AAAA,+BAAqC;AACrC,+BAA8B;AAG9B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,MAA0B,EAAE,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAA;IACxB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAA;QAC1D,MAAM,QAAQ,GACZ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAA;QAC1B,MAAM,GAAG,GACP,8CAA8C;YAC9C,YAAY,QAAQ,EAAE,CAAA;QACxB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,sBAAsB;SAC7B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,yCAAyC;QACzC,MAAM,GAAG,GAAG,0CAA0C,CAAA;QACtD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAE5B,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,GAAG,GACP,8DAA8D,CAAA;QAChE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI;YACJ,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,WAAW,CAAA;QAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAE;gBAC5D,IAAI;gBACJ,IAAI,EAAE,QAAQ;aACf,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,kBAAe,OAAO,CAAA","sourcesContent":["import { parse, resolve } from 'path'\nimport { inspect } from 'util'\nimport { RimrafAsyncOptions } from './index.js'\n\nconst pathArg = (path: string, opt: RimrafAsyncOptions = {}) => {\n const type = typeof path\n if (type !== 'string') {\n const ctor = path && type === 'object' && path.constructor\n const received =\n ctor && ctor.name ? `an instance of ${ctor.name}`\n : type === 'object' ? inspect(path)\n : `type ${type} ${path}`\n const msg =\n 'The \"path\" argument must be of type string. ' +\n `Received ${received}`\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_TYPE',\n })\n }\n\n if (/\\0/.test(path)) {\n // simulate same failure that node raises\n const msg = 'path must be a string without null bytes'\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_VALUE',\n })\n }\n\n path = resolve(path)\n const { root } = parse(path)\n\n if (path === root && opt.preserveRoot !== false) {\n const msg =\n 'refusing to remove root directory without preserveRoot:false'\n throw Object.assign(new Error(msg), {\n path,\n code: 'ERR_PRESERVE_ROOT',\n })\n }\n\n if (process.platform === 'win32') {\n const badWinChars = /[*|\"<>?:]/\n const { root } = parse(path)\n if (badWinChars.test(path.substring(root.length))) {\n throw Object.assign(new Error('Illegal characters in path.'), {\n path,\n code: 'EINVAL',\n })\n }\n }\n\n return path\n}\n\nexport default pathArg\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts new file mode 100644 index 0000000..2a580cf --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts @@ -0,0 +1,3 @@ +export declare const readdirOrError: (path: string) => Promise[] | Error>; +export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent[] | Error; +//# sourceMappingURL=readdir-or-error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map new file mode 100644 index 0000000..1f91434 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"readdir-or-error.d.ts","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,wDACH,CAAA;AACxC,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,+CAM9C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js new file mode 100644 index 0000000..75330cb --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.readdirOrErrorSync = exports.readdirOrError = void 0; +// returns an array of entries if readdir() works, +// or the error that readdir() raised if not. +const fs_js_1 = require("./fs.js"); +const { readdir } = fs_js_1.promises; +const readdirOrError = (path) => readdir(path).catch(er => er); +exports.readdirOrError = readdirOrError; +const readdirOrErrorSync = (path) => { + try { + return (0, fs_js_1.readdirSync)(path); + } + catch (er) { + return er; + } +}; +exports.readdirOrErrorSync = readdirOrErrorSync; +//# sourceMappingURL=readdir-or-error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map new file mode 100644 index 0000000..4abb067 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"readdir-or-error.js","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":";;;AAAA,kDAAkD;AAClD,6CAA6C;AAC7C,mCAA+C;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAQ,CAAA;AAErB,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAW,CAAC,CAAA;AAD3B,QAAA,cAAc,kBACa;AACjC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE;IACjD,IAAI,CAAC;QACH,OAAO,IAAA,mBAAW,EAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,OAAO,EAAW,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AANY,QAAA,kBAAkB,sBAM9B","sourcesContent":["// returns an array of entries if readdir() works,\n// or the error that readdir() raised if not.\nimport { promises, readdirSync } from './fs.js'\nconst { readdir } = promises\n\nexport const readdirOrError = (path: string) =>\n readdir(path).catch(er => er as Error)\nexport const readdirOrErrorSync = (path: string) => {\n try {\n return readdirSync(path)\n } catch (er) {\n return er as Error\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts new file mode 100644 index 0000000..b01b023 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts @@ -0,0 +1,8 @@ +import { RimrafAsyncOptions, RimrafOptions } from './index.js'; +export declare const MAXBACKOFF = 200; +export declare const RATE = 1.2; +export declare const MAXRETRIES = 10; +export declare const codes: Set; +export declare const retryBusy: (fn: (path: string) => Promise) => (path: string, opt: RimrafAsyncOptions, backoff?: number, total?: number) => Promise; +export declare const retryBusySync: (fn: (path: string) => T) => (path: string, opt: RimrafOptions) => T; +//# sourceMappingURL=retry-busy.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map new file mode 100644 index 0000000..554f140 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"retry-busy.d.ts","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,eAAO,MAAM,UAAU,MAAM,CAAA;AAC7B,eAAO,MAAM,IAAI,MAAM,CAAA;AACvB,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,KAAK,aAAyC,CAAA;AAE3D,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAEnD,MAAM,OACP,kBAAkB,iDA8B1B,CAAA;AAGD,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAChC,MAAM,OAAO,aAAa,MAqBjD,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js new file mode 100644 index 0000000..7278365 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js @@ -0,0 +1,65 @@ +"use strict"; +// note: max backoff is the maximum that any *single* backoff will do +Object.defineProperty(exports, "__esModule", { value: true }); +exports.retryBusySync = exports.retryBusy = exports.codes = exports.MAXRETRIES = exports.RATE = exports.MAXBACKOFF = void 0; +const promises_1 = require("timers/promises"); +const error_js_1 = require("./error.js"); +exports.MAXBACKOFF = 200; +exports.RATE = 1.2; +exports.MAXRETRIES = 10; +exports.codes = new Set(['EMFILE', 'ENFILE', 'EBUSY']); +const retryBusy = (fn) => { + const method = async (path, opt, backoff = 1, total = 0) => { + const mbo = opt.maxBackoff || exports.MAXBACKOFF; + const rate = opt.backoff || exports.RATE; + const max = opt.maxRetries || exports.MAXRETRIES; + let retries = 0; + while (true) { + try { + return await fn(path); + } + catch (er) { + if ((0, error_js_1.isFsError)(er) && er.path === path && exports.codes.has(er.code)) { + backoff = Math.ceil(backoff * rate); + total = backoff + total; + if (total < mbo) { + await (0, promises_1.setTimeout)(backoff); + return method(path, opt, backoff, total); + } + if (retries < max) { + retries++; + continue; + } + } + throw er; + } + } + }; + return method; +}; +exports.retryBusy = retryBusy; +// just retries, no async so no backoff +const retryBusySync = (fn) => { + const method = (path, opt) => { + const max = opt.maxRetries || exports.MAXRETRIES; + let retries = 0; + while (true) { + try { + return fn(path); + } + catch (er) { + if ((0, error_js_1.isFsError)(er) && + er.path === path && + exports.codes.has(er.code) && + retries < max) { + retries++; + continue; + } + throw er; + } + } + }; + return method; +}; +exports.retryBusySync = retryBusySync; +//# sourceMappingURL=retry-busy.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map new file mode 100644 index 0000000..4bb5076 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"retry-busy.js","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":";AAAA,qEAAqE;;;AAErE,8CAA4C;AAE5C,yCAAsC;AAEzB,QAAA,UAAU,GAAG,GAAG,CAAA;AAChB,QAAA,IAAI,GAAG,GAAG,CAAA;AACV,QAAA,UAAU,GAAG,EAAE,CAAA;AACf,QAAA,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;AAEpD,MAAM,SAAS,GAAG,CAAI,EAAgC,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,KAAK,EAClB,IAAY,EACZ,GAAuB,EACvB,OAAO,GAAG,CAAC,EACX,KAAK,GAAG,CAAC,EACT,EAAE;QACF,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,YAAI,CAAA;QAChC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,aAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;oBACnC,KAAK,GAAG,OAAO,GAAG,KAAK,CAAA;oBACvB,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;wBAChB,MAAM,IAAA,qBAAU,EAAC,OAAO,CAAC,CAAA;wBACzB,OAAO,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;oBAC1C,CAAC;oBACD,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;wBAClB,OAAO,EAAE,CAAA;wBACT,SAAQ;oBACV,CAAC;gBACH,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAjCY,QAAA,SAAS,aAiCrB;AAED,uCAAuC;AAChC,MAAM,aAAa,GAAG,CAAI,EAAuB,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAkB,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IACE,IAAA,oBAAS,EAAC,EAAE,CAAC;oBACb,EAAE,CAAC,IAAI,KAAK,IAAI;oBAChB,aAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;oBAClB,OAAO,GAAG,GAAG,EACb,CAAC;oBACD,OAAO,EAAE,CAAA;oBACT,SAAQ;gBACV,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAtBY,QAAA,aAAa,iBAsBzB","sourcesContent":["// note: max backoff is the maximum that any *single* backoff will do\n\nimport { setTimeout } from 'timers/promises'\nimport { RimrafAsyncOptions, RimrafOptions } from './index.js'\nimport { isFsError } from './error.js'\n\nexport const MAXBACKOFF = 200\nexport const RATE = 1.2\nexport const MAXRETRIES = 10\nexport const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY'])\n\nexport const retryBusy = (fn: (path: string) => Promise) => {\n const method = async (\n path: string,\n opt: RimrafAsyncOptions,\n backoff = 1,\n total = 0,\n ) => {\n const mbo = opt.maxBackoff || MAXBACKOFF\n const rate = opt.backoff || RATE\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return await fn(path)\n } catch (er) {\n if (isFsError(er) && er.path === path && codes.has(er.code)) {\n backoff = Math.ceil(backoff * rate)\n total = backoff + total\n if (total < mbo) {\n await setTimeout(backoff)\n return method(path, opt, backoff, total)\n }\n if (retries < max) {\n retries++\n continue\n }\n }\n throw er\n }\n }\n }\n\n return method\n}\n\n// just retries, no async so no backoff\nexport const retryBusySync = (fn: (path: string) => T) => {\n const method = (path: string, opt: RimrafOptions) => {\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return fn(path)\n } catch (er) {\n if (\n isFsError(er) &&\n er.path === path &&\n codes.has(er.code) &&\n retries < max\n ) {\n retries++\n continue\n }\n throw er\n }\n }\n }\n return method\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts new file mode 100644 index 0000000..35c5c86 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts @@ -0,0 +1,3 @@ +export declare const rimrafManual: (path: string, opt: import("./opt-arg.js").RimrafAsyncOptions) => Promise; +export declare const rimrafManualSync: (path: string, opt: import("./opt-arg.js").RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-manual.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map new file mode 100644 index 0000000..96115d0 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-manual.d.ts","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,oFACmC,CAAA;AAC5D,eAAO,MAAM,gBAAgB,0EACuC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js new file mode 100644 index 0000000..81ab8bf --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimrafManualSync = exports.rimrafManual = void 0; +const rimraf_posix_js_1 = require("./rimraf-posix.js"); +const rimraf_windows_js_1 = require("./rimraf-windows.js"); +exports.rimrafManual = process.platform === 'win32' ? rimraf_windows_js_1.rimrafWindows : rimraf_posix_js_1.rimrafPosix; +exports.rimrafManualSync = process.platform === 'win32' ? rimraf_windows_js_1.rimrafWindowsSync : rimraf_posix_js_1.rimrafPosixSync; +//# sourceMappingURL=rimraf-manual.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map new file mode 100644 index 0000000..410c6f8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-manual.js","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":";;;AAAA,uDAAgE;AAChE,2DAAsE;AAEzD,QAAA,YAAY,GACvB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iCAAa,CAAC,CAAC,CAAC,6BAAW,CAAA;AAC/C,QAAA,gBAAgB,GAC3B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,qCAAiB,CAAC,CAAC,CAAC,iCAAe,CAAA","sourcesContent":["import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\n\nexport const rimrafManual =\n process.platform === 'win32' ? rimrafWindows : rimrafPosix\nexport const rimrafManualSync =\n process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts new file mode 100644 index 0000000..5d41d40 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafMoveRemove: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafMoveRemoveSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-move-remove.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map new file mode 100644 index 0000000..722538e --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-move-remove.d.ts","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAalE,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AA0ED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js new file mode 100644 index 0000000..7e9b2cb --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js @@ -0,0 +1,138 @@ +"use strict"; +// https://youtu.be/uhRWMGBjlO8?t=537 +// +// 1. readdir +// 2. for each entry +// a. if a non-empty directory, recurse +// b. if an empty directory, move to random hidden file name in $TEMP +// c. unlink/rmdir $TEMP +// +// This works around the fact that unlink/rmdir is non-atomic and takes +// a non-deterministic amount of time to complete. +// +// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimrafMoveRemoveSync = exports.rimrafMoveRemove = void 0; +const path_1 = require("path"); +const default_tmp_js_1 = require("./default-tmp.js"); +const ignore_enoent_js_1 = require("./ignore-enoent.js"); +const fs_js_1 = require("./fs.js"); +const readdir_or_error_js_1 = require("./readdir-or-error.js"); +const fix_eperm_js_1 = require("./fix-eperm.js"); +const error_js_1 = require("./error.js"); +const { lstat, rename, unlink, rmdir } = fs_js_1.promises; +// crypto.randomBytes is much slower, and Math.random() is enough here +const uniqueFilename = (path) => `.${(0, path_1.basename)(path)}.${Math.random()}`; +const unlinkFixEPERM = (0, fix_eperm_js_1.fixEPERM)(unlink); +const unlinkFixEPERMSync = (0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.unlinkSync); +const rimrafMoveRemove = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)))) ?? true); +}; +exports.rimrafMoveRemove = rimrafMoveRemove; +const rimrafMoveRemoveDir = async (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + if (!opt.tmp) { + return rimrafMoveRemoveDir(path, { ...opt, tmp: await (0, default_tmp_js_1.defaultTmp)(path) }, ent); + } + if (path === opt.tmp && (0, path_1.parse)(path).root !== path) { + throw new Error('cannot delete temp directory used for deletion'); + } + const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await (0, ignore_enoent_js_1.ignoreENOENT)(tmpUnlink(path, opt.tmp, unlinkFixEPERM)); + return true; + } + const removedAll = (await Promise.all(entries.map(ent => rimrafMoveRemoveDir((0, path_1.resolve)(path, ent.name), opt, ent)))).every(v => v === true); + if (!removedAll) { + return false; + } + // we don't ever ACTUALLY try to unlink /, because that can never work + // but when preserveRoot is false, we could be operating on it. + // No need to check if preserveRoot is not false. + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await (0, ignore_enoent_js_1.ignoreENOENT)(tmpUnlink(path, opt.tmp, rmdir)); + return true; +}; +const tmpUnlink = async (path, tmp, rm) => { + const tmpFile = (0, path_1.resolve)(tmp, uniqueFilename(path)); + await rename(path, tmpFile); + return await rm(tmpFile); +}; +const rimrafMoveRemoveSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafMoveRemoveDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ?? true); +}; +exports.rimrafMoveRemoveSync = rimrafMoveRemoveSync; +const rimrafMoveRemoveDirSync = (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + if (!opt.tmp) { + return rimrafMoveRemoveDirSync(path, { ...opt, tmp: (0, default_tmp_js_1.defaultTmpSync)(path) }, ent); + } + const tmp = opt.tmp; + if (path === opt.tmp && (0, path_1.parse)(path).root !== path) { + throw new Error('cannot delete temp directory used for deletion'); + } + const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const p = (0, path_1.resolve)(path, ent.name); + removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll; + } + if (!removedAll) { + return false; + } + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => tmpUnlinkSync(path, tmp, fs_js_1.rmdirSync)); + return true; +}; +const tmpUnlinkSync = (path, tmp, rmSync) => { + const tmpFile = (0, path_1.resolve)(tmp, uniqueFilename(path)); + (0, fs_js_1.renameSync)(path, tmpFile); + return rmSync(tmpFile); +}; +//# sourceMappingURL=rimraf-move-remove.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map new file mode 100644 index 0000000..9b20a9d --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-move-remove.js","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"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","sourcesContent":["// https://youtu.be/uhRWMGBjlO8?t=537\n//\n// 1. readdir\n// 2. for each entry\n// a. if a non-empty directory, recurse\n// b. if an empty directory, move to random hidden file name in $TEMP\n// c. unlink/rmdir $TEMP\n//\n// This works around the fact that unlink/rmdir is non-atomic and takes\n// a non-deterministic amount of time to complete.\n//\n// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm.\n\nimport { basename, parse, resolve } from 'path'\nimport { defaultTmp, defaultTmpSync } from './default-tmp.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport {\n lstatSync,\n promises,\n renameSync,\n rmdirSync,\n unlinkSync,\n} from './fs.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { errorCode } from './error.js'\nconst { lstat, rename, unlink, rmdir } = promises\n\n// crypto.randomBytes is much slower, and Math.random() is enough here\nconst uniqueFilename = (path: string) =>\n `.${basename(path)}.${Math.random()}`\n\nconst unlinkFixEPERM = fixEPERM(unlink)\nconst unlinkFixEPERMSync = fixEPERMSync(unlinkSync)\n\nexport const rimrafMoveRemove = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nconst rimrafMoveRemoveDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDir(\n path,\n { ...opt, tmp: await defaultTmp(path) },\n ent,\n )\n }\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir))\n return true\n}\n\nconst tmpUnlink = async (\n path: string,\n tmp: string,\n rm: (p: string) => Promise,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n await rename(path, tmpFile)\n return await rm(tmpFile)\n}\n\nexport const rimrafMoveRemoveSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafMoveRemoveDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafMoveRemoveDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDirSync(\n path,\n { ...opt, tmp: defaultTmpSync(path) },\n ent,\n )\n }\n const tmp: string = opt.tmp\n\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll\n }\n if (!removedAll) {\n return false\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync))\n return true\n}\n\nconst tmpUnlinkSync = (\n path: string,\n tmp: string,\n rmSync: (p: string) => void,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n renameSync(path, tmpFile)\n return rmSync(tmpFile)\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts new file mode 100644 index 0000000..cc84bf7 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafNative: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafNativeSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map new file mode 100644 index 0000000..6bb2a08 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-native.d.ts","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAIlE,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,KAAK,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,iBAAiB,KACrB,OAOF,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js new file mode 100644 index 0000000..ab9f633 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimrafNativeSync = exports.rimrafNative = void 0; +const fs_js_1 = require("./fs.js"); +const { rm } = fs_js_1.promises; +const rimrafNative = async (path, opt) => { + await rm(path, { + ...opt, + force: true, + recursive: true, + }); + return true; +}; +exports.rimrafNative = rimrafNative; +const rimrafNativeSync = (path, opt) => { + (0, fs_js_1.rmSync)(path, { + ...opt, + force: true, + recursive: true, + }); + return true; +}; +exports.rimrafNativeSync = rimrafNativeSync; +//# sourceMappingURL=rimraf-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map new file mode 100644 index 0000000..6eddd44 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-native.js","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":";;;AACA,mCAA0C;AAC1C,MAAM,EAAE,EAAE,EAAE,GAAG,gBAAQ,CAAA;AAEhB,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAY,EACZ,GAAuB,EACL,EAAE;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAVY,QAAA,YAAY,gBAUxB;AAEM,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,GAAsB,EACb,EAAE;IACX,IAAA,cAAM,EAAC,IAAI,EAAE;QACX,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAVY,QAAA,gBAAgB,oBAU5B","sourcesContent":["import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { promises, rmSync } from './fs.js'\nconst { rm } = promises\n\nexport const rimrafNative = async (\n path: string,\n opt: RimrafAsyncOptions,\n): Promise => {\n await rm(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n\nexport const rimrafNativeSync = (\n path: string,\n opt: RimrafSyncOptions,\n): boolean => {\n rmSync(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts new file mode 100644 index 0000000..8e532ef --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafPosix: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafPosixSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-posix.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map new file mode 100644 index 0000000..c7b1b6a --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-posix.d.ts","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKlE,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAK,iBAAiB,YAOnE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js new file mode 100644 index 0000000..554d5d6 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js @@ -0,0 +1,102 @@ +"use strict"; +// the simple recursive removal, where unlink and rmdir are atomic +// Note that this approach does NOT work on Windows! +// We stat first and only unlink if the Dirent isn't a directory, +// because sunos will let root unlink a directory, and some +// SUPER weird breakage happens as a result. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimrafPosixSync = exports.rimrafPosix = void 0; +const fs_js_1 = require("./fs.js"); +const path_1 = require("path"); +const readdir_or_error_js_1 = require("./readdir-or-error.js"); +const ignore_enoent_js_1 = require("./ignore-enoent.js"); +const error_js_1 = require("./error.js"); +const { lstat, rmdir, unlink } = fs_js_1.promises; +const rimrafPosix = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafPosixDir(path, opt, stat)))) ?? true); +}; +exports.rimrafPosix = rimrafPosix; +const rimrafPosixSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafPosixDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ?? true); +}; +exports.rimrafPosixSync = rimrafPosixSync; +const rimrafPosixDir = async (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await (0, ignore_enoent_js_1.ignoreENOENT)(unlink(path)); + return true; + } + const removedAll = (await Promise.all(entries.map(ent => rimrafPosixDir((0, path_1.resolve)(path, ent.name), opt, ent)))).every(v => v === true); + if (!removedAll) { + return false; + } + // we don't ever ACTUALLY try to unlink /, because that can never work + // but when preserveRoot is false, we could be operating on it. + // No need to check if preserveRoot is not false. + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await (0, ignore_enoent_js_1.ignoreENOENT)(rmdir(path)); + return true; +}; +const rimrafPosixDirSync = (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => (0, fs_js_1.unlinkSync)(path)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const p = (0, path_1.resolve)(path, ent.name); + removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll; + } + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => (0, fs_js_1.rmdirSync)(path)); + return true; +}; +//# sourceMappingURL=rimraf-posix.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map new file mode 100644 index 0000000..c137458 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-posix.js","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"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","sourcesContent":["// the simple recursive removal, where unlink and rmdir are atomic\n// Note that this approach does NOT work on Windows!\n// We stat first and only unlink if the Dirent isn't a directory,\n// because sunos will let root unlink a directory, and some\n// SUPER weird breakage happens as a result.\n\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { parse, resolve } from 'path'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { errorCode } from './error.js'\nconst { lstat, rmdir, unlink } = promises\n\nexport const rimrafPosix = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafPosixDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nexport const rimrafPosixSync = (path: string, opt: RimrafSyncOptions) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafPosixDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafPosixDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(unlink(path))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafPosixDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n\n await ignoreENOENT(rmdir(path))\n return true\n}\n\nconst rimrafPosixDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => unlinkSync(path))\n return true\n }\n let removedAll: boolean = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (!removedAll) {\n return false\n }\n\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n\n ignoreENOENTSync(() => rmdirSync(path))\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts new file mode 100644 index 0000000..5556890 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafWindows: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafWindowsSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-windows.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map new file mode 100644 index 0000000..bcca3f3 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-windows.d.ts","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AA2DlE,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js new file mode 100644 index 0000000..c49968c --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js @@ -0,0 +1,159 @@ +"use strict"; +// This is the same as rimrafPosix, with the following changes: +// +// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff +// 2. All non-directories are removed first and then all directories are +// removed in a second sweep. +// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on +// the that folder. +// +// Note: "move then remove" is 2-10 times slower, and just as unreliable. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rimrafWindowsSync = exports.rimrafWindows = void 0; +const path_1 = require("path"); +const fix_eperm_js_1 = require("./fix-eperm.js"); +const fs_js_1 = require("./fs.js"); +const ignore_enoent_js_1 = require("./ignore-enoent.js"); +const readdir_or_error_js_1 = require("./readdir-or-error.js"); +const retry_busy_js_1 = require("./retry-busy.js"); +const rimraf_move_remove_js_1 = require("./rimraf-move-remove.js"); +const error_js_1 = require("./error.js"); +const { unlink, rmdir, lstat } = fs_js_1.promises; +const rimrafWindowsFile = (0, retry_busy_js_1.retryBusy)((0, fix_eperm_js_1.fixEPERM)(unlink)); +const rimrafWindowsFileSync = (0, retry_busy_js_1.retryBusySync)((0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.unlinkSync)); +const rimrafWindowsDirRetry = (0, retry_busy_js_1.retryBusy)((0, fix_eperm_js_1.fixEPERM)(rmdir)); +const rimrafWindowsDirRetrySync = (0, retry_busy_js_1.retryBusySync)((0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.rmdirSync)); +const rimrafWindowsDirMoveRemoveFallback = async (path, +// already filtered, remove from options so we don't call unnecessarily +// eslint-disable-next-line @typescript-eslint/no-unused-vars +{ filter, ...opt }) => { + /* c8 ignore next */ + opt?.signal?.throwIfAborted(); + try { + await rimrafWindowsDirRetry(path, opt); + return true; + } + catch (er) { + if ((0, error_js_1.errorCode)(er) === 'ENOTEMPTY') { + return (0, rimraf_move_remove_js_1.rimrafMoveRemove)(path, opt); + } + throw er; + } +}; +const rimrafWindowsDirMoveRemoveFallbackSync = (path, +// already filtered, remove from options so we don't call unnecessarily +// eslint-disable-next-line @typescript-eslint/no-unused-vars +{ filter, ...opt }) => { + opt?.signal?.throwIfAborted(); + try { + rimrafWindowsDirRetrySync(path, opt); + return true; + } + catch (er) { + if ((0, error_js_1.errorCode)(er) === 'ENOTEMPTY') { + return (0, rimraf_move_remove_js_1.rimrafMoveRemoveSync)(path, opt); + } + throw er; + } +}; +const START = Symbol('start'); +const CHILD = Symbol('child'); +const FINISH = Symbol('finish'); +const rimrafWindows = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)))) ?? true); +}; +exports.rimrafWindows = rimrafWindows; +const rimrafWindowsSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsDirSync(path, opt, (0, fs_js_1.lstatSync)(path), START)) ?? true); +}; +exports.rimrafWindowsSync = rimrafWindowsSync; +const rimrafWindowsDir = async (path, opt, ent, state = START) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + // is a file + await (0, ignore_enoent_js_1.ignoreENOENT)(rimrafWindowsFile(path, opt)); + return true; + } + const s = state === START ? CHILD : state; + const removedAll = (await Promise.all(entries.map(ent => rimrafWindowsDir((0, path_1.resolve)(path, ent.name), opt, ent, s)))).every(v => v === true); + if (state === START) { + return rimrafWindowsDir(path, opt, ent, FINISH); + } + else if (state === FINISH) { + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await (0, ignore_enoent_js_1.ignoreENOENT)(rimrafWindowsDirMoveRemoveFallback(path, opt)); + } + return true; +}; +const rimrafWindowsDirSync = (path, opt, ent, state = START) => { + const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { + return true; + } + if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + // is a file + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsFileSync(path, opt)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const s = state === START ? CHILD : state; + const p = (0, path_1.resolve)(path, ent.name); + removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll; + } + if (state === START) { + return rimrafWindowsDirSync(path, opt, ent, FINISH); + } + else if (state === FINISH) { + if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + (0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsDirMoveRemoveFallbackSync(path, opt)); + } + return true; +}; +//# sourceMappingURL=rimraf-windows.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map new file mode 100644 index 0000000..7ff8651 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-windows.js","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"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","sourcesContent":["// This is the same as rimrafPosix, with the following changes:\n//\n// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff\n// 2. All non-directories are removed first and then all directories are\n// removed in a second sweep.\n// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on\n// the that folder.\n//\n// Note: \"move then remove\" is 2-10 times slower, and just as unreliable.\n\nimport { Dirent, Stats } from 'fs'\nimport { parse, resolve } from 'path'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { retryBusy, retryBusySync } from './retry-busy.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { errorCode } from './error.js'\nconst { unlink, rmdir, lstat } = promises\n\nconst rimrafWindowsFile = retryBusy(fixEPERM(unlink))\nconst rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync))\nconst rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir))\nconst rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync))\n\nconst rimrafWindowsDirMoveRemoveFallback = async (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafAsyncOptions,\n): Promise => {\n /* c8 ignore next */\n opt?.signal?.throwIfAborted()\n try {\n await rimrafWindowsDirRetry(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemove(path, opt)\n }\n throw er\n }\n}\n\nconst rimrafWindowsDirMoveRemoveFallbackSync = (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafSyncOptions,\n): boolean => {\n opt?.signal?.throwIfAborted()\n try {\n rimrafWindowsDirRetrySync(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemoveSync(path, opt)\n }\n throw er\n }\n}\n\nconst START = Symbol('start')\nconst CHILD = Symbol('child')\nconst FINISH = Symbol('finish')\n\nexport const rimrafWindows = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)),\n )) ?? true\n )\n}\n\nexport const rimrafWindowsSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafWindowsDirSync(path, opt, lstatSync(path), START),\n ) ?? true\n )\n}\n\nconst rimrafWindowsDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n state = START,\n): Promise => {\n opt?.signal?.throwIfAborted()\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n // is a file\n await ignoreENOENT(rimrafWindowsFile(path, opt))\n return true\n }\n\n const s = state === START ? CHILD : state\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafWindowsDir(resolve(path, ent.name), opt, ent, s),\n ),\n )\n ).every(v => v === true)\n\n if (state === START) {\n return rimrafWindowsDir(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt))\n }\n return true\n}\n\nconst rimrafWindowsDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n state = START,\n): boolean => {\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n // is a file\n ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const s = state === START ? CHILD : state\n const p = resolve(path, ent.name)\n removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll\n }\n\n if (state === START) {\n return rimrafWindowsDirSync(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() =>\n rimrafWindowsDirMoveRemoveFallbackSync(path, opt),\n )\n }\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts new file mode 100644 index 0000000..e191fd9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafOptions } from './index.js'; +export declare const useNative: (opt?: RimrafAsyncOptions) => boolean; +export declare const useNativeSync: (opt?: RimrafOptions) => boolean; +//# sourceMappingURL=use-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map new file mode 100644 index 0000000..be687c1 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"use-native.d.ts","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW9D,eAAO,MAAM,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,kBAAkB,KAAK,OAGf,CAAA;AACvC,eAAO,MAAM,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,aAAa,KAAK,OAGd,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js new file mode 100644 index 0000000..68c0e83 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.useNativeSync = exports.useNative = void 0; +/* c8 ignore next */ +const [major = 0, minor = 0] = process.version + .replace(/^v/, '') + .split('.') + .map(v => parseInt(v, 10)); +const hasNative = major > 14 || (major === 14 && minor >= 14); +// we do NOT use native by default on Windows, because Node's native +// rm implementation is less advanced. Change this code if that changes. +exports.useNative = !hasNative || process.platform === 'win32' ? + () => false + : opt => !opt?.signal && !opt?.filter; +exports.useNativeSync = !hasNative || process.platform === 'win32' ? + () => false + : opt => !opt?.signal && !opt?.filter; +//# sourceMappingURL=use-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map new file mode 100644 index 0000000..9b4a046 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map @@ -0,0 +1 @@ +{"version":3,"file":"use-native.js","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":";;;AAEA,oBAAoB;AACpB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO;KAC3C,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;KACjB,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5B,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAE7D,oEAAoE;AACpE,yEAAyE;AAC5D,QAAA,SAAS,GACpB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA;AAC1B,QAAA,aAAa,GACxB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafOptions } from './index.js'\n\n/* c8 ignore next */\nconst [major = 0, minor = 0] = process.version\n .replace(/^v/, '')\n .split('.')\n .map(v => parseInt(v, 10))\nconst hasNative = major > 14 || (major === 14 && minor >= 14)\n\n// we do NOT use native by default on Windows, because Node's native\n// rm implementation is less advanced. Change this code if that changes.\nexport const useNative: (opt?: RimrafAsyncOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\nexport const useNativeSync: (opt?: RimrafOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts new file mode 100644 index 0000000..77298e4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts @@ -0,0 +1,3 @@ +#!/usr/bin/env node +export {}; +//# sourceMappingURL=bin.d.mts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map new file mode 100644 index 0000000..ec64bdd --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.d.mts","sourceRoot":"","sources":["../../src/bin.mts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs new file mode 100644 index 0000000..77441b1 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs @@ -0,0 +1,250 @@ +#!/usr/bin/env node +import { rimraf } from './index.js'; +import { loadPackageJson } from 'package-json-from-dist'; +const { version } = loadPackageJson(import.meta.url, '../package.json'); +const runHelpForUsage = () => console.error('run `rimraf --help` for usage information'); +const help = `rimraf version ${version} + +Usage: rimraf [ ...] +Deletes all files and folders at "path", recursively. + +Options: + -- Treat all subsequent arguments as paths + -h --help Display this usage info + --version Display version + --preserve-root Do not remove '/' recursively (default) + --no-preserve-root Do not treat '/' specially + -G --no-glob Treat arguments as literal paths, not globs (default) + -g --glob Treat arguments as glob patterns + -v --verbose Be verbose when deleting files, showing them as + they are removed. Not compatible with --impl=native + -V --no-verbose Be silent when deleting files, showing nothing as + they are removed (default) + -i --interactive Ask for confirmation before deleting anything + Not compatible with --impl=native + -I --no-interactive Do not ask for confirmation before deleting + + --impl= Specify the implementation to use: + rimraf: choose the best option (default) + native: the built-in implementation in Node.js + manual: the platform-specific JS implementation + posix: the Posix JS implementation + windows: the Windows JS implementation (falls back to + move-remove on ENOTEMPTY) + move-remove: a slow reliable Windows fallback + +Implementation-specific options: + --tmp= Temp file folder for 'move-remove' implementation + --max-retries= maxRetries for 'native' and 'windows' implementations + --retry-delay= retryDelay for 'native' implementation, default 100 + --backoff= Exponential backoff factor for retries (default: 1.2) +`; +import { parse, relative, resolve } from 'path'; +const cwd = process.cwd(); +import { createInterface } from 'readline'; +const prompt = async (rl, q) => new Promise(res => rl.question(q, res)); +const interactiveRimraf = async (impl, paths, opt) => { + const existingFilter = opt.filter || (() => true); + let allRemaining = false; + let noneRemaining = false; + const queue = []; + let processing = false; + const processQueue = async () => { + if (processing) + return; + processing = true; + let next; + while ((next = queue.shift())) { + await next(); + } + processing = false; + }; + const oneAtATime = (fn) => async (s, e) => { + const p = new Promise(res => { + queue.push(async () => { + const result = await fn(s, e); + res(result); + return result; + }); + }); + void processQueue(); + return p; + }; + const rl = createInterface({ + input: process.stdin, + output: process.stdout, + }); + opt.filter = oneAtATime(async (path, ent) => { + if (noneRemaining) { + return false; + } + while (!allRemaining) { + const a = (await prompt(rl, `rm? ${relative(cwd, path)}\n[(Yes)/No/All/Quit] > `)).trim(); + if (/^n/i.test(a)) { + return false; + } + else if (/^a/i.test(a)) { + allRemaining = true; + break; + } + else if (/^q/i.test(a)) { + noneRemaining = true; + return false; + } + else if (a === '' || /^y/i.test(a)) { + break; + } + else { + continue; + } + } + return existingFilter(path, ent); + }); + await impl(paths, opt); + rl.close(); +}; +const main = async (...args) => { + const verboseFilter = (s) => { + console.log(relative(cwd, s)); + return true; + }; + const opt = {}; + const paths = []; + let dashdash = false; + let impl = rimraf; + let interactive = false; + for (const arg of args) { + if (dashdash) { + paths.push(arg); + continue; + } + if (arg === '--') { + dashdash = true; + continue; + } + else if (arg === '-rf' || arg === '-fr') { + // this never did anything, but people put it there I guess + continue; + } + else if (arg === '-h' || arg === '--help') { + console.log(help); + return 0; + } + else if (arg === '--version') { + console.log(version); + return 0; + } + else if (arg === '--interactive' || arg === '-i') { + interactive = true; + continue; + } + else if (arg === '--no-interactive' || arg === '-I') { + interactive = false; + continue; + } + else if (arg === '--verbose' || arg === '-v') { + opt.filter = verboseFilter; + continue; + } + else if (arg === '--no-verbose' || arg === '-V') { + opt.filter = undefined; + continue; + } + else if (arg === '-g' || arg === '--glob') { + opt.glob = true; + continue; + } + else if (arg === '-G' || arg === '--no-glob') { + opt.glob = false; + continue; + } + else if (arg === '--preserve-root') { + opt.preserveRoot = true; + continue; + } + else if (arg === '--no-preserve-root') { + opt.preserveRoot = false; + continue; + } + else if (/^--tmp=/.test(arg)) { + const val = arg.substring('--tmp='.length); + opt.tmp = val; + continue; + } + else if (/^--max-retries=/.test(arg)) { + const val = +arg.substring('--max-retries='.length); + opt.maxRetries = val; + continue; + } + else if (/^--retry-delay=/.test(arg)) { + const val = +arg.substring('--retry-delay='.length); + opt.retryDelay = val; + continue; + } + else if (/^--backoff=/.test(arg)) { + const val = +arg.substring('--backoff='.length); + opt.backoff = val; + continue; + } + else if (/^--impl=/.test(arg)) { + const val = arg.substring('--impl='.length); + switch (val) { + case 'rimraf': + impl = rimraf; + continue; + case 'native': + case 'manual': + case 'posix': + case 'windows': + impl = rimraf[val]; + continue; + case 'move-remove': + impl = rimraf.moveRemove; + continue; + default: + console.error(`unknown implementation: ${val}`); + runHelpForUsage(); + return 1; + } + } + else if (/^-/.test(arg)) { + console.error(`unknown option: ${arg}`); + runHelpForUsage(); + return 1; + } + else { + paths.push(arg); + } + } + if (opt.preserveRoot !== false) { + for (const path of paths.map(p => resolve(p))) { + if (path === parse(path).root) { + console.error(`rimraf: it is dangerous to operate recursively on '/'`); + console.error('use --no-preserve-root to override this failsafe'); + return 1; + } + } + } + if (!paths.length) { + console.error('rimraf: must provide a path to remove'); + runHelpForUsage(); + return 1; + } + if (impl === rimraf.native && (interactive || opt.filter)) { + console.error('native implementation does not support -v or -i'); + runHelpForUsage(); + return 1; + } + if (interactive) { + await interactiveRimraf(impl, paths, opt); + } + else { + await impl(paths, opt); + } + return 0; +}; +main(...process.argv.slice(2)).then(code => process.exit(code), er => { + console.error(er); + process.exit(1); +}); +//# sourceMappingURL=bin.mjs.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map new file mode 100644 index 0000000..4baed42 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.mjs","sourceRoot":"","sources":["../../src/bin.mts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport type { RimrafAsyncOptions } from './index.js'\nimport { rimraf } from './index.js'\nimport { loadPackageJson } from 'package-json-from-dist'\n\nconst { version } = loadPackageJson(\n import.meta.url,\n '../package.json',\n) as {\n version: string\n}\n\nconst runHelpForUsage = () =>\n console.error('run `rimraf --help` for usage information')\n\nconst help = `rimraf version ${version}\n\nUsage: rimraf [ ...]\nDeletes all files and folders at \"path\", recursively.\n\nOptions:\n -- Treat all subsequent arguments as paths\n -h --help Display this usage info\n --version Display version\n --preserve-root Do not remove '/' recursively (default)\n --no-preserve-root Do not treat '/' specially\n -G --no-glob Treat arguments as literal paths, not globs (default)\n -g --glob Treat arguments as glob patterns\n -v --verbose Be verbose when deleting files, showing them as\n they are removed. Not compatible with --impl=native\n -V --no-verbose Be silent when deleting files, showing nothing as\n they are removed (default)\n -i --interactive Ask for confirmation before deleting anything\n Not compatible with --impl=native\n -I --no-interactive Do not ask for confirmation before deleting\n\n --impl= Specify the implementation to use:\n rimraf: choose the best option (default)\n native: the built-in implementation in Node.js\n manual: the platform-specific JS implementation\n posix: the Posix JS implementation\n windows: the Windows JS implementation (falls back to\n move-remove on ENOTEMPTY)\n move-remove: a slow reliable Windows fallback\n\nImplementation-specific options:\n --tmp= Temp file folder for 'move-remove' implementation\n --max-retries= maxRetries for 'native' and 'windows' implementations\n --retry-delay= retryDelay for 'native' implementation, default 100\n --backoff= Exponential backoff factor for retries (default: 1.2)\n`\n\nimport { parse, relative, resolve } from 'path'\nconst cwd = process.cwd()\n\nimport { Dirent, Stats } from 'fs'\nimport { createInterface, Interface } from 'readline'\n\nconst prompt = async (rl: Interface, q: string) =>\n new Promise(res => rl.question(q, res))\n\nconst interactiveRimraf = async (\n impl: (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ) => Promise,\n paths: string[],\n opt: RimrafAsyncOptions,\n) => {\n const existingFilter = opt.filter || (() => true)\n let allRemaining = false\n let noneRemaining = false\n const queue: (() => Promise)[] = []\n let processing = false\n const processQueue = async () => {\n if (processing) return\n processing = true\n let next: (() => Promise) | undefined\n while ((next = queue.shift())) {\n await next()\n }\n processing = false\n }\n const oneAtATime =\n (fn: (s: string, e: Dirent | Stats) => Promise) =>\n async (s: string, e: Dirent | Stats): Promise => {\n const p = new Promise(res => {\n queue.push(async () => {\n const result = await fn(s, e)\n res(result)\n return result\n })\n })\n void processQueue()\n return p\n }\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n opt.filter = oneAtATime(\n async (path: string, ent: Dirent | Stats): Promise => {\n if (noneRemaining) {\n return false\n }\n while (!allRemaining) {\n const a = (\n await prompt(\n rl,\n `rm? ${relative(cwd, path)}\\n[(Yes)/No/All/Quit] > `,\n )\n ).trim()\n if (/^n/i.test(a)) {\n return false\n } else if (/^a/i.test(a)) {\n allRemaining = true\n break\n } else if (/^q/i.test(a)) {\n noneRemaining = true\n return false\n } else if (a === '' || /^y/i.test(a)) {\n break\n } else {\n continue\n }\n }\n return existingFilter(path, ent)\n },\n )\n await impl(paths, opt)\n rl.close()\n}\n\nconst main = async (...args: string[]) => {\n const verboseFilter = (s: string) => {\n console.log(relative(cwd, s))\n return true\n }\n\n const opt: RimrafAsyncOptions = {}\n const paths: string[] = []\n let dashdash = false\n let impl: (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ) => Promise = rimraf\n\n let interactive = false\n\n for (const arg of args) {\n if (dashdash) {\n paths.push(arg)\n continue\n }\n if (arg === '--') {\n dashdash = true\n continue\n } else if (arg === '-rf' || arg === '-fr') {\n // this never did anything, but people put it there I guess\n continue\n } else if (arg === '-h' || arg === '--help') {\n console.log(help)\n return 0\n } else if (arg === '--version') {\n console.log(version)\n return 0\n } else if (arg === '--interactive' || arg === '-i') {\n interactive = true\n continue\n } else if (arg === '--no-interactive' || arg === '-I') {\n interactive = false\n continue\n } else if (arg === '--verbose' || arg === '-v') {\n opt.filter = verboseFilter\n continue\n } else if (arg === '--no-verbose' || arg === '-V') {\n opt.filter = undefined\n continue\n } else if (arg === '-g' || arg === '--glob') {\n opt.glob = true\n continue\n } else if (arg === '-G' || arg === '--no-glob') {\n opt.glob = false\n continue\n } else if (arg === '--preserve-root') {\n opt.preserveRoot = true\n continue\n } else if (arg === '--no-preserve-root') {\n opt.preserveRoot = false\n continue\n } else if (/^--tmp=/.test(arg)) {\n const val = arg.substring('--tmp='.length)\n opt.tmp = val\n continue\n } else if (/^--max-retries=/.test(arg)) {\n const val = +arg.substring('--max-retries='.length)\n opt.maxRetries = val\n continue\n } else if (/^--retry-delay=/.test(arg)) {\n const val = +arg.substring('--retry-delay='.length)\n opt.retryDelay = val\n continue\n } else if (/^--backoff=/.test(arg)) {\n const val = +arg.substring('--backoff='.length)\n opt.backoff = val\n continue\n } else if (/^--impl=/.test(arg)) {\n const val = arg.substring('--impl='.length)\n switch (val) {\n case 'rimraf':\n impl = rimraf\n continue\n case 'native':\n case 'manual':\n case 'posix':\n case 'windows':\n impl = rimraf[val]\n continue\n case 'move-remove':\n impl = rimraf.moveRemove\n continue\n default:\n console.error(`unknown implementation: ${val}`)\n runHelpForUsage()\n return 1\n }\n } else if (/^-/.test(arg)) {\n console.error(`unknown option: ${arg}`)\n runHelpForUsage()\n return 1\n } else {\n paths.push(arg)\n }\n }\n\n if (opt.preserveRoot !== false) {\n for (const path of paths.map(p => resolve(p))) {\n if (path === parse(path).root) {\n console.error(\n `rimraf: it is dangerous to operate recursively on '/'`,\n )\n console.error('use --no-preserve-root to override this failsafe')\n return 1\n }\n }\n }\n\n if (!paths.length) {\n console.error('rimraf: must provide a path to remove')\n runHelpForUsage()\n return 1\n }\n\n if (impl === rimraf.native && (interactive || opt.filter)) {\n console.error('native implementation does not support -v or -i')\n runHelpForUsage()\n return 1\n }\n\n if (interactive) {\n await interactiveRimraf(impl, paths, opt)\n } else {\n await impl(paths, opt)\n }\n\n return 0\n}\n\nmain(...process.argv.slice(2)).then(\n code => process.exit(code),\n er => {\n console.error(er)\n process.exit(1)\n },\n)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts new file mode 100644 index 0000000..a68e925 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts @@ -0,0 +1,3 @@ +export declare const defaultTmp: (path: string) => Promise; +export declare const defaultTmpSync: (path: string) => string; +//# sourceMappingURL=default-tmp.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map new file mode 100644 index 0000000..e3200d4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"default-tmp.d.ts","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAiEA,eAAO,MAAM,UAAU,SApCc,MAAM,oBAqCuB,CAAA;AAClE,eAAO,MAAM,cAAc,SAtBQ,MAAM,WAuBiC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js new file mode 100644 index 0000000..b02a9b9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js @@ -0,0 +1,55 @@ +// The default temporary folder location for use in the windows algorithm. +// It's TEMPting to use dirname(path), since that's guaranteed to be on the +// same device. However, this means that: +// rimraf(path).then(() => rimraf(dirname(path))) +// will often fail with EBUSY, because the parent dir contains +// marked-for-deletion directory entries (which do not show up in readdir). +// The approach here is to use os.tmpdir() if it's on the same drive letter, +// or resolve(path, '\\temp') if it exists, or the root of the drive if not. +// On Posix (not that you'd be likely to use the windows algorithm there), +// it uses os.tmpdir() always. +import { tmpdir } from 'os'; +import { parse, resolve } from 'path'; +import { promises, statSync } from './fs.js'; +const { stat } = promises; +const isDirSync = (path) => { + try { + return statSync(path).isDirectory(); + } + catch { + return false; + } +}; +const isDir = (path) => stat(path).then(st => st.isDirectory(), () => false); +const win32DefaultTmp = async (path) => { + const { root } = parse(path); + const tmp = tmpdir(); + const { root: tmpRoot } = parse(tmp); + if (root.toLowerCase() === tmpRoot.toLowerCase()) { + return tmp; + } + const driveTmp = resolve(root, '/temp'); + if (await isDir(driveTmp)) { + return driveTmp; + } + return root; +}; +const win32DefaultTmpSync = (path) => { + const { root } = parse(path); + const tmp = tmpdir(); + const { root: tmpRoot } = parse(tmp); + if (root.toLowerCase() === tmpRoot.toLowerCase()) { + return tmp; + } + const driveTmp = resolve(root, '/temp'); + if (isDirSync(driveTmp)) { + return driveTmp; + } + return root; +}; +// eslint-disable-next-line @typescript-eslint/require-await +const posixDefaultTmp = async () => tmpdir(); +const posixDefaultTmpSync = () => tmpdir(); +export const defaultTmp = process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp; +export const defaultTmpSync = process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync; +//# sourceMappingURL=default-tmp.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map new file mode 100644 index 0000000..259e96e --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map @@ -0,0 +1 @@ +{"version":3,"file":"default-tmp.js","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0CAA0C;AAC1C,iDAAiD;AACjD,8DAA8D;AAC9D,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,8BAA8B;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAC3B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAA;AAEzB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACb,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EACtB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAA;AAEH,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAA;AAC5C,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,MAAM,EAAE,CAAA;AAE1C,MAAM,CAAC,MAAM,UAAU,GACrB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAA;AAClE,MAAM,CAAC,MAAM,cAAc,GACzB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAA","sourcesContent":["// The default temporary folder location for use in the windows algorithm.\n// It's TEMPting to use dirname(path), since that's guaranteed to be on the\n// same device. However, this means that:\n// rimraf(path).then(() => rimraf(dirname(path)))\n// will often fail with EBUSY, because the parent dir contains\n// marked-for-deletion directory entries (which do not show up in readdir).\n// The approach here is to use os.tmpdir() if it's on the same drive letter,\n// or resolve(path, '\\\\temp') if it exists, or the root of the drive if not.\n// On Posix (not that you'd be likely to use the windows algorithm there),\n// it uses os.tmpdir() always.\nimport { tmpdir } from 'os'\nimport { parse, resolve } from 'path'\nimport { promises, statSync } from './fs.js'\nconst { stat } = promises\n\nconst isDirSync = (path: string) => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n\nconst isDir = (path: string) =>\n stat(path).then(\n st => st.isDirectory(),\n () => false,\n )\n\nconst win32DefaultTmp = async (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (await isDir(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\nconst win32DefaultTmpSync = (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (isDirSync(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await\nconst posixDefaultTmp = async () => tmpdir()\nconst posixDefaultTmpSync = () => tmpdir()\n\nexport const defaultTmp =\n process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp\nexport const defaultTmpSync =\n process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts new file mode 100644 index 0000000..5ba53c8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts @@ -0,0 +1,6 @@ +export declare const isFsError: (o: unknown) => o is NodeJS.ErrnoException & { + code: string; + path: string; +}; +export declare const errorCode: (er: unknown) => unknown; +//# sourceMappingURL=error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map new file mode 100644 index 0000000..6671be4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,GACpB,GAAG,OAAO,KACT,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACkD,CAAA;AAEhE,eAAO,MAAM,SAAS,GAAI,IAAI,OAAO,YACmB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.js b/apps/extension/node_modules/rimraf/dist/esm/error.js new file mode 100644 index 0000000..593c9a6 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/error.js @@ -0,0 +1,5 @@ +const isRecord = (o) => !!o && typeof o === 'object'; +const hasString = (o, key) => key in o && typeof o[key] === 'string'; +export const isFsError = (o) => isRecord(o) && hasString(o, 'code') && hasString(o, 'path'); +export const errorCode = (er) => isRecord(er) && hasString(er, 'code') ? er.code : null; +//# sourceMappingURL=error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.js.map b/apps/extension/node_modules/rimraf/dist/esm/error.js.map new file mode 100644 index 0000000..d096bc0 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAC5D,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAA;AAE9B,MAAM,SAAS,GAAG,CAAC,CAA0B,EAAE,GAAW,EAAE,EAAE,CAC5D,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAA;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,CAAU,EAIV,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAEhE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAW,EAAE,EAAE,CACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA","sourcesContent":["const isRecord = (o: unknown): o is Record =>\n !!o && typeof o === 'object'\n\nconst hasString = (o: Record, key: string) =>\n key in o && typeof o[key] === 'string'\n\nexport const isFsError = (\n o: unknown,\n): o is NodeJS.ErrnoException & {\n code: string\n path: string\n} => isRecord(o) && hasString(o, 'code') && hasString(o, 'path')\n\nexport const errorCode = (er: unknown) =>\n isRecord(er) && hasString(er, 'code') ? er.code : null\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts new file mode 100644 index 0000000..4b329ef --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts @@ -0,0 +1,3 @@ +export declare const fixEPERM: (fn: (path: string) => Promise) => (path: string) => Promise; +export declare const fixEPERMSync: (fn: (path: string) => unknown) => (path: string) => void; +//# sourceMappingURL=fix-eperm.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map new file mode 100644 index 0000000..498e950 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fix-eperm.d.ts","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,GAClB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAChC,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBjC,CAAA;AAEH,eAAO,MAAM,YAAY,GACtB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,MAC7B,MAAM,MAAM,KAAG,IAYf,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js new file mode 100644 index 0000000..e3fb094 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js @@ -0,0 +1,33 @@ +import { errorCode } from './error.js'; +import { chmodSync, promises } from './fs.js'; +import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; +const { chmod } = promises; +export const fixEPERM = (fn) => async (path) => { + try { + return void (await ignoreENOENT(fn(path))); + } + catch (er) { + if (errorCode(er) === 'EPERM') { + if (!(await ignoreENOENT(chmod(path, 0o666).then(() => true), er))) { + return; + } + return void (await fn(path)); + } + throw er; + } +}; +export const fixEPERMSync = (fn) => (path) => { + try { + return void ignoreENOENTSync(() => fn(path)); + } + catch (er) { + if (errorCode(er) === 'EPERM') { + if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) { + return; + } + return void fn(path); + } + throw er; + } +}; +//# sourceMappingURL=fix-eperm.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map new file mode 100644 index 0000000..fde0181 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fix-eperm.js","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;AAE1B,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,EAAsC,EAAE,EAAE,CAC3C,KAAK,EAAE,IAAY,EAAiB,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IACE,CAAC,CAAC,MAAM,YAAY,CAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACnC,EAAE,CACH,CAAC,EACF,CAAC;gBACD,OAAM;YACR,CAAC;YACD,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9B,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,YAAY,GACvB,CAAC,EAA6B,EAAE,EAAE,CAClC,CAAC,IAAY,EAAQ,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,KAAK,gBAAgB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { errorCode } from './error.js'\nimport { chmodSync, promises } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nconst { chmod } = promises\n\nexport const fixEPERM =\n (fn: (path: string) => Promise) =>\n async (path: string): Promise => {\n try {\n return void (await ignoreENOENT(fn(path)))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (\n !(await ignoreENOENT(\n chmod(path, 0o666).then(() => true),\n er,\n ))\n ) {\n return\n }\n return void (await fn(path))\n }\n throw er\n }\n }\n\nexport const fixEPERMSync =\n (fn: (path: string) => unknown) =>\n (path: string): void => {\n try {\n return void ignoreENOENTSync(() => fn(path))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) {\n return\n }\n return void fn(path)\n }\n throw er\n }\n }\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts new file mode 100644 index 0000000..4e6fbab --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts @@ -0,0 +1,16 @@ +import fs, { Dirent } from 'fs'; +import fsPromises from 'fs/promises'; +export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; +export declare const readdirSync: (path: fs.PathLike) => Dirent[]; +export declare const promises: { + chmod: typeof fsPromises.chmod; + mkdir: typeof fsPromises.mkdir; + readdir: (path: fs.PathLike) => Promise[]>; + rename: typeof fsPromises.rename; + rm: typeof fsPromises.rm; + rmdir: typeof fsPromises.rmdir; + stat: typeof fsPromises.stat; + lstat: typeof fsPromises.lstat; + unlink: typeof fsPromises.unlink; +}; +//# sourceMappingURL=fs.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map new file mode 100644 index 0000000..ed3c8db --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAyB,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAKpC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,QAAQ,KAAG,MAAM,EACf,CAAA;AAEvC,eAAO,MAAM,QAAQ;;;oBAGH,EAAE,CAAC,QAAQ;;;;;;;CAQ5B,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.js b/apps/extension/node_modules/rimraf/dist/esm/fs.js new file mode 100644 index 0000000..0a4cb30 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fs.js @@ -0,0 +1,18 @@ +import { readdirSync as rdSync } from 'fs'; +import fsPromises from 'fs/promises'; +// sync ones just take the sync version from node +// readdir forces withFileTypes: true +export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; +export const readdirSync = (path) => rdSync(path, { withFileTypes: true }); +export const promises = { + chmod: fsPromises.chmod, + mkdir: fsPromises.mkdir, + readdir: (path) => fsPromises.readdir(path, { withFileTypes: true }), + rename: fsPromises.rename, + rm: fsPromises.rm, + rmdir: fsPromises.rmdir, + stat: fsPromises.stat, + lstat: fsPromises.lstat, + unlink: fsPromises.unlink, +}; +//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.js.map b/apps/extension/node_modules/rimraf/dist/esm/fs.js.map new file mode 100644 index 0000000..2cd1bb2 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/fs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAW,EAAU,WAAW,IAAI,MAAM,EAAE,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAEpC,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAY,EAAE,CACzD,MAAM,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;AAEvC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,OAAO,EAAE,CAAC,IAAiB,EAAE,EAAE,CAC7B,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,EAAE,EAAE,UAAU,CAAC,EAAE;IACjB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,MAAM,EAAE,UAAU,CAAC,MAAM;CAC1B,CAAA","sourcesContent":["import fs, { Dirent, readdirSync as rdSync } from 'fs'\nimport fsPromises from 'fs/promises'\n\n// sync ones just take the sync version from node\n// readdir forces withFileTypes: true\n\nexport {\n chmodSync,\n mkdirSync,\n renameSync,\n rmdirSync,\n rmSync,\n statSync,\n lstatSync,\n unlinkSync,\n} from 'fs'\n\nexport const readdirSync = (path: fs.PathLike): Dirent[] =>\n rdSync(path, { withFileTypes: true })\n\nexport const promises = {\n chmod: fsPromises.chmod,\n mkdir: fsPromises.mkdir,\n readdir: (path: fs.PathLike) =>\n fsPromises.readdir(path, { withFileTypes: true }),\n rename: fsPromises.rename,\n rm: fsPromises.rm,\n rmdir: fsPromises.rmdir,\n stat: fsPromises.stat,\n lstat: fsPromises.lstat,\n unlink: fsPromises.unlink,\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts new file mode 100644 index 0000000..e56d721 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts @@ -0,0 +1,3 @@ +export declare const ignoreENOENT: (p: Promise, rethrow?: unknown) => Promise; +export declare const ignoreENOENTSync: (fn: () => T, rethrow?: unknown) => T | undefined; +//# sourceMappingURL=ignore-enoent.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map new file mode 100644 index 0000000..14097fc --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ignore-enoent.d.ts","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,GAAU,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,OAAO,sBAMlE,CAAA;AAEJ,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,UAAU,OAAO,kBASjE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js new file mode 100644 index 0000000..a40d5e6 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js @@ -0,0 +1,19 @@ +import { errorCode } from './error.js'; +export const ignoreENOENT = async (p, rethrow) => p.catch(er => { + if (errorCode(er) === 'ENOENT') { + return; + } + throw rethrow ?? er; +}); +export const ignoreENOENTSync = (fn, rethrow) => { + try { + return fn(); + } + catch (er) { + if (errorCode(er) === 'ENOENT') { + return; + } + throw rethrow ?? er; + } +}; +//# sourceMappingURL=ignore-enoent.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map new file mode 100644 index 0000000..4e33d44 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ignore-enoent.js","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAK,CAAa,EAAE,OAAiB,EAAE,EAAE,CACxE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;IACX,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAM;IACR,CAAC;IACD,MAAM,OAAO,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAI,EAAW,EAAE,OAAiB,EAAE,EAAE;IACpE,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,OAAO,IAAI,EAAE,CAAA;IACrB,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { errorCode } from './error.js'\n\nexport const ignoreENOENT = async (p: Promise, rethrow?: unknown) =>\n p.catch(er => {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n })\n\nexport const ignoreENOENTSync = (fn: () => T, rethrow?: unknown) => {\n try {\n return fn()\n } catch (er) {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts new file mode 100644 index 0000000..9ec4a12 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts @@ -0,0 +1,50 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './opt-arg.js'; +export { assertRimrafOptions, isRimrafOptions, type RimrafAsyncOptions, type RimrafOptions, type RimrafSyncOptions, } from './opt-arg.js'; +export declare const nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +export declare const rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +export declare const rimraf: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + rimraf: (path: string | string[], opt?: RimrafAsyncOptions) => Promise; + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { + sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; + }; + moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; +}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map new file mode 100644 index 0000000..e69bc3c --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.js b/apps/extension/node_modules/rimraf/dist/esm/index.js new file mode 100644 index 0000000..2026b40 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/index.js @@ -0,0 +1,76 @@ +import { glob, globSync } from 'glob'; +import { optArg, optArgSync, } from './opt-arg.js'; +import pathArg from './path-arg.js'; +import { rimrafManual, rimrafManualSync } from './rimraf-manual.js'; +import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; +import { rimrafNative, rimrafNativeSync } from './rimraf-native.js'; +import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'; +import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'; +import { useNative, useNativeSync } from './use-native.js'; +export { assertRimrafOptions, isRimrafOptions, } from './opt-arg.js'; +const wrap = (fn) => async (path, opt) => { + const options = optArg(opt); + if (options.glob) { + path = await glob(path, options.glob); + } + if (Array.isArray(path)) { + return !!(await Promise.all(path.map(p => fn(pathArg(p, options), options)))).reduce((a, b) => a && b, true); + } + else { + return !!(await fn(pathArg(path, options), options)); + } +}; +const wrapSync = (fn) => (path, opt) => { + const options = optArgSync(opt); + if (options.glob) { + path = globSync(path, options.glob); + } + if (Array.isArray(path)) { + return !!path + .map(p => fn(pathArg(p, options), options)) + .reduce((a, b) => a && b, true); + } + else { + return !!fn(pathArg(path, options), options); + } +}; +export const nativeSync = wrapSync(rimrafNativeSync); +export const native = Object.assign(wrap(rimrafNative), { + sync: nativeSync, +}); +export const manualSync = wrapSync(rimrafManualSync); +export const manual = Object.assign(wrap(rimrafManual), { + sync: manualSync, +}); +export const windowsSync = wrapSync(rimrafWindowsSync); +export const windows = Object.assign(wrap(rimrafWindows), { + sync: windowsSync, +}); +export const posixSync = wrapSync(rimrafPosixSync); +export const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync }); +export const moveRemoveSync = wrapSync(rimrafMoveRemoveSync); +export const moveRemove = Object.assign(wrap(rimrafMoveRemove), { + sync: moveRemoveSync, +}); +export const rimrafSync = wrapSync((path, opt) => useNativeSync(opt) ? + rimrafNativeSync(path, opt) + : rimrafManualSync(path, opt)); +export const sync = rimrafSync; +const rimraf_ = wrap((path, opt) => useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt)); +export const rimraf = Object.assign(rimraf_, { + rimraf: rimraf_, + sync: rimrafSync, + rimrafSync: rimrafSync, + manual, + manualSync, + native, + nativeSync, + posix, + posixSync, + windows, + windowsSync, + moveRemove, + moveRemoveSync, +}); +rimraf.rimraf = rimraf; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.js.map b/apps/extension/node_modules/rimraf/dist/esm/index.js.map new file mode 100644 index 0000000..e61b4ca --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EACL,MAAM,EACN,UAAU,GAGX,MAAM,cAAc,CAAA;AACrB,OAAO,OAAO,MAAM,eAAe,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE1D,OAAO,EACL,mBAAmB,EACnB,eAAe,GAIhB,MAAM,cAAc,CAAA;AAErB,MAAM,IAAI,GACR,CAAC,EAA0D,EAAE,EAAE,CAC/D,KAAK,EACH,IAAuB,EACvB,GAAwB,EACN,EAAE;IACpB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,CACP,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CACnE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;IACtD,CAAC;AACH,CAAC,CAAA;AAEH,MAAM,QAAQ,GACZ,CAAC,EAAgD,EAAE,EAAE,CACrD,CAAC,IAAuB,EAAE,GAAuB,EAAW,EAAE;IAC5D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,IAAI;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;aAC1C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;IACtD,IAAI,EAAE,UAAU;CACjB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;IACtD,IAAI,EAAE,UAAU;CACjB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;AACtD,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE;IACxD,IAAI,EAAE,WAAW;CAClB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAA;AAClD,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;AAE1E,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAA;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE;IAC9D,IAAI,EAAE,cAAc;CACrB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAC/C,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAClB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC;IAC7B,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,CAC9B,CAAA;AACD,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAA;AAE9B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CACjC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CACnE,CAAA;AACD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE;IAC3C,MAAM,EAAE,OAAO;IACf,IAAI,EAAE,UAAU;IAChB,UAAU,EAAE,UAAU;IACtB,MAAM;IACN,UAAU;IACV,MAAM;IACN,UAAU;IACV,KAAK;IACL,SAAS;IACT,OAAO;IACP,WAAW;IACX,UAAU;IACV,cAAc;CACf,CAAC,CAAA;AACF,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA","sourcesContent":["import { glob, globSync } from 'glob'\nimport {\n optArg,\n optArgSync,\n RimrafAsyncOptions,\n RimrafSyncOptions,\n} from './opt-arg.js'\nimport pathArg from './path-arg.js'\nimport { rimrafManual, rimrafManualSync } from './rimraf-manual.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { rimrafNative, rimrafNativeSync } from './rimraf-native.js'\nimport { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\nimport { useNative, useNativeSync } from './use-native.js'\n\nexport {\n assertRimrafOptions,\n isRimrafOptions,\n type RimrafAsyncOptions,\n type RimrafOptions,\n type RimrafSyncOptions,\n} from './opt-arg.js'\n\nconst wrap =\n (fn: (p: string, o: RimrafAsyncOptions) => Promise) =>\n async (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ): Promise => {\n const options = optArg(opt)\n if (options.glob) {\n path = await glob(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!(\n await Promise.all(path.map(p => fn(pathArg(p, options), options)))\n ).reduce((a, b) => a && b, true)\n } else {\n return !!(await fn(pathArg(path, options), options))\n }\n }\n\nconst wrapSync =\n (fn: (p: string, o: RimrafSyncOptions) => boolean) =>\n (path: string | string[], opt?: RimrafSyncOptions): boolean => {\n const options = optArgSync(opt)\n if (options.glob) {\n path = globSync(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!path\n .map(p => fn(pathArg(p, options), options))\n .reduce((a, b) => a && b, true)\n } else {\n return !!fn(pathArg(path, options), options)\n }\n }\n\nexport const nativeSync = wrapSync(rimrafNativeSync)\nexport const native = Object.assign(wrap(rimrafNative), {\n sync: nativeSync,\n})\n\nexport const manualSync = wrapSync(rimrafManualSync)\nexport const manual = Object.assign(wrap(rimrafManual), {\n sync: manualSync,\n})\n\nexport const windowsSync = wrapSync(rimrafWindowsSync)\nexport const windows = Object.assign(wrap(rimrafWindows), {\n sync: windowsSync,\n})\n\nexport const posixSync = wrapSync(rimrafPosixSync)\nexport const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync })\n\nexport const moveRemoveSync = wrapSync(rimrafMoveRemoveSync)\nexport const moveRemove = Object.assign(wrap(rimrafMoveRemove), {\n sync: moveRemoveSync,\n})\n\nexport const rimrafSync = wrapSync((path, opt) =>\n useNativeSync(opt) ?\n rimrafNativeSync(path, opt)\n : rimrafManualSync(path, opt),\n)\nexport const sync = rimrafSync\n\nconst rimraf_ = wrap((path, opt) =>\n useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt),\n)\nexport const rimraf = Object.assign(rimraf_, {\n rimraf: rimraf_,\n sync: rimrafSync,\n rimrafSync: rimrafSync,\n manual,\n manualSync,\n native,\n nativeSync,\n posix,\n posixSync,\n windows,\n windowsSync,\n moveRemove,\n moveRemoveSync,\n})\nrimraf.rimraf = rimraf\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts new file mode 100644 index 0000000..c869d4a --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts @@ -0,0 +1,34 @@ +import { Dirent, Stats } from 'fs'; +import { GlobOptions } from 'glob'; +export declare const isRimrafOptions: (o: any) => o is RimrafOptions; +export declare const assertRimrafOptions: (o: any) => void; +export interface RimrafAsyncOptions { + preserveRoot?: boolean; + tmp?: string; + maxRetries?: number; + retryDelay?: number; + backoff?: number; + maxBackoff?: number; + signal?: AbortSignal; + glob?: boolean | GlobOptions; + filter?: ((path: string, ent: Dirent | Stats) => boolean) | ((path: string, ent: Dirent | Stats) => Promise); +} +export interface RimrafSyncOptions extends RimrafAsyncOptions { + filter?: (path: string, ent: Dirent | Stats) => boolean; +} +export type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions; +export declare const optArg: (opt?: RimrafAsyncOptions) => (RimrafAsyncOptions & { + glob: GlobOptions & { + withFileTypes: false; + }; +}) | (RimrafAsyncOptions & { + glob: undefined; +}); +export declare const optArgSync: (opt?: RimrafSyncOptions) => (RimrafSyncOptions & { + glob: GlobOptions & { + withFileTypes: false; + }; +}) | (RimrafSyncOptions & { + glob: undefined; +}); +//# sourceMappingURL=opt-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map new file mode 100644 index 0000000..93e1f92 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"opt-arg.d.ts","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAKlC,eAAO,MAAM,eAAe,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,aAWX,CAAA;AAEnC,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAM7C,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;IAC5B,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,GAChD,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAA;CACxD;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAqClE,eAAO,MAAM,MAAM,GAAI,MAAK,kBAAuB;UA/BvC,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA6B0C,CAAA;AACpE,eAAO,MAAM,UAAU,GAAI,MAAK,iBAAsB;UAhC1C,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA8B6C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js new file mode 100644 index 0000000..c699db7 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js @@ -0,0 +1,47 @@ +const typeOrUndef = (val, t) => typeof val === 'undefined' || typeof val === t; +export const isRimrafOptions = (o) => !!o && + typeof o === 'object' && + typeOrUndef(o.preserveRoot, 'boolean') && + typeOrUndef(o.tmp, 'string') && + typeOrUndef(o.maxRetries, 'number') && + typeOrUndef(o.retryDelay, 'number') && + typeOrUndef(o.backoff, 'number') && + typeOrUndef(o.maxBackoff, 'number') && + (typeOrUndef(o.glob, 'boolean') || + (o.glob && typeof o.glob === 'object')) && + typeOrUndef(o.filter, 'function'); +export const assertRimrafOptions = (o) => { + if (!isRimrafOptions(o)) { + throw new Error('invalid rimraf options'); + } +}; +const optArgT = (opt) => { + assertRimrafOptions(opt); + const { glob, ...options } = opt; + if (!glob) { + return options; + } + const globOpt = glob === true ? + opt.signal ? + { signal: opt.signal } + : {} + : opt.signal ? + { + signal: opt.signal, + ...glob, + } + : glob; + return { + ...options, + glob: { + ...globOpt, + // always get absolute paths from glob, to ensure + // that we are referencing the correct thing. + absolute: true, + withFileTypes: false, + }, + }; +}; +export const optArg = (opt = {}) => optArgT(opt); +export const optArgSync = (opt = {}) => optArgT(opt); +//# sourceMappingURL=opt-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map new file mode 100644 index 0000000..57956e9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map @@ -0,0 +1 @@ +{"version":3,"file":"opt-arg.js","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,CAAS,EAAE,EAAE,CAC1C,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,KAAK,CAAC,CAAA;AAEhD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAM,EAAsB,EAAE,CAC5D,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,QAAQ;IACrB,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC;IACtC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IAC5B,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC;QAC7B,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAEnC,MAAM,CAAC,MAAM,mBAAmB,GAAqB,CACnD,CAAM,EACsB,EAAE;IAC9B,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC,CAAA;AAsBD,MAAM,OAAO,GAAG,CACd,GAAM,EAKsB,EAAE;IAC9B,mBAAmB,CAAC,GAAG,CAAC,CAAA;IACxB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAA;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,OAAkC,CAAA;IAC3C,CAAC;IACD,MAAM,OAAO,GACX,IAAI,KAAK,IAAI,CAAC,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,CAAC;YACV,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACxB,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACZ;gBACE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,IAAI;aACR;YACH,CAAC,CAAC,IAAI,CAAA;IACR,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE;YACJ,GAAG,OAAO;YACV,iDAAiD;YACjD,6CAA6C;YAC7C,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,KAAK;SACrB;KACsD,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAA0B,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAyB,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA","sourcesContent":["import { Dirent, Stats } from 'fs'\nimport { GlobOptions } from 'glob'\n\nconst typeOrUndef = (val: any, t: string) =>\n typeof val === 'undefined' || typeof val === t\n\nexport const isRimrafOptions = (o: any): o is RimrafOptions =>\n !!o &&\n typeof o === 'object' &&\n typeOrUndef(o.preserveRoot, 'boolean') &&\n typeOrUndef(o.tmp, 'string') &&\n typeOrUndef(o.maxRetries, 'number') &&\n typeOrUndef(o.retryDelay, 'number') &&\n typeOrUndef(o.backoff, 'number') &&\n typeOrUndef(o.maxBackoff, 'number') &&\n (typeOrUndef(o.glob, 'boolean') ||\n (o.glob && typeof o.glob === 'object')) &&\n typeOrUndef(o.filter, 'function')\n\nexport const assertRimrafOptions: (o: any) => void = (\n o: any,\n): asserts o is RimrafOptions => {\n if (!isRimrafOptions(o)) {\n throw new Error('invalid rimraf options')\n }\n}\n\nexport interface RimrafAsyncOptions {\n preserveRoot?: boolean\n tmp?: string\n maxRetries?: number\n retryDelay?: number\n backoff?: number\n maxBackoff?: number\n signal?: AbortSignal\n glob?: boolean | GlobOptions\n filter?:\n | ((path: string, ent: Dirent | Stats) => boolean)\n | ((path: string, ent: Dirent | Stats) => Promise)\n}\n\nexport interface RimrafSyncOptions extends RimrafAsyncOptions {\n filter?: (path: string, ent: Dirent | Stats) => boolean\n}\n\nexport type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions\n\nconst optArgT = (\n opt: T,\n):\n | (T & {\n glob: GlobOptions & { withFileTypes: false }\n })\n | (T & { glob: undefined }) => {\n assertRimrafOptions(opt)\n const { glob, ...options } = opt\n if (!glob) {\n return options as T & { glob: undefined }\n }\n const globOpt =\n glob === true ?\n opt.signal ?\n { signal: opt.signal }\n : {}\n : opt.signal ?\n {\n signal: opt.signal,\n ...glob,\n }\n : glob\n return {\n ...options,\n glob: {\n ...globOpt,\n // always get absolute paths from glob, to ensure\n // that we are referencing the correct thing.\n absolute: true,\n withFileTypes: false,\n },\n } as T & { glob: GlobOptions & { withFileTypes: false } }\n}\n\nexport const optArg = (opt: RimrafAsyncOptions = {}) => optArgT(opt)\nexport const optArgSync = (opt: RimrafSyncOptions = {}) => optArgT(opt)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/package.json b/apps/extension/node_modules/rimraf/dist/esm/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts new file mode 100644 index 0000000..c0b7e7c --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions } from './index.js'; +declare const pathArg: (path: string, opt?: RimrafAsyncOptions) => string; +export default pathArg; +//# sourceMappingURL=path-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map new file mode 100644 index 0000000..2112460 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"path-arg.d.ts","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,QAAA,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,MAAK,kBAAuB,WAkD1D,CAAA;AAED,eAAe,OAAO,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js new file mode 100644 index 0000000..d8df8a2 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js @@ -0,0 +1,47 @@ +import { parse, resolve } from 'path'; +import { inspect } from 'util'; +const pathArg = (path, opt = {}) => { + const type = typeof path; + if (type !== 'string') { + const ctor = path && type === 'object' && path.constructor; + const received = ctor && ctor.name ? `an instance of ${ctor.name}` + : type === 'object' ? inspect(path) + : `type ${type} ${path}`; + const msg = 'The "path" argument must be of type string. ' + + `Received ${received}`; + throw Object.assign(new TypeError(msg), { + path, + code: 'ERR_INVALID_ARG_TYPE', + }); + } + if (/\0/.test(path)) { + // simulate same failure that node raises + const msg = 'path must be a string without null bytes'; + throw Object.assign(new TypeError(msg), { + path, + code: 'ERR_INVALID_ARG_VALUE', + }); + } + path = resolve(path); + const { root } = parse(path); + if (path === root && opt.preserveRoot !== false) { + const msg = 'refusing to remove root directory without preserveRoot:false'; + throw Object.assign(new Error(msg), { + path, + code: 'ERR_PRESERVE_ROOT', + }); + } + if (process.platform === 'win32') { + const badWinChars = /[*|"<>?:]/; + const { root } = parse(path); + if (badWinChars.test(path.substring(root.length))) { + throw Object.assign(new Error('Illegal characters in path.'), { + path, + code: 'EINVAL', + }); + } + } + return path; +}; +export default pathArg; +//# sourceMappingURL=path-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map new file mode 100644 index 0000000..c744f08 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map @@ -0,0 +1 @@ +{"version":3,"file":"path-arg.js","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAG9B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,MAA0B,EAAE,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAA;IACxB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAA;QAC1D,MAAM,QAAQ,GACZ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAA;QAC1B,MAAM,GAAG,GACP,8CAA8C;YAC9C,YAAY,QAAQ,EAAE,CAAA;QACxB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,sBAAsB;SAC7B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,yCAAyC;QACzC,MAAM,GAAG,GAAG,0CAA0C,CAAA;QACtD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAE5B,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,GAAG,GACP,8DAA8D,CAAA;QAChE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI;YACJ,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,WAAW,CAAA;QAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAE;gBAC5D,IAAI;gBACJ,IAAI,EAAE,QAAQ;aACf,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,eAAe,OAAO,CAAA","sourcesContent":["import { parse, resolve } from 'path'\nimport { inspect } from 'util'\nimport { RimrafAsyncOptions } from './index.js'\n\nconst pathArg = (path: string, opt: RimrafAsyncOptions = {}) => {\n const type = typeof path\n if (type !== 'string') {\n const ctor = path && type === 'object' && path.constructor\n const received =\n ctor && ctor.name ? `an instance of ${ctor.name}`\n : type === 'object' ? inspect(path)\n : `type ${type} ${path}`\n const msg =\n 'The \"path\" argument must be of type string. ' +\n `Received ${received}`\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_TYPE',\n })\n }\n\n if (/\\0/.test(path)) {\n // simulate same failure that node raises\n const msg = 'path must be a string without null bytes'\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_VALUE',\n })\n }\n\n path = resolve(path)\n const { root } = parse(path)\n\n if (path === root && opt.preserveRoot !== false) {\n const msg =\n 'refusing to remove root directory without preserveRoot:false'\n throw Object.assign(new Error(msg), {\n path,\n code: 'ERR_PRESERVE_ROOT',\n })\n }\n\n if (process.platform === 'win32') {\n const badWinChars = /[*|\"<>?:]/\n const { root } = parse(path)\n if (badWinChars.test(path.substring(root.length))) {\n throw Object.assign(new Error('Illegal characters in path.'), {\n path,\n code: 'EINVAL',\n })\n }\n }\n\n return path\n}\n\nexport default pathArg\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts new file mode 100644 index 0000000..2a580cf --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts @@ -0,0 +1,3 @@ +export declare const readdirOrError: (path: string) => Promise[] | Error>; +export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent[] | Error; +//# sourceMappingURL=readdir-or-error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map new file mode 100644 index 0000000..1f91434 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"readdir-or-error.d.ts","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,wDACH,CAAA;AACxC,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,+CAM9C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js new file mode 100644 index 0000000..7123513 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js @@ -0,0 +1,14 @@ +// returns an array of entries if readdir() works, +// or the error that readdir() raised if not. +import { promises, readdirSync } from './fs.js'; +const { readdir } = promises; +export const readdirOrError = (path) => readdir(path).catch(er => er); +export const readdirOrErrorSync = (path) => { + try { + return readdirSync(path); + } + catch (er) { + return er; + } +}; +//# sourceMappingURL=readdir-or-error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map new file mode 100644 index 0000000..e5011a9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"readdir-or-error.js","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,6CAA6C;AAC7C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAA;AAE5B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAW,CAAC,CAAA;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE;IACjD,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,OAAO,EAAW,CAAA;IACpB,CAAC;AACH,CAAC,CAAA","sourcesContent":["// returns an array of entries if readdir() works,\n// or the error that readdir() raised if not.\nimport { promises, readdirSync } from './fs.js'\nconst { readdir } = promises\n\nexport const readdirOrError = (path: string) =>\n readdir(path).catch(er => er as Error)\nexport const readdirOrErrorSync = (path: string) => {\n try {\n return readdirSync(path)\n } catch (er) {\n return er as Error\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts new file mode 100644 index 0000000..b01b023 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts @@ -0,0 +1,8 @@ +import { RimrafAsyncOptions, RimrafOptions } from './index.js'; +export declare const MAXBACKOFF = 200; +export declare const RATE = 1.2; +export declare const MAXRETRIES = 10; +export declare const codes: Set; +export declare const retryBusy: (fn: (path: string) => Promise) => (path: string, opt: RimrafAsyncOptions, backoff?: number, total?: number) => Promise; +export declare const retryBusySync: (fn: (path: string) => T) => (path: string, opt: RimrafOptions) => T; +//# sourceMappingURL=retry-busy.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map new file mode 100644 index 0000000..554f140 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"retry-busy.d.ts","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,eAAO,MAAM,UAAU,MAAM,CAAA;AAC7B,eAAO,MAAM,IAAI,MAAM,CAAA;AACvB,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,KAAK,aAAyC,CAAA;AAE3D,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAEnD,MAAM,OACP,kBAAkB,iDA8B1B,CAAA;AAGD,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAChC,MAAM,OAAO,aAAa,MAqBjD,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js new file mode 100644 index 0000000..263af08 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js @@ -0,0 +1,60 @@ +// note: max backoff is the maximum that any *single* backoff will do +import { setTimeout } from 'timers/promises'; +import { isFsError } from './error.js'; +export const MAXBACKOFF = 200; +export const RATE = 1.2; +export const MAXRETRIES = 10; +export const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY']); +export const retryBusy = (fn) => { + const method = async (path, opt, backoff = 1, total = 0) => { + const mbo = opt.maxBackoff || MAXBACKOFF; + const rate = opt.backoff || RATE; + const max = opt.maxRetries || MAXRETRIES; + let retries = 0; + while (true) { + try { + return await fn(path); + } + catch (er) { + if (isFsError(er) && er.path === path && codes.has(er.code)) { + backoff = Math.ceil(backoff * rate); + total = backoff + total; + if (total < mbo) { + await setTimeout(backoff); + return method(path, opt, backoff, total); + } + if (retries < max) { + retries++; + continue; + } + } + throw er; + } + } + }; + return method; +}; +// just retries, no async so no backoff +export const retryBusySync = (fn) => { + const method = (path, opt) => { + const max = opt.maxRetries || MAXRETRIES; + let retries = 0; + while (true) { + try { + return fn(path); + } + catch (er) { + if (isFsError(er) && + er.path === path && + codes.has(er.code) && + retries < max) { + retries++; + continue; + } + throw er; + } + } + }; + return method; +}; +//# sourceMappingURL=retry-busy.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map new file mode 100644 index 0000000..78e420e --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"retry-busy.js","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;AAC7B,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAA;AACvB,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;AAE3D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,EAAgC,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,KAAK,EAClB,IAAY,EACZ,GAAuB,EACvB,OAAO,GAAG,CAAC,EACX,KAAK,GAAG,CAAC,EACT,EAAE;QACF,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAA;QAChC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;oBACnC,KAAK,GAAG,OAAO,GAAG,KAAK,CAAA;oBACvB,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;wBAChB,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;wBACzB,OAAO,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;oBAC1C,CAAC;oBACD,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;wBAClB,OAAO,EAAE,CAAA;wBACT,SAAQ;oBACV,CAAC;gBACH,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,uCAAuC;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAI,EAAuB,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAkB,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IACE,SAAS,CAAC,EAAE,CAAC;oBACb,EAAE,CAAC,IAAI,KAAK,IAAI;oBAChB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;oBAClB,OAAO,GAAG,GAAG,EACb,CAAC;oBACD,OAAO,EAAE,CAAA;oBACT,SAAQ;gBACV,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["// note: max backoff is the maximum that any *single* backoff will do\n\nimport { setTimeout } from 'timers/promises'\nimport { RimrafAsyncOptions, RimrafOptions } from './index.js'\nimport { isFsError } from './error.js'\n\nexport const MAXBACKOFF = 200\nexport const RATE = 1.2\nexport const MAXRETRIES = 10\nexport const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY'])\n\nexport const retryBusy = (fn: (path: string) => Promise) => {\n const method = async (\n path: string,\n opt: RimrafAsyncOptions,\n backoff = 1,\n total = 0,\n ) => {\n const mbo = opt.maxBackoff || MAXBACKOFF\n const rate = opt.backoff || RATE\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return await fn(path)\n } catch (er) {\n if (isFsError(er) && er.path === path && codes.has(er.code)) {\n backoff = Math.ceil(backoff * rate)\n total = backoff + total\n if (total < mbo) {\n await setTimeout(backoff)\n return method(path, opt, backoff, total)\n }\n if (retries < max) {\n retries++\n continue\n }\n }\n throw er\n }\n }\n }\n\n return method\n}\n\n// just retries, no async so no backoff\nexport const retryBusySync = (fn: (path: string) => T) => {\n const method = (path: string, opt: RimrafOptions) => {\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return fn(path)\n } catch (er) {\n if (\n isFsError(er) &&\n er.path === path &&\n codes.has(er.code) &&\n retries < max\n ) {\n retries++\n continue\n }\n throw er\n }\n }\n }\n return method\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts new file mode 100644 index 0000000..35c5c86 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts @@ -0,0 +1,3 @@ +export declare const rimrafManual: (path: string, opt: import("./opt-arg.js").RimrafAsyncOptions) => Promise; +export declare const rimrafManualSync: (path: string, opt: import("./opt-arg.js").RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-manual.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map new file mode 100644 index 0000000..96115d0 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-manual.d.ts","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,oFACmC,CAAA;AAC5D,eAAO,MAAM,gBAAgB,0EACuC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js new file mode 100644 index 0000000..76f5b44 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js @@ -0,0 +1,5 @@ +import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'; +import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'; +export const rimrafManual = process.platform === 'win32' ? rimrafWindows : rimrafPosix; +export const rimrafManualSync = process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync; +//# sourceMappingURL=rimraf-manual.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map new file mode 100644 index 0000000..197a3ff --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-manual.js","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEtE,MAAM,CAAC,MAAM,YAAY,GACvB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAA;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAC3B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAA","sourcesContent":["import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\n\nexport const rimrafManual =\n process.platform === 'win32' ? rimrafWindows : rimrafPosix\nexport const rimrafManualSync =\n process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts new file mode 100644 index 0000000..5d41d40 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafMoveRemove: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafMoveRemoveSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-move-remove.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map new file mode 100644 index 0000000..722538e --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-move-remove.d.ts","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAalE,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AA0ED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js new file mode 100644 index 0000000..729b831 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js @@ -0,0 +1,133 @@ +// https://youtu.be/uhRWMGBjlO8?t=537 +// +// 1. readdir +// 2. for each entry +// a. if a non-empty directory, recurse +// b. if an empty directory, move to random hidden file name in $TEMP +// c. unlink/rmdir $TEMP +// +// This works around the fact that unlink/rmdir is non-atomic and takes +// a non-deterministic amount of time to complete. +// +// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm. +import { basename, parse, resolve } from 'path'; +import { defaultTmp, defaultTmpSync } from './default-tmp.js'; +import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; +import { lstatSync, promises, renameSync, rmdirSync, unlinkSync, } from './fs.js'; +import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; +import { fixEPERM, fixEPERMSync } from './fix-eperm.js'; +import { errorCode } from './error.js'; +const { lstat, rename, unlink, rmdir } = promises; +// crypto.randomBytes is much slower, and Math.random() is enough here +const uniqueFilename = (path) => `.${basename(path)}.${Math.random()}`; +const unlinkFixEPERM = fixEPERM(unlink); +const unlinkFixEPERMSync = fixEPERMSync(unlinkSync); +export const rimrafMoveRemove = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await ignoreENOENT(lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)))) ?? true); +}; +const rimrafMoveRemoveDir = async (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + if (!opt.tmp) { + return rimrafMoveRemoveDir(path, { ...opt, tmp: await defaultTmp(path) }, ent); + } + if (path === opt.tmp && parse(path).root !== path) { + throw new Error('cannot delete temp directory used for deletion'); + } + const entries = ent.isDirectory() ? await readdirOrError(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM)); + return true; + } + const removedAll = (await Promise.all(entries.map(ent => rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent)))).every(v => v === true); + if (!removedAll) { + return false; + } + // we don't ever ACTUALLY try to unlink /, because that can never work + // but when preserveRoot is false, we could be operating on it. + // No need to check if preserveRoot is not false. + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir)); + return true; +}; +const tmpUnlink = async (path, tmp, rm) => { + const tmpFile = resolve(tmp, uniqueFilename(path)); + await rename(path, tmpFile); + return await rm(tmpFile); +}; +export const rimrafMoveRemoveSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return (ignoreENOENTSync(() => rimrafMoveRemoveDirSync(path, opt, lstatSync(path))) ?? true); +}; +const rimrafMoveRemoveDirSync = (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + if (!opt.tmp) { + return rimrafMoveRemoveDirSync(path, { ...opt, tmp: defaultTmpSync(path) }, ent); + } + const tmp = opt.tmp; + if (path === opt.tmp && parse(path).root !== path) { + throw new Error('cannot delete temp directory used for deletion'); + } + const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const p = resolve(path, ent.name); + removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll; + } + if (!removedAll) { + return false; + } + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync)); + return true; +}; +const tmpUnlinkSync = (path, tmp, rmSync) => { + const tmpFile = resolve(tmp, uniqueFilename(path)); + renameSync(path, tmpFile); + return rmSync(tmpFile); +}; +//# sourceMappingURL=rimraf-move-remove.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map new file mode 100644 index 0000000..dc41dff --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-move-remove.js","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,aAAa;AACb,oBAAoB;AACpB,yCAAyC;AACzC,uEAAuE;AACvE,0BAA0B;AAC1B,EAAE;AACF,uEAAuE;AACvE,kDAAkD;AAClD,EAAE;AACF,0EAA0E;AAE1E,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EACL,SAAS,EACT,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;AAEjD,sEAAsE;AACtE,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAA;AAEvC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;AACvC,MAAM,kBAAkB,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;AAEnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,IAAY,EACZ,GAAuB,EACvB,EAAE;IACF,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,CAAC,MAAM,YAAY,CACjB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAC/D,CAAC,IAAI,IAAI,CACX,CAAA;AACH,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,KAAK,EAC/B,IAAY,EACZ,GAAuB,EACvB,GAAmB,EACD,EAAE;IACpB,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACb,OAAO,mBAAmB,CACxB,IAAI,EACJ,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE,EACvC,GAAG,CACJ,CAAA;IACH,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,MAAM,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAA;QAC5D,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAChB,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CACvD,CACF,CACF,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;IACxB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sEAAsE;IACtE,+DAA+D;IAC/D,iDAAiD;IACjD,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IACnD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,IAAY,EACZ,GAAW,EACX,EAA6B,EAC7B,EAAE;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC3B,OAAO,MAAM,EAAE,CAAC,OAAO,CAAC,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAY,EACZ,GAAsB,EACtB,EAAE;IACF,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,gBAAgB,CAAC,GAAG,EAAE,CACpB,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CACpD,IAAI,IAAI,CACV,CAAA;AACH,CAAC,CAAA;AAED,MAAM,uBAAuB,GAAG,CAC9B,IAAY,EACZ,GAAsB,EACtB,GAAmB,EACV,EAAE;IACX,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACb,OAAO,uBAAuB,CAC5B,IAAI,EACJ,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,EACrC,GAAG,CACJ,CAAA;IACH,CAAC;IACD,MAAM,GAAG,GAAW,GAAG,CAAC,GAAG,CAAA;IAE3B,IAAI,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,gBAAgB,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAA;QACpE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,UAAU,GAAG,IAAI,CAAA;IACrB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,UAAU,GAAG,uBAAuB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,UAAU,CAAA;IACjE,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,gBAAgB,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAA;IAC3D,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CACpB,IAAY,EACZ,GAAW,EACX,MAA2B,EAC3B,EAAE;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACzB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC,CAAA","sourcesContent":["// https://youtu.be/uhRWMGBjlO8?t=537\n//\n// 1. readdir\n// 2. for each entry\n// a. if a non-empty directory, recurse\n// b. if an empty directory, move to random hidden file name in $TEMP\n// c. unlink/rmdir $TEMP\n//\n// This works around the fact that unlink/rmdir is non-atomic and takes\n// a non-deterministic amount of time to complete.\n//\n// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm.\n\nimport { basename, parse, resolve } from 'path'\nimport { defaultTmp, defaultTmpSync } from './default-tmp.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport {\n lstatSync,\n promises,\n renameSync,\n rmdirSync,\n unlinkSync,\n} from './fs.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { errorCode } from './error.js'\nconst { lstat, rename, unlink, rmdir } = promises\n\n// crypto.randomBytes is much slower, and Math.random() is enough here\nconst uniqueFilename = (path: string) =>\n `.${basename(path)}.${Math.random()}`\n\nconst unlinkFixEPERM = fixEPERM(unlink)\nconst unlinkFixEPERMSync = fixEPERMSync(unlinkSync)\n\nexport const rimrafMoveRemove = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nconst rimrafMoveRemoveDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDir(\n path,\n { ...opt, tmp: await defaultTmp(path) },\n ent,\n )\n }\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir))\n return true\n}\n\nconst tmpUnlink = async (\n path: string,\n tmp: string,\n rm: (p: string) => Promise,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n await rename(path, tmpFile)\n return await rm(tmpFile)\n}\n\nexport const rimrafMoveRemoveSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafMoveRemoveDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafMoveRemoveDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDirSync(\n path,\n { ...opt, tmp: defaultTmpSync(path) },\n ent,\n )\n }\n const tmp: string = opt.tmp\n\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll\n }\n if (!removedAll) {\n return false\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync))\n return true\n}\n\nconst tmpUnlinkSync = (\n path: string,\n tmp: string,\n rmSync: (p: string) => void,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n renameSync(path, tmpFile)\n return rmSync(tmpFile)\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts new file mode 100644 index 0000000..cc84bf7 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafNative: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafNativeSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map new file mode 100644 index 0000000..6bb2a08 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-native.d.ts","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAIlE,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,KAAK,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,iBAAiB,KACrB,OAOF,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js new file mode 100644 index 0000000..719161f --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js @@ -0,0 +1,19 @@ +import { promises, rmSync } from './fs.js'; +const { rm } = promises; +export const rimrafNative = async (path, opt) => { + await rm(path, { + ...opt, + force: true, + recursive: true, + }); + return true; +}; +export const rimrafNativeSync = (path, opt) => { + rmSync(path, { + ...opt, + force: true, + recursive: true, + }); + return true; +}; +//# sourceMappingURL=rimraf-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map new file mode 100644 index 0000000..fde373b --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-native.js","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAC1C,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAY,EACZ,GAAuB,EACL,EAAE;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,GAAsB,EACb,EAAE;IACX,MAAM,CAAC,IAAI,EAAE;QACX,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { promises, rmSync } from './fs.js'\nconst { rm } = promises\n\nexport const rimrafNative = async (\n path: string,\n opt: RimrafAsyncOptions,\n): Promise => {\n await rm(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n\nexport const rimrafNativeSync = (\n path: string,\n opt: RimrafSyncOptions,\n): boolean => {\n rmSync(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts new file mode 100644 index 0000000..8e532ef --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafPosix: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafPosixSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-posix.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map new file mode 100644 index 0000000..c7b1b6a --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-posix.d.ts","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKlE,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAK,iBAAiB,YAOnE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js new file mode 100644 index 0000000..b850aed --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js @@ -0,0 +1,97 @@ +// the simple recursive removal, where unlink and rmdir are atomic +// Note that this approach does NOT work on Windows! +// We stat first and only unlink if the Dirent isn't a directory, +// because sunos will let root unlink a directory, and some +// SUPER weird breakage happens as a result. +import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'; +import { parse, resolve } from 'path'; +import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; +import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; +import { errorCode } from './error.js'; +const { lstat, rmdir, unlink } = promises; +export const rimrafPosix = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await ignoreENOENT(lstat(path).then(stat => rimrafPosixDir(path, opt, stat)))) ?? true); +}; +export const rimrafPosixSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return (ignoreENOENTSync(() => rimrafPosixDirSync(path, opt, lstatSync(path))) ?? true); +}; +const rimrafPosixDir = async (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? await readdirOrError(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await ignoreENOENT(unlink(path)); + return true; + } + const removedAll = (await Promise.all(entries.map(ent => rimrafPosixDir(resolve(path, ent.name), opt, ent)))).every(v => v === true); + if (!removedAll) { + return false; + } + // we don't ever ACTUALLY try to unlink /, because that can never work + // but when preserveRoot is false, we could be operating on it. + // No need to check if preserveRoot is not false. + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await ignoreENOENT(rmdir(path)); + return true; +}; +const rimrafPosixDirSync = (path, opt, ent) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + ignoreENOENTSync(() => unlinkSync(path)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const p = resolve(path, ent.name); + removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll; + } + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + ignoreENOENTSync(() => rmdirSync(path)); + return true; +}; +//# sourceMappingURL=rimraf-posix.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map new file mode 100644 index 0000000..afcfefa --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-posix.js","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"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","sourcesContent":["// the simple recursive removal, where unlink and rmdir are atomic\n// Note that this approach does NOT work on Windows!\n// We stat first and only unlink if the Dirent isn't a directory,\n// because sunos will let root unlink a directory, and some\n// SUPER weird breakage happens as a result.\n\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { parse, resolve } from 'path'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { errorCode } from './error.js'\nconst { lstat, rmdir, unlink } = promises\n\nexport const rimrafPosix = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafPosixDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nexport const rimrafPosixSync = (path: string, opt: RimrafSyncOptions) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafPosixDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafPosixDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(unlink(path))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafPosixDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n\n await ignoreENOENT(rmdir(path))\n return true\n}\n\nconst rimrafPosixDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => unlinkSync(path))\n return true\n }\n let removedAll: boolean = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (!removedAll) {\n return false\n }\n\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n\n ignoreENOENTSync(() => rmdirSync(path))\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts new file mode 100644 index 0000000..5556890 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; +export declare const rimrafWindows: (path: string, opt: RimrafAsyncOptions) => Promise; +export declare const rimrafWindowsSync: (path: string, opt: RimrafSyncOptions) => boolean; +//# sourceMappingURL=rimraf-windows.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map new file mode 100644 index 0000000..bcca3f3 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-windows.d.ts","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AA2DlE,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js new file mode 100644 index 0000000..1563ba4 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js @@ -0,0 +1,154 @@ +// This is the same as rimrafPosix, with the following changes: +// +// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff +// 2. All non-directories are removed first and then all directories are +// removed in a second sweep. +// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on +// the that folder. +// +// Note: "move then remove" is 2-10 times slower, and just as unreliable. +import { parse, resolve } from 'path'; +import { fixEPERM, fixEPERMSync } from './fix-eperm.js'; +import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'; +import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; +import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; +import { retryBusy, retryBusySync } from './retry-busy.js'; +import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; +import { errorCode } from './error.js'; +const { unlink, rmdir, lstat } = promises; +const rimrafWindowsFile = retryBusy(fixEPERM(unlink)); +const rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync)); +const rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir)); +const rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync)); +const rimrafWindowsDirMoveRemoveFallback = async (path, +// already filtered, remove from options so we don't call unnecessarily +// eslint-disable-next-line @typescript-eslint/no-unused-vars +{ filter, ...opt }) => { + /* c8 ignore next */ + opt?.signal?.throwIfAborted(); + try { + await rimrafWindowsDirRetry(path, opt); + return true; + } + catch (er) { + if (errorCode(er) === 'ENOTEMPTY') { + return rimrafMoveRemove(path, opt); + } + throw er; + } +}; +const rimrafWindowsDirMoveRemoveFallbackSync = (path, +// already filtered, remove from options so we don't call unnecessarily +// eslint-disable-next-line @typescript-eslint/no-unused-vars +{ filter, ...opt }) => { + opt?.signal?.throwIfAborted(); + try { + rimrafWindowsDirRetrySync(path, opt); + return true; + } + catch (er) { + if (errorCode(er) === 'ENOTEMPTY') { + return rimrafMoveRemoveSync(path, opt); + } + throw er; + } +}; +const START = Symbol('start'); +const CHILD = Symbol('child'); +const FINISH = Symbol('finish'); +export const rimrafWindows = async (path, opt) => { + opt?.signal?.throwIfAborted(); + return ((await ignoreENOENT(lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)))) ?? true); +}; +export const rimrafWindowsSync = (path, opt) => { + opt?.signal?.throwIfAborted(); + return (ignoreENOENTSync(() => rimrafWindowsDirSync(path, opt, lstatSync(path), START)) ?? true); +}; +const rimrafWindowsDir = async (path, opt, ent, state = START) => { + opt?.signal?.throwIfAborted(); + const entries = ent.isDirectory() ? await readdirOrError(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + // is a file + await ignoreENOENT(rimrafWindowsFile(path, opt)); + return true; + } + const s = state === START ? CHILD : state; + const removedAll = (await Promise.all(entries.map(ent => rimrafWindowsDir(resolve(path, ent.name), opt, ent, s)))).every(v => v === true); + if (state === START) { + return rimrafWindowsDir(path, opt, ent, FINISH); + } + else if (state === FINISH) { + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !(await opt.filter(path, ent))) { + return false; + } + await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt)); + } + return true; +}; +const rimrafWindowsDirSync = (path, opt, ent, state = START) => { + const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; + if (!Array.isArray(entries)) { + // this can only happen if lstat/readdir lied, or if the dir was + // swapped out with a file at just the right moment. + /* c8 ignore start */ + if (entries) { + if (errorCode(entries) === 'ENOENT') { + return true; + } + if (errorCode(entries) !== 'ENOTDIR') { + throw entries; + } + } + /* c8 ignore stop */ + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + // is a file + ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt)); + return true; + } + let removedAll = true; + for (const ent of entries) { + const s = state === START ? CHILD : state; + const p = resolve(path, ent.name); + removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll; + } + if (state === START) { + return rimrafWindowsDirSync(path, opt, ent, FINISH); + } + else if (state === FINISH) { + if (opt.preserveRoot === false && path === parse(path).root) { + return false; + } + if (!removedAll) { + return false; + } + if (opt.filter && !opt.filter(path, ent)) { + return false; + } + ignoreENOENTSync(() => rimrafWindowsDirMoveRemoveFallbackSync(path, opt)); + } + return true; +}; +//# sourceMappingURL=rimraf-windows.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map new file mode 100644 index 0000000..9a35cba --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rimraf-windows.js","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,sEAAsE;AACtE,wEAAwE;AACxE,gCAAgC;AAChC,0EAA0E;AAC1E,sBAAsB;AACtB,EAAE;AACF,yEAAyE;AAGzE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAErC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;AAEzC,MAAM,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;AACrD,MAAM,qBAAqB,GAAG,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAA;AACrE,MAAM,qBAAqB,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AACxD,MAAM,yBAAyB,GAAG,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;AAExE,MAAM,kCAAkC,GAAG,KAAK,EAC9C,IAAY;AACZ,uEAAuE;AACvE,6DAA6D;AAC7D,EAAE,MAAM,EAAE,GAAG,GAAG,EAAsB,EACpB,EAAE;IACpB,oBAAoB;IACpB,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,IAAI,CAAC;QACH,MAAM,qBAAqB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACpC,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED,MAAM,sCAAsC,GAAG,CAC7C,IAAY;AACZ,uEAAuE;AACvE,6DAA6D;AAC7D,EAAE,MAAM,EAAE,GAAG,GAAG,EAAqB,EAC5B,EAAE;IACX,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,IAAI,CAAC;QACH,yBAAyB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACxC,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;AAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;AAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;AAE/B,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,IAAY,EACZ,GAAuB,EACvB,EAAE;IACF,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,CAAC,MAAM,YAAY,CACjB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CACnE,CAAC,IAAI,IAAI,CACX,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAAY,EACZ,GAAsB,EACtB,EAAE;IACF,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,gBAAgB,CAAC,GAAG,EAAE,CACpB,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CACxD,IAAI,IAAI,CACV,CAAA;AACH,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,KAAK,EAC5B,IAAY,EACZ,GAAuB,EACvB,GAAmB,EACnB,KAAK,GAAG,KAAK,EACK,EAAE;IACpB,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAE7B,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,YAAY;QACZ,MAAM,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;QAChD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;IACzC,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAChB,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CACvD,CACF,CACF,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;IAExB,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,OAAO,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACjD,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,MAAM,YAAY,CAAC,kCAAkC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;IACnE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,CAC3B,IAAY,EACZ,GAAsB,EACtB,GAAmB,EACnB,KAAK,GAAG,KAAK,EACJ,EAAE;IACX,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,YAAY;QACZ,gBAAgB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;QACxD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,UAAU,GAAG,IAAI,CAAA;IACrB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;QACzC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,UAAU,GAAG,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,UAAU,CAAA;IACjE,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,OAAO,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACrD,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,gBAAgB,CAAC,GAAG,EAAE,CACpB,sCAAsC,CAAC,IAAI,EAAE,GAAG,CAAC,CAClD,CAAA;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["// This is the same as rimrafPosix, with the following changes:\n//\n// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff\n// 2. All non-directories are removed first and then all directories are\n// removed in a second sweep.\n// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on\n// the that folder.\n//\n// Note: \"move then remove\" is 2-10 times slower, and just as unreliable.\n\nimport { Dirent, Stats } from 'fs'\nimport { parse, resolve } from 'path'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { retryBusy, retryBusySync } from './retry-busy.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { errorCode } from './error.js'\nconst { unlink, rmdir, lstat } = promises\n\nconst rimrafWindowsFile = retryBusy(fixEPERM(unlink))\nconst rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync))\nconst rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir))\nconst rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync))\n\nconst rimrafWindowsDirMoveRemoveFallback = async (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafAsyncOptions,\n): Promise => {\n /* c8 ignore next */\n opt?.signal?.throwIfAborted()\n try {\n await rimrafWindowsDirRetry(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemove(path, opt)\n }\n throw er\n }\n}\n\nconst rimrafWindowsDirMoveRemoveFallbackSync = (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafSyncOptions,\n): boolean => {\n opt?.signal?.throwIfAborted()\n try {\n rimrafWindowsDirRetrySync(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemoveSync(path, opt)\n }\n throw er\n }\n}\n\nconst START = Symbol('start')\nconst CHILD = Symbol('child')\nconst FINISH = Symbol('finish')\n\nexport const rimrafWindows = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)),\n )) ?? true\n )\n}\n\nexport const rimrafWindowsSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafWindowsDirSync(path, opt, lstatSync(path), START),\n ) ?? true\n )\n}\n\nconst rimrafWindowsDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n state = START,\n): Promise => {\n opt?.signal?.throwIfAborted()\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n // is a file\n await ignoreENOENT(rimrafWindowsFile(path, opt))\n return true\n }\n\n const s = state === START ? CHILD : state\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafWindowsDir(resolve(path, ent.name), opt, ent, s),\n ),\n )\n ).every(v => v === true)\n\n if (state === START) {\n return rimrafWindowsDir(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt))\n }\n return true\n}\n\nconst rimrafWindowsDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n state = START,\n): boolean => {\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n // is a file\n ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const s = state === START ? CHILD : state\n const p = resolve(path, ent.name)\n removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll\n }\n\n if (state === START) {\n return rimrafWindowsDirSync(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() =>\n rimrafWindowsDirMoveRemoveFallbackSync(path, opt),\n )\n }\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts new file mode 100644 index 0000000..e191fd9 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts @@ -0,0 +1,4 @@ +import { RimrafAsyncOptions, RimrafOptions } from './index.js'; +export declare const useNative: (opt?: RimrafAsyncOptions) => boolean; +export declare const useNativeSync: (opt?: RimrafOptions) => boolean; +//# sourceMappingURL=use-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map new file mode 100644 index 0000000..be687c1 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"use-native.d.ts","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW9D,eAAO,MAAM,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,kBAAkB,KAAK,OAGf,CAAA;AACvC,eAAO,MAAM,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,aAAa,KAAK,OAGd,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.js b/apps/extension/node_modules/rimraf/dist/esm/use-native.js new file mode 100644 index 0000000..08098d8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/use-native.js @@ -0,0 +1,15 @@ +/* c8 ignore next */ +const [major = 0, minor = 0] = process.version + .replace(/^v/, '') + .split('.') + .map(v => parseInt(v, 10)); +const hasNative = major > 14 || (major === 14 && minor >= 14); +// we do NOT use native by default on Windows, because Node's native +// rm implementation is less advanced. Change this code if that changes. +export const useNative = !hasNative || process.platform === 'win32' ? + () => false + : opt => !opt?.signal && !opt?.filter; +export const useNativeSync = !hasNative || process.platform === 'win32' ? + () => false + : opt => !opt?.signal && !opt?.filter; +//# sourceMappingURL=use-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map b/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map new file mode 100644 index 0000000..5feb7d6 --- /dev/null +++ b/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map @@ -0,0 +1 @@ +{"version":3,"file":"use-native.js","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAEA,oBAAoB;AACpB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO;KAC3C,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;KACjB,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5B,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAE7D,oEAAoE;AACpE,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA;AACvC,MAAM,CAAC,MAAM,aAAa,GACxB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafOptions } from './index.js'\n\n/* c8 ignore next */\nconst [major = 0, minor = 0] = process.version\n .replace(/^v/, '')\n .split('.')\n .map(v => parseInt(v, 10))\nconst hasNative = major > 14 || (major === 14 && minor >= 14)\n\n// we do NOT use native by default on Windows, because Node's native\n// rm implementation is less advanced. Change this code if that changes.\nexport const useNative: (opt?: RimrafAsyncOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\nexport const useNativeSync: (opt?: RimrafOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf new file mode 100644 index 0000000..ce0aefc --- /dev/null +++ b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../../dist/esm/bin.mjs" "$@" +else + exec node "$basedir/../../dist/esm/bin.mjs" "$@" +fi diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD new file mode 100644 index 0000000..5a6ddd7 --- /dev/null +++ b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD @@ -0,0 +1,12 @@ +@SETLOCAL +@IF NOT DEFINED NODE_PATH ( + @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" +) ELSE ( + @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules;%NODE_PATH%" +) +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\..\dist\esm\bin.mjs" %* +) ELSE ( + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\..\dist\esm\bin.mjs" %* +) diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 new file mode 100644 index 0000000..f4911c8 --- /dev/null +++ b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 @@ -0,0 +1,41 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +$pathsep=":" +$env_node_path=$env:NODE_PATH +$new_node_path="D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" + $pathsep=";" +} else { + $new_node_path="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" +} +if ([string]::IsNullOrEmpty($env_node_path)) { + $env:NODE_PATH=$new_node_path +} else { + $env:NODE_PATH="$new_node_path$pathsep$env_node_path" +} + +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../../dist/esm/bin.mjs" $args + } else { + & "$basedir/node$exe" "$basedir/../../dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../../dist/esm/bin.mjs" $args + } else { + & "node$exe" "$basedir/../../dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} +$env:NODE_PATH=$env_node_path +exit $ret diff --git a/apps/extension/node_modules/rimraf/package.json b/apps/extension/node_modules/rimraf/package.json new file mode 100644 index 0000000..b00e93e --- /dev/null +++ b/apps/extension/node_modules/rimraf/package.json @@ -0,0 +1,77 @@ +{ + "name": "rimraf", + "version": "6.1.3", + "type": "module", + "tshy": { + "main": true, + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "bin": "./dist/esm/bin.mjs", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "files": [ + "dist" + ], + "description": "A deep deletion module for node (like `rm -rf`)", + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "BlueOak-1.0.0", + "repository": "git@github.com:isaacs/rimraf.git", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" + }, + "devDependencies": { + "@types/node": "^25.2.0", + "mkdirp": "^3.0.1", + "prettier": "^3.6.2", + "tap": "^21.1.1", + "tshy": "^3.0.3", + "typedoc": "^0.28.14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "engines": { + "node": "20 || >=22" + }, + "dependencies": { + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "keywords": [ + "rm", + "rm -rf", + "rm -fr", + "remove", + "directory", + "cli", + "rmdir", + "recursive" + ], + "module": "./dist/esm/index.js" +} diff --git a/apps/extension/package.json b/apps/extension/package.json new file mode 100644 index 0000000..fd60ef2 --- /dev/null +++ b/apps/extension/package.json @@ -0,0 +1,19 @@ +{ + "name": "@data-recipe/extension", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "clean": "rimraf dist", + "build": "tsup src/background.ts src/content.ts src/page-hook.ts src/sidepanel.ts --format iife --target es2020 --splitting false --clean --out-dir dist && node scripts/copy-assets.mjs", + "dev": "tsup src/background.ts src/content.ts src/page-hook.ts src/sidepanel.ts --format iife --target es2020 --splitting false --watch --out-dir dist --onSuccess \"node scripts/copy-assets.mjs\"", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@data-recipe/detector": "workspace:*", + "@data-recipe/recipe-core": "workspace:*" + }, + "devDependencies": { + "rimraf": "^6.0.1" + } +} diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json new file mode 100644 index 0000000..7496e3a --- /dev/null +++ b/apps/extension/public/manifest.json @@ -0,0 +1,30 @@ +{ + "manifest_version": 3, + "name": "DataRecipe / AI 有数", + "description": "发现网页背后的数据来源,并生成可复用的数据配方草稿。", + "version": "0.1.0", + "action": { + "default_title": "AI 有数" + }, + "background": { + "service_worker": "background.global.js" + }, + "content_scripts": [ + { + "matches": [""], + "js": ["content.global.js"], + "run_at": "document_start" + } + ], + "side_panel": { + "default_path": "sidepanel.html" + }, + "permissions": ["activeTab", "sidePanel", "tabs", "scripting"], + "host_permissions": [""], + "web_accessible_resources": [ + { + "resources": ["page-hook.global.js"], + "matches": [""] + } + ] +} diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css new file mode 100644 index 0000000..73ea911 --- /dev/null +++ b/apps/extension/public/sidepanel.css @@ -0,0 +1,223 @@ +:root { + color-scheme: light; + font-family: + Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", + sans-serif; + color: #202124; + background: #f7f8fa; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + min-width: 360px; +} + +button { + border: 1px solid #c9cdd4; + border-radius: 6px; + background: #ffffff; + color: #202124; + cursor: pointer; + font: inherit; + min-height: 36px; + padding: 0 12px; +} + +button:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +button.primary { + border-color: #0f766e; + background: #0f766e; + color: #ffffff; +} + +.app { + display: flex; + flex-direction: column; + gap: 14px; + min-height: 100vh; + padding: 16px; +} + +.header { + align-items: center; + display: flex; + justify-content: space-between; + gap: 12px; +} + +.eyebrow { + color: #5f6368; + font-size: 12px; + margin: 0 0 4px; +} + +h1 { + font-size: 22px; + line-height: 1.2; + margin: 0; +} + +.status { + border: 1px solid #d7dae0; + border-radius: 999px; + color: #5f6368; + font-size: 12px; + padding: 4px 9px; + white-space: nowrap; +} + +.status.active { + border-color: #14b8a6; + color: #0f766e; +} + +.toolbar { + display: grid; + gap: 8px; + grid-template-columns: 1fr 1fr; +} + +.summary { + align-items: baseline; + background: #ffffff; + border: 1px solid #e1e4e8; + border-radius: 8px; + display: flex; + gap: 6px; + padding: 12px; +} + +.summary strong { + font-size: 24px; +} + +.layout { + display: grid; + gap: 12px; +} + +.request-list, +.detail { + background: #ffffff; + border: 1px solid #e1e4e8; + border-radius: 8px; + min-width: 0; + padding: 12px; +} + +.section-title { + color: #5f6368; + font-size: 12px; + font-weight: 600; + margin-bottom: 10px; +} + +.list-empty, +.empty-detail { + color: #6b7280; + font-size: 13px; + line-height: 1.5; +} + +.request-item { + border: 1px solid #e5e7eb; + border-radius: 6px; + cursor: pointer; + display: grid; + gap: 5px; + margin-bottom: 8px; + padding: 10px; + text-align: left; + width: 100%; +} + +.request-item.active { + border-color: #0f766e; + box-shadow: 0 0 0 1px #0f766e inset; +} + +.request-title { + color: #111827; + font-size: 13px; + font-weight: 650; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.meta { + color: #6b7280; + display: flex; + flex-wrap: wrap; + font-size: 12px; + gap: 6px; +} + +.pill { + background: #eef2f7; + border-radius: 999px; + padding: 2px 7px; +} + +.finding { + color: #374151; + font-size: 13px; + line-height: 1.5; +} + +.detail-block { + margin-bottom: 14px; +} + +.detail-block h2 { + font-size: 14px; + margin: 0 0 8px; +} + +.key-value { + display: grid; + gap: 8px; +} + +.key-value dt { + color: #6b7280; + font-size: 12px; +} + +.key-value dd { + font-size: 13px; + margin: 2px 0 0; + overflow-wrap: anywhere; +} + +pre { + background: #111827; + border-radius: 6px; + color: #f9fafb; + font-size: 12px; + line-height: 1.45; + margin: 0; + max-height: 260px; + overflow: auto; + padding: 10px; + white-space: pre-wrap; +} + +details { + border-top: 1px solid #e5e7eb; + padding-top: 10px; +} + +summary { + cursor: pointer; + font-size: 13px; + font-weight: 600; +} diff --git a/apps/extension/public/sidepanel.html b/apps/extension/public/sidepanel.html new file mode 100644 index 0000000..23bf639 --- /dev/null +++ b/apps/extension/public/sidepanel.html @@ -0,0 +1,43 @@ + + + + + + AI 有数 + + + +
+
+
+

DataRecipe

+

AI 有数

+
+ 未开始 +
+ +
+ + +
+ +
+ 0 + 个数据来源 +
+ +
+
+
发现的数据来源
+
还没有发现数据来源
+
+ +
+
详情
+
点击「开始发现」,然后在页面里触发一次查询。
+
+
+
+ + + diff --git a/apps/extension/scripts/copy-assets.mjs b/apps/extension/scripts/copy-assets.mjs new file mode 100644 index 0000000..63ec88a --- /dev/null +++ b/apps/extension/scripts/copy-assets.mjs @@ -0,0 +1,10 @@ +import { cp, mkdir } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = dirname(dirname(fileURLToPath(import.meta.url))); +const publicDir = join(root, "public"); +const distDir = join(root, "dist"); + +await mkdir(distDir, { recursive: true }); +await cp(publicDir, distDir, { recursive: true }); diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts new file mode 100644 index 0000000..11e95c6 --- /dev/null +++ b/apps/extension/src/background.ts @@ -0,0 +1,124 @@ +import type { CapturedRequest } from "@data-recipe/detector"; +import type { PanelEvent, PanelMessage, PanelSnapshot, RuntimeMessage, TabControlMessage } from "./messages"; + +const tabCaptures = new Map(); +const activeTabs = new Set(); +const panelPorts = new Set(); + +chrome.runtime.onInstalled.addListener(() => { + if (chrome.sidePanel?.setPanelBehavior) { + void chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }); + } +}); + +chrome.action.onClicked.addListener(async (tab) => { + if (tab.id && chrome.sidePanel?.open) { + await chrome.sidePanel.open({ tabId: tab.id }); + } +}); + +chrome.runtime.onMessage.addListener((message: RuntimeMessage, sender) => { + if (message.type !== "captured-request" || !sender.tab?.id) { + return; + } + + const tabId = sender.tab.id; + const captures = tabCaptures.get(tabId) ?? []; + captures.unshift(message.capture); + tabCaptures.set(tabId, captures.slice(0, 100)); + + broadcast({ + type: "capture-added", + capture: message.capture, + snapshot: createSnapshot(tabId) + }); +}); + +chrome.runtime.onConnect.addListener((port) => { + if (port.name !== "data-recipe-sidepanel") { + return; + } + + panelPorts.add(port); + port.onDisconnect.addListener(() => panelPorts.delete(port)); + port.onMessage.addListener((message: PanelMessage) => { + void handlePanelMessage(port, message); + }); + + void sendSnapshot(port); +}); + +async function handlePanelMessage(port: chrome.runtime.Port, message: PanelMessage): Promise { + const tabId = await getActiveTabId(); + + if (message.type === "get-snapshot") { + send(port, { type: "snapshot", snapshot: createSnapshot(tabId) }); + return; + } + + if (!tabId) { + send(port, { type: "snapshot", snapshot: createSnapshot(null) }); + return; + } + + if (message.type === "start-discovery") { + activeTabs.add(tabId); + await sendControlMessage(tabId, { type: "start-discovery" }); + send(port, { type: "snapshot", snapshot: createSnapshot(tabId) }); + return; + } + + if (message.type === "stop-discovery") { + activeTabs.delete(tabId); + await sendControlMessage(tabId, { type: "stop-discovery" }); + send(port, { type: "snapshot", snapshot: createSnapshot(tabId) }); + return; + } + + if (message.type === "clear-captures") { + tabCaptures.set(tabId, []); + send(port, { type: "snapshot", snapshot: createSnapshot(tabId) }); + } +} + +async function sendSnapshot(port: chrome.runtime.Port): Promise { + const tabId = await getActiveTabId(); + send(port, { type: "snapshot", snapshot: createSnapshot(tabId) }); +} + +async function getActiveTabId(): Promise { + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + return tab?.id ?? null; +} + +async function sendControlMessage(tabId: number, message: TabControlMessage): Promise { + try { + await chrome.tabs.sendMessage(tabId, message); + } catch { + await chrome.scripting.executeScript({ + target: { tabId }, + files: ["content.global.js"] + }); + await chrome.tabs.sendMessage(tabId, message); + } +} + +function createSnapshot(tabId: number | null): PanelSnapshot { + return { + tabId, + state: tabId && activeTabs.has(tabId) ? "active" : "idle", + captures: tabId ? tabCaptures.get(tabId) ?? [] : [] + }; +} + +function broadcast(event: PanelEvent): void { + panelPorts.forEach((port) => send(port, event)); +} + +function send(port: chrome.runtime.Port, event: PanelEvent): void { + try { + port.postMessage(event); + } catch { + panelPorts.delete(port); + } +} diff --git a/apps/extension/src/content.ts b/apps/extension/src/content.ts new file mode 100644 index 0000000..72dfaf6 --- /dev/null +++ b/apps/extension/src/content.ts @@ -0,0 +1,59 @@ +import { formatPreview, parseQueryFromUrl, tryParseJson, type CapturedRequest } from "@data-recipe/detector"; +import type { PageCapturedMessage, PageControlMessage, TabControlMessage } from "./messages"; + +const scriptId = "data-recipe-page-hook"; + +injectPageHook(); + +chrome.runtime.onMessage.addListener((message: TabControlMessage) => { + if (message.type === "start-discovery" || message.type === "stop-discovery") { + postControl(message.type); + } +}); + +window.addEventListener("message", (event: MessageEvent) => { + if (event.source !== window || event.data?.source !== "data-recipe-page-hook") { + return; + } + + if (event.data.type !== "captured-request") { + return; + } + + const payload = event.data.payload; + const responseBody = + typeof payload.responseBody === "string" ? tryParseJson(payload.responseBody) : payload.responseBody; + + const capture: CapturedRequest = { + ...payload, + id: `${Date.now()}-${Math.random().toString(16).slice(2)}`, + pageUrl: window.location.href, + query: parseQueryFromUrl(payload.url), + responseBody, + responsePreview: formatPreview(responseBody), + capturedAt: Date.now() + }; + + void chrome.runtime.sendMessage({ type: "captured-request", capture }); +}); + +function injectPageHook(): void { + if (document.getElementById(scriptId)) { + return; + } + + const script = document.createElement("script"); + script.id = scriptId; + script.src = chrome.runtime.getURL("page-hook.global.js"); + script.async = false; + (document.documentElement || document.head).appendChild(script); + script.remove(); +} + +function postControl(type: PageControlMessage["type"]): void { + const message: PageControlMessage = { + source: "data-recipe-content", + type + }; + window.postMessage(message, "*"); +} diff --git a/apps/extension/src/messages.ts b/apps/extension/src/messages.ts new file mode 100644 index 0000000..633d65a --- /dev/null +++ b/apps/extension/src/messages.ts @@ -0,0 +1,38 @@ +import type { CapturedRequest } from "@data-recipe/detector"; + +export type DiscoveryState = "idle" | "active"; + +export interface PanelSnapshot { + tabId: number | null; + state: DiscoveryState; + captures: CapturedRequest[]; +} + +export type RuntimeMessage = + | { type: "captured-request"; capture: CapturedRequest } + | { type: "content-ready" }; + +export type TabControlMessage = + | { type: "start-discovery" } + | { type: "stop-discovery" }; + +export type PanelMessage = + | { type: "get-snapshot" } + | { type: "start-discovery" } + | { type: "stop-discovery" } + | { type: "clear-captures" }; + +export type PanelEvent = + | { type: "snapshot"; snapshot: PanelSnapshot } + | { type: "capture-added"; capture: CapturedRequest; snapshot: PanelSnapshot }; + +export interface PageCapturedMessage { + source: "data-recipe-page-hook"; + type: "captured-request"; + payload: Omit; +} + +export interface PageControlMessage { + source: "data-recipe-content"; + type: "start-discovery" | "stop-discovery"; +} diff --git a/apps/extension/src/page-hook.ts b/apps/extension/src/page-hook.ts new file mode 100644 index 0000000..cec3135 --- /dev/null +++ b/apps/extension/src/page-hook.ts @@ -0,0 +1,203 @@ +import type { PageControlMessage } from "./messages"; + +type CapturePayload = { + url: string; + method: string; + status: number; + requestBody: unknown; + responseBody: unknown; + responsePreview: string; + transport: "fetch" | "xhr"; +}; + +const state = { + enabled: false, + fetchPatched: false, + xhrPatched: false +}; + +patchFetch(); +patchXhr(); + +window.addEventListener("message", (event: MessageEvent) => { + if (event.source !== window || event.data?.source !== "data-recipe-content") { + return; + } + + state.enabled = event.data.type === "start-discovery"; +}); + +function patchFetch(): void { + if (state.fetchPatched || !window.fetch) { + return; + } + + state.fetchPatched = true; + const originalFetch = window.fetch.bind(window); + + window.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise => { + const requestInfo = await readFetchRequest(input, init); + const response = await originalFetch(input, init); + + if (state.enabled) { + void readResponseBody(response.clone()).then((responseBody) => { + emitCapture({ + ...requestInfo, + status: response.status, + responseBody, + responsePreview: makePreview(responseBody), + transport: "fetch" + }); + }); + } + + return response; + }; +} + +function patchXhr(): void { + if (state.xhrPatched || !window.XMLHttpRequest) { + return; + } + + state.xhrPatched = true; + const originalOpen = XMLHttpRequest.prototype.open; + const originalSend = XMLHttpRequest.prototype.send; + + XMLHttpRequest.prototype.open = function open(method: string, url: string | URL): void { + this.__dataRecipe = { + method, + url: String(url), + requestBody: null + }; + return originalOpen.apply(this, arguments as unknown as Parameters); + }; + + XMLHttpRequest.prototype.send = function send(body?: Document | XMLHttpRequestBodyInit | null): void { + if (this.__dataRecipe) { + this.__dataRecipe.requestBody = serializeBody(body); + } + + this.addEventListener("loadend", () => { + if (!state.enabled || !this.__dataRecipe) { + return; + } + + const responseBody = parseJsonLike(this.responseText); + emitCapture({ + url: toAbsoluteUrl(this.__dataRecipe.url), + method: this.__dataRecipe.method, + status: this.status, + requestBody: this.__dataRecipe.requestBody, + responseBody, + responsePreview: makePreview(responseBody), + transport: "xhr" + }); + }); + + return originalSend.apply(this, arguments as unknown as Parameters); + }; +} + +async function readFetchRequest(input: RequestInfo | URL, init?: RequestInit): Promise> { + const method = init?.method ?? (input instanceof Request ? input.method : "GET"); + const url = input instanceof Request ? input.url : String(input); + const requestBody = init?.body !== undefined ? serializeBody(init.body) : await readRequestClone(input); + + return { + url: toAbsoluteUrl(url), + method: method.toUpperCase(), + requestBody + }; +} + +async function readRequestClone(input: RequestInfo | URL): Promise { + if (!(input instanceof Request)) { + return null; + } + + try { + return parseJsonLike(await input.clone().text()); + } catch { + return null; + } +} + +async function readResponseBody(response: Response): Promise { + try { + return parseJsonLike(await response.text()); + } catch { + return null; + } +} + +function serializeBody(body: unknown): unknown { + if (body === undefined || body === null) { + return null; + } + + if (typeof body === "string") { + return parseJsonLike(body); + } + + if (body instanceof URLSearchParams) { + return Object.fromEntries(body.entries()); + } + + if (body instanceof FormData) { + return Object.fromEntries(Array.from(body.entries()).map(([key, value]) => [key, String(value)])); + } + + if (body instanceof Blob || body instanceof ArrayBuffer) { + return "[binary body]"; + } + + return String(body); +} + +function parseJsonLike(text: string): unknown { + const trimmed = text.trim(); + if (!trimmed) { + return null; + } + + try { + return JSON.parse(trimmed); + } catch { + return trimmed; + } +} + +function makePreview(value: unknown): string { + const text = typeof value === "string" ? value : JSON.stringify(value, null, 2); + return text.length > 1800 ? `${text.slice(0, 1800)}...` : text; +} + +function toAbsoluteUrl(url: string): string { + try { + return new URL(url, window.location.href).href; + } catch { + return url; + } +} + +function emitCapture(payload: CapturePayload): void { + window.postMessage( + { + source: "data-recipe-page-hook", + type: "captured-request", + payload + }, + "*" + ); +} + +declare global { + interface XMLHttpRequest { + __dataRecipe?: { + method: string; + url: string; + requestBody: unknown; + }; + } +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts new file mode 100644 index 0000000..28cd06c --- /dev/null +++ b/apps/extension/src/sidepanel.ts @@ -0,0 +1,211 @@ +import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; +import type { PanelEvent, PanelSnapshot } from "./messages"; + +const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); + +const state: { + snapshot: PanelSnapshot; + selectedId: string | null; +} = { + snapshot: { + tabId: null, + state: "idle", + captures: [] + }, + selectedId: null +}; + +const elements = { + statusBadge: getElement("statusBadge"), + startButton: getElement("startButton"), + stopButton: getElement("stopButton"), + captureCount: getElement("captureCount"), + requestList: getElement("requestList"), + requestDetail: getElement("requestDetail") +}; + +elements.startButton.addEventListener("click", () => port.postMessage({ type: "start-discovery" })); +elements.stopButton.addEventListener("click", () => port.postMessage({ type: "stop-discovery" })); + +port.onMessage.addListener((event: PanelEvent) => { + if (event.type === "snapshot") { + applySnapshot(event.snapshot); + return; + } + + if (event.type === "capture-added") { + applySnapshot(event.snapshot); + state.selectedId = event.capture.id; + render(); + } +}); + +port.postMessage({ type: "get-snapshot" }); + +function applySnapshot(snapshot: PanelSnapshot): void { + state.snapshot = snapshot; + if (!state.selectedId && snapshot.captures[0]) { + state.selectedId = snapshot.captures[0].id; + } + render(); +} + +function render(): void { + const isActive = state.snapshot.state === "active"; + elements.statusBadge.textContent = isActive ? "发现中" : "未开始"; + elements.statusBadge.classList.toggle("active", isActive); + elements.startButton.disabled = isActive; + elements.stopButton.disabled = !isActive; + elements.captureCount.textContent = String(state.snapshot.captures.length); + + renderList(); + renderDetail(); +} + +function renderList(): void { + const captures = state.snapshot.captures; + elements.requestList.innerHTML = ""; + + if (captures.length === 0) { + elements.requestList.className = "list-empty"; + elements.requestList.textContent = "还没有发现数据来源"; + return; + } + + elements.requestList.className = ""; + + captures.forEach((capture) => { + const detection = summarizeResponse(capture.responseBody); + const button = document.createElement("button"); + button.type = "button"; + button.className = `request-item${capture.id === state.selectedId ? " active" : ""}`; + button.addEventListener("click", () => { + state.selectedId = capture.id; + render(); + }); + + const title = document.createElement("div"); + title.className = "request-title"; + title.textContent = readableUrl(capture.url); + + const meta = document.createElement("div"); + meta.className = "meta"; + meta.append(pill(capture.method), pill(String(capture.status)), pill(detection.looksLikeList ? "像列表数据" : "普通数据")); + + button.append(title, meta); + elements.requestList.append(button); + }); +} + +function renderDetail(): void { + const capture = state.snapshot.captures.find((item) => item.id === state.selectedId); + + if (!capture) { + elements.requestDetail.className = "empty-detail"; + elements.requestDetail.textContent = "点击「开始发现」,然后在页面里触发一次查询。"; + return; + } + + const detection = summarizeResponse(capture.responseBody); + const recipe = buildRecipeFromCapture(capture); + + elements.requestDetail.className = ""; + elements.requestDetail.innerHTML = ""; + elements.requestDetail.append( + block("基础信息", keyValues([ + ["数据来源", capture.url], + ["请求方式", capture.method], + ["状态", String(capture.status)], + ["发现时间", new Date(capture.capturedAt).toLocaleString()] + ])), + block("智能判断", findingList([ + detection.looksLikeList ? "看起来像列表数据" : "暂未判断为列表数据", + detection.hasArray ? `包含数组:${detection.arrayPaths.join(", ")}` : "暂未发现数组", + detection.keywordPaths.length > 0 + ? `可能包含总数、页码或列表字段:${detection.keywordPaths.join(", ")}` + : "暂未发现 total / count / page / records / list 等字段" + ])), + block("查询条件", pre(JSON.stringify({ query: capture.query, body: capture.requestBody ?? {} }, null, 2))), + block("返回预览", pre(capture.responsePreview || "无可展示内容")), + advancedInfo(capture, recipe) + ); +} + +function advancedInfo(capture: CapturedRequest, recipe: unknown): HTMLElement { + const details = document.createElement("details"); + const summary = document.createElement("summary"); + summary.textContent = "高级信息"; + const content = document.createElement("div"); + content.className = "detail-block"; + content.append( + block("传输方式", keyValues([["类型", capture.transport]])), + block("数据配方草稿", pre(JSON.stringify(recipe, null, 2))) + ); + details.append(summary, content); + return details; +} + +function block(titleText: string, content: HTMLElement): HTMLElement { + const section = document.createElement("section"); + section.className = "detail-block"; + const title = document.createElement("h2"); + title.textContent = titleText; + section.append(title, content); + return section; +} + +function keyValues(items: Array<[string, string]>): HTMLElement { + const list = document.createElement("dl"); + list.className = "key-value"; + items.forEach(([key, value]) => { + const wrapper = document.createElement("div"); + const dt = document.createElement("dt"); + const dd = document.createElement("dd"); + dt.textContent = key; + dd.textContent = value; + wrapper.append(dt, dd); + list.append(wrapper); + }); + return list; +} + +function findingList(items: string[]): HTMLElement { + const container = document.createElement("div"); + container.className = "finding"; + items.forEach((item) => { + const line = document.createElement("div"); + line.textContent = item; + container.append(line); + }); + return container; +} + +function pre(text: string): HTMLElement { + const element = document.createElement("pre"); + element.textContent = text; + return element; +} + +function pill(text: string): HTMLElement { + const element = document.createElement("span"); + element.className = "pill"; + element.textContent = text; + return element; +} + +function readableUrl(urlValue: string): string { + try { + const url = new URL(urlValue); + return `${url.hostname}${url.pathname}`; + } catch { + return urlValue; + } +} + +function getElement(id: string): T { + const element = document.getElementById(id); + if (!element) { + throw new Error(`Missing element: ${id}`); + } + return element as T; +} diff --git a/apps/extension/tsconfig.json b/apps/extension/tsconfig.json new file mode 100644 index 0000000..7dd6ed9 --- /dev/null +++ b/apps/extension/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": ["chrome"], + "noEmit": true + }, + "include": ["src", "scripts"] +} diff --git a/docs/test-page.html b/docs/test-page.html new file mode 100644 index 0000000..9086569 --- /dev/null +++ b/docs/test-page.html @@ -0,0 +1,86 @@ + + + + + + DataRecipe 测试页 + + + +
+

DataRecipe 测试页

+

加载插件后打开侧边栏,点击「开始发现」,再点击下面的按钮触发 fetch 或 XHR 请求。

+ + +
等待请求...
+
+ + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..0a5a26f --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "data-recipe", + "version": "0.1.0", + "private": true, + "description": "Turn web page queries and API responses into reusable data recipes for AI agents.", + "scripts": { + "build": "pnpm -r build", + "typecheck": "pnpm -r typecheck", + "dev:extension": "pnpm --filter @data-recipe/extension dev", + "build:extension": "pnpm --filter @data-recipe/extension build" + }, + "devDependencies": { + "@types/chrome": "^0.0.268", + "tsup": "^8.2.4", + "typescript": "^5.5.4" + }, + "packageManager": "pnpm@9.7.0" +} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/package.json b/packages/detector/node_modules/@data-recipe/recipe-core/package.json new file mode 100644 index 0000000..e4538ee --- /dev/null +++ b/packages/detector/node_modules/@data-recipe/recipe-core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@data-recipe/recipe-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + } +} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts b/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts new file mode 100644 index 0000000..7cdb195 --- /dev/null +++ b/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts @@ -0,0 +1,111 @@ +export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; + +export type JsonObject = Record; + +export interface DataRecipe { + name: string; + displayName: string; + source: DataRecipeSource; + request: DataRecipeRequest; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: DataRecipeField[]; +} + +export interface DataRecipeSource { + type: "web_api"; + pageUrl: string; + apiUrl: string; + method: HttpMethod; +} + +export interface DataRecipeRequest { + query: JsonObject; + body: unknown; +} + +export interface DataRecipeResponse { + type: "list" | "object" | "unknown"; + listPath: string; + totalPath: string; +} + +export interface DataRecipePagination { + type: "page_number" | "cursor" | "unknown"; + pageParam: string; + pageSizeParam: string; + totalPath: string; +} + +export interface DataRecipeField { + name: string; + path: string; + type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + sample?: unknown; +} + +export interface CreateRecipeInput { + pageUrl: string; + apiUrl: string; + method: HttpMethod; + query: JsonObject; + body: unknown; + responseType: DataRecipeResponse["type"]; + listPath: string; + totalPath: string; + fields: DataRecipeField[]; +} + +export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { + const name = buildRecipeName(input.apiUrl); + + return { + name, + displayName: "数据来源", + source: { + type: "web_api", + pageUrl: input.pageUrl, + apiUrl: input.apiUrl, + method: input.method + }, + request: { + query: input.query, + body: input.body ?? {} + }, + response: { + type: input.responseType, + listPath: input.listPath, + totalPath: input.totalPath + }, + pagination: { + type: "page_number", + pageParam: "", + pageSizeParam: "", + totalPath: input.totalPath + }, + fields: input.fields + }; +} + +function buildRecipeName(apiUrl: string): string { + try { + const url = new URL(apiUrl); + const pathPart = url.pathname + .split("/") + .filter(Boolean) + .slice(-2) + .join("_"); + return normalizeName(pathPart || url.hostname); + } catch { + return normalizeName(apiUrl || "data_source"); + } +} + +function normalizeName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_+|_+$/g, ""); + + return normalized || "data_source"; +} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json b/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/detector/package.json b/packages/detector/package.json new file mode 100644 index 0000000..e7a9ca2 --- /dev/null +++ b/packages/detector/package.json @@ -0,0 +1,15 @@ +{ + "name": "@data-recipe/detector", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@data-recipe/recipe-core": "workspace:*" + } +} diff --git a/packages/detector/src/index.ts b/packages/detector/src/index.ts new file mode 100644 index 0000000..00145a3 --- /dev/null +++ b/packages/detector/src/index.ts @@ -0,0 +1,215 @@ +import { + createDataRecipeDraft, + type DataRecipe, + type DataRecipeField, + type JsonObject +} from "@data-recipe/recipe-core"; + +export interface CapturedRequest { + id: string; + pageUrl: string; + url: string; + method: string; + status: number; + requestBody: unknown; + query: JsonObject; + responseBody: unknown; + responsePreview: string; + capturedAt: number; + transport: "fetch" | "xhr"; +} + +export interface ResponseDetection { + isJson: boolean; + looksLikeList: boolean; + hasArray: boolean; + arrayPaths: string[]; + listPath: string; + totalPath: string; + keywordPaths: string[]; + fields: DataRecipeField[]; +} + +const TOTAL_KEYS = new Set(["total", "count", "totalCount", "total_count", "recordCount", "record_count"]); +const LIST_KEYS = new Set(["records", "list", "items", "rows", "data", "result"]); +const PAGE_KEYS = new Set(["page", "pageNo", "pageNum", "page_number", "current", "currentPage", "pageSize"]); + +export function parseQueryFromUrl(urlValue: string): JsonObject { + try { + const url = new URL(urlValue); + const query: JsonObject = {}; + url.searchParams.forEach((value, key) => { + if (query[key] === undefined) { + query[key] = value; + } else if (Array.isArray(query[key])) { + (query[key] as string[]).push(value); + } else { + query[key] = [query[key], value]; + } + }); + return query; + } catch { + return {}; + } +} + +export function tryParseJson(text: string): unknown { + if (!text.trim()) { + return null; + } + + try { + return JSON.parse(text); + } catch { + return text; + } +} + +export function summarizeResponse(responseBody: unknown): ResponseDetection { + const isJson = responseBody !== null && typeof responseBody === "object"; + const arrayPaths: string[] = []; + const keywordPaths: string[] = []; + const totalPaths: string[] = []; + + if (isJson) { + walk(responseBody, "$", (path, value, key) => { + if (Array.isArray(value)) { + arrayPaths.push(path); + } + + if (key && (TOTAL_KEYS.has(key) || LIST_KEYS.has(key) || PAGE_KEYS.has(key))) { + keywordPaths.push(path); + } + + if (key && TOTAL_KEYS.has(key) && typeof value !== "object") { + totalPaths.push(path); + } + }); + } + + const listPath = pickListPath(responseBody, arrayPaths); + const fields = inferFieldsAtPath(responseBody, listPath); + + return { + isJson, + looksLikeList: arrayPaths.length > 0 && fields.length > 0, + hasArray: arrayPaths.length > 0, + arrayPaths, + listPath, + totalPath: totalPaths[0] ?? "", + keywordPaths, + fields + }; +} + +export function buildRecipeFromCapture(capture: CapturedRequest): DataRecipe { + const detection = summarizeResponse(capture.responseBody); + + return createDataRecipeDraft({ + pageUrl: capture.pageUrl, + apiUrl: capture.url, + method: capture.method, + query: capture.query, + body: capture.requestBody ?? {}, + responseType: detection.looksLikeList ? "list" : detection.isJson ? "object" : "unknown", + listPath: detection.listPath, + totalPath: detection.totalPath, + fields: detection.fields + }); +} + +export function formatPreview(value: unknown, maxLength = 1800): string { + const text = typeof value === "string" ? value : JSON.stringify(value, null, 2); + + if (!text) { + return ""; + } + + return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; +} + +function pickListPath(responseBody: unknown, arrayPaths: string[]): string { + if (arrayPaths.length === 0) { + return ""; + } + + const preferred = arrayPaths.find((path) => { + const key = path.split(".").at(-1) ?? ""; + return LIST_KEYS.has(key); + }); + + return preferred ?? arrayPaths[0] ?? ""; +} + +function inferFieldsAtPath(responseBody: unknown, listPath: string): DataRecipeField[] { + const target = getByPath(responseBody, listPath); + const sample = Array.isArray(target) ? target.find((item) => item && typeof item === "object") : null; + + if (!sample || typeof sample !== "object" || Array.isArray(sample)) { + return []; + } + + return Object.entries(sample).map(([key, value]) => ({ + name: key, + path: `${listPath}.${key}`, + type: inferJsonType(value), + sample: simplifySample(value) + })); +} + +function getByPath(value: unknown, path: string): unknown { + if (!path || path === "$") { + return value; + } + + return path + .replace(/^\$\./, "") + .split(".") + .filter(Boolean) + .reduce((current, part) => { + if (current && typeof current === "object" && part in current) { + return (current as Record)[part]; + } + return undefined; + }, value); +} + +function walk(value: unknown, path: string, visit: (path: string, value: unknown, key?: string) => void): void { + visit(path, value, path.split(".").at(-1)); + + if (!value || typeof value !== "object") { + return; + } + + if (Array.isArray(value)) { + value.slice(0, 3).forEach((item, index) => walk(item, `${path}[${index}]`, visit)); + return; + } + + Object.entries(value).forEach(([key, child]) => { + const childPath = path === "$" ? `$.${key}` : `${path}.${key}`; + walk(child, childPath, visit); + }); +} + +function inferJsonType(value: unknown): DataRecipeField["type"] { + if (value === null) return "null"; + if (Array.isArray(value)) return "array"; + if (typeof value === "string") return "string"; + if (typeof value === "number") return "number"; + if (typeof value === "boolean") return "boolean"; + if (typeof value === "object") return "object"; + return "unknown"; +} + +function simplifySample(value: unknown): unknown { + if (Array.isArray(value)) { + return value.slice(0, 2); + } + + if (value && typeof value === "object") { + return Object.fromEntries(Object.entries(value).slice(0, 5)); + } + + return value; +} diff --git a/packages/detector/tsconfig.json b/packages/detector/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/packages/detector/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/recipe-core/package.json b/packages/recipe-core/package.json new file mode 100644 index 0000000..e4538ee --- /dev/null +++ b/packages/recipe-core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@data-recipe/recipe-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + } +} diff --git a/packages/recipe-core/src/index.ts b/packages/recipe-core/src/index.ts new file mode 100644 index 0000000..7cdb195 --- /dev/null +++ b/packages/recipe-core/src/index.ts @@ -0,0 +1,111 @@ +export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; + +export type JsonObject = Record; + +export interface DataRecipe { + name: string; + displayName: string; + source: DataRecipeSource; + request: DataRecipeRequest; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: DataRecipeField[]; +} + +export interface DataRecipeSource { + type: "web_api"; + pageUrl: string; + apiUrl: string; + method: HttpMethod; +} + +export interface DataRecipeRequest { + query: JsonObject; + body: unknown; +} + +export interface DataRecipeResponse { + type: "list" | "object" | "unknown"; + listPath: string; + totalPath: string; +} + +export interface DataRecipePagination { + type: "page_number" | "cursor" | "unknown"; + pageParam: string; + pageSizeParam: string; + totalPath: string; +} + +export interface DataRecipeField { + name: string; + path: string; + type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + sample?: unknown; +} + +export interface CreateRecipeInput { + pageUrl: string; + apiUrl: string; + method: HttpMethod; + query: JsonObject; + body: unknown; + responseType: DataRecipeResponse["type"]; + listPath: string; + totalPath: string; + fields: DataRecipeField[]; +} + +export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { + const name = buildRecipeName(input.apiUrl); + + return { + name, + displayName: "数据来源", + source: { + type: "web_api", + pageUrl: input.pageUrl, + apiUrl: input.apiUrl, + method: input.method + }, + request: { + query: input.query, + body: input.body ?? {} + }, + response: { + type: input.responseType, + listPath: input.listPath, + totalPath: input.totalPath + }, + pagination: { + type: "page_number", + pageParam: "", + pageSizeParam: "", + totalPath: input.totalPath + }, + fields: input.fields + }; +} + +function buildRecipeName(apiUrl: string): string { + try { + const url = new URL(apiUrl); + const pathPart = url.pathname + .split("/") + .filter(Boolean) + .slice(-2) + .join("_"); + return normalizeName(pathPart || url.hostname); + } catch { + return normalizeName(apiUrl || "data_source"); + } +} + +function normalizeName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_+|_+$/g, ""); + + return normalized || "data_source"; +} diff --git a/packages/recipe-core/tsconfig.json b/packages/recipe-core/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/packages/recipe-core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json new file mode 100644 index 0000000..e4538ee --- /dev/null +++ b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@data-recipe/recipe-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + } +} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts new file mode 100644 index 0000000..7cdb195 --- /dev/null +++ b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts @@ -0,0 +1,111 @@ +export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; + +export type JsonObject = Record; + +export interface DataRecipe { + name: string; + displayName: string; + source: DataRecipeSource; + request: DataRecipeRequest; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: DataRecipeField[]; +} + +export interface DataRecipeSource { + type: "web_api"; + pageUrl: string; + apiUrl: string; + method: HttpMethod; +} + +export interface DataRecipeRequest { + query: JsonObject; + body: unknown; +} + +export interface DataRecipeResponse { + type: "list" | "object" | "unknown"; + listPath: string; + totalPath: string; +} + +export interface DataRecipePagination { + type: "page_number" | "cursor" | "unknown"; + pageParam: string; + pageSizeParam: string; + totalPath: string; +} + +export interface DataRecipeField { + name: string; + path: string; + type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + sample?: unknown; +} + +export interface CreateRecipeInput { + pageUrl: string; + apiUrl: string; + method: HttpMethod; + query: JsonObject; + body: unknown; + responseType: DataRecipeResponse["type"]; + listPath: string; + totalPath: string; + fields: DataRecipeField[]; +} + +export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { + const name = buildRecipeName(input.apiUrl); + + return { + name, + displayName: "数据来源", + source: { + type: "web_api", + pageUrl: input.pageUrl, + apiUrl: input.apiUrl, + method: input.method + }, + request: { + query: input.query, + body: input.body ?? {} + }, + response: { + type: input.responseType, + listPath: input.listPath, + totalPath: input.totalPath + }, + pagination: { + type: "page_number", + pageParam: "", + pageSizeParam: "", + totalPath: input.totalPath + }, + fields: input.fields + }; +} + +function buildRecipeName(apiUrl: string): string { + try { + const url = new URL(apiUrl); + const pathPart = url.pathname + .split("/") + .filter(Boolean) + .slice(-2) + .join("_"); + return normalizeName(pathPart || url.hostname); + } catch { + return normalizeName(apiUrl || "data_source"); + } +} + +function normalizeName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_+|_+$/g, ""); + + return normalized || "data_source"; +} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/recipe-runner/package.json b/packages/recipe-runner/package.json new file mode 100644 index 0000000..0cc0225 --- /dev/null +++ b/packages/recipe-runner/package.json @@ -0,0 +1,15 @@ +{ + "name": "@data-recipe/recipe-runner", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@data-recipe/recipe-core": "workspace:*" + } +} diff --git a/packages/recipe-runner/src/index.ts b/packages/recipe-runner/src/index.ts new file mode 100644 index 0000000..3250f01 --- /dev/null +++ b/packages/recipe-runner/src/index.ts @@ -0,0 +1,6 @@ +import type { DataRecipe } from "@data-recipe/recipe-core"; + +export interface RecipeRunResult { + recipe: DataRecipe; + rows: unknown[]; +} diff --git a/packages/recipe-runner/tsconfig.json b/packages/recipe-runner/tsconfig.json new file mode 100644 index 0000000..c34ef95 --- /dev/null +++ b/packages/recipe-runner/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..3ff5faa --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "apps/*" + - "packages/*" diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..65996e7 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM"], + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "noUncheckedIndexedAccess": true, + "resolveJsonModule": true, + "isolatedModules": true + } +} From 9aa51d935e3e7035eb3d4faa34ed78aa5678441e Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:12:23 +0800 Subject: [PATCH 02/25] chore: ignore generated dependencies --- .gitignore | 5 + apps/extension/node_modules/.bin/rimraf | 17 -- apps/extension/node_modules/.bin/rimraf.CMD | 12 - apps/extension/node_modules/.bin/rimraf.ps1 | 41 --- .../@data-recipe/recipe-core/package.json | 12 - .../@data-recipe/recipe-core/src/index.ts | 111 -------- .../@data-recipe/recipe-core/tsconfig.json | 10 - .../@data-recipe/detector/package.json | 15 -- .../@data-recipe/detector/src/index.ts | 215 --------------- .../@data-recipe/detector/tsconfig.json | 10 - .../@data-recipe/recipe-core/package.json | 12 - .../@data-recipe/recipe-core/src/index.ts | 111 -------- .../@data-recipe/recipe-core/tsconfig.json | 10 - apps/extension/node_modules/rimraf/LICENSE.md | 55 ---- apps/extension/node_modules/rimraf/README.md | 255 ------------------ .../rimraf/dist/commonjs/default-tmp.d.ts | 3 - .../rimraf/dist/commonjs/default-tmp.d.ts.map | 1 - .../rimraf/dist/commonjs/default-tmp.js | 58 ---- .../rimraf/dist/commonjs/default-tmp.js.map | 1 - .../rimraf/dist/commonjs/error.d.ts | 6 - .../rimraf/dist/commonjs/error.d.ts.map | 1 - .../rimraf/dist/commonjs/error.js | 10 - .../rimraf/dist/commonjs/error.js.map | 1 - .../rimraf/dist/commonjs/fix-eperm.d.ts | 3 - .../rimraf/dist/commonjs/fix-eperm.d.ts.map | 1 - .../rimraf/dist/commonjs/fix-eperm.js | 38 --- .../rimraf/dist/commonjs/fix-eperm.js.map | 1 - .../node_modules/rimraf/dist/commonjs/fs.d.ts | 16 -- .../rimraf/dist/commonjs/fs.d.ts.map | 1 - .../node_modules/rimraf/dist/commonjs/fs.js | 33 --- .../rimraf/dist/commonjs/fs.js.map | 1 - .../rimraf/dist/commonjs/ignore-enoent.d.ts | 3 - .../dist/commonjs/ignore-enoent.d.ts.map | 1 - .../rimraf/dist/commonjs/ignore-enoent.js | 24 -- .../rimraf/dist/commonjs/ignore-enoent.js.map | 1 - .../rimraf/dist/commonjs/index.d.ts | 50 ---- .../rimraf/dist/commonjs/index.d.ts.map | 1 - .../rimraf/dist/commonjs/index.js | 84 ------ .../rimraf/dist/commonjs/index.js.map | 1 - .../rimraf/dist/commonjs/opt-arg.d.ts | 34 --- .../rimraf/dist/commonjs/opt-arg.d.ts.map | 1 - .../rimraf/dist/commonjs/opt-arg.js | 54 ---- .../rimraf/dist/commonjs/opt-arg.js.map | 1 - .../rimraf/dist/commonjs/package.json | 3 - .../rimraf/dist/commonjs/path-arg.d.ts | 4 - .../rimraf/dist/commonjs/path-arg.d.ts.map | 1 - .../rimraf/dist/commonjs/path-arg.js | 49 ---- .../rimraf/dist/commonjs/path-arg.js.map | 1 - .../dist/commonjs/readdir-or-error.d.ts | 3 - .../dist/commonjs/readdir-or-error.d.ts.map | 1 - .../rimraf/dist/commonjs/readdir-or-error.js | 19 -- .../dist/commonjs/readdir-or-error.js.map | 1 - .../rimraf/dist/commonjs/retry-busy.d.ts | 8 - .../rimraf/dist/commonjs/retry-busy.d.ts.map | 1 - .../rimraf/dist/commonjs/retry-busy.js | 65 ----- .../rimraf/dist/commonjs/retry-busy.js.map | 1 - .../rimraf/dist/commonjs/rimraf-manual.d.ts | 3 - .../dist/commonjs/rimraf-manual.d.ts.map | 1 - .../rimraf/dist/commonjs/rimraf-manual.js | 8 - .../rimraf/dist/commonjs/rimraf-manual.js.map | 1 - .../dist/commonjs/rimraf-move-remove.d.ts | 4 - .../dist/commonjs/rimraf-move-remove.d.ts.map | 1 - .../dist/commonjs/rimraf-move-remove.js | 138 ---------- .../dist/commonjs/rimraf-move-remove.js.map | 1 - .../rimraf/dist/commonjs/rimraf-native.d.ts | 4 - .../dist/commonjs/rimraf-native.d.ts.map | 1 - .../rimraf/dist/commonjs/rimraf-native.js | 24 -- .../rimraf/dist/commonjs/rimraf-native.js.map | 1 - .../rimraf/dist/commonjs/rimraf-posix.d.ts | 4 - .../dist/commonjs/rimraf-posix.d.ts.map | 1 - .../rimraf/dist/commonjs/rimraf-posix.js | 102 ------- .../rimraf/dist/commonjs/rimraf-posix.js.map | 1 - .../rimraf/dist/commonjs/rimraf-windows.d.ts | 4 - .../dist/commonjs/rimraf-windows.d.ts.map | 1 - .../rimraf/dist/commonjs/rimraf-windows.js | 159 ----------- .../dist/commonjs/rimraf-windows.js.map | 1 - .../rimraf/dist/commonjs/use-native.d.ts | 4 - .../rimraf/dist/commonjs/use-native.d.ts.map | 1 - .../rimraf/dist/commonjs/use-native.js | 18 -- .../rimraf/dist/commonjs/use-native.js.map | 1 - .../node_modules/rimraf/dist/esm/bin.d.mts | 3 - .../rimraf/dist/esm/bin.d.mts.map | 1 - .../node_modules/rimraf/dist/esm/bin.mjs | 250 ----------------- .../node_modules/rimraf/dist/esm/bin.mjs.map | 1 - .../rimraf/dist/esm/default-tmp.d.ts | 3 - .../rimraf/dist/esm/default-tmp.d.ts.map | 1 - .../rimraf/dist/esm/default-tmp.js | 55 ---- .../rimraf/dist/esm/default-tmp.js.map | 1 - .../node_modules/rimraf/dist/esm/error.d.ts | 6 - .../rimraf/dist/esm/error.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/error.js | 5 - .../node_modules/rimraf/dist/esm/error.js.map | 1 - .../rimraf/dist/esm/fix-eperm.d.ts | 3 - .../rimraf/dist/esm/fix-eperm.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/fix-eperm.js | 33 --- .../rimraf/dist/esm/fix-eperm.js.map | 1 - .../node_modules/rimraf/dist/esm/fs.d.ts | 16 -- .../node_modules/rimraf/dist/esm/fs.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/fs.js | 18 -- .../node_modules/rimraf/dist/esm/fs.js.map | 1 - .../rimraf/dist/esm/ignore-enoent.d.ts | 3 - .../rimraf/dist/esm/ignore-enoent.d.ts.map | 1 - .../rimraf/dist/esm/ignore-enoent.js | 19 -- .../rimraf/dist/esm/ignore-enoent.js.map | 1 - .../node_modules/rimraf/dist/esm/index.d.ts | 50 ---- .../rimraf/dist/esm/index.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/index.js | 76 ------ .../node_modules/rimraf/dist/esm/index.js.map | 1 - .../node_modules/rimraf/dist/esm/opt-arg.d.ts | 34 --- .../rimraf/dist/esm/opt-arg.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/opt-arg.js | 47 ---- .../rimraf/dist/esm/opt-arg.js.map | 1 - .../node_modules/rimraf/dist/esm/package.json | 3 - .../rimraf/dist/esm/path-arg.d.ts | 4 - .../rimraf/dist/esm/path-arg.d.ts.map | 1 - .../node_modules/rimraf/dist/esm/path-arg.js | 47 ---- .../rimraf/dist/esm/path-arg.js.map | 1 - .../rimraf/dist/esm/readdir-or-error.d.ts | 3 - .../rimraf/dist/esm/readdir-or-error.d.ts.map | 1 - .../rimraf/dist/esm/readdir-or-error.js | 14 - .../rimraf/dist/esm/readdir-or-error.js.map | 1 - .../rimraf/dist/esm/retry-busy.d.ts | 8 - .../rimraf/dist/esm/retry-busy.d.ts.map | 1 - .../rimraf/dist/esm/retry-busy.js | 60 ----- .../rimraf/dist/esm/retry-busy.js.map | 1 - .../rimraf/dist/esm/rimraf-manual.d.ts | 3 - .../rimraf/dist/esm/rimraf-manual.d.ts.map | 1 - .../rimraf/dist/esm/rimraf-manual.js | 5 - .../rimraf/dist/esm/rimraf-manual.js.map | 1 - .../rimraf/dist/esm/rimraf-move-remove.d.ts | 4 - .../dist/esm/rimraf-move-remove.d.ts.map | 1 - .../rimraf/dist/esm/rimraf-move-remove.js | 133 --------- .../rimraf/dist/esm/rimraf-move-remove.js.map | 1 - .../rimraf/dist/esm/rimraf-native.d.ts | 4 - .../rimraf/dist/esm/rimraf-native.d.ts.map | 1 - .../rimraf/dist/esm/rimraf-native.js | 19 -- .../rimraf/dist/esm/rimraf-native.js.map | 1 - .../rimraf/dist/esm/rimraf-posix.d.ts | 4 - .../rimraf/dist/esm/rimraf-posix.d.ts.map | 1 - .../rimraf/dist/esm/rimraf-posix.js | 97 ------- .../rimraf/dist/esm/rimraf-posix.js.map | 1 - .../rimraf/dist/esm/rimraf-windows.d.ts | 4 - .../rimraf/dist/esm/rimraf-windows.d.ts.map | 1 - .../rimraf/dist/esm/rimraf-windows.js | 154 ----------- .../rimraf/dist/esm/rimraf-windows.js.map | 1 - .../rimraf/dist/esm/use-native.d.ts | 4 - .../rimraf/dist/esm/use-native.d.ts.map | 1 - .../rimraf/dist/esm/use-native.js | 15 -- .../rimraf/dist/esm/use-native.js.map | 1 - .../rimraf/node_modules/.bin/rimraf | 17 -- .../rimraf/node_modules/.bin/rimraf.CMD | 12 - .../rimraf/node_modules/.bin/rimraf.ps1 | 41 --- .../node_modules/rimraf/package.json | 77 ------ .../@data-recipe/recipe-core/package.json | 12 - .../@data-recipe/recipe-core/src/index.ts | 111 -------- .../@data-recipe/recipe-core/tsconfig.json | 10 - .../@data-recipe/recipe-core/package.json | 12 - .../@data-recipe/recipe-core/src/index.ts | 111 -------- .../@data-recipe/recipe-core/tsconfig.json | 10 - 159 files changed, 5 insertions(+), 3610 deletions(-) create mode 100644 .gitignore delete mode 100644 apps/extension/node_modules/.bin/rimraf delete mode 100644 apps/extension/node_modules/.bin/rimraf.CMD delete mode 100644 apps/extension/node_modules/.bin/rimraf.ps1 delete mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json delete mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts delete mode 100644 apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json delete mode 100644 apps/extension/node_modules/@data-recipe/detector/package.json delete mode 100644 apps/extension/node_modules/@data-recipe/detector/src/index.ts delete mode 100644 apps/extension/node_modules/@data-recipe/detector/tsconfig.json delete mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/package.json delete mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts delete mode 100644 apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json delete mode 100644 apps/extension/node_modules/rimraf/LICENSE.md delete mode 100644 apps/extension/node_modules/rimraf/README.md delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/error.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/index.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/package.json delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.js delete mode 100644 apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.d.mts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.mjs delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/error.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/fs.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/index.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/package.json delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.js delete mode 100644 apps/extension/node_modules/rimraf/dist/esm/use-native.js.map delete mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf delete mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD delete mode 100644 apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 delete mode 100644 apps/extension/node_modules/rimraf/package.json delete mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/package.json delete mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts delete mode 100644 packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json delete mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json delete mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts delete mode 100644 packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fe0009 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +.turbo/ +.DS_Store +*.log diff --git a/apps/extension/node_modules/.bin/rimraf b/apps/extension/node_modules/.bin/rimraf deleted file mode 100644 index b19312d..0000000 --- a/apps/extension/node_modules/.bin/rimraf +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*) basedir=`cygpath -w "$basedir"`;; -esac - -if [ -z "$NODE_PATH" ]; then - export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" -else - export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules:$NODE_PATH" -fi -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../rimraf/dist/esm/bin.mjs" "$@" -else - exec node "$basedir/../rimraf/dist/esm/bin.mjs" "$@" -fi diff --git a/apps/extension/node_modules/.bin/rimraf.CMD b/apps/extension/node_modules/.bin/rimraf.CMD deleted file mode 100644 index 6c04d44..0000000 --- a/apps/extension/node_modules/.bin/rimraf.CMD +++ /dev/null @@ -1,12 +0,0 @@ -@SETLOCAL -@IF NOT DEFINED NODE_PATH ( - @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" -) ELSE ( - @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules;%NODE_PATH%" -) -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" "%~dp0\..\rimraf\dist\esm\bin.mjs" %* -) ELSE ( - @SET PATHEXT=%PATHEXT:;.JS;=;% - node "%~dp0\..\rimraf\dist\esm\bin.mjs" %* -) diff --git a/apps/extension/node_modules/.bin/rimraf.ps1 b/apps/extension/node_modules/.bin/rimraf.ps1 deleted file mode 100644 index e5e1227..0000000 --- a/apps/extension/node_modules/.bin/rimraf.ps1 +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -$pathsep=":" -$env_node_path=$env:NODE_PATH -$new_node_path="D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" - $pathsep=";" -} else { - $new_node_path="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" -} -if ([string]::IsNullOrEmpty($env_node_path)) { - $env:NODE_PATH=$new_node_path -} else { - $env:NODE_PATH="$new_node_path$pathsep$env_node_path" -} - -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args - } else { - & "$basedir/node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args - } else { - & "node$exe" "$basedir/../rimraf/dist/esm/bin.mjs" $args - } - $ret=$LASTEXITCODE -} -$env:NODE_PATH=$env_node_path -exit $ret diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json deleted file mode 100644 index e4538ee..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@data-recipe/recipe-core", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - } -} diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts deleted file mode 100644 index 7cdb195..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/src/index.ts +++ /dev/null @@ -1,111 +0,0 @@ -export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; - -export type JsonObject = Record; - -export interface DataRecipe { - name: string; - displayName: string; - source: DataRecipeSource; - request: DataRecipeRequest; - response: DataRecipeResponse; - pagination: DataRecipePagination; - fields: DataRecipeField[]; -} - -export interface DataRecipeSource { - type: "web_api"; - pageUrl: string; - apiUrl: string; - method: HttpMethod; -} - -export interface DataRecipeRequest { - query: JsonObject; - body: unknown; -} - -export interface DataRecipeResponse { - type: "list" | "object" | "unknown"; - listPath: string; - totalPath: string; -} - -export interface DataRecipePagination { - type: "page_number" | "cursor" | "unknown"; - pageParam: string; - pageSizeParam: string; - totalPath: string; -} - -export interface DataRecipeField { - name: string; - path: string; - type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; - sample?: unknown; -} - -export interface CreateRecipeInput { - pageUrl: string; - apiUrl: string; - method: HttpMethod; - query: JsonObject; - body: unknown; - responseType: DataRecipeResponse["type"]; - listPath: string; - totalPath: string; - fields: DataRecipeField[]; -} - -export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { - const name = buildRecipeName(input.apiUrl); - - return { - name, - displayName: "数据来源", - source: { - type: "web_api", - pageUrl: input.pageUrl, - apiUrl: input.apiUrl, - method: input.method - }, - request: { - query: input.query, - body: input.body ?? {} - }, - response: { - type: input.responseType, - listPath: input.listPath, - totalPath: input.totalPath - }, - pagination: { - type: "page_number", - pageParam: "", - pageSizeParam: "", - totalPath: input.totalPath - }, - fields: input.fields - }; -} - -function buildRecipeName(apiUrl: string): string { - try { - const url = new URL(apiUrl); - const pathPart = url.pathname - .split("/") - .filter(Boolean) - .slice(-2) - .join("_"); - return normalizeName(pathPart || url.hostname); - } catch { - return normalizeName(apiUrl || "data_source"); - } -} - -function normalizeName(value: string): string { - const normalized = value - .toLowerCase() - .replace(/[^a-z0-9]+/g, "_") - .replace(/^_+|_+$/g, ""); - - return normalized || "data_source"; -} diff --git a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json b/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json deleted file mode 100644 index c34ef95..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/node_modules/@data-recipe/recipe-core/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src"] -} diff --git a/apps/extension/node_modules/@data-recipe/detector/package.json b/apps/extension/node_modules/@data-recipe/detector/package.json deleted file mode 100644 index e7a9ca2..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@data-recipe/detector", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "@data-recipe/recipe-core": "workspace:*" - } -} diff --git a/apps/extension/node_modules/@data-recipe/detector/src/index.ts b/apps/extension/node_modules/@data-recipe/detector/src/index.ts deleted file mode 100644 index 00145a3..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/src/index.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { - createDataRecipeDraft, - type DataRecipe, - type DataRecipeField, - type JsonObject -} from "@data-recipe/recipe-core"; - -export interface CapturedRequest { - id: string; - pageUrl: string; - url: string; - method: string; - status: number; - requestBody: unknown; - query: JsonObject; - responseBody: unknown; - responsePreview: string; - capturedAt: number; - transport: "fetch" | "xhr"; -} - -export interface ResponseDetection { - isJson: boolean; - looksLikeList: boolean; - hasArray: boolean; - arrayPaths: string[]; - listPath: string; - totalPath: string; - keywordPaths: string[]; - fields: DataRecipeField[]; -} - -const TOTAL_KEYS = new Set(["total", "count", "totalCount", "total_count", "recordCount", "record_count"]); -const LIST_KEYS = new Set(["records", "list", "items", "rows", "data", "result"]); -const PAGE_KEYS = new Set(["page", "pageNo", "pageNum", "page_number", "current", "currentPage", "pageSize"]); - -export function parseQueryFromUrl(urlValue: string): JsonObject { - try { - const url = new URL(urlValue); - const query: JsonObject = {}; - url.searchParams.forEach((value, key) => { - if (query[key] === undefined) { - query[key] = value; - } else if (Array.isArray(query[key])) { - (query[key] as string[]).push(value); - } else { - query[key] = [query[key], value]; - } - }); - return query; - } catch { - return {}; - } -} - -export function tryParseJson(text: string): unknown { - if (!text.trim()) { - return null; - } - - try { - return JSON.parse(text); - } catch { - return text; - } -} - -export function summarizeResponse(responseBody: unknown): ResponseDetection { - const isJson = responseBody !== null && typeof responseBody === "object"; - const arrayPaths: string[] = []; - const keywordPaths: string[] = []; - const totalPaths: string[] = []; - - if (isJson) { - walk(responseBody, "$", (path, value, key) => { - if (Array.isArray(value)) { - arrayPaths.push(path); - } - - if (key && (TOTAL_KEYS.has(key) || LIST_KEYS.has(key) || PAGE_KEYS.has(key))) { - keywordPaths.push(path); - } - - if (key && TOTAL_KEYS.has(key) && typeof value !== "object") { - totalPaths.push(path); - } - }); - } - - const listPath = pickListPath(responseBody, arrayPaths); - const fields = inferFieldsAtPath(responseBody, listPath); - - return { - isJson, - looksLikeList: arrayPaths.length > 0 && fields.length > 0, - hasArray: arrayPaths.length > 0, - arrayPaths, - listPath, - totalPath: totalPaths[0] ?? "", - keywordPaths, - fields - }; -} - -export function buildRecipeFromCapture(capture: CapturedRequest): DataRecipe { - const detection = summarizeResponse(capture.responseBody); - - return createDataRecipeDraft({ - pageUrl: capture.pageUrl, - apiUrl: capture.url, - method: capture.method, - query: capture.query, - body: capture.requestBody ?? {}, - responseType: detection.looksLikeList ? "list" : detection.isJson ? "object" : "unknown", - listPath: detection.listPath, - totalPath: detection.totalPath, - fields: detection.fields - }); -} - -export function formatPreview(value: unknown, maxLength = 1800): string { - const text = typeof value === "string" ? value : JSON.stringify(value, null, 2); - - if (!text) { - return ""; - } - - return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; -} - -function pickListPath(responseBody: unknown, arrayPaths: string[]): string { - if (arrayPaths.length === 0) { - return ""; - } - - const preferred = arrayPaths.find((path) => { - const key = path.split(".").at(-1) ?? ""; - return LIST_KEYS.has(key); - }); - - return preferred ?? arrayPaths[0] ?? ""; -} - -function inferFieldsAtPath(responseBody: unknown, listPath: string): DataRecipeField[] { - const target = getByPath(responseBody, listPath); - const sample = Array.isArray(target) ? target.find((item) => item && typeof item === "object") : null; - - if (!sample || typeof sample !== "object" || Array.isArray(sample)) { - return []; - } - - return Object.entries(sample).map(([key, value]) => ({ - name: key, - path: `${listPath}.${key}`, - type: inferJsonType(value), - sample: simplifySample(value) - })); -} - -function getByPath(value: unknown, path: string): unknown { - if (!path || path === "$") { - return value; - } - - return path - .replace(/^\$\./, "") - .split(".") - .filter(Boolean) - .reduce((current, part) => { - if (current && typeof current === "object" && part in current) { - return (current as Record)[part]; - } - return undefined; - }, value); -} - -function walk(value: unknown, path: string, visit: (path: string, value: unknown, key?: string) => void): void { - visit(path, value, path.split(".").at(-1)); - - if (!value || typeof value !== "object") { - return; - } - - if (Array.isArray(value)) { - value.slice(0, 3).forEach((item, index) => walk(item, `${path}[${index}]`, visit)); - return; - } - - Object.entries(value).forEach(([key, child]) => { - const childPath = path === "$" ? `$.${key}` : `${path}.${key}`; - walk(child, childPath, visit); - }); -} - -function inferJsonType(value: unknown): DataRecipeField["type"] { - if (value === null) return "null"; - if (Array.isArray(value)) return "array"; - if (typeof value === "string") return "string"; - if (typeof value === "number") return "number"; - if (typeof value === "boolean") return "boolean"; - if (typeof value === "object") return "object"; - return "unknown"; -} - -function simplifySample(value: unknown): unknown { - if (Array.isArray(value)) { - return value.slice(0, 2); - } - - if (value && typeof value === "object") { - return Object.fromEntries(Object.entries(value).slice(0, 5)); - } - - return value; -} diff --git a/apps/extension/node_modules/@data-recipe/detector/tsconfig.json b/apps/extension/node_modules/@data-recipe/detector/tsconfig.json deleted file mode 100644 index c34ef95..0000000 --- a/apps/extension/node_modules/@data-recipe/detector/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src"] -} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/package.json b/apps/extension/node_modules/@data-recipe/recipe-core/package.json deleted file mode 100644 index e4538ee..0000000 --- a/apps/extension/node_modules/@data-recipe/recipe-core/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@data-recipe/recipe-core", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - } -} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts b/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts deleted file mode 100644 index 7cdb195..0000000 --- a/apps/extension/node_modules/@data-recipe/recipe-core/src/index.ts +++ /dev/null @@ -1,111 +0,0 @@ -export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; - -export type JsonObject = Record; - -export interface DataRecipe { - name: string; - displayName: string; - source: DataRecipeSource; - request: DataRecipeRequest; - response: DataRecipeResponse; - pagination: DataRecipePagination; - fields: DataRecipeField[]; -} - -export interface DataRecipeSource { - type: "web_api"; - pageUrl: string; - apiUrl: string; - method: HttpMethod; -} - -export interface DataRecipeRequest { - query: JsonObject; - body: unknown; -} - -export interface DataRecipeResponse { - type: "list" | "object" | "unknown"; - listPath: string; - totalPath: string; -} - -export interface DataRecipePagination { - type: "page_number" | "cursor" | "unknown"; - pageParam: string; - pageSizeParam: string; - totalPath: string; -} - -export interface DataRecipeField { - name: string; - path: string; - type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; - sample?: unknown; -} - -export interface CreateRecipeInput { - pageUrl: string; - apiUrl: string; - method: HttpMethod; - query: JsonObject; - body: unknown; - responseType: DataRecipeResponse["type"]; - listPath: string; - totalPath: string; - fields: DataRecipeField[]; -} - -export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { - const name = buildRecipeName(input.apiUrl); - - return { - name, - displayName: "数据来源", - source: { - type: "web_api", - pageUrl: input.pageUrl, - apiUrl: input.apiUrl, - method: input.method - }, - request: { - query: input.query, - body: input.body ?? {} - }, - response: { - type: input.responseType, - listPath: input.listPath, - totalPath: input.totalPath - }, - pagination: { - type: "page_number", - pageParam: "", - pageSizeParam: "", - totalPath: input.totalPath - }, - fields: input.fields - }; -} - -function buildRecipeName(apiUrl: string): string { - try { - const url = new URL(apiUrl); - const pathPart = url.pathname - .split("/") - .filter(Boolean) - .slice(-2) - .join("_"); - return normalizeName(pathPart || url.hostname); - } catch { - return normalizeName(apiUrl || "data_source"); - } -} - -function normalizeName(value: string): string { - const normalized = value - .toLowerCase() - .replace(/[^a-z0-9]+/g, "_") - .replace(/^_+|_+$/g, ""); - - return normalized || "data_source"; -} diff --git a/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json b/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json deleted file mode 100644 index c34ef95..0000000 --- a/apps/extension/node_modules/@data-recipe/recipe-core/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src"] -} diff --git a/apps/extension/node_modules/rimraf/LICENSE.md b/apps/extension/node_modules/rimraf/LICENSE.md deleted file mode 100644 index c5402b9..0000000 --- a/apps/extension/node_modules/rimraf/LICENSE.md +++ /dev/null @@ -1,55 +0,0 @@ -# Blue Oak Model License - -Version 1.0.0 - -## Purpose - -This license gives everyone as much permission to work with -this software as possible, while protecting contributors -from liability. - -## Acceptance - -In order to receive this license, you must agree to its -rules. The rules of this license are both obligations -under that agreement and conditions to your license. -You must not do anything with this software that triggers -a rule that you cannot or will not follow. - -## Copyright - -Each contributor licenses you to do everything with this -software that would otherwise infringe that contributor's -copyright in it. - -## Notices - -You must ensure that everyone who gets a copy of -any part of this software from you, with or without -changes, also gets the text of this license or a link to -. - -## Excuse - -If anyone notifies you in writing that you have not -complied with [Notices](#notices), you can keep your -license by taking all practical steps to comply within 30 -days after the notice. If you do not do so, your license -ends immediately. - -## Patent - -Each contributor licenses you to do everything with this -software that would otherwise infringe any patent claims -they can license or become able to license. - -## Reliability - -No contributor can revoke this license. - -## No Liability - -***As far as the law allows, this software comes as is, -without any warranty or condition, and no contributor -will be liable to anyone for any damages related to this -software or this license, under any kind of legal claim.*** diff --git a/apps/extension/node_modules/rimraf/README.md b/apps/extension/node_modules/rimraf/README.md deleted file mode 100644 index 2e53476..0000000 --- a/apps/extension/node_modules/rimraf/README.md +++ /dev/null @@ -1,255 +0,0 @@ -The [UNIX command]() `rm -rf` for node -in a cross-platform implementation. - -Install with `npm install rimraf`. - -> [!CAUTION] -> -> ## Please Be Safe, this tool deletes and moves stuff, by design -> -> The _intended purpose_ of this tool is to remove files and -> directories from the filesystem, aggressively and recursively -> removing all items that it can find under a given target. -> -> It goes without saying that you _must not pass untrusted input -> to this function or CLI tool_, just as you would not to the -> `rm(1)` command or the `unlink(2)` function. It is very -> challenging to guarantee that _any_ user input will be safe to -> remove recursively in this way. -> -> Furthermore, note that if you allow untrusted parties to -> provide arguments to the `rimraf` command line tool, they may -> also specify the `--tmp=` folder used by the -> `--impl=move-remove` strategy, which can move files to an -> arbitrary place on disk. -> -> Because the intended purpose of this tool is the permanent -> destruction of filesystem entries, any security reports that -> rely on untrusted input being passed to the function or command -> line tool will be rejected. -> -> **It is your responsibility as a user to never pass untrusted -> user input to this module, or your system can be destroyed or -> compromised.** - -## Major Changes - -### v5 to v6 - -- Require node `20` or `>=22` -- Add `--version` to CLI - -### v4 to v5 - -- There is no default export anymore. Import the functions directly - using, e.g., `import { rimrafSync } from 'rimraf'`. - -### v3 to v4 - -- The function returns a `Promise` instead of taking a callback. -- Globbing requires the `--glob` CLI option or `glob` option property - to be set. (Removed in 4.0 and 4.1, opt-in support added in 4.2.) -- Functions take arrays of paths, as well as a single path. -- Native implementation used by default when available, except on - Windows, where this implementation is faster and more reliable. -- New implementation on Windows, falling back to "move then - remove" strategy when exponential backoff for `EBUSY` fails to - resolve the situation. -- Simplified implementation on POSIX, since the Windows - affordances are not necessary there. -- As of 4.3, return/resolve value is boolean instead of undefined. - -## API - -Hybrid module, load either with `import` or `require()`. - -```js -// 'rimraf' export is the one you probably want, but other -// strategies exported as well. -import { rimraf, rimrafSync, native, nativeSync } from 'rimraf' -// or -const { rimraf, rimrafSync, native, nativeSync } = require('rimraf') -``` - -All removal functions return a boolean indicating that all -entries were successfully removed. - -The only case in which this will not return `true` is if -something was omitted from the removal via a `filter` option. - -### `rimraf(f, [opts]) -> Promise` - -This first parameter is a path or array of paths. The second -argument is an options object. - -Options: - -- `preserveRoot`: If set to boolean `false`, then allow the - recursive removal of the root directory. Otherwise, this is - not allowed. -- `tmp`: Windows only. Temp folder to place files and - folders for the "move then remove" fallback. Must be on the - same physical device as the path being deleted. Defaults to - `os.tmpdir()` when that is on the same drive letter as the path - being deleted, or `${drive}:\temp` if present, or `${drive}:\` - if not. -- `maxRetries`: Windows and Native only. Maximum number of - retry attempts in case of `EBUSY`, `EMFILE`, and `ENFILE` - errors. Default `10` for Windows implementation, `0` for Native - implementation. -- `backoff`: Windows only. Rate of exponential backoff for async - removal in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. - Should be a number greater than 1. Default `1.2` -- `maxBackoff`: Windows only. Maximum total backoff time in ms to - attempt asynchronous retries in case of `EBUSY`, `EMFILE`, and - `ENFILE` errors. Default `200`. With the default `1.2` backoff - rate, this results in 14 retries, with the final retry being - delayed 33ms. -- `retryDelay`: Native only. Time to wait between retries, using - linear backoff. Default `100`. -- `signal` Pass in an AbortSignal to cancel the directory - removal. This is useful when removing large folder structures, - if you'd like to limit the time spent. - - Using a `signal` option prevents the use of Node's built-in - `fs.rm` because that implementation does not support abort - signals. - -- `glob` Boolean flag to treat path as glob pattern, or an object - specifying [`glob` options](https://github.com/isaacs/node-glob). -- `filter` Method that returns a boolean indicating whether that - path should be deleted. With async `rimraf` methods, this may - return a Promise that resolves to a boolean. (Since Promises - are truthy, returning a Promise from a sync filter is the same - as just not filtering anything.) - - The first argument to the filter is the path string. The - second argument is either a `Dirent` or `Stats` object for that - path. (The first path explored will be a `Stats`, the rest - will be `Dirent`.) - - If a filter method is provided, it will _only_ remove entries - if the filter returns (or resolves to) a truthy value. Omitting - a directory will still allow its children to be removed, unless - they are also filtered out, but any parents of a filtered entry - will not be removed, since the directory will not be empty in - that case. - - Using a filter method prevents the use of Node's built-in - `fs.rm` because that implementation does not support filtering. - -Any other options are provided to the native Node.js `fs.rm` implementation -when that is used. - -This will attempt to choose the best implementation, based on the Node.js -version and `process.platform`. To force a specific implementation, use -one of the other functions provided. - -### `rimraf.sync(f, [opts])`
`rimraf.rimrafSync(f, [opts])` - -Synchronous form of `rimraf()` - -Note that, unlike many file system operations, the synchronous form will -typically be significantly _slower_ than the async form, because recursive -deletion is extremely parallelizable. - -### `rimraf.native(f, [opts])` - -Uses the built-in `fs.rm` implementation that Node.js provides. This is -used by default on Node.js versions greater than or equal to `14.14.0`. - -### `rimraf.native.sync(f, [opts])`
`rimraf.nativeSync(f, [opts])` - -Synchronous form of `rimraf.native` - -### `rimraf.manual(f, [opts])` - -Use the JavaScript implementation appropriate for your operating system. - -### `rimraf.manual.sync(f, [opts])`
`rimraf.manualSync(f, opts)` - -Synchronous form of `rimraf.manual()` - -### `rimraf.windows(f, [opts])` - -JavaScript implementation of file removal appropriate for Windows -platforms. Works around `unlink` and `rmdir` not being atomic -operations, and `EPERM` when deleting files with certain -permission modes. - -First deletes all non-directory files within the tree, and then -removes all directories, which should ideally be empty by that -time. When an `ENOTEMPTY` is raised in the second pass, falls -back to the `rimraf.moveRemove` strategy as needed. - -### `rimraf.windows.sync(path, [opts])`
`rimraf.windowsSync(path, [opts])` - -Synchronous form of `rimraf.windows()` - -### `rimraf.moveRemove(path, [opts])` - -Moves all files and folders to the parent directory of `path` -with a temporary filename prior to attempting to remove them. - -Note that, in cases where the operation fails, this _may_ leave -files lying around in the parent directory with names like -`.file-basename.txt.0.123412341`. Until the Windows kernel -provides a way to perform atomic `unlink` and `rmdir` operations, -this is, unfortunately, unavoidable. - -To move files to a different temporary directory other than the -parent, provide `opts.tmp`. Note that this _must_ be on the same -physical device as the folder being deleted, or else the -operation will fail. - -This is the slowest strategy, but most reliable on Windows -platforms. Used as a last-ditch fallback by `rimraf.windows()`. - -### `rimraf.moveRemove.sync(path, [opts])`
`rimraf.moveRemoveSync(path, [opts])` - -Synchronous form of `rimraf.moveRemove()` - -### Command Line Interface - -``` -rimraf version 6.0.1 - -Usage: rimraf [ ...] -Deletes all files and folders at "path", recursively. - -Options: - -- Treat all subsequent arguments as paths - -h --help Display this usage info - --version Display version - --preserve-root Do not remove '/' recursively (default) - --no-preserve-root Do not treat '/' specially - -G --no-glob Treat arguments as literal paths, not globs (default) - -g --glob Treat arguments as glob patterns - -v --verbose Be verbose when deleting files, showing them as - they are removed. Not compatible with --impl=native - -V --no-verbose Be silent when deleting files, showing nothing as - they are removed (default) - -i --interactive Ask for confirmation before deleting anything - Not compatible with --impl=native - -I --no-interactive Do not ask for confirmation before deleting - - --impl= Specify the implementation to use: - rimraf: choose the best option (default) - native: the built-in implementation in Node.js - manual: the platform-specific JS implementation - posix: the Posix JS implementation - windows: the Windows JS implementation (falls back to - move-remove on ENOTEMPTY) - move-remove: a slow reliable Windows fallback - -Implementation-specific options: - --tmp= Temp file folder for 'move-remove' implementation - --max-retries= maxRetries for 'native' and 'windows' implementations - --retry-delay= retryDelay for 'native' implementation, default 100 - --backoff= Exponential backoff factor for retries (default: 1.2) -``` - -## mkdirp - -If you need to _create_ a directory recursively, check out -[mkdirp](https://github.com/isaacs/node-mkdirp). diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts deleted file mode 100644 index a68e925..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const defaultTmp: (path: string) => Promise; -export declare const defaultTmpSync: (path: string) => string; -//# sourceMappingURL=default-tmp.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map deleted file mode 100644 index e3200d4..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"default-tmp.d.ts","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAiEA,eAAO,MAAM,UAAU,SApCc,MAAM,oBAqCuB,CAAA;AAClE,eAAO,MAAM,cAAc,SAtBQ,MAAM,WAuBiC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js deleted file mode 100644 index 8061980..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.defaultTmpSync = exports.defaultTmp = void 0; -// The default temporary folder location for use in the windows algorithm. -// It's TEMPting to use dirname(path), since that's guaranteed to be on the -// same device. However, this means that: -// rimraf(path).then(() => rimraf(dirname(path))) -// will often fail with EBUSY, because the parent dir contains -// marked-for-deletion directory entries (which do not show up in readdir). -// The approach here is to use os.tmpdir() if it's on the same drive letter, -// or resolve(path, '\\temp') if it exists, or the root of the drive if not. -// On Posix (not that you'd be likely to use the windows algorithm there), -// it uses os.tmpdir() always. -const os_1 = require("os"); -const path_1 = require("path"); -const fs_js_1 = require("./fs.js"); -const { stat } = fs_js_1.promises; -const isDirSync = (path) => { - try { - return (0, fs_js_1.statSync)(path).isDirectory(); - } - catch { - return false; - } -}; -const isDir = (path) => stat(path).then(st => st.isDirectory(), () => false); -const win32DefaultTmp = async (path) => { - const { root } = (0, path_1.parse)(path); - const tmp = (0, os_1.tmpdir)(); - const { root: tmpRoot } = (0, path_1.parse)(tmp); - if (root.toLowerCase() === tmpRoot.toLowerCase()) { - return tmp; - } - const driveTmp = (0, path_1.resolve)(root, '/temp'); - if (await isDir(driveTmp)) { - return driveTmp; - } - return root; -}; -const win32DefaultTmpSync = (path) => { - const { root } = (0, path_1.parse)(path); - const tmp = (0, os_1.tmpdir)(); - const { root: tmpRoot } = (0, path_1.parse)(tmp); - if (root.toLowerCase() === tmpRoot.toLowerCase()) { - return tmp; - } - const driveTmp = (0, path_1.resolve)(root, '/temp'); - if (isDirSync(driveTmp)) { - return driveTmp; - } - return root; -}; -// eslint-disable-next-line @typescript-eslint/require-await -const posixDefaultTmp = async () => (0, os_1.tmpdir)(); -const posixDefaultTmpSync = () => (0, os_1.tmpdir)(); -exports.defaultTmp = process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp; -exports.defaultTmpSync = process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync; -//# sourceMappingURL=default-tmp.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map deleted file mode 100644 index 5681ff8..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/default-tmp.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"default-tmp.js","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0CAA0C;AAC1C,iDAAiD;AACjD,8DAA8D;AAC9D,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,8BAA8B;AAC9B,2BAA2B;AAC3B,+BAAqC;AACrC,mCAA4C;AAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAQ,CAAA;AAEzB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,OAAO,IAAA,gBAAQ,EAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACb,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EACtB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAA;AAEH,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,IAAA,WAAM,GAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAA,YAAK,EAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,IAAA,WAAM,GAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAA,YAAK,EAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC,IAAA,WAAM,GAAE,CAAA;AAC5C,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,IAAA,WAAM,GAAE,CAAA;AAE7B,QAAA,UAAU,GACrB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAA;AACrD,QAAA,cAAc,GACzB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAA","sourcesContent":["// The default temporary folder location for use in the windows algorithm.\n// It's TEMPting to use dirname(path), since that's guaranteed to be on the\n// same device. However, this means that:\n// rimraf(path).then(() => rimraf(dirname(path)))\n// will often fail with EBUSY, because the parent dir contains\n// marked-for-deletion directory entries (which do not show up in readdir).\n// The approach here is to use os.tmpdir() if it's on the same drive letter,\n// or resolve(path, '\\\\temp') if it exists, or the root of the drive if not.\n// On Posix (not that you'd be likely to use the windows algorithm there),\n// it uses os.tmpdir() always.\nimport { tmpdir } from 'os'\nimport { parse, resolve } from 'path'\nimport { promises, statSync } from './fs.js'\nconst { stat } = promises\n\nconst isDirSync = (path: string) => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n\nconst isDir = (path: string) =>\n stat(path).then(\n st => st.isDirectory(),\n () => false,\n )\n\nconst win32DefaultTmp = async (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (await isDir(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\nconst win32DefaultTmpSync = (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (isDirSync(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await\nconst posixDefaultTmp = async () => tmpdir()\nconst posixDefaultTmpSync = () => tmpdir()\n\nexport const defaultTmp =\n process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp\nexport const defaultTmpSync =\n process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts deleted file mode 100644 index 5ba53c8..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare const isFsError: (o: unknown) => o is NodeJS.ErrnoException & { - code: string; - path: string; -}; -export declare const errorCode: (er: unknown) => unknown; -//# sourceMappingURL=error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map deleted file mode 100644 index 6671be4..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/error.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,GACpB,GAAG,OAAO,KACT,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACkD,CAAA;AAEhE,eAAO,MAAM,SAAS,GAAI,IAAI,OAAO,YACmB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.js b/apps/extension/node_modules/rimraf/dist/commonjs/error.js deleted file mode 100644 index 3a96451..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/error.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.errorCode = exports.isFsError = void 0; -const isRecord = (o) => !!o && typeof o === 'object'; -const hasString = (o, key) => key in o && typeof o[key] === 'string'; -const isFsError = (o) => isRecord(o) && hasString(o, 'code') && hasString(o, 'path'); -exports.isFsError = isFsError; -const errorCode = (er) => isRecord(er) && hasString(er, 'code') ? er.code : null; -exports.errorCode = errorCode; -//# sourceMappingURL=error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map deleted file mode 100644 index 4b7ee21..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/error.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAC5D,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAA;AAE9B,MAAM,SAAS,GAAG,CAAC,CAA0B,EAAE,GAAW,EAAE,EAAE,CAC5D,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAA;AAEjC,MAAM,SAAS,GAAG,CACvB,CAAU,EAIV,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AALnD,QAAA,SAAS,aAK0C;AAEzD,MAAM,SAAS,GAAG,CAAC,EAAW,EAAE,EAAE,CACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AAD3C,QAAA,SAAS,aACkC","sourcesContent":["const isRecord = (o: unknown): o is Record =>\n !!o && typeof o === 'object'\n\nconst hasString = (o: Record, key: string) =>\n key in o && typeof o[key] === 'string'\n\nexport const isFsError = (\n o: unknown,\n): o is NodeJS.ErrnoException & {\n code: string\n path: string\n} => isRecord(o) && hasString(o, 'code') && hasString(o, 'path')\n\nexport const errorCode = (er: unknown) =>\n isRecord(er) && hasString(er, 'code') ? er.code : null\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts deleted file mode 100644 index 4b329ef..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const fixEPERM: (fn: (path: string) => Promise) => (path: string) => Promise; -export declare const fixEPERMSync: (fn: (path: string) => unknown) => (path: string) => void; -//# sourceMappingURL=fix-eperm.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map deleted file mode 100644 index 498e950..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fix-eperm.d.ts","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,GAClB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAChC,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBjC,CAAA;AAEH,eAAO,MAAM,YAAY,GACtB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,MAC7B,MAAM,MAAM,KAAG,IAYf,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js deleted file mode 100644 index 1a60f8d..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fixEPERMSync = exports.fixEPERM = void 0; -const error_js_1 = require("./error.js"); -const fs_js_1 = require("./fs.js"); -const ignore_enoent_js_1 = require("./ignore-enoent.js"); -const { chmod } = fs_js_1.promises; -const fixEPERM = (fn) => async (path) => { - try { - return void (await (0, ignore_enoent_js_1.ignoreENOENT)(fn(path))); - } - catch (er) { - if ((0, error_js_1.errorCode)(er) === 'EPERM') { - if (!(await (0, ignore_enoent_js_1.ignoreENOENT)(chmod(path, 0o666).then(() => true), er))) { - return; - } - return void (await fn(path)); - } - throw er; - } -}; -exports.fixEPERM = fixEPERM; -const fixEPERMSync = (fn) => (path) => { - try { - return void (0, ignore_enoent_js_1.ignoreENOENTSync)(() => fn(path)); - } - catch (er) { - if ((0, error_js_1.errorCode)(er) === 'EPERM') { - if (!(0, ignore_enoent_js_1.ignoreENOENTSync)(() => ((0, fs_js_1.chmodSync)(path, 0o666), true), er)) { - return; - } - return void fn(path); - } - throw er; - } -}; -exports.fixEPERMSync = fixEPERMSync; -//# sourceMappingURL=fix-eperm.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map deleted file mode 100644 index 17a4e56..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fix-eperm.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fix-eperm.js","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,mCAA6C;AAC7C,yDAAmE;AACnE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAQ,CAAA;AAEnB,MAAM,QAAQ,GACnB,CAAC,EAAsC,EAAE,EAAE,CAC3C,KAAK,EAAE,IAAY,EAAiB,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,IAAA,+BAAY,EAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IACE,CAAC,CAAC,MAAM,IAAA,+BAAY,EAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACnC,EAAE,CACH,CAAC,EACF,CAAC;gBACD,OAAM;YACR,CAAC;YACD,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9B,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAnBU,QAAA,QAAQ,YAmBlB;AAEI,MAAM,YAAY,GACvB,CAAC,EAA6B,EAAE,EAAE,CAClC,CAAC,IAAY,EAAQ,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,KAAK,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,CAAC,IAAA,iBAAS,EAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAdU,QAAA,YAAY,gBActB","sourcesContent":["import { errorCode } from './error.js'\nimport { chmodSync, promises } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nconst { chmod } = promises\n\nexport const fixEPERM =\n (fn: (path: string) => Promise) =>\n async (path: string): Promise => {\n try {\n return void (await ignoreENOENT(fn(path)))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (\n !(await ignoreENOENT(\n chmod(path, 0o666).then(() => true),\n er,\n ))\n ) {\n return\n }\n return void (await fn(path))\n }\n throw er\n }\n }\n\nexport const fixEPERMSync =\n (fn: (path: string) => unknown) =>\n (path: string): void => {\n try {\n return void ignoreENOENTSync(() => fn(path))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) {\n return\n }\n return void fn(path)\n }\n throw er\n }\n }\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts deleted file mode 100644 index 4e6fbab..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import fs, { Dirent } from 'fs'; -import fsPromises from 'fs/promises'; -export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; -export declare const readdirSync: (path: fs.PathLike) => Dirent[]; -export declare const promises: { - chmod: typeof fsPromises.chmod; - mkdir: typeof fsPromises.mkdir; - readdir: (path: fs.PathLike) => Promise[]>; - rename: typeof fsPromises.rename; - rm: typeof fsPromises.rm; - rmdir: typeof fsPromises.rmdir; - stat: typeof fsPromises.stat; - lstat: typeof fsPromises.lstat; - unlink: typeof fsPromises.unlink; -}; -//# sourceMappingURL=fs.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map deleted file mode 100644 index ed3c8db..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fs.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAyB,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAKpC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,QAAQ,KAAG,MAAM,EACf,CAAA;AAEvC,eAAO,MAAM,QAAQ;;;oBAGH,EAAE,CAAC,QAAQ;;;;;;;CAQ5B,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js deleted file mode 100644 index 3736587..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promises = exports.readdirSync = exports.unlinkSync = exports.lstatSync = exports.statSync = exports.rmSync = exports.rmdirSync = exports.renameSync = exports.mkdirSync = exports.chmodSync = void 0; -const fs_1 = require("fs"); -const promises_1 = __importDefault(require("fs/promises")); -// sync ones just take the sync version from node -// readdir forces withFileTypes: true -var fs_2 = require("fs"); -Object.defineProperty(exports, "chmodSync", { enumerable: true, get: function () { return fs_2.chmodSync; } }); -Object.defineProperty(exports, "mkdirSync", { enumerable: true, get: function () { return fs_2.mkdirSync; } }); -Object.defineProperty(exports, "renameSync", { enumerable: true, get: function () { return fs_2.renameSync; } }); -Object.defineProperty(exports, "rmdirSync", { enumerable: true, get: function () { return fs_2.rmdirSync; } }); -Object.defineProperty(exports, "rmSync", { enumerable: true, get: function () { return fs_2.rmSync; } }); -Object.defineProperty(exports, "statSync", { enumerable: true, get: function () { return fs_2.statSync; } }); -Object.defineProperty(exports, "lstatSync", { enumerable: true, get: function () { return fs_2.lstatSync; } }); -Object.defineProperty(exports, "unlinkSync", { enumerable: true, get: function () { return fs_2.unlinkSync; } }); -const readdirSync = (path) => (0, fs_1.readdirSync)(path, { withFileTypes: true }); -exports.readdirSync = readdirSync; -exports.promises = { - chmod: promises_1.default.chmod, - mkdir: promises_1.default.mkdir, - readdir: (path) => promises_1.default.readdir(path, { withFileTypes: true }), - rename: promises_1.default.rename, - rm: promises_1.default.rm, - rmdir: promises_1.default.rmdir, - stat: promises_1.default.stat, - lstat: promises_1.default.lstat, - unlink: promises_1.default.unlink, -}; -//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map deleted file mode 100644 index 1cc3b0f..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/fs.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAsD;AACtD,2DAAoC;AAEpC,iDAAiD;AACjD,qCAAqC;AAErC,yBASW;AART,+FAAA,SAAS,OAAA;AACT,+FAAA,SAAS,OAAA;AACT,gGAAA,UAAU,OAAA;AACV,+FAAA,SAAS,OAAA;AACT,4FAAA,MAAM,OAAA;AACN,8FAAA,QAAQ,OAAA;AACR,+FAAA,SAAS,OAAA;AACT,gGAAA,UAAU,OAAA;AAGL,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAY,EAAE,CACzD,IAAA,gBAAM,EAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;AAD1B,QAAA,WAAW,eACe;AAE1B,QAAA,QAAQ,GAAG;IACtB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,OAAO,EAAE,CAAC,IAAiB,EAAE,EAAE,CAC7B,kBAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,EAAE,kBAAU,CAAC,MAAM;IACzB,EAAE,EAAE,kBAAU,CAAC,EAAE;IACjB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,IAAI,EAAE,kBAAU,CAAC,IAAI;IACrB,KAAK,EAAE,kBAAU,CAAC,KAAK;IACvB,MAAM,EAAE,kBAAU,CAAC,MAAM;CAC1B,CAAA","sourcesContent":["import fs, { Dirent, readdirSync as rdSync } from 'fs'\nimport fsPromises from 'fs/promises'\n\n// sync ones just take the sync version from node\n// readdir forces withFileTypes: true\n\nexport {\n chmodSync,\n mkdirSync,\n renameSync,\n rmdirSync,\n rmSync,\n statSync,\n lstatSync,\n unlinkSync,\n} from 'fs'\n\nexport const readdirSync = (path: fs.PathLike): Dirent[] =>\n rdSync(path, { withFileTypes: true })\n\nexport const promises = {\n chmod: fsPromises.chmod,\n mkdir: fsPromises.mkdir,\n readdir: (path: fs.PathLike) =>\n fsPromises.readdir(path, { withFileTypes: true }),\n rename: fsPromises.rename,\n rm: fsPromises.rm,\n rmdir: fsPromises.rmdir,\n stat: fsPromises.stat,\n lstat: fsPromises.lstat,\n unlink: fsPromises.unlink,\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts deleted file mode 100644 index e56d721..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const ignoreENOENT: (p: Promise, rethrow?: unknown) => Promise; -export declare const ignoreENOENTSync: (fn: () => T, rethrow?: unknown) => T | undefined; -//# sourceMappingURL=ignore-enoent.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map deleted file mode 100644 index 14097fc..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ignore-enoent.d.ts","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,GAAU,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,OAAO,sBAMlE,CAAA;AAEJ,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,UAAU,OAAO,kBASjE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js deleted file mode 100644 index f37c380..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.ignoreENOENTSync = exports.ignoreENOENT = void 0; -const error_js_1 = require("./error.js"); -const ignoreENOENT = async (p, rethrow) => p.catch(er => { - if ((0, error_js_1.errorCode)(er) === 'ENOENT') { - return; - } - throw rethrow ?? er; -}); -exports.ignoreENOENT = ignoreENOENT; -const ignoreENOENTSync = (fn, rethrow) => { - try { - return fn(); - } - catch (er) { - if ((0, error_js_1.errorCode)(er) === 'ENOENT') { - return; - } - throw rethrow ?? er; - } -}; -exports.ignoreENOENTSync = ignoreENOENTSync; -//# sourceMappingURL=ignore-enoent.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map deleted file mode 100644 index 8877bde..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ignore-enoent.js","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAE/B,MAAM,YAAY,GAAG,KAAK,EAAK,CAAa,EAAE,OAAiB,EAAE,EAAE,CACxE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;IACX,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAM;IACR,CAAC;IACD,MAAM,OAAO,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA;AANS,QAAA,YAAY,gBAMrB;AAEG,MAAM,gBAAgB,GAAG,CAAI,EAAW,EAAE,OAAiB,EAAE,EAAE;IACpE,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,OAAO,IAAI,EAAE,CAAA;IACrB,CAAC;AACH,CAAC,CAAA;AATY,QAAA,gBAAgB,oBAS5B","sourcesContent":["import { errorCode } from './error.js'\n\nexport const ignoreENOENT = async (p: Promise, rethrow?: unknown) =>\n p.catch(er => {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n })\n\nexport const ignoreENOENTSync = (fn: () => T, rethrow?: unknown) => {\n try {\n return fn()\n } catch (er) {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts deleted file mode 100644 index 9ec4a12..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './opt-arg.js'; -export { assertRimrafOptions, isRimrafOptions, type RimrafAsyncOptions, type RimrafOptions, type RimrafSyncOptions, } from './opt-arg.js'; -export declare const nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const rimraf: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - rimraf: (path: string | string[], opt?: RimrafAsyncOptions) => Promise; - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map deleted file mode 100644 index e69bc3c..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.js b/apps/extension/node_modules/rimraf/dist/commonjs/index.js deleted file mode 100644 index be36db6..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/index.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimraf = exports.sync = exports.rimrafSync = exports.moveRemove = exports.moveRemoveSync = exports.posix = exports.posixSync = exports.windows = exports.windowsSync = exports.manual = exports.manualSync = exports.native = exports.nativeSync = exports.isRimrafOptions = exports.assertRimrafOptions = void 0; -const glob_1 = require("glob"); -const opt_arg_js_1 = require("./opt-arg.js"); -const path_arg_js_1 = __importDefault(require("./path-arg.js")); -const rimraf_manual_js_1 = require("./rimraf-manual.js"); -const rimraf_move_remove_js_1 = require("./rimraf-move-remove.js"); -const rimraf_native_js_1 = require("./rimraf-native.js"); -const rimraf_posix_js_1 = require("./rimraf-posix.js"); -const rimraf_windows_js_1 = require("./rimraf-windows.js"); -const use_native_js_1 = require("./use-native.js"); -var opt_arg_js_2 = require("./opt-arg.js"); -Object.defineProperty(exports, "assertRimrafOptions", { enumerable: true, get: function () { return opt_arg_js_2.assertRimrafOptions; } }); -Object.defineProperty(exports, "isRimrafOptions", { enumerable: true, get: function () { return opt_arg_js_2.isRimrafOptions; } }); -const wrap = (fn) => async (path, opt) => { - const options = (0, opt_arg_js_1.optArg)(opt); - if (options.glob) { - path = await (0, glob_1.glob)(path, options.glob); - } - if (Array.isArray(path)) { - return !!(await Promise.all(path.map(p => fn((0, path_arg_js_1.default)(p, options), options)))).reduce((a, b) => a && b, true); - } - else { - return !!(await fn((0, path_arg_js_1.default)(path, options), options)); - } -}; -const wrapSync = (fn) => (path, opt) => { - const options = (0, opt_arg_js_1.optArgSync)(opt); - if (options.glob) { - path = (0, glob_1.globSync)(path, options.glob); - } - if (Array.isArray(path)) { - return !!path - .map(p => fn((0, path_arg_js_1.default)(p, options), options)) - .reduce((a, b) => a && b, true); - } - else { - return !!fn((0, path_arg_js_1.default)(path, options), options); - } -}; -exports.nativeSync = wrapSync(rimraf_native_js_1.rimrafNativeSync); -exports.native = Object.assign(wrap(rimraf_native_js_1.rimrafNative), { - sync: exports.nativeSync, -}); -exports.manualSync = wrapSync(rimraf_manual_js_1.rimrafManualSync); -exports.manual = Object.assign(wrap(rimraf_manual_js_1.rimrafManual), { - sync: exports.manualSync, -}); -exports.windowsSync = wrapSync(rimraf_windows_js_1.rimrafWindowsSync); -exports.windows = Object.assign(wrap(rimraf_windows_js_1.rimrafWindows), { - sync: exports.windowsSync, -}); -exports.posixSync = wrapSync(rimraf_posix_js_1.rimrafPosixSync); -exports.posix = Object.assign(wrap(rimraf_posix_js_1.rimrafPosix), { sync: exports.posixSync }); -exports.moveRemoveSync = wrapSync(rimraf_move_remove_js_1.rimrafMoveRemoveSync); -exports.moveRemove = Object.assign(wrap(rimraf_move_remove_js_1.rimrafMoveRemove), { - sync: exports.moveRemoveSync, -}); -exports.rimrafSync = wrapSync((path, opt) => (0, use_native_js_1.useNativeSync)(opt) ? - (0, rimraf_native_js_1.rimrafNativeSync)(path, opt) - : (0, rimraf_manual_js_1.rimrafManualSync)(path, opt)); -exports.sync = exports.rimrafSync; -const rimraf_ = wrap((path, opt) => (0, use_native_js_1.useNative)(opt) ? (0, rimraf_native_js_1.rimrafNative)(path, opt) : (0, rimraf_manual_js_1.rimrafManual)(path, opt)); -exports.rimraf = Object.assign(rimraf_, { - rimraf: rimraf_, - sync: exports.rimrafSync, - rimrafSync: exports.rimrafSync, - manual: exports.manual, - manualSync: exports.manualSync, - native: exports.native, - nativeSync: exports.nativeSync, - posix: exports.posix, - posixSync: exports.posixSync, - windows: exports.windows, - windowsSync: exports.windowsSync, - moveRemove: exports.moveRemove, - moveRemoveSync: exports.moveRemoveSync, -}); -exports.rimraf.rimraf = exports.rimraf; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map deleted file mode 100644 index 6624e13..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { glob, globSync } from 'glob'\nimport {\n optArg,\n optArgSync,\n RimrafAsyncOptions,\n RimrafSyncOptions,\n} from './opt-arg.js'\nimport pathArg from './path-arg.js'\nimport { rimrafManual, rimrafManualSync } from './rimraf-manual.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { rimrafNative, rimrafNativeSync } from './rimraf-native.js'\nimport { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\nimport { useNative, useNativeSync } from './use-native.js'\n\nexport {\n assertRimrafOptions,\n isRimrafOptions,\n type RimrafAsyncOptions,\n type RimrafOptions,\n type RimrafSyncOptions,\n} from './opt-arg.js'\n\nconst wrap =\n (fn: (p: string, o: RimrafAsyncOptions) => Promise) =>\n async (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ): Promise => {\n const options = optArg(opt)\n if (options.glob) {\n path = await glob(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!(\n await Promise.all(path.map(p => fn(pathArg(p, options), options)))\n ).reduce((a, b) => a && b, true)\n } else {\n return !!(await fn(pathArg(path, options), options))\n }\n }\n\nconst wrapSync =\n (fn: (p: string, o: RimrafSyncOptions) => boolean) =>\n (path: string | string[], opt?: RimrafSyncOptions): boolean => {\n const options = optArgSync(opt)\n if (options.glob) {\n path = globSync(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!path\n .map(p => fn(pathArg(p, options), options))\n .reduce((a, b) => a && b, true)\n } else {\n return !!fn(pathArg(path, options), options)\n }\n }\n\nexport const nativeSync = wrapSync(rimrafNativeSync)\nexport const native = Object.assign(wrap(rimrafNative), {\n sync: nativeSync,\n})\n\nexport const manualSync = wrapSync(rimrafManualSync)\nexport const manual = Object.assign(wrap(rimrafManual), {\n sync: manualSync,\n})\n\nexport const windowsSync = wrapSync(rimrafWindowsSync)\nexport const windows = Object.assign(wrap(rimrafWindows), {\n sync: windowsSync,\n})\n\nexport const posixSync = wrapSync(rimrafPosixSync)\nexport const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync })\n\nexport const moveRemoveSync = wrapSync(rimrafMoveRemoveSync)\nexport const moveRemove = Object.assign(wrap(rimrafMoveRemove), {\n sync: moveRemoveSync,\n})\n\nexport const rimrafSync = wrapSync((path, opt) =>\n useNativeSync(opt) ?\n rimrafNativeSync(path, opt)\n : rimrafManualSync(path, opt),\n)\nexport const sync = rimrafSync\n\nconst rimraf_ = wrap((path, opt) =>\n useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt),\n)\nexport const rimraf = Object.assign(rimraf_, {\n rimraf: rimraf_,\n sync: rimrafSync,\n rimrafSync: rimrafSync,\n manual,\n manualSync,\n native,\n nativeSync,\n posix,\n posixSync,\n windows,\n windowsSync,\n moveRemove,\n moveRemoveSync,\n})\nrimraf.rimraf = rimraf\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts deleted file mode 100644 index c869d4a..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Dirent, Stats } from 'fs'; -import { GlobOptions } from 'glob'; -export declare const isRimrafOptions: (o: any) => o is RimrafOptions; -export declare const assertRimrafOptions: (o: any) => void; -export interface RimrafAsyncOptions { - preserveRoot?: boolean; - tmp?: string; - maxRetries?: number; - retryDelay?: number; - backoff?: number; - maxBackoff?: number; - signal?: AbortSignal; - glob?: boolean | GlobOptions; - filter?: ((path: string, ent: Dirent | Stats) => boolean) | ((path: string, ent: Dirent | Stats) => Promise); -} -export interface RimrafSyncOptions extends RimrafAsyncOptions { - filter?: (path: string, ent: Dirent | Stats) => boolean; -} -export type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions; -export declare const optArg: (opt?: RimrafAsyncOptions) => (RimrafAsyncOptions & { - glob: GlobOptions & { - withFileTypes: false; - }; -}) | (RimrafAsyncOptions & { - glob: undefined; -}); -export declare const optArgSync: (opt?: RimrafSyncOptions) => (RimrafSyncOptions & { - glob: GlobOptions & { - withFileTypes: false; - }; -}) | (RimrafSyncOptions & { - glob: undefined; -}); -//# sourceMappingURL=opt-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map deleted file mode 100644 index 93e1f92..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"opt-arg.d.ts","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAKlC,eAAO,MAAM,eAAe,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,aAWX,CAAA;AAEnC,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAM7C,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;IAC5B,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,GAChD,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAA;CACxD;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAqClE,eAAO,MAAM,MAAM,GAAI,MAAK,kBAAuB;UA/BvC,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA6B0C,CAAA;AACpE,eAAO,MAAM,UAAU,GAAI,MAAK,iBAAsB;UAhC1C,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA8B6C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js deleted file mode 100644 index 70538b5..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js +++ /dev/null @@ -1,54 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.optArgSync = exports.optArg = exports.assertRimrafOptions = exports.isRimrafOptions = void 0; -const typeOrUndef = (val, t) => typeof val === 'undefined' || typeof val === t; -const isRimrafOptions = (o) => !!o && - typeof o === 'object' && - typeOrUndef(o.preserveRoot, 'boolean') && - typeOrUndef(o.tmp, 'string') && - typeOrUndef(o.maxRetries, 'number') && - typeOrUndef(o.retryDelay, 'number') && - typeOrUndef(o.backoff, 'number') && - typeOrUndef(o.maxBackoff, 'number') && - (typeOrUndef(o.glob, 'boolean') || - (o.glob && typeof o.glob === 'object')) && - typeOrUndef(o.filter, 'function'); -exports.isRimrafOptions = isRimrafOptions; -const assertRimrafOptions = (o) => { - if (!(0, exports.isRimrafOptions)(o)) { - throw new Error('invalid rimraf options'); - } -}; -exports.assertRimrafOptions = assertRimrafOptions; -const optArgT = (opt) => { - (0, exports.assertRimrafOptions)(opt); - const { glob, ...options } = opt; - if (!glob) { - return options; - } - const globOpt = glob === true ? - opt.signal ? - { signal: opt.signal } - : {} - : opt.signal ? - { - signal: opt.signal, - ...glob, - } - : glob; - return { - ...options, - glob: { - ...globOpt, - // always get absolute paths from glob, to ensure - // that we are referencing the correct thing. - absolute: true, - withFileTypes: false, - }, - }; -}; -const optArg = (opt = {}) => optArgT(opt); -exports.optArg = optArg; -const optArgSync = (opt = {}) => optArgT(opt); -exports.optArgSync = optArgSync; -//# sourceMappingURL=opt-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map deleted file mode 100644 index 9d97431..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/opt-arg.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"opt-arg.js","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":";;;AAGA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,CAAS,EAAE,EAAE,CAC1C,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,KAAK,CAAC,CAAA;AAEzC,MAAM,eAAe,GAAG,CAAC,CAAM,EAAsB,EAAE,CAC5D,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,QAAQ;IACrB,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC;IACtC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IAC5B,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC;QAC7B,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAXtB,QAAA,eAAe,mBAWO;AAE5B,MAAM,mBAAmB,GAAqB,CACnD,CAAM,EACsB,EAAE;IAC9B,IAAI,CAAC,IAAA,uBAAe,EAAC,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC,CAAA;AANY,QAAA,mBAAmB,uBAM/B;AAsBD,MAAM,OAAO,GAAG,CACd,GAAM,EAKsB,EAAE;IAC9B,IAAA,2BAAmB,EAAC,GAAG,CAAC,CAAA;IACxB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAA;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,OAAkC,CAAA;IAC3C,CAAC;IACD,MAAM,OAAO,GACX,IAAI,KAAK,IAAI,CAAC,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,CAAC;YACV,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACxB,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACZ;gBACE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,IAAI;aACR;YACH,CAAC,CAAC,IAAI,CAAA;IACR,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE;YACJ,GAAG,OAAO;YACV,iDAAiD;YACjD,6CAA6C;YAC7C,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,KAAK;SACrB;KACsD,CAAA;AAC3D,CAAC,CAAA;AAEM,MAAM,MAAM,GAAG,CAAC,MAA0B,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAAvD,QAAA,MAAM,UAAiD;AAC7D,MAAM,UAAU,GAAG,CAAC,MAAyB,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAA1D,QAAA,UAAU,cAAgD","sourcesContent":["import { Dirent, Stats } from 'fs'\nimport { GlobOptions } from 'glob'\n\nconst typeOrUndef = (val: any, t: string) =>\n typeof val === 'undefined' || typeof val === t\n\nexport const isRimrafOptions = (o: any): o is RimrafOptions =>\n !!o &&\n typeof o === 'object' &&\n typeOrUndef(o.preserveRoot, 'boolean') &&\n typeOrUndef(o.tmp, 'string') &&\n typeOrUndef(o.maxRetries, 'number') &&\n typeOrUndef(o.retryDelay, 'number') &&\n typeOrUndef(o.backoff, 'number') &&\n typeOrUndef(o.maxBackoff, 'number') &&\n (typeOrUndef(o.glob, 'boolean') ||\n (o.glob && typeof o.glob === 'object')) &&\n typeOrUndef(o.filter, 'function')\n\nexport const assertRimrafOptions: (o: any) => void = (\n o: any,\n): asserts o is RimrafOptions => {\n if (!isRimrafOptions(o)) {\n throw new Error('invalid rimraf options')\n }\n}\n\nexport interface RimrafAsyncOptions {\n preserveRoot?: boolean\n tmp?: string\n maxRetries?: number\n retryDelay?: number\n backoff?: number\n maxBackoff?: number\n signal?: AbortSignal\n glob?: boolean | GlobOptions\n filter?:\n | ((path: string, ent: Dirent | Stats) => boolean)\n | ((path: string, ent: Dirent | Stats) => Promise)\n}\n\nexport interface RimrafSyncOptions extends RimrafAsyncOptions {\n filter?: (path: string, ent: Dirent | Stats) => boolean\n}\n\nexport type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions\n\nconst optArgT = (\n opt: T,\n):\n | (T & {\n glob: GlobOptions & { withFileTypes: false }\n })\n | (T & { glob: undefined }) => {\n assertRimrafOptions(opt)\n const { glob, ...options } = opt\n if (!glob) {\n return options as T & { glob: undefined }\n }\n const globOpt =\n glob === true ?\n opt.signal ?\n { signal: opt.signal }\n : {}\n : opt.signal ?\n {\n signal: opt.signal,\n ...glob,\n }\n : glob\n return {\n ...options,\n glob: {\n ...globOpt,\n // always get absolute paths from glob, to ensure\n // that we are referencing the correct thing.\n absolute: true,\n withFileTypes: false,\n },\n } as T & { glob: GlobOptions & { withFileTypes: false } }\n}\n\nexport const optArg = (opt: RimrafAsyncOptions = {}) => optArgT(opt)\nexport const optArgSync = (opt: RimrafSyncOptions = {}) => optArgT(opt)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/package.json b/apps/extension/node_modules/rimraf/dist/commonjs/package.json deleted file mode 100644 index 5bbefff..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts deleted file mode 100644 index c0b7e7c..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions } from './index.js'; -declare const pathArg: (path: string, opt?: RimrafAsyncOptions) => string; -export default pathArg; -//# sourceMappingURL=path-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map deleted file mode 100644 index 2112460..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"path-arg.d.ts","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,QAAA,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,MAAK,kBAAuB,WAkD1D,CAAA;AAED,eAAe,OAAO,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js deleted file mode 100644 index 981cd7d..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const path_1 = require("path"); -const util_1 = require("util"); -const pathArg = (path, opt = {}) => { - const type = typeof path; - if (type !== 'string') { - const ctor = path && type === 'object' && path.constructor; - const received = ctor && ctor.name ? `an instance of ${ctor.name}` - : type === 'object' ? (0, util_1.inspect)(path) - : `type ${type} ${path}`; - const msg = 'The "path" argument must be of type string. ' + - `Received ${received}`; - throw Object.assign(new TypeError(msg), { - path, - code: 'ERR_INVALID_ARG_TYPE', - }); - } - if (/\0/.test(path)) { - // simulate same failure that node raises - const msg = 'path must be a string without null bytes'; - throw Object.assign(new TypeError(msg), { - path, - code: 'ERR_INVALID_ARG_VALUE', - }); - } - path = (0, path_1.resolve)(path); - const { root } = (0, path_1.parse)(path); - if (path === root && opt.preserveRoot !== false) { - const msg = 'refusing to remove root directory without preserveRoot:false'; - throw Object.assign(new Error(msg), { - path, - code: 'ERR_PRESERVE_ROOT', - }); - } - if (process.platform === 'win32') { - const badWinChars = /[*|"<>?:]/; - const { root } = (0, path_1.parse)(path); - if (badWinChars.test(path.substring(root.length))) { - throw Object.assign(new Error('Illegal characters in path.'), { - path, - code: 'EINVAL', - }); - } - } - return path; -}; -exports.default = pathArg; -//# sourceMappingURL=path-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map deleted file mode 100644 index a41add7..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/path-arg.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"path-arg.js","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":";;AAAA,+BAAqC;AACrC,+BAA8B;AAG9B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,MAA0B,EAAE,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAA;IACxB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAA;QAC1D,MAAM,QAAQ,GACZ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAA;QAC1B,MAAM,GAAG,GACP,8CAA8C;YAC9C,YAAY,QAAQ,EAAE,CAAA;QACxB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,sBAAsB;SAC7B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,yCAAyC;QACzC,MAAM,GAAG,GAAG,0CAA0C,CAAA;QACtD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;IAE5B,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,GAAG,GACP,8DAA8D,CAAA;QAChE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI;YACJ,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,WAAW,CAAA;QAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAE;gBAC5D,IAAI;gBACJ,IAAI,EAAE,QAAQ;aACf,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,kBAAe,OAAO,CAAA","sourcesContent":["import { parse, resolve } from 'path'\nimport { inspect } from 'util'\nimport { RimrafAsyncOptions } from './index.js'\n\nconst pathArg = (path: string, opt: RimrafAsyncOptions = {}) => {\n const type = typeof path\n if (type !== 'string') {\n const ctor = path && type === 'object' && path.constructor\n const received =\n ctor && ctor.name ? `an instance of ${ctor.name}`\n : type === 'object' ? inspect(path)\n : `type ${type} ${path}`\n const msg =\n 'The \"path\" argument must be of type string. ' +\n `Received ${received}`\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_TYPE',\n })\n }\n\n if (/\\0/.test(path)) {\n // simulate same failure that node raises\n const msg = 'path must be a string without null bytes'\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_VALUE',\n })\n }\n\n path = resolve(path)\n const { root } = parse(path)\n\n if (path === root && opt.preserveRoot !== false) {\n const msg =\n 'refusing to remove root directory without preserveRoot:false'\n throw Object.assign(new Error(msg), {\n path,\n code: 'ERR_PRESERVE_ROOT',\n })\n }\n\n if (process.platform === 'win32') {\n const badWinChars = /[*|\"<>?:]/\n const { root } = parse(path)\n if (badWinChars.test(path.substring(root.length))) {\n throw Object.assign(new Error('Illegal characters in path.'), {\n path,\n code: 'EINVAL',\n })\n }\n }\n\n return path\n}\n\nexport default pathArg\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts deleted file mode 100644 index 2a580cf..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const readdirOrError: (path: string) => Promise[] | Error>; -export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent[] | Error; -//# sourceMappingURL=readdir-or-error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map deleted file mode 100644 index 1f91434..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"readdir-or-error.d.ts","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,wDACH,CAAA;AACxC,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,+CAM9C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js deleted file mode 100644 index 75330cb..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.readdirOrErrorSync = exports.readdirOrError = void 0; -// returns an array of entries if readdir() works, -// or the error that readdir() raised if not. -const fs_js_1 = require("./fs.js"); -const { readdir } = fs_js_1.promises; -const readdirOrError = (path) => readdir(path).catch(er => er); -exports.readdirOrError = readdirOrError; -const readdirOrErrorSync = (path) => { - try { - return (0, fs_js_1.readdirSync)(path); - } - catch (er) { - return er; - } -}; -exports.readdirOrErrorSync = readdirOrErrorSync; -//# sourceMappingURL=readdir-or-error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map deleted file mode 100644 index 4abb067..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"readdir-or-error.js","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":";;;AAAA,kDAAkD;AAClD,6CAA6C;AAC7C,mCAA+C;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAQ,CAAA;AAErB,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAW,CAAC,CAAA;AAD3B,QAAA,cAAc,kBACa;AACjC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE;IACjD,IAAI,CAAC;QACH,OAAO,IAAA,mBAAW,EAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,OAAO,EAAW,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AANY,QAAA,kBAAkB,sBAM9B","sourcesContent":["// returns an array of entries if readdir() works,\n// or the error that readdir() raised if not.\nimport { promises, readdirSync } from './fs.js'\nconst { readdir } = promises\n\nexport const readdirOrError = (path: string) =>\n readdir(path).catch(er => er as Error)\nexport const readdirOrErrorSync = (path: string) => {\n try {\n return readdirSync(path)\n } catch (er) {\n return er as Error\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts deleted file mode 100644 index b01b023..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RimrafAsyncOptions, RimrafOptions } from './index.js'; -export declare const MAXBACKOFF = 200; -export declare const RATE = 1.2; -export declare const MAXRETRIES = 10; -export declare const codes: Set; -export declare const retryBusy: (fn: (path: string) => Promise) => (path: string, opt: RimrafAsyncOptions, backoff?: number, total?: number) => Promise; -export declare const retryBusySync: (fn: (path: string) => T) => (path: string, opt: RimrafOptions) => T; -//# sourceMappingURL=retry-busy.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map deleted file mode 100644 index 554f140..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"retry-busy.d.ts","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,eAAO,MAAM,UAAU,MAAM,CAAA;AAC7B,eAAO,MAAM,IAAI,MAAM,CAAA;AACvB,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,KAAK,aAAyC,CAAA;AAE3D,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAEnD,MAAM,OACP,kBAAkB,iDA8B1B,CAAA;AAGD,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAChC,MAAM,OAAO,aAAa,MAqBjD,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js deleted file mode 100644 index 7278365..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; -// note: max backoff is the maximum that any *single* backoff will do -Object.defineProperty(exports, "__esModule", { value: true }); -exports.retryBusySync = exports.retryBusy = exports.codes = exports.MAXRETRIES = exports.RATE = exports.MAXBACKOFF = void 0; -const promises_1 = require("timers/promises"); -const error_js_1 = require("./error.js"); -exports.MAXBACKOFF = 200; -exports.RATE = 1.2; -exports.MAXRETRIES = 10; -exports.codes = new Set(['EMFILE', 'ENFILE', 'EBUSY']); -const retryBusy = (fn) => { - const method = async (path, opt, backoff = 1, total = 0) => { - const mbo = opt.maxBackoff || exports.MAXBACKOFF; - const rate = opt.backoff || exports.RATE; - const max = opt.maxRetries || exports.MAXRETRIES; - let retries = 0; - while (true) { - try { - return await fn(path); - } - catch (er) { - if ((0, error_js_1.isFsError)(er) && er.path === path && exports.codes.has(er.code)) { - backoff = Math.ceil(backoff * rate); - total = backoff + total; - if (total < mbo) { - await (0, promises_1.setTimeout)(backoff); - return method(path, opt, backoff, total); - } - if (retries < max) { - retries++; - continue; - } - } - throw er; - } - } - }; - return method; -}; -exports.retryBusy = retryBusy; -// just retries, no async so no backoff -const retryBusySync = (fn) => { - const method = (path, opt) => { - const max = opt.maxRetries || exports.MAXRETRIES; - let retries = 0; - while (true) { - try { - return fn(path); - } - catch (er) { - if ((0, error_js_1.isFsError)(er) && - er.path === path && - exports.codes.has(er.code) && - retries < max) { - retries++; - continue; - } - throw er; - } - } - }; - return method; -}; -exports.retryBusySync = retryBusySync; -//# sourceMappingURL=retry-busy.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map deleted file mode 100644 index 4bb5076..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/retry-busy.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"retry-busy.js","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":";AAAA,qEAAqE;;;AAErE,8CAA4C;AAE5C,yCAAsC;AAEzB,QAAA,UAAU,GAAG,GAAG,CAAA;AAChB,QAAA,IAAI,GAAG,GAAG,CAAA;AACV,QAAA,UAAU,GAAG,EAAE,CAAA;AACf,QAAA,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;AAEpD,MAAM,SAAS,GAAG,CAAI,EAAgC,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,KAAK,EAClB,IAAY,EACZ,GAAuB,EACvB,OAAO,GAAG,CAAC,EACX,KAAK,GAAG,CAAC,EACT,EAAE;QACF,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,YAAI,CAAA;QAChC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,IAAA,oBAAS,EAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,aAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;oBACnC,KAAK,GAAG,OAAO,GAAG,KAAK,CAAA;oBACvB,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;wBAChB,MAAM,IAAA,qBAAU,EAAC,OAAO,CAAC,CAAA;wBACzB,OAAO,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;oBAC1C,CAAC;oBACD,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;wBAClB,OAAO,EAAE,CAAA;wBACT,SAAQ;oBACV,CAAC;gBACH,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAjCY,QAAA,SAAS,aAiCrB;AAED,uCAAuC;AAChC,MAAM,aAAa,GAAG,CAAI,EAAuB,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAkB,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IACE,IAAA,oBAAS,EAAC,EAAE,CAAC;oBACb,EAAE,CAAC,IAAI,KAAK,IAAI;oBAChB,aAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;oBAClB,OAAO,GAAG,GAAG,EACb,CAAC;oBACD,OAAO,EAAE,CAAA;oBACT,SAAQ;gBACV,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAtBY,QAAA,aAAa,iBAsBzB","sourcesContent":["// note: max backoff is the maximum that any *single* backoff will do\n\nimport { setTimeout } from 'timers/promises'\nimport { RimrafAsyncOptions, RimrafOptions } from './index.js'\nimport { isFsError } from './error.js'\n\nexport const MAXBACKOFF = 200\nexport const RATE = 1.2\nexport const MAXRETRIES = 10\nexport const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY'])\n\nexport const retryBusy = (fn: (path: string) => Promise) => {\n const method = async (\n path: string,\n opt: RimrafAsyncOptions,\n backoff = 1,\n total = 0,\n ) => {\n const mbo = opt.maxBackoff || MAXBACKOFF\n const rate = opt.backoff || RATE\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return await fn(path)\n } catch (er) {\n if (isFsError(er) && er.path === path && codes.has(er.code)) {\n backoff = Math.ceil(backoff * rate)\n total = backoff + total\n if (total < mbo) {\n await setTimeout(backoff)\n return method(path, opt, backoff, total)\n }\n if (retries < max) {\n retries++\n continue\n }\n }\n throw er\n }\n }\n }\n\n return method\n}\n\n// just retries, no async so no backoff\nexport const retryBusySync = (fn: (path: string) => T) => {\n const method = (path: string, opt: RimrafOptions) => {\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return fn(path)\n } catch (er) {\n if (\n isFsError(er) &&\n er.path === path &&\n codes.has(er.code) &&\n retries < max\n ) {\n retries++\n continue\n }\n throw er\n }\n }\n }\n return method\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts deleted file mode 100644 index 35c5c86..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const rimrafManual: (path: string, opt: import("./opt-arg.js").RimrafAsyncOptions) => Promise; -export declare const rimrafManualSync: (path: string, opt: import("./opt-arg.js").RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-manual.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map deleted file mode 100644 index 96115d0..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-manual.d.ts","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,oFACmC,CAAA;AAC5D,eAAO,MAAM,gBAAgB,0EACuC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js deleted file mode 100644 index 81ab8bf..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimrafManualSync = exports.rimrafManual = void 0; -const rimraf_posix_js_1 = require("./rimraf-posix.js"); -const rimraf_windows_js_1 = require("./rimraf-windows.js"); -exports.rimrafManual = process.platform === 'win32' ? rimraf_windows_js_1.rimrafWindows : rimraf_posix_js_1.rimrafPosix; -exports.rimrafManualSync = process.platform === 'win32' ? rimraf_windows_js_1.rimrafWindowsSync : rimraf_posix_js_1.rimrafPosixSync; -//# sourceMappingURL=rimraf-manual.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map deleted file mode 100644 index 410c6f8..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-manual.js","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":";;;AAAA,uDAAgE;AAChE,2DAAsE;AAEzD,QAAA,YAAY,GACvB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iCAAa,CAAC,CAAC,CAAC,6BAAW,CAAA;AAC/C,QAAA,gBAAgB,GAC3B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,qCAAiB,CAAC,CAAC,CAAC,iCAAe,CAAA","sourcesContent":["import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\n\nexport const rimrafManual =\n process.platform === 'win32' ? rimrafWindows : rimrafPosix\nexport const rimrafManualSync =\n process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts deleted file mode 100644 index 5d41d40..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafMoveRemove: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafMoveRemoveSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-move-remove.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map deleted file mode 100644 index 722538e..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-move-remove.d.ts","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAalE,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AA0ED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js deleted file mode 100644 index 7e9b2cb..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js +++ /dev/null @@ -1,138 +0,0 @@ -"use strict"; -// https://youtu.be/uhRWMGBjlO8?t=537 -// -// 1. readdir -// 2. for each entry -// a. if a non-empty directory, recurse -// b. if an empty directory, move to random hidden file name in $TEMP -// c. unlink/rmdir $TEMP -// -// This works around the fact that unlink/rmdir is non-atomic and takes -// a non-deterministic amount of time to complete. -// -// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm. -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimrafMoveRemoveSync = exports.rimrafMoveRemove = void 0; -const path_1 = require("path"); -const default_tmp_js_1 = require("./default-tmp.js"); -const ignore_enoent_js_1 = require("./ignore-enoent.js"); -const fs_js_1 = require("./fs.js"); -const readdir_or_error_js_1 = require("./readdir-or-error.js"); -const fix_eperm_js_1 = require("./fix-eperm.js"); -const error_js_1 = require("./error.js"); -const { lstat, rename, unlink, rmdir } = fs_js_1.promises; -// crypto.randomBytes is much slower, and Math.random() is enough here -const uniqueFilename = (path) => `.${(0, path_1.basename)(path)}.${Math.random()}`; -const unlinkFixEPERM = (0, fix_eperm_js_1.fixEPERM)(unlink); -const unlinkFixEPERMSync = (0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.unlinkSync); -const rimrafMoveRemove = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)))) ?? true); -}; -exports.rimrafMoveRemove = rimrafMoveRemove; -const rimrafMoveRemoveDir = async (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - if (!opt.tmp) { - return rimrafMoveRemoveDir(path, { ...opt, tmp: await (0, default_tmp_js_1.defaultTmp)(path) }, ent); - } - if (path === opt.tmp && (0, path_1.parse)(path).root !== path) { - throw new Error('cannot delete temp directory used for deletion'); - } - const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await (0, ignore_enoent_js_1.ignoreENOENT)(tmpUnlink(path, opt.tmp, unlinkFixEPERM)); - return true; - } - const removedAll = (await Promise.all(entries.map(ent => rimrafMoveRemoveDir((0, path_1.resolve)(path, ent.name), opt, ent)))).every(v => v === true); - if (!removedAll) { - return false; - } - // we don't ever ACTUALLY try to unlink /, because that can never work - // but when preserveRoot is false, we could be operating on it. - // No need to check if preserveRoot is not false. - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await (0, ignore_enoent_js_1.ignoreENOENT)(tmpUnlink(path, opt.tmp, rmdir)); - return true; -}; -const tmpUnlink = async (path, tmp, rm) => { - const tmpFile = (0, path_1.resolve)(tmp, uniqueFilename(path)); - await rename(path, tmpFile); - return await rm(tmpFile); -}; -const rimrafMoveRemoveSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafMoveRemoveDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ?? true); -}; -exports.rimrafMoveRemoveSync = rimrafMoveRemoveSync; -const rimrafMoveRemoveDirSync = (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - if (!opt.tmp) { - return rimrafMoveRemoveDirSync(path, { ...opt, tmp: (0, default_tmp_js_1.defaultTmpSync)(path) }, ent); - } - const tmp = opt.tmp; - if (path === opt.tmp && (0, path_1.parse)(path).root !== path) { - throw new Error('cannot delete temp directory used for deletion'); - } - const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const p = (0, path_1.resolve)(path, ent.name); - removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll; - } - if (!removedAll) { - return false; - } - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => tmpUnlinkSync(path, tmp, fs_js_1.rmdirSync)); - return true; -}; -const tmpUnlinkSync = (path, tmp, rmSync) => { - const tmpFile = (0, path_1.resolve)(tmp, uniqueFilename(path)); - (0, fs_js_1.renameSync)(path, tmpFile); - return rmSync(tmpFile); -}; -//# sourceMappingURL=rimraf-move-remove.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map deleted file mode 100644 index 9b20a9d..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-move-remove.js","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"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","sourcesContent":["// https://youtu.be/uhRWMGBjlO8?t=537\n//\n// 1. readdir\n// 2. for each entry\n// a. if a non-empty directory, recurse\n// b. if an empty directory, move to random hidden file name in $TEMP\n// c. unlink/rmdir $TEMP\n//\n// This works around the fact that unlink/rmdir is non-atomic and takes\n// a non-deterministic amount of time to complete.\n//\n// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm.\n\nimport { basename, parse, resolve } from 'path'\nimport { defaultTmp, defaultTmpSync } from './default-tmp.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport {\n lstatSync,\n promises,\n renameSync,\n rmdirSync,\n unlinkSync,\n} from './fs.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { errorCode } from './error.js'\nconst { lstat, rename, unlink, rmdir } = promises\n\n// crypto.randomBytes is much slower, and Math.random() is enough here\nconst uniqueFilename = (path: string) =>\n `.${basename(path)}.${Math.random()}`\n\nconst unlinkFixEPERM = fixEPERM(unlink)\nconst unlinkFixEPERMSync = fixEPERMSync(unlinkSync)\n\nexport const rimrafMoveRemove = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nconst rimrafMoveRemoveDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDir(\n path,\n { ...opt, tmp: await defaultTmp(path) },\n ent,\n )\n }\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir))\n return true\n}\n\nconst tmpUnlink = async (\n path: string,\n tmp: string,\n rm: (p: string) => Promise,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n await rename(path, tmpFile)\n return await rm(tmpFile)\n}\n\nexport const rimrafMoveRemoveSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafMoveRemoveDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafMoveRemoveDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDirSync(\n path,\n { ...opt, tmp: defaultTmpSync(path) },\n ent,\n )\n }\n const tmp: string = opt.tmp\n\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll\n }\n if (!removedAll) {\n return false\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync))\n return true\n}\n\nconst tmpUnlinkSync = (\n path: string,\n tmp: string,\n rmSync: (p: string) => void,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n renameSync(path, tmpFile)\n return rmSync(tmpFile)\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts deleted file mode 100644 index cc84bf7..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafNative: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafNativeSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map deleted file mode 100644 index 6bb2a08..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-native.d.ts","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAIlE,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,KAAK,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,iBAAiB,KACrB,OAOF,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js deleted file mode 100644 index ab9f633..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimrafNativeSync = exports.rimrafNative = void 0; -const fs_js_1 = require("./fs.js"); -const { rm } = fs_js_1.promises; -const rimrafNative = async (path, opt) => { - await rm(path, { - ...opt, - force: true, - recursive: true, - }); - return true; -}; -exports.rimrafNative = rimrafNative; -const rimrafNativeSync = (path, opt) => { - (0, fs_js_1.rmSync)(path, { - ...opt, - force: true, - recursive: true, - }); - return true; -}; -exports.rimrafNativeSync = rimrafNativeSync; -//# sourceMappingURL=rimraf-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map deleted file mode 100644 index 6eddd44..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-native.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-native.js","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":";;;AACA,mCAA0C;AAC1C,MAAM,EAAE,EAAE,EAAE,GAAG,gBAAQ,CAAA;AAEhB,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAY,EACZ,GAAuB,EACL,EAAE;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAVY,QAAA,YAAY,gBAUxB;AAEM,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,GAAsB,EACb,EAAE;IACX,IAAA,cAAM,EAAC,IAAI,EAAE;QACX,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAVY,QAAA,gBAAgB,oBAU5B","sourcesContent":["import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { promises, rmSync } from './fs.js'\nconst { rm } = promises\n\nexport const rimrafNative = async (\n path: string,\n opt: RimrafAsyncOptions,\n): Promise => {\n await rm(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n\nexport const rimrafNativeSync = (\n path: string,\n opt: RimrafSyncOptions,\n): boolean => {\n rmSync(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts deleted file mode 100644 index 8e532ef..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafPosix: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafPosixSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-posix.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map deleted file mode 100644 index c7b1b6a..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-posix.d.ts","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKlE,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAK,iBAAiB,YAOnE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js deleted file mode 100644 index 554d5d6..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js +++ /dev/null @@ -1,102 +0,0 @@ -"use strict"; -// the simple recursive removal, where unlink and rmdir are atomic -// Note that this approach does NOT work on Windows! -// We stat first and only unlink if the Dirent isn't a directory, -// because sunos will let root unlink a directory, and some -// SUPER weird breakage happens as a result. -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimrafPosixSync = exports.rimrafPosix = void 0; -const fs_js_1 = require("./fs.js"); -const path_1 = require("path"); -const readdir_or_error_js_1 = require("./readdir-or-error.js"); -const ignore_enoent_js_1 = require("./ignore-enoent.js"); -const error_js_1 = require("./error.js"); -const { lstat, rmdir, unlink } = fs_js_1.promises; -const rimrafPosix = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafPosixDir(path, opt, stat)))) ?? true); -}; -exports.rimrafPosix = rimrafPosix; -const rimrafPosixSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafPosixDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ?? true); -}; -exports.rimrafPosixSync = rimrafPosixSync; -const rimrafPosixDir = async (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await (0, ignore_enoent_js_1.ignoreENOENT)(unlink(path)); - return true; - } - const removedAll = (await Promise.all(entries.map(ent => rimrafPosixDir((0, path_1.resolve)(path, ent.name), opt, ent)))).every(v => v === true); - if (!removedAll) { - return false; - } - // we don't ever ACTUALLY try to unlink /, because that can never work - // but when preserveRoot is false, we could be operating on it. - // No need to check if preserveRoot is not false. - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await (0, ignore_enoent_js_1.ignoreENOENT)(rmdir(path)); - return true; -}; -const rimrafPosixDirSync = (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => (0, fs_js_1.unlinkSync)(path)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const p = (0, path_1.resolve)(path, ent.name); - removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll; - } - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => (0, fs_js_1.rmdirSync)(path)); - return true; -}; -//# sourceMappingURL=rimraf-posix.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map deleted file mode 100644 index c137458..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-posix.js","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":";AAAA,kEAAkE;AAClE,oDAAoD;AACpD,iEAAiE;AACjE,2DAA2D;AAC3D,4CAA4C;;;AAE5C,mCAAoE;AACpE,+BAAqC;AACrC,+DAA0E;AAG1E,yDAAmE;AACnE,yCAAsC;AACtC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,gBAAQ,CAAA;AAElC,MAAM,WAAW,GAAG,KAAK,EAC9B,IAAY,EACZ,GAAuB,EACvB,EAAE;IACF,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,CAAC,MAAM,IAAA,+BAAY,EACjB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAC1D,CAAC,IAAI,IAAI,CACX,CAAA;AACH,CAAC,CAAA;AAVY,QAAA,WAAW,eAUvB;AAEM,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,GAAsB,EAAE,EAAE;IACtE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CACL,IAAA,mCAAgB,EAAC,GAAG,EAAE,CACpB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAA,iBAAS,EAAC,IAAI,CAAC,CAAC,CAC/C,IAAI,IAAI,CACV,CAAA;AACH,CAAC,CAAA;AAPY,QAAA,eAAe,mBAO3B;AAED,MAAM,cAAc,GAAG,KAAK,EAC1B,IAAY,EACZ,GAAuB,EACvB,GAAmB,EACD,EAAE;IACpB,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,IAAA,oCAAc,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,IAAA,oBAAS,EAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,IAAA,oBAAS,EAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,MAAM,IAAA,+BAAY,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAChB,cAAc,CAAC,IAAA,cAAO,EAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAClD,CACF,CACF,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;IAExB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sEAAsE;IACtE,+DAA+D;IAC/D,iDAAiD;IACjD,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,IAAA,YAAK,EAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,IAAA,+BAAY,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CACzB,IAAY,EACZ,GAAsB,EACtB,GAAmB,EACV,EAAE;IACX,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAA,wCAAkB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,oDAAoD;QACpD,qBAAqB;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,IAAA,oBAAS,EAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,IAAA,oBAAS,EAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,UAAU,GAAY,IAAI,CAAA;IAC9B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,UAAU,GAAG,kBAAkB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,UAAU,CAAA;IAC5D,CAAC;IACD,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,IAAA,YAAK,EAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAA,mCAAgB,EAAC,GAAG,EAAE,CAAC,IAAA,iBAAS,EAAC,IAAI,CAAC,CAAC,CAAA;IACvC,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["// the simple recursive removal, where unlink and rmdir are atomic\n// Note that this approach does NOT work on Windows!\n// We stat first and only unlink if the Dirent isn't a directory,\n// because sunos will let root unlink a directory, and some\n// SUPER weird breakage happens as a result.\n\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { parse, resolve } from 'path'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { errorCode } from './error.js'\nconst { lstat, rmdir, unlink } = promises\n\nexport const rimrafPosix = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafPosixDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nexport const rimrafPosixSync = (path: string, opt: RimrafSyncOptions) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafPosixDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafPosixDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(unlink(path))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafPosixDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n\n await ignoreENOENT(rmdir(path))\n return true\n}\n\nconst rimrafPosixDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => unlinkSync(path))\n return true\n }\n let removedAll: boolean = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (!removedAll) {\n return false\n }\n\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n\n ignoreENOENTSync(() => rmdirSync(path))\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts deleted file mode 100644 index 5556890..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafWindows: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafWindowsSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-windows.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map deleted file mode 100644 index bcca3f3..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-windows.d.ts","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AA2DlE,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js deleted file mode 100644 index c49968c..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js +++ /dev/null @@ -1,159 +0,0 @@ -"use strict"; -// This is the same as rimrafPosix, with the following changes: -// -// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff -// 2. All non-directories are removed first and then all directories are -// removed in a second sweep. -// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on -// the that folder. -// -// Note: "move then remove" is 2-10 times slower, and just as unreliable. -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rimrafWindowsSync = exports.rimrafWindows = void 0; -const path_1 = require("path"); -const fix_eperm_js_1 = require("./fix-eperm.js"); -const fs_js_1 = require("./fs.js"); -const ignore_enoent_js_1 = require("./ignore-enoent.js"); -const readdir_or_error_js_1 = require("./readdir-or-error.js"); -const retry_busy_js_1 = require("./retry-busy.js"); -const rimraf_move_remove_js_1 = require("./rimraf-move-remove.js"); -const error_js_1 = require("./error.js"); -const { unlink, rmdir, lstat } = fs_js_1.promises; -const rimrafWindowsFile = (0, retry_busy_js_1.retryBusy)((0, fix_eperm_js_1.fixEPERM)(unlink)); -const rimrafWindowsFileSync = (0, retry_busy_js_1.retryBusySync)((0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.unlinkSync)); -const rimrafWindowsDirRetry = (0, retry_busy_js_1.retryBusy)((0, fix_eperm_js_1.fixEPERM)(rmdir)); -const rimrafWindowsDirRetrySync = (0, retry_busy_js_1.retryBusySync)((0, fix_eperm_js_1.fixEPERMSync)(fs_js_1.rmdirSync)); -const rimrafWindowsDirMoveRemoveFallback = async (path, -// already filtered, remove from options so we don't call unnecessarily -// eslint-disable-next-line @typescript-eslint/no-unused-vars -{ filter, ...opt }) => { - /* c8 ignore next */ - opt?.signal?.throwIfAborted(); - try { - await rimrafWindowsDirRetry(path, opt); - return true; - } - catch (er) { - if ((0, error_js_1.errorCode)(er) === 'ENOTEMPTY') { - return (0, rimraf_move_remove_js_1.rimrafMoveRemove)(path, opt); - } - throw er; - } -}; -const rimrafWindowsDirMoveRemoveFallbackSync = (path, -// already filtered, remove from options so we don't call unnecessarily -// eslint-disable-next-line @typescript-eslint/no-unused-vars -{ filter, ...opt }) => { - opt?.signal?.throwIfAborted(); - try { - rimrafWindowsDirRetrySync(path, opt); - return true; - } - catch (er) { - if ((0, error_js_1.errorCode)(er) === 'ENOTEMPTY') { - return (0, rimraf_move_remove_js_1.rimrafMoveRemoveSync)(path, opt); - } - throw er; - } -}; -const START = Symbol('start'); -const CHILD = Symbol('child'); -const FINISH = Symbol('finish'); -const rimrafWindows = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await (0, ignore_enoent_js_1.ignoreENOENT)(lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)))) ?? true); -}; -exports.rimrafWindows = rimrafWindows; -const rimrafWindowsSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsDirSync(path, opt, (0, fs_js_1.lstatSync)(path), START)) ?? true); -}; -exports.rimrafWindowsSync = rimrafWindowsSync; -const rimrafWindowsDir = async (path, opt, ent, state = START) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? await (0, readdir_or_error_js_1.readdirOrError)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - // is a file - await (0, ignore_enoent_js_1.ignoreENOENT)(rimrafWindowsFile(path, opt)); - return true; - } - const s = state === START ? CHILD : state; - const removedAll = (await Promise.all(entries.map(ent => rimrafWindowsDir((0, path_1.resolve)(path, ent.name), opt, ent, s)))).every(v => v === true); - if (state === START) { - return rimrafWindowsDir(path, opt, ent, FINISH); - } - else if (state === FINISH) { - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await (0, ignore_enoent_js_1.ignoreENOENT)(rimrafWindowsDirMoveRemoveFallback(path, opt)); - } - return true; -}; -const rimrafWindowsDirSync = (path, opt, ent, state = START) => { - const entries = ent.isDirectory() ? (0, readdir_or_error_js_1.readdirOrErrorSync)(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if ((0, error_js_1.errorCode)(entries) === 'ENOENT') { - return true; - } - if ((0, error_js_1.errorCode)(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - // is a file - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsFileSync(path, opt)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const s = state === START ? CHILD : state; - const p = (0, path_1.resolve)(path, ent.name); - removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll; - } - if (state === START) { - return rimrafWindowsDirSync(path, opt, ent, FINISH); - } - else if (state === FINISH) { - if (opt.preserveRoot === false && path === (0, path_1.parse)(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - (0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafWindowsDirMoveRemoveFallbackSync(path, opt)); - } - return true; -}; -//# sourceMappingURL=rimraf-windows.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map deleted file mode 100644 index 7ff8651..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-windows.js","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"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","sourcesContent":["// This is the same as rimrafPosix, with the following changes:\n//\n// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff\n// 2. All non-directories are removed first and then all directories are\n// removed in a second sweep.\n// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on\n// the that folder.\n//\n// Note: \"move then remove\" is 2-10 times slower, and just as unreliable.\n\nimport { Dirent, Stats } from 'fs'\nimport { parse, resolve } from 'path'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { retryBusy, retryBusySync } from './retry-busy.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { errorCode } from './error.js'\nconst { unlink, rmdir, lstat } = promises\n\nconst rimrafWindowsFile = retryBusy(fixEPERM(unlink))\nconst rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync))\nconst rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir))\nconst rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync))\n\nconst rimrafWindowsDirMoveRemoveFallback = async (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafAsyncOptions,\n): Promise => {\n /* c8 ignore next */\n opt?.signal?.throwIfAborted()\n try {\n await rimrafWindowsDirRetry(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemove(path, opt)\n }\n throw er\n }\n}\n\nconst rimrafWindowsDirMoveRemoveFallbackSync = (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafSyncOptions,\n): boolean => {\n opt?.signal?.throwIfAborted()\n try {\n rimrafWindowsDirRetrySync(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemoveSync(path, opt)\n }\n throw er\n }\n}\n\nconst START = Symbol('start')\nconst CHILD = Symbol('child')\nconst FINISH = Symbol('finish')\n\nexport const rimrafWindows = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)),\n )) ?? true\n )\n}\n\nexport const rimrafWindowsSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafWindowsDirSync(path, opt, lstatSync(path), START),\n ) ?? true\n )\n}\n\nconst rimrafWindowsDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n state = START,\n): Promise => {\n opt?.signal?.throwIfAborted()\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n // is a file\n await ignoreENOENT(rimrafWindowsFile(path, opt))\n return true\n }\n\n const s = state === START ? CHILD : state\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafWindowsDir(resolve(path, ent.name), opt, ent, s),\n ),\n )\n ).every(v => v === true)\n\n if (state === START) {\n return rimrafWindowsDir(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt))\n }\n return true\n}\n\nconst rimrafWindowsDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n state = START,\n): boolean => {\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n // is a file\n ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const s = state === START ? CHILD : state\n const p = resolve(path, ent.name)\n removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll\n }\n\n if (state === START) {\n return rimrafWindowsDirSync(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() =>\n rimrafWindowsDirMoveRemoveFallbackSync(path, opt),\n )\n }\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts deleted file mode 100644 index e191fd9..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafOptions } from './index.js'; -export declare const useNative: (opt?: RimrafAsyncOptions) => boolean; -export declare const useNativeSync: (opt?: RimrafOptions) => boolean; -//# sourceMappingURL=use-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map deleted file mode 100644 index be687c1..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"use-native.d.ts","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW9D,eAAO,MAAM,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,kBAAkB,KAAK,OAGf,CAAA;AACvC,eAAO,MAAM,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,aAAa,KAAK,OAGd,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js deleted file mode 100644 index 68c0e83..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.useNativeSync = exports.useNative = void 0; -/* c8 ignore next */ -const [major = 0, minor = 0] = process.version - .replace(/^v/, '') - .split('.') - .map(v => parseInt(v, 10)); -const hasNative = major > 14 || (major === 14 && minor >= 14); -// we do NOT use native by default on Windows, because Node's native -// rm implementation is less advanced. Change this code if that changes. -exports.useNative = !hasNative || process.platform === 'win32' ? - () => false - : opt => !opt?.signal && !opt?.filter; -exports.useNativeSync = !hasNative || process.platform === 'win32' ? - () => false - : opt => !opt?.signal && !opt?.filter; -//# sourceMappingURL=use-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map b/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map deleted file mode 100644 index 9b4a046..0000000 --- a/apps/extension/node_modules/rimraf/dist/commonjs/use-native.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"use-native.js","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":";;;AAEA,oBAAoB;AACpB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO;KAC3C,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;KACjB,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5B,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAE7D,oEAAoE;AACpE,yEAAyE;AAC5D,QAAA,SAAS,GACpB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA;AAC1B,QAAA,aAAa,GACxB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafOptions } from './index.js'\n\n/* c8 ignore next */\nconst [major = 0, minor = 0] = process.version\n .replace(/^v/, '')\n .split('.')\n .map(v => parseInt(v, 10))\nconst hasNative = major > 14 || (major === 14 && minor >= 14)\n\n// we do NOT use native by default on Windows, because Node's native\n// rm implementation is less advanced. Change this code if that changes.\nexport const useNative: (opt?: RimrafAsyncOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\nexport const useNativeSync: (opt?: RimrafOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts deleted file mode 100644 index 77298e4..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node -export {}; -//# sourceMappingURL=bin.d.mts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map b/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map deleted file mode 100644 index ec64bdd..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/bin.d.mts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"bin.d.mts","sourceRoot":"","sources":["../../src/bin.mts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs deleted file mode 100644 index 77441b1..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env node -import { rimraf } from './index.js'; -import { loadPackageJson } from 'package-json-from-dist'; -const { version } = loadPackageJson(import.meta.url, '../package.json'); -const runHelpForUsage = () => console.error('run `rimraf --help` for usage information'); -const help = `rimraf version ${version} - -Usage: rimraf [ ...] -Deletes all files and folders at "path", recursively. - -Options: - -- Treat all subsequent arguments as paths - -h --help Display this usage info - --version Display version - --preserve-root Do not remove '/' recursively (default) - --no-preserve-root Do not treat '/' specially - -G --no-glob Treat arguments as literal paths, not globs (default) - -g --glob Treat arguments as glob patterns - -v --verbose Be verbose when deleting files, showing them as - they are removed. Not compatible with --impl=native - -V --no-verbose Be silent when deleting files, showing nothing as - they are removed (default) - -i --interactive Ask for confirmation before deleting anything - Not compatible with --impl=native - -I --no-interactive Do not ask for confirmation before deleting - - --impl= Specify the implementation to use: - rimraf: choose the best option (default) - native: the built-in implementation in Node.js - manual: the platform-specific JS implementation - posix: the Posix JS implementation - windows: the Windows JS implementation (falls back to - move-remove on ENOTEMPTY) - move-remove: a slow reliable Windows fallback - -Implementation-specific options: - --tmp= Temp file folder for 'move-remove' implementation - --max-retries= maxRetries for 'native' and 'windows' implementations - --retry-delay= retryDelay for 'native' implementation, default 100 - --backoff= Exponential backoff factor for retries (default: 1.2) -`; -import { parse, relative, resolve } from 'path'; -const cwd = process.cwd(); -import { createInterface } from 'readline'; -const prompt = async (rl, q) => new Promise(res => rl.question(q, res)); -const interactiveRimraf = async (impl, paths, opt) => { - const existingFilter = opt.filter || (() => true); - let allRemaining = false; - let noneRemaining = false; - const queue = []; - let processing = false; - const processQueue = async () => { - if (processing) - return; - processing = true; - let next; - while ((next = queue.shift())) { - await next(); - } - processing = false; - }; - const oneAtATime = (fn) => async (s, e) => { - const p = new Promise(res => { - queue.push(async () => { - const result = await fn(s, e); - res(result); - return result; - }); - }); - void processQueue(); - return p; - }; - const rl = createInterface({ - input: process.stdin, - output: process.stdout, - }); - opt.filter = oneAtATime(async (path, ent) => { - if (noneRemaining) { - return false; - } - while (!allRemaining) { - const a = (await prompt(rl, `rm? ${relative(cwd, path)}\n[(Yes)/No/All/Quit] > `)).trim(); - if (/^n/i.test(a)) { - return false; - } - else if (/^a/i.test(a)) { - allRemaining = true; - break; - } - else if (/^q/i.test(a)) { - noneRemaining = true; - return false; - } - else if (a === '' || /^y/i.test(a)) { - break; - } - else { - continue; - } - } - return existingFilter(path, ent); - }); - await impl(paths, opt); - rl.close(); -}; -const main = async (...args) => { - const verboseFilter = (s) => { - console.log(relative(cwd, s)); - return true; - }; - const opt = {}; - const paths = []; - let dashdash = false; - let impl = rimraf; - let interactive = false; - for (const arg of args) { - if (dashdash) { - paths.push(arg); - continue; - } - if (arg === '--') { - dashdash = true; - continue; - } - else if (arg === '-rf' || arg === '-fr') { - // this never did anything, but people put it there I guess - continue; - } - else if (arg === '-h' || arg === '--help') { - console.log(help); - return 0; - } - else if (arg === '--version') { - console.log(version); - return 0; - } - else if (arg === '--interactive' || arg === '-i') { - interactive = true; - continue; - } - else if (arg === '--no-interactive' || arg === '-I') { - interactive = false; - continue; - } - else if (arg === '--verbose' || arg === '-v') { - opt.filter = verboseFilter; - continue; - } - else if (arg === '--no-verbose' || arg === '-V') { - opt.filter = undefined; - continue; - } - else if (arg === '-g' || arg === '--glob') { - opt.glob = true; - continue; - } - else if (arg === '-G' || arg === '--no-glob') { - opt.glob = false; - continue; - } - else if (arg === '--preserve-root') { - opt.preserveRoot = true; - continue; - } - else if (arg === '--no-preserve-root') { - opt.preserveRoot = false; - continue; - } - else if (/^--tmp=/.test(arg)) { - const val = arg.substring('--tmp='.length); - opt.tmp = val; - continue; - } - else if (/^--max-retries=/.test(arg)) { - const val = +arg.substring('--max-retries='.length); - opt.maxRetries = val; - continue; - } - else if (/^--retry-delay=/.test(arg)) { - const val = +arg.substring('--retry-delay='.length); - opt.retryDelay = val; - continue; - } - else if (/^--backoff=/.test(arg)) { - const val = +arg.substring('--backoff='.length); - opt.backoff = val; - continue; - } - else if (/^--impl=/.test(arg)) { - const val = arg.substring('--impl='.length); - switch (val) { - case 'rimraf': - impl = rimraf; - continue; - case 'native': - case 'manual': - case 'posix': - case 'windows': - impl = rimraf[val]; - continue; - case 'move-remove': - impl = rimraf.moveRemove; - continue; - default: - console.error(`unknown implementation: ${val}`); - runHelpForUsage(); - return 1; - } - } - else if (/^-/.test(arg)) { - console.error(`unknown option: ${arg}`); - runHelpForUsage(); - return 1; - } - else { - paths.push(arg); - } - } - if (opt.preserveRoot !== false) { - for (const path of paths.map(p => resolve(p))) { - if (path === parse(path).root) { - console.error(`rimraf: it is dangerous to operate recursively on '/'`); - console.error('use --no-preserve-root to override this failsafe'); - return 1; - } - } - } - if (!paths.length) { - console.error('rimraf: must provide a path to remove'); - runHelpForUsage(); - return 1; - } - if (impl === rimraf.native && (interactive || opt.filter)) { - console.error('native implementation does not support -v or -i'); - runHelpForUsage(); - return 1; - } - if (interactive) { - await interactiveRimraf(impl, paths, opt); - } - else { - await impl(paths, opt); - } - return 0; -}; -main(...process.argv.slice(2)).then(code => process.exit(code), er => { - console.error(er); - process.exit(1); -}); -//# sourceMappingURL=bin.mjs.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map b/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map deleted file mode 100644 index 4baed42..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/bin.mjs.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"bin.mjs","sourceRoot":"","sources":["../../src/bin.mts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport type { RimrafAsyncOptions } from './index.js'\nimport { rimraf } from './index.js'\nimport { loadPackageJson } from 'package-json-from-dist'\n\nconst { version } = loadPackageJson(\n import.meta.url,\n '../package.json',\n) as {\n version: string\n}\n\nconst runHelpForUsage = () =>\n console.error('run `rimraf --help` for usage information')\n\nconst help = `rimraf version ${version}\n\nUsage: rimraf [ ...]\nDeletes all files and folders at \"path\", recursively.\n\nOptions:\n -- Treat all subsequent arguments as paths\n -h --help Display this usage info\n --version Display version\n --preserve-root Do not remove '/' recursively (default)\n --no-preserve-root Do not treat '/' specially\n -G --no-glob Treat arguments as literal paths, not globs (default)\n -g --glob Treat arguments as glob patterns\n -v --verbose Be verbose when deleting files, showing them as\n they are removed. Not compatible with --impl=native\n -V --no-verbose Be silent when deleting files, showing nothing as\n they are removed (default)\n -i --interactive Ask for confirmation before deleting anything\n Not compatible with --impl=native\n -I --no-interactive Do not ask for confirmation before deleting\n\n --impl= Specify the implementation to use:\n rimraf: choose the best option (default)\n native: the built-in implementation in Node.js\n manual: the platform-specific JS implementation\n posix: the Posix JS implementation\n windows: the Windows JS implementation (falls back to\n move-remove on ENOTEMPTY)\n move-remove: a slow reliable Windows fallback\n\nImplementation-specific options:\n --tmp= Temp file folder for 'move-remove' implementation\n --max-retries= maxRetries for 'native' and 'windows' implementations\n --retry-delay= retryDelay for 'native' implementation, default 100\n --backoff= Exponential backoff factor for retries (default: 1.2)\n`\n\nimport { parse, relative, resolve } from 'path'\nconst cwd = process.cwd()\n\nimport { Dirent, Stats } from 'fs'\nimport { createInterface, Interface } from 'readline'\n\nconst prompt = async (rl: Interface, q: string) =>\n new Promise(res => rl.question(q, res))\n\nconst interactiveRimraf = async (\n impl: (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ) => Promise,\n paths: string[],\n opt: RimrafAsyncOptions,\n) => {\n const existingFilter = opt.filter || (() => true)\n let allRemaining = false\n let noneRemaining = false\n const queue: (() => Promise)[] = []\n let processing = false\n const processQueue = async () => {\n if (processing) return\n processing = true\n let next: (() => Promise) | undefined\n while ((next = queue.shift())) {\n await next()\n }\n processing = false\n }\n const oneAtATime =\n (fn: (s: string, e: Dirent | Stats) => Promise) =>\n async (s: string, e: Dirent | Stats): Promise => {\n const p = new Promise(res => {\n queue.push(async () => {\n const result = await fn(s, e)\n res(result)\n return result\n })\n })\n void processQueue()\n return p\n }\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n opt.filter = oneAtATime(\n async (path: string, ent: Dirent | Stats): Promise => {\n if (noneRemaining) {\n return false\n }\n while (!allRemaining) {\n const a = (\n await prompt(\n rl,\n `rm? ${relative(cwd, path)}\\n[(Yes)/No/All/Quit] > `,\n )\n ).trim()\n if (/^n/i.test(a)) {\n return false\n } else if (/^a/i.test(a)) {\n allRemaining = true\n break\n } else if (/^q/i.test(a)) {\n noneRemaining = true\n return false\n } else if (a === '' || /^y/i.test(a)) {\n break\n } else {\n continue\n }\n }\n return existingFilter(path, ent)\n },\n )\n await impl(paths, opt)\n rl.close()\n}\n\nconst main = async (...args: string[]) => {\n const verboseFilter = (s: string) => {\n console.log(relative(cwd, s))\n return true\n }\n\n const opt: RimrafAsyncOptions = {}\n const paths: string[] = []\n let dashdash = false\n let impl: (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ) => Promise = rimraf\n\n let interactive = false\n\n for (const arg of args) {\n if (dashdash) {\n paths.push(arg)\n continue\n }\n if (arg === '--') {\n dashdash = true\n continue\n } else if (arg === '-rf' || arg === '-fr') {\n // this never did anything, but people put it there I guess\n continue\n } else if (arg === '-h' || arg === '--help') {\n console.log(help)\n return 0\n } else if (arg === '--version') {\n console.log(version)\n return 0\n } else if (arg === '--interactive' || arg === '-i') {\n interactive = true\n continue\n } else if (arg === '--no-interactive' || arg === '-I') {\n interactive = false\n continue\n } else if (arg === '--verbose' || arg === '-v') {\n opt.filter = verboseFilter\n continue\n } else if (arg === '--no-verbose' || arg === '-V') {\n opt.filter = undefined\n continue\n } else if (arg === '-g' || arg === '--glob') {\n opt.glob = true\n continue\n } else if (arg === '-G' || arg === '--no-glob') {\n opt.glob = false\n continue\n } else if (arg === '--preserve-root') {\n opt.preserveRoot = true\n continue\n } else if (arg === '--no-preserve-root') {\n opt.preserveRoot = false\n continue\n } else if (/^--tmp=/.test(arg)) {\n const val = arg.substring('--tmp='.length)\n opt.tmp = val\n continue\n } else if (/^--max-retries=/.test(arg)) {\n const val = +arg.substring('--max-retries='.length)\n opt.maxRetries = val\n continue\n } else if (/^--retry-delay=/.test(arg)) {\n const val = +arg.substring('--retry-delay='.length)\n opt.retryDelay = val\n continue\n } else if (/^--backoff=/.test(arg)) {\n const val = +arg.substring('--backoff='.length)\n opt.backoff = val\n continue\n } else if (/^--impl=/.test(arg)) {\n const val = arg.substring('--impl='.length)\n switch (val) {\n case 'rimraf':\n impl = rimraf\n continue\n case 'native':\n case 'manual':\n case 'posix':\n case 'windows':\n impl = rimraf[val]\n continue\n case 'move-remove':\n impl = rimraf.moveRemove\n continue\n default:\n console.error(`unknown implementation: ${val}`)\n runHelpForUsage()\n return 1\n }\n } else if (/^-/.test(arg)) {\n console.error(`unknown option: ${arg}`)\n runHelpForUsage()\n return 1\n } else {\n paths.push(arg)\n }\n }\n\n if (opt.preserveRoot !== false) {\n for (const path of paths.map(p => resolve(p))) {\n if (path === parse(path).root) {\n console.error(\n `rimraf: it is dangerous to operate recursively on '/'`,\n )\n console.error('use --no-preserve-root to override this failsafe')\n return 1\n }\n }\n }\n\n if (!paths.length) {\n console.error('rimraf: must provide a path to remove')\n runHelpForUsage()\n return 1\n }\n\n if (impl === rimraf.native && (interactive || opt.filter)) {\n console.error('native implementation does not support -v or -i')\n runHelpForUsage()\n return 1\n }\n\n if (interactive) {\n await interactiveRimraf(impl, paths, opt)\n } else {\n await impl(paths, opt)\n }\n\n return 0\n}\n\nmain(...process.argv.slice(2)).then(\n code => process.exit(code),\n er => {\n console.error(er)\n process.exit(1)\n },\n)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts deleted file mode 100644 index a68e925..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const defaultTmp: (path: string) => Promise; -export declare const defaultTmpSync: (path: string) => string; -//# sourceMappingURL=default-tmp.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map deleted file mode 100644 index e3200d4..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"default-tmp.d.ts","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAiEA,eAAO,MAAM,UAAU,SApCc,MAAM,oBAqCuB,CAAA;AAClE,eAAO,MAAM,cAAc,SAtBQ,MAAM,WAuBiC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js deleted file mode 100644 index b02a9b9..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js +++ /dev/null @@ -1,55 +0,0 @@ -// The default temporary folder location for use in the windows algorithm. -// It's TEMPting to use dirname(path), since that's guaranteed to be on the -// same device. However, this means that: -// rimraf(path).then(() => rimraf(dirname(path))) -// will often fail with EBUSY, because the parent dir contains -// marked-for-deletion directory entries (which do not show up in readdir). -// The approach here is to use os.tmpdir() if it's on the same drive letter, -// or resolve(path, '\\temp') if it exists, or the root of the drive if not. -// On Posix (not that you'd be likely to use the windows algorithm there), -// it uses os.tmpdir() always. -import { tmpdir } from 'os'; -import { parse, resolve } from 'path'; -import { promises, statSync } from './fs.js'; -const { stat } = promises; -const isDirSync = (path) => { - try { - return statSync(path).isDirectory(); - } - catch { - return false; - } -}; -const isDir = (path) => stat(path).then(st => st.isDirectory(), () => false); -const win32DefaultTmp = async (path) => { - const { root } = parse(path); - const tmp = tmpdir(); - const { root: tmpRoot } = parse(tmp); - if (root.toLowerCase() === tmpRoot.toLowerCase()) { - return tmp; - } - const driveTmp = resolve(root, '/temp'); - if (await isDir(driveTmp)) { - return driveTmp; - } - return root; -}; -const win32DefaultTmpSync = (path) => { - const { root } = parse(path); - const tmp = tmpdir(); - const { root: tmpRoot } = parse(tmp); - if (root.toLowerCase() === tmpRoot.toLowerCase()) { - return tmp; - } - const driveTmp = resolve(root, '/temp'); - if (isDirSync(driveTmp)) { - return driveTmp; - } - return root; -}; -// eslint-disable-next-line @typescript-eslint/require-await -const posixDefaultTmp = async () => tmpdir(); -const posixDefaultTmpSync = () => tmpdir(); -export const defaultTmp = process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp; -export const defaultTmpSync = process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync; -//# sourceMappingURL=default-tmp.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map b/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map deleted file mode 100644 index 259e96e..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/default-tmp.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"default-tmp.js","sourceRoot":"","sources":["../../src/default-tmp.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0CAA0C;AAC1C,iDAAiD;AACjD,8DAA8D;AAC9D,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,8BAA8B;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAC3B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAA;AAEzB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACb,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EACtB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAA;AAEH,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAA;AAC5C,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,MAAM,EAAE,CAAA;AAE1C,MAAM,CAAC,MAAM,UAAU,GACrB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAA;AAClE,MAAM,CAAC,MAAM,cAAc,GACzB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAA","sourcesContent":["// The default temporary folder location for use in the windows algorithm.\n// It's TEMPting to use dirname(path), since that's guaranteed to be on the\n// same device. However, this means that:\n// rimraf(path).then(() => rimraf(dirname(path)))\n// will often fail with EBUSY, because the parent dir contains\n// marked-for-deletion directory entries (which do not show up in readdir).\n// The approach here is to use os.tmpdir() if it's on the same drive letter,\n// or resolve(path, '\\\\temp') if it exists, or the root of the drive if not.\n// On Posix (not that you'd be likely to use the windows algorithm there),\n// it uses os.tmpdir() always.\nimport { tmpdir } from 'os'\nimport { parse, resolve } from 'path'\nimport { promises, statSync } from './fs.js'\nconst { stat } = promises\n\nconst isDirSync = (path: string) => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n\nconst isDir = (path: string) =>\n stat(path).then(\n st => st.isDirectory(),\n () => false,\n )\n\nconst win32DefaultTmp = async (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (await isDir(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\nconst win32DefaultTmpSync = (path: string) => {\n const { root } = parse(path)\n const tmp = tmpdir()\n const { root: tmpRoot } = parse(tmp)\n if (root.toLowerCase() === tmpRoot.toLowerCase()) {\n return tmp\n }\n\n const driveTmp = resolve(root, '/temp')\n if (isDirSync(driveTmp)) {\n return driveTmp\n }\n\n return root\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await\nconst posixDefaultTmp = async () => tmpdir()\nconst posixDefaultTmpSync = () => tmpdir()\n\nexport const defaultTmp =\n process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp\nexport const defaultTmpSync =\n process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts deleted file mode 100644 index 5ba53c8..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare const isFsError: (o: unknown) => o is NodeJS.ErrnoException & { - code: string; - path: string; -}; -export declare const errorCode: (er: unknown) => unknown; -//# sourceMappingURL=error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map deleted file mode 100644 index 6671be4..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/error.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,GACpB,GAAG,OAAO,KACT,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACkD,CAAA;AAEhE,eAAO,MAAM,SAAS,GAAI,IAAI,OAAO,YACmB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.js b/apps/extension/node_modules/rimraf/dist/esm/error.js deleted file mode 100644 index 593c9a6..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/error.js +++ /dev/null @@ -1,5 +0,0 @@ -const isRecord = (o) => !!o && typeof o === 'object'; -const hasString = (o, key) => key in o && typeof o[key] === 'string'; -export const isFsError = (o) => isRecord(o) && hasString(o, 'code') && hasString(o, 'path'); -export const errorCode = (er) => isRecord(er) && hasString(er, 'code') ? er.code : null; -//# sourceMappingURL=error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/error.js.map b/apps/extension/node_modules/rimraf/dist/esm/error.js.map deleted file mode 100644 index d096bc0..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/error.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAC5D,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAA;AAE9B,MAAM,SAAS,GAAG,CAAC,CAA0B,EAAE,GAAW,EAAE,EAAE,CAC5D,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAA;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,CAAU,EAIV,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAEhE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAW,EAAE,EAAE,CACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA","sourcesContent":["const isRecord = (o: unknown): o is Record =>\n !!o && typeof o === 'object'\n\nconst hasString = (o: Record, key: string) =>\n key in o && typeof o[key] === 'string'\n\nexport const isFsError = (\n o: unknown,\n): o is NodeJS.ErrnoException & {\n code: string\n path: string\n} => isRecord(o) && hasString(o, 'code') && hasString(o, 'path')\n\nexport const errorCode = (er: unknown) =>\n isRecord(er) && hasString(er, 'code') ? er.code : null\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts deleted file mode 100644 index 4b329ef..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const fixEPERM: (fn: (path: string) => Promise) => (path: string) => Promise; -export declare const fixEPERMSync: (fn: (path: string) => unknown) => (path: string) => void; -//# sourceMappingURL=fix-eperm.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map deleted file mode 100644 index 498e950..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fix-eperm.d.ts","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,GAClB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAChC,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBjC,CAAA;AAEH,eAAO,MAAM,YAAY,GACtB,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,MAC7B,MAAM,MAAM,KAAG,IAYf,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js deleted file mode 100644 index e3fb094..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js +++ /dev/null @@ -1,33 +0,0 @@ -import { errorCode } from './error.js'; -import { chmodSync, promises } from './fs.js'; -import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; -const { chmod } = promises; -export const fixEPERM = (fn) => async (path) => { - try { - return void (await ignoreENOENT(fn(path))); - } - catch (er) { - if (errorCode(er) === 'EPERM') { - if (!(await ignoreENOENT(chmod(path, 0o666).then(() => true), er))) { - return; - } - return void (await fn(path)); - } - throw er; - } -}; -export const fixEPERMSync = (fn) => (path) => { - try { - return void ignoreENOENTSync(() => fn(path)); - } - catch (er) { - if (errorCode(er) === 'EPERM') { - if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) { - return; - } - return void fn(path); - } - throw er; - } -}; -//# sourceMappingURL=fix-eperm.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map b/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map deleted file mode 100644 index fde0181..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fix-eperm.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fix-eperm.js","sourceRoot":"","sources":["../../src/fix-eperm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACnE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;AAE1B,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,EAAsC,EAAE,EAAE,CAC3C,KAAK,EAAE,IAAY,EAAiB,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IACE,CAAC,CAAC,MAAM,YAAY,CAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACnC,EAAE,CACH,CAAC,EACF,CAAC;gBACD,OAAM;YACR,CAAC;YACD,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9B,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,YAAY,GACvB,CAAC,EAA6B,EAAE,EAAE,CAClC,CAAC,IAAY,EAAQ,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,KAAK,gBAAgB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QACD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { errorCode } from './error.js'\nimport { chmodSync, promises } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nconst { chmod } = promises\n\nexport const fixEPERM =\n (fn: (path: string) => Promise) =>\n async (path: string): Promise => {\n try {\n return void (await ignoreENOENT(fn(path)))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (\n !(await ignoreENOENT(\n chmod(path, 0o666).then(() => true),\n er,\n ))\n ) {\n return\n }\n return void (await fn(path))\n }\n throw er\n }\n }\n\nexport const fixEPERMSync =\n (fn: (path: string) => unknown) =>\n (path: string): void => {\n try {\n return void ignoreENOENTSync(() => fn(path))\n } catch (er) {\n if (errorCode(er) === 'EPERM') {\n if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) {\n return\n }\n return void fn(path)\n }\n throw er\n }\n }\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts deleted file mode 100644 index 4e6fbab..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import fs, { Dirent } from 'fs'; -import fsPromises from 'fs/promises'; -export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; -export declare const readdirSync: (path: fs.PathLike) => Dirent[]; -export declare const promises: { - chmod: typeof fsPromises.chmod; - mkdir: typeof fsPromises.mkdir; - readdir: (path: fs.PathLike) => Promise[]>; - rename: typeof fsPromises.rename; - rm: typeof fsPromises.rm; - rmdir: typeof fsPromises.rmdir; - stat: typeof fsPromises.stat; - lstat: typeof fsPromises.lstat; - unlink: typeof fsPromises.unlink; -}; -//# sourceMappingURL=fs.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map deleted file mode 100644 index ed3c8db..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fs.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAyB,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAKpC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,QAAQ,KAAG,MAAM,EACf,CAAA;AAEvC,eAAO,MAAM,QAAQ;;;oBAGH,EAAE,CAAC,QAAQ;;;;;;;CAQ5B,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.js b/apps/extension/node_modules/rimraf/dist/esm/fs.js deleted file mode 100644 index 0a4cb30..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fs.js +++ /dev/null @@ -1,18 +0,0 @@ -import { readdirSync as rdSync } from 'fs'; -import fsPromises from 'fs/promises'; -// sync ones just take the sync version from node -// readdir forces withFileTypes: true -export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs'; -export const readdirSync = (path) => rdSync(path, { withFileTypes: true }); -export const promises = { - chmod: fsPromises.chmod, - mkdir: fsPromises.mkdir, - readdir: (path) => fsPromises.readdir(path, { withFileTypes: true }), - rename: fsPromises.rename, - rm: fsPromises.rm, - rmdir: fsPromises.rmdir, - stat: fsPromises.stat, - lstat: fsPromises.lstat, - unlink: fsPromises.unlink, -}; -//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/fs.js.map b/apps/extension/node_modules/rimraf/dist/esm/fs.js.map deleted file mode 100644 index 2cd1bb2..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/fs.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/fs.ts"],"names":[],"mappings":"AAAA,OAAW,EAAU,WAAW,IAAI,MAAM,EAAE,MAAM,IAAI,CAAA;AACtD,OAAO,UAAU,MAAM,aAAa,CAAA;AAEpC,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,IAAI,CAAA;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAY,EAAE,CACzD,MAAM,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;AAEvC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,OAAO,EAAE,CAAC,IAAiB,EAAE,EAAE,CAC7B,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,EAAE,EAAE,UAAU,CAAC,EAAE;IACjB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,MAAM,EAAE,UAAU,CAAC,MAAM;CAC1B,CAAA","sourcesContent":["import fs, { Dirent, readdirSync as rdSync } from 'fs'\nimport fsPromises from 'fs/promises'\n\n// sync ones just take the sync version from node\n// readdir forces withFileTypes: true\n\nexport {\n chmodSync,\n mkdirSync,\n renameSync,\n rmdirSync,\n rmSync,\n statSync,\n lstatSync,\n unlinkSync,\n} from 'fs'\n\nexport const readdirSync = (path: fs.PathLike): Dirent[] =>\n rdSync(path, { withFileTypes: true })\n\nexport const promises = {\n chmod: fsPromises.chmod,\n mkdir: fsPromises.mkdir,\n readdir: (path: fs.PathLike) =>\n fsPromises.readdir(path, { withFileTypes: true }),\n rename: fsPromises.rename,\n rm: fsPromises.rm,\n rmdir: fsPromises.rmdir,\n stat: fsPromises.stat,\n lstat: fsPromises.lstat,\n unlink: fsPromises.unlink,\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts deleted file mode 100644 index e56d721..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const ignoreENOENT: (p: Promise, rethrow?: unknown) => Promise; -export declare const ignoreENOENTSync: (fn: () => T, rethrow?: unknown) => T | undefined; -//# sourceMappingURL=ignore-enoent.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map deleted file mode 100644 index 14097fc..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ignore-enoent.d.ts","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,GAAU,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,OAAO,sBAMlE,CAAA;AAEJ,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,UAAU,OAAO,kBASjE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js deleted file mode 100644 index a40d5e6..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js +++ /dev/null @@ -1,19 +0,0 @@ -import { errorCode } from './error.js'; -export const ignoreENOENT = async (p, rethrow) => p.catch(er => { - if (errorCode(er) === 'ENOENT') { - return; - } - throw rethrow ?? er; -}); -export const ignoreENOENTSync = (fn, rethrow) => { - try { - return fn(); - } - catch (er) { - if (errorCode(er) === 'ENOENT') { - return; - } - throw rethrow ?? er; - } -}; -//# sourceMappingURL=ignore-enoent.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map b/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map deleted file mode 100644 index 4e33d44..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/ignore-enoent.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ignore-enoent.js","sourceRoot":"","sources":["../../src/ignore-enoent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAK,CAAa,EAAE,OAAiB,EAAE,EAAE,CACxE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;IACX,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAM;IACR,CAAC;IACD,MAAM,OAAO,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAI,EAAW,EAAE,OAAiB,EAAE,EAAE;IACpE,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,OAAO,IAAI,EAAE,CAAA;IACrB,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { errorCode } from './error.js'\n\nexport const ignoreENOENT = async (p: Promise, rethrow?: unknown) =>\n p.catch(er => {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n })\n\nexport const ignoreENOENTSync = (fn: () => T, rethrow?: unknown) => {\n try {\n return fn()\n } catch (er) {\n if (errorCode(er) === 'ENOENT') {\n return\n }\n throw rethrow ?? er\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts deleted file mode 100644 index 9ec4a12..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './opt-arg.js'; -export { assertRimrafOptions, isRimrafOptions, type RimrafAsyncOptions, type RimrafOptions, type RimrafSyncOptions, } from './opt-arg.js'; -export declare const nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -export declare const rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -export declare const rimraf: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - rimraf: (path: string | string[], opt?: RimrafAsyncOptions) => Promise; - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - rimrafSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - manual: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - manualSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - native: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - nativeSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - posix: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - posixSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - windows: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - windowsSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - moveRemove: ((path: string | string[], opt?: RimrafAsyncOptions) => Promise) & { - sync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; - }; - moveRemoveSync: (path: string | string[], opt?: RimrafSyncOptions) => boolean; -}; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map deleted file mode 100644 index e69bc3c..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.js b/apps/extension/node_modules/rimraf/dist/esm/index.js deleted file mode 100644 index 2026b40..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/index.js +++ /dev/null @@ -1,76 +0,0 @@ -import { glob, globSync } from 'glob'; -import { optArg, optArgSync, } from './opt-arg.js'; -import pathArg from './path-arg.js'; -import { rimrafManual, rimrafManualSync } from './rimraf-manual.js'; -import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; -import { rimrafNative, rimrafNativeSync } from './rimraf-native.js'; -import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'; -import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'; -import { useNative, useNativeSync } from './use-native.js'; -export { assertRimrafOptions, isRimrafOptions, } from './opt-arg.js'; -const wrap = (fn) => async (path, opt) => { - const options = optArg(opt); - if (options.glob) { - path = await glob(path, options.glob); - } - if (Array.isArray(path)) { - return !!(await Promise.all(path.map(p => fn(pathArg(p, options), options)))).reduce((a, b) => a && b, true); - } - else { - return !!(await fn(pathArg(path, options), options)); - } -}; -const wrapSync = (fn) => (path, opt) => { - const options = optArgSync(opt); - if (options.glob) { - path = globSync(path, options.glob); - } - if (Array.isArray(path)) { - return !!path - .map(p => fn(pathArg(p, options), options)) - .reduce((a, b) => a && b, true); - } - else { - return !!fn(pathArg(path, options), options); - } -}; -export const nativeSync = wrapSync(rimrafNativeSync); -export const native = Object.assign(wrap(rimrafNative), { - sync: nativeSync, -}); -export const manualSync = wrapSync(rimrafManualSync); -export const manual = Object.assign(wrap(rimrafManual), { - sync: manualSync, -}); -export const windowsSync = wrapSync(rimrafWindowsSync); -export const windows = Object.assign(wrap(rimrafWindows), { - sync: windowsSync, -}); -export const posixSync = wrapSync(rimrafPosixSync); -export const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync }); -export const moveRemoveSync = wrapSync(rimrafMoveRemoveSync); -export const moveRemove = Object.assign(wrap(rimrafMoveRemove), { - sync: moveRemoveSync, -}); -export const rimrafSync = wrapSync((path, opt) => useNativeSync(opt) ? - rimrafNativeSync(path, opt) - : rimrafManualSync(path, opt)); -export const sync = rimrafSync; -const rimraf_ = wrap((path, opt) => useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt)); -export const rimraf = Object.assign(rimraf_, { - rimraf: rimraf_, - sync: rimrafSync, - rimrafSync: rimrafSync, - manual, - manualSync, - native, - nativeSync, - posix, - posixSync, - windows, - windowsSync, - moveRemove, - moveRemoveSync, -}); -rimraf.rimraf = rimraf; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/index.js.map b/apps/extension/node_modules/rimraf/dist/esm/index.js.map deleted file mode 100644 index e61b4ca..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { glob, globSync } from 'glob'\nimport {\n optArg,\n optArgSync,\n RimrafAsyncOptions,\n RimrafSyncOptions,\n} from './opt-arg.js'\nimport pathArg from './path-arg.js'\nimport { rimrafManual, rimrafManualSync } from './rimraf-manual.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { rimrafNative, rimrafNativeSync } from './rimraf-native.js'\nimport { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\nimport { useNative, useNativeSync } from './use-native.js'\n\nexport {\n assertRimrafOptions,\n isRimrafOptions,\n type RimrafAsyncOptions,\n type RimrafOptions,\n type RimrafSyncOptions,\n} from './opt-arg.js'\n\nconst wrap =\n (fn: (p: string, o: RimrafAsyncOptions) => Promise) =>\n async (\n path: string | string[],\n opt?: RimrafAsyncOptions,\n ): Promise => {\n const options = optArg(opt)\n if (options.glob) {\n path = await glob(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!(\n await Promise.all(path.map(p => fn(pathArg(p, options), options)))\n ).reduce((a, b) => a && b, true)\n } else {\n return !!(await fn(pathArg(path, options), options))\n }\n }\n\nconst wrapSync =\n (fn: (p: string, o: RimrafSyncOptions) => boolean) =>\n (path: string | string[], opt?: RimrafSyncOptions): boolean => {\n const options = optArgSync(opt)\n if (options.glob) {\n path = globSync(path, options.glob)\n }\n if (Array.isArray(path)) {\n return !!path\n .map(p => fn(pathArg(p, options), options))\n .reduce((a, b) => a && b, true)\n } else {\n return !!fn(pathArg(path, options), options)\n }\n }\n\nexport const nativeSync = wrapSync(rimrafNativeSync)\nexport const native = Object.assign(wrap(rimrafNative), {\n sync: nativeSync,\n})\n\nexport const manualSync = wrapSync(rimrafManualSync)\nexport const manual = Object.assign(wrap(rimrafManual), {\n sync: manualSync,\n})\n\nexport const windowsSync = wrapSync(rimrafWindowsSync)\nexport const windows = Object.assign(wrap(rimrafWindows), {\n sync: windowsSync,\n})\n\nexport const posixSync = wrapSync(rimrafPosixSync)\nexport const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync })\n\nexport const moveRemoveSync = wrapSync(rimrafMoveRemoveSync)\nexport const moveRemove = Object.assign(wrap(rimrafMoveRemove), {\n sync: moveRemoveSync,\n})\n\nexport const rimrafSync = wrapSync((path, opt) =>\n useNativeSync(opt) ?\n rimrafNativeSync(path, opt)\n : rimrafManualSync(path, opt),\n)\nexport const sync = rimrafSync\n\nconst rimraf_ = wrap((path, opt) =>\n useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt),\n)\nexport const rimraf = Object.assign(rimraf_, {\n rimraf: rimraf_,\n sync: rimrafSync,\n rimrafSync: rimrafSync,\n manual,\n manualSync,\n native,\n nativeSync,\n posix,\n posixSync,\n windows,\n windowsSync,\n moveRemove,\n moveRemoveSync,\n})\nrimraf.rimraf = rimraf\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts deleted file mode 100644 index c869d4a..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Dirent, Stats } from 'fs'; -import { GlobOptions } from 'glob'; -export declare const isRimrafOptions: (o: any) => o is RimrafOptions; -export declare const assertRimrafOptions: (o: any) => void; -export interface RimrafAsyncOptions { - preserveRoot?: boolean; - tmp?: string; - maxRetries?: number; - retryDelay?: number; - backoff?: number; - maxBackoff?: number; - signal?: AbortSignal; - glob?: boolean | GlobOptions; - filter?: ((path: string, ent: Dirent | Stats) => boolean) | ((path: string, ent: Dirent | Stats) => Promise); -} -export interface RimrafSyncOptions extends RimrafAsyncOptions { - filter?: (path: string, ent: Dirent | Stats) => boolean; -} -export type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions; -export declare const optArg: (opt?: RimrafAsyncOptions) => (RimrafAsyncOptions & { - glob: GlobOptions & { - withFileTypes: false; - }; -}) | (RimrafAsyncOptions & { - glob: undefined; -}); -export declare const optArgSync: (opt?: RimrafSyncOptions) => (RimrafSyncOptions & { - glob: GlobOptions & { - withFileTypes: false; - }; -}) | (RimrafSyncOptions & { - glob: undefined; -}); -//# sourceMappingURL=opt-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map deleted file mode 100644 index 93e1f92..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"opt-arg.d.ts","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAKlC,eAAO,MAAM,eAAe,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,aAWX,CAAA;AAEnC,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAM7C,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;IAC5B,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,GAChD,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,KAAK,OAAO,CAAA;CACxD;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAqClE,eAAO,MAAM,MAAM,GAAI,MAAK,kBAAuB;UA/BvC,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA6B0C,CAAA;AACpE,eAAO,MAAM,UAAU,GAAI,MAAK,iBAAsB;UAhC1C,WAAW,GAAG;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE;;UAEjC,SAAS;EA8B6C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js deleted file mode 100644 index c699db7..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js +++ /dev/null @@ -1,47 +0,0 @@ -const typeOrUndef = (val, t) => typeof val === 'undefined' || typeof val === t; -export const isRimrafOptions = (o) => !!o && - typeof o === 'object' && - typeOrUndef(o.preserveRoot, 'boolean') && - typeOrUndef(o.tmp, 'string') && - typeOrUndef(o.maxRetries, 'number') && - typeOrUndef(o.retryDelay, 'number') && - typeOrUndef(o.backoff, 'number') && - typeOrUndef(o.maxBackoff, 'number') && - (typeOrUndef(o.glob, 'boolean') || - (o.glob && typeof o.glob === 'object')) && - typeOrUndef(o.filter, 'function'); -export const assertRimrafOptions = (o) => { - if (!isRimrafOptions(o)) { - throw new Error('invalid rimraf options'); - } -}; -const optArgT = (opt) => { - assertRimrafOptions(opt); - const { glob, ...options } = opt; - if (!glob) { - return options; - } - const globOpt = glob === true ? - opt.signal ? - { signal: opt.signal } - : {} - : opt.signal ? - { - signal: opt.signal, - ...glob, - } - : glob; - return { - ...options, - glob: { - ...globOpt, - // always get absolute paths from glob, to ensure - // that we are referencing the correct thing. - absolute: true, - withFileTypes: false, - }, - }; -}; -export const optArg = (opt = {}) => optArgT(opt); -export const optArgSync = (opt = {}) => optArgT(opt); -//# sourceMappingURL=opt-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map b/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map deleted file mode 100644 index 57956e9..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/opt-arg.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"opt-arg.js","sourceRoot":"","sources":["../../src/opt-arg.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,CAAS,EAAE,EAAE,CAC1C,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,KAAK,CAAC,CAAA;AAEhD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAM,EAAsB,EAAE,CAC5D,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,QAAQ;IACrB,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC;IACtC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IAC5B,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACnC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC;QAC7B,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAEnC,MAAM,CAAC,MAAM,mBAAmB,GAAqB,CACnD,CAAM,EACsB,EAAE;IAC9B,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC,CAAA;AAsBD,MAAM,OAAO,GAAG,CACd,GAAM,EAKsB,EAAE;IAC9B,mBAAmB,CAAC,GAAG,CAAC,CAAA;IACxB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAA;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,OAAkC,CAAA;IAC3C,CAAC;IACD,MAAM,OAAO,GACX,IAAI,KAAK,IAAI,CAAC,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,CAAC;YACV,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACxB,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACZ;gBACE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,IAAI;aACR;YACH,CAAC,CAAC,IAAI,CAAA;IACR,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE;YACJ,GAAG,OAAO;YACV,iDAAiD;YACjD,6CAA6C;YAC7C,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,KAAK;SACrB;KACsD,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAA0B,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAyB,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA","sourcesContent":["import { Dirent, Stats } from 'fs'\nimport { GlobOptions } from 'glob'\n\nconst typeOrUndef = (val: any, t: string) =>\n typeof val === 'undefined' || typeof val === t\n\nexport const isRimrafOptions = (o: any): o is RimrafOptions =>\n !!o &&\n typeof o === 'object' &&\n typeOrUndef(o.preserveRoot, 'boolean') &&\n typeOrUndef(o.tmp, 'string') &&\n typeOrUndef(o.maxRetries, 'number') &&\n typeOrUndef(o.retryDelay, 'number') &&\n typeOrUndef(o.backoff, 'number') &&\n typeOrUndef(o.maxBackoff, 'number') &&\n (typeOrUndef(o.glob, 'boolean') ||\n (o.glob && typeof o.glob === 'object')) &&\n typeOrUndef(o.filter, 'function')\n\nexport const assertRimrafOptions: (o: any) => void = (\n o: any,\n): asserts o is RimrafOptions => {\n if (!isRimrafOptions(o)) {\n throw new Error('invalid rimraf options')\n }\n}\n\nexport interface RimrafAsyncOptions {\n preserveRoot?: boolean\n tmp?: string\n maxRetries?: number\n retryDelay?: number\n backoff?: number\n maxBackoff?: number\n signal?: AbortSignal\n glob?: boolean | GlobOptions\n filter?:\n | ((path: string, ent: Dirent | Stats) => boolean)\n | ((path: string, ent: Dirent | Stats) => Promise)\n}\n\nexport interface RimrafSyncOptions extends RimrafAsyncOptions {\n filter?: (path: string, ent: Dirent | Stats) => boolean\n}\n\nexport type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions\n\nconst optArgT = (\n opt: T,\n):\n | (T & {\n glob: GlobOptions & { withFileTypes: false }\n })\n | (T & { glob: undefined }) => {\n assertRimrafOptions(opt)\n const { glob, ...options } = opt\n if (!glob) {\n return options as T & { glob: undefined }\n }\n const globOpt =\n glob === true ?\n opt.signal ?\n { signal: opt.signal }\n : {}\n : opt.signal ?\n {\n signal: opt.signal,\n ...glob,\n }\n : glob\n return {\n ...options,\n glob: {\n ...globOpt,\n // always get absolute paths from glob, to ensure\n // that we are referencing the correct thing.\n absolute: true,\n withFileTypes: false,\n },\n } as T & { glob: GlobOptions & { withFileTypes: false } }\n}\n\nexport const optArg = (opt: RimrafAsyncOptions = {}) => optArgT(opt)\nexport const optArgSync = (opt: RimrafSyncOptions = {}) => optArgT(opt)\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/package.json b/apps/extension/node_modules/rimraf/dist/esm/package.json deleted file mode 100644 index 3dbc1ca..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts deleted file mode 100644 index c0b7e7c..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions } from './index.js'; -declare const pathArg: (path: string, opt?: RimrafAsyncOptions) => string; -export default pathArg; -//# sourceMappingURL=path-arg.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map deleted file mode 100644 index 2112460..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/path-arg.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"path-arg.d.ts","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,QAAA,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,MAAK,kBAAuB,WAkD1D,CAAA;AAED,eAAe,OAAO,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js deleted file mode 100644 index d8df8a2..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js +++ /dev/null @@ -1,47 +0,0 @@ -import { parse, resolve } from 'path'; -import { inspect } from 'util'; -const pathArg = (path, opt = {}) => { - const type = typeof path; - if (type !== 'string') { - const ctor = path && type === 'object' && path.constructor; - const received = ctor && ctor.name ? `an instance of ${ctor.name}` - : type === 'object' ? inspect(path) - : `type ${type} ${path}`; - const msg = 'The "path" argument must be of type string. ' + - `Received ${received}`; - throw Object.assign(new TypeError(msg), { - path, - code: 'ERR_INVALID_ARG_TYPE', - }); - } - if (/\0/.test(path)) { - // simulate same failure that node raises - const msg = 'path must be a string without null bytes'; - throw Object.assign(new TypeError(msg), { - path, - code: 'ERR_INVALID_ARG_VALUE', - }); - } - path = resolve(path); - const { root } = parse(path); - if (path === root && opt.preserveRoot !== false) { - const msg = 'refusing to remove root directory without preserveRoot:false'; - throw Object.assign(new Error(msg), { - path, - code: 'ERR_PRESERVE_ROOT', - }); - } - if (process.platform === 'win32') { - const badWinChars = /[*|"<>?:]/; - const { root } = parse(path); - if (badWinChars.test(path.substring(root.length))) { - throw Object.assign(new Error('Illegal characters in path.'), { - path, - code: 'EINVAL', - }); - } - } - return path; -}; -export default pathArg; -//# sourceMappingURL=path-arg.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map b/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map deleted file mode 100644 index c744f08..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/path-arg.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"path-arg.js","sourceRoot":"","sources":["../../src/path-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAG9B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,MAA0B,EAAE,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAA;IACxB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAA;QAC1D,MAAM,QAAQ,GACZ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAA;QAC1B,MAAM,GAAG,GACP,8CAA8C;YAC9C,YAAY,QAAQ,EAAE,CAAA;QACxB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,sBAAsB;SAC7B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,yCAAyC;QACzC,MAAM,GAAG,GAAG,0CAA0C,CAAA;QACtD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAE5B,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,GAAG,GACP,8DAA8D,CAAA;QAChE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI;YACJ,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,WAAW,CAAA;QAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAE;gBAC5D,IAAI;gBACJ,IAAI,EAAE,QAAQ;aACf,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,eAAe,OAAO,CAAA","sourcesContent":["import { parse, resolve } from 'path'\nimport { inspect } from 'util'\nimport { RimrafAsyncOptions } from './index.js'\n\nconst pathArg = (path: string, opt: RimrafAsyncOptions = {}) => {\n const type = typeof path\n if (type !== 'string') {\n const ctor = path && type === 'object' && path.constructor\n const received =\n ctor && ctor.name ? `an instance of ${ctor.name}`\n : type === 'object' ? inspect(path)\n : `type ${type} ${path}`\n const msg =\n 'The \"path\" argument must be of type string. ' +\n `Received ${received}`\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_TYPE',\n })\n }\n\n if (/\\0/.test(path)) {\n // simulate same failure that node raises\n const msg = 'path must be a string without null bytes'\n throw Object.assign(new TypeError(msg), {\n path,\n code: 'ERR_INVALID_ARG_VALUE',\n })\n }\n\n path = resolve(path)\n const { root } = parse(path)\n\n if (path === root && opt.preserveRoot !== false) {\n const msg =\n 'refusing to remove root directory without preserveRoot:false'\n throw Object.assign(new Error(msg), {\n path,\n code: 'ERR_PRESERVE_ROOT',\n })\n }\n\n if (process.platform === 'win32') {\n const badWinChars = /[*|\"<>?:]/\n const { root } = parse(path)\n if (badWinChars.test(path.substring(root.length))) {\n throw Object.assign(new Error('Illegal characters in path.'), {\n path,\n code: 'EINVAL',\n })\n }\n }\n\n return path\n}\n\nexport default pathArg\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts deleted file mode 100644 index 2a580cf..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const readdirOrError: (path: string) => Promise[] | Error>; -export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent[] | Error; -//# sourceMappingURL=readdir-or-error.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map deleted file mode 100644 index 1f91434..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"readdir-or-error.d.ts","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,wDACH,CAAA;AACxC,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,+CAM9C,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js deleted file mode 100644 index 7123513..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js +++ /dev/null @@ -1,14 +0,0 @@ -// returns an array of entries if readdir() works, -// or the error that readdir() raised if not. -import { promises, readdirSync } from './fs.js'; -const { readdir } = promises; -export const readdirOrError = (path) => readdir(path).catch(er => er); -export const readdirOrErrorSync = (path) => { - try { - return readdirSync(path); - } - catch (er) { - return er; - } -}; -//# sourceMappingURL=readdir-or-error.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map b/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map deleted file mode 100644 index e5011a9..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/readdir-or-error.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"readdir-or-error.js","sourceRoot":"","sources":["../../src/readdir-or-error.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,6CAA6C;AAC7C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAA;AAE5B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAW,CAAC,CAAA;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE;IACjD,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,OAAO,EAAW,CAAA;IACpB,CAAC;AACH,CAAC,CAAA","sourcesContent":["// returns an array of entries if readdir() works,\n// or the error that readdir() raised if not.\nimport { promises, readdirSync } from './fs.js'\nconst { readdir } = promises\n\nexport const readdirOrError = (path: string) =>\n readdir(path).catch(er => er as Error)\nexport const readdirOrErrorSync = (path: string) => {\n try {\n return readdirSync(path)\n } catch (er) {\n return er as Error\n }\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts deleted file mode 100644 index b01b023..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RimrafAsyncOptions, RimrafOptions } from './index.js'; -export declare const MAXBACKOFF = 200; -export declare const RATE = 1.2; -export declare const MAXRETRIES = 10; -export declare const codes: Set; -export declare const retryBusy: (fn: (path: string) => Promise) => (path: string, opt: RimrafAsyncOptions, backoff?: number, total?: number) => Promise; -export declare const retryBusySync: (fn: (path: string) => T) => (path: string, opt: RimrafOptions) => T; -//# sourceMappingURL=retry-busy.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map deleted file mode 100644 index 554f140..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"retry-busy.d.ts","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,eAAO,MAAM,UAAU,MAAM,CAAA;AAC7B,eAAO,MAAM,IAAI,MAAM,CAAA;AACvB,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,KAAK,aAAyC,CAAA;AAE3D,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAEnD,MAAM,OACP,kBAAkB,iDA8B1B,CAAA;AAGD,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAChC,MAAM,OAAO,aAAa,MAqBjD,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js deleted file mode 100644 index 263af08..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js +++ /dev/null @@ -1,60 +0,0 @@ -// note: max backoff is the maximum that any *single* backoff will do -import { setTimeout } from 'timers/promises'; -import { isFsError } from './error.js'; -export const MAXBACKOFF = 200; -export const RATE = 1.2; -export const MAXRETRIES = 10; -export const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY']); -export const retryBusy = (fn) => { - const method = async (path, opt, backoff = 1, total = 0) => { - const mbo = opt.maxBackoff || MAXBACKOFF; - const rate = opt.backoff || RATE; - const max = opt.maxRetries || MAXRETRIES; - let retries = 0; - while (true) { - try { - return await fn(path); - } - catch (er) { - if (isFsError(er) && er.path === path && codes.has(er.code)) { - backoff = Math.ceil(backoff * rate); - total = backoff + total; - if (total < mbo) { - await setTimeout(backoff); - return method(path, opt, backoff, total); - } - if (retries < max) { - retries++; - continue; - } - } - throw er; - } - } - }; - return method; -}; -// just retries, no async so no backoff -export const retryBusySync = (fn) => { - const method = (path, opt) => { - const max = opt.maxRetries || MAXRETRIES; - let retries = 0; - while (true) { - try { - return fn(path); - } - catch (er) { - if (isFsError(er) && - er.path === path && - codes.has(er.code) && - retries < max) { - retries++; - continue; - } - throw er; - } - } - }; - return method; -}; -//# sourceMappingURL=retry-busy.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map b/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map deleted file mode 100644 index 78e420e..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/retry-busy.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"retry-busy.js","sourceRoot":"","sources":["../../src/retry-busy.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;AAC7B,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAA;AACvB,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;AAE3D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,EAAgC,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,KAAK,EAClB,IAAY,EACZ,GAAuB,EACvB,OAAO,GAAG,CAAC,EACX,KAAK,GAAG,CAAC,EACT,EAAE;QACF,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAA;QAChC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;oBACnC,KAAK,GAAG,OAAO,GAAG,KAAK,CAAA;oBACvB,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;wBAChB,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;wBACzB,OAAO,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;oBAC1C,CAAC;oBACD,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;wBAClB,OAAO,EAAE,CAAA;wBACT,SAAQ;oBACV,CAAC;gBACH,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,uCAAuC;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAI,EAAuB,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAkB,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,UAAU,CAAA;QACxC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IACE,SAAS,CAAC,EAAE,CAAC;oBACb,EAAE,CAAC,IAAI,KAAK,IAAI;oBAChB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;oBAClB,OAAO,GAAG,GAAG,EACb,CAAC;oBACD,OAAO,EAAE,CAAA;oBACT,SAAQ;gBACV,CAAC;gBACD,MAAM,EAAE,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["// note: max backoff is the maximum that any *single* backoff will do\n\nimport { setTimeout } from 'timers/promises'\nimport { RimrafAsyncOptions, RimrafOptions } from './index.js'\nimport { isFsError } from './error.js'\n\nexport const MAXBACKOFF = 200\nexport const RATE = 1.2\nexport const MAXRETRIES = 10\nexport const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY'])\n\nexport const retryBusy = (fn: (path: string) => Promise) => {\n const method = async (\n path: string,\n opt: RimrafAsyncOptions,\n backoff = 1,\n total = 0,\n ) => {\n const mbo = opt.maxBackoff || MAXBACKOFF\n const rate = opt.backoff || RATE\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return await fn(path)\n } catch (er) {\n if (isFsError(er) && er.path === path && codes.has(er.code)) {\n backoff = Math.ceil(backoff * rate)\n total = backoff + total\n if (total < mbo) {\n await setTimeout(backoff)\n return method(path, opt, backoff, total)\n }\n if (retries < max) {\n retries++\n continue\n }\n }\n throw er\n }\n }\n }\n\n return method\n}\n\n// just retries, no async so no backoff\nexport const retryBusySync = (fn: (path: string) => T) => {\n const method = (path: string, opt: RimrafOptions) => {\n const max = opt.maxRetries || MAXRETRIES\n let retries = 0\n while (true) {\n try {\n return fn(path)\n } catch (er) {\n if (\n isFsError(er) &&\n er.path === path &&\n codes.has(er.code) &&\n retries < max\n ) {\n retries++\n continue\n }\n throw er\n }\n }\n }\n return method\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts deleted file mode 100644 index 35c5c86..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare const rimrafManual: (path: string, opt: import("./opt-arg.js").RimrafAsyncOptions) => Promise; -export declare const rimrafManualSync: (path: string, opt: import("./opt-arg.js").RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-manual.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map deleted file mode 100644 index 96115d0..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-manual.d.ts","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,oFACmC,CAAA;AAC5D,eAAO,MAAM,gBAAgB,0EACuC,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js deleted file mode 100644 index 76f5b44..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js +++ /dev/null @@ -1,5 +0,0 @@ -import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'; -import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'; -export const rimrafManual = process.platform === 'win32' ? rimrafWindows : rimrafPosix; -export const rimrafManualSync = process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync; -//# sourceMappingURL=rimraf-manual.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map deleted file mode 100644 index 197a3ff..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-manual.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-manual.js","sourceRoot":"","sources":["../../src/rimraf-manual.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEtE,MAAM,CAAC,MAAM,YAAY,GACvB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAA;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAC3B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAA","sourcesContent":["import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js'\nimport { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js'\n\nexport const rimrafManual =\n process.platform === 'win32' ? rimrafWindows : rimrafPosix\nexport const rimrafManualSync =\n process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts deleted file mode 100644 index 5d41d40..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafMoveRemove: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafMoveRemoveSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-move-remove.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map deleted file mode 100644 index 722538e..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-move-remove.d.ts","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAalE,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AA0ED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js deleted file mode 100644 index 729b831..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js +++ /dev/null @@ -1,133 +0,0 @@ -// https://youtu.be/uhRWMGBjlO8?t=537 -// -// 1. readdir -// 2. for each entry -// a. if a non-empty directory, recurse -// b. if an empty directory, move to random hidden file name in $TEMP -// c. unlink/rmdir $TEMP -// -// This works around the fact that unlink/rmdir is non-atomic and takes -// a non-deterministic amount of time to complete. -// -// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm. -import { basename, parse, resolve } from 'path'; -import { defaultTmp, defaultTmpSync } from './default-tmp.js'; -import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; -import { lstatSync, promises, renameSync, rmdirSync, unlinkSync, } from './fs.js'; -import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; -import { fixEPERM, fixEPERMSync } from './fix-eperm.js'; -import { errorCode } from './error.js'; -const { lstat, rename, unlink, rmdir } = promises; -// crypto.randomBytes is much slower, and Math.random() is enough here -const uniqueFilename = (path) => `.${basename(path)}.${Math.random()}`; -const unlinkFixEPERM = fixEPERM(unlink); -const unlinkFixEPERMSync = fixEPERMSync(unlinkSync); -export const rimrafMoveRemove = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await ignoreENOENT(lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)))) ?? true); -}; -const rimrafMoveRemoveDir = async (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - if (!opt.tmp) { - return rimrafMoveRemoveDir(path, { ...opt, tmp: await defaultTmp(path) }, ent); - } - if (path === opt.tmp && parse(path).root !== path) { - throw new Error('cannot delete temp directory used for deletion'); - } - const entries = ent.isDirectory() ? await readdirOrError(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM)); - return true; - } - const removedAll = (await Promise.all(entries.map(ent => rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent)))).every(v => v === true); - if (!removedAll) { - return false; - } - // we don't ever ACTUALLY try to unlink /, because that can never work - // but when preserveRoot is false, we could be operating on it. - // No need to check if preserveRoot is not false. - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir)); - return true; -}; -const tmpUnlink = async (path, tmp, rm) => { - const tmpFile = resolve(tmp, uniqueFilename(path)); - await rename(path, tmpFile); - return await rm(tmpFile); -}; -export const rimrafMoveRemoveSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return (ignoreENOENTSync(() => rimrafMoveRemoveDirSync(path, opt, lstatSync(path))) ?? true); -}; -const rimrafMoveRemoveDirSync = (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - if (!opt.tmp) { - return rimrafMoveRemoveDirSync(path, { ...opt, tmp: defaultTmpSync(path) }, ent); - } - const tmp = opt.tmp; - if (path === opt.tmp && parse(path).root !== path) { - throw new Error('cannot delete temp directory used for deletion'); - } - const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const p = resolve(path, ent.name); - removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll; - } - if (!removedAll) { - return false; - } - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync)); - return true; -}; -const tmpUnlinkSync = (path, tmp, rmSync) => { - const tmpFile = resolve(tmp, uniqueFilename(path)); - renameSync(path, tmpFile); - return rmSync(tmpFile); -}; -//# sourceMappingURL=rimraf-move-remove.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map deleted file mode 100644 index dc41dff..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-move-remove.js","sourceRoot":"","sources":["../../src/rimraf-move-remove.ts"],"names":[],"mappings":"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","sourcesContent":["// https://youtu.be/uhRWMGBjlO8?t=537\n//\n// 1. readdir\n// 2. for each entry\n// a. if a non-empty directory, recurse\n// b. if an empty directory, move to random hidden file name in $TEMP\n// c. unlink/rmdir $TEMP\n//\n// This works around the fact that unlink/rmdir is non-atomic and takes\n// a non-deterministic amount of time to complete.\n//\n// However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm.\n\nimport { basename, parse, resolve } from 'path'\nimport { defaultTmp, defaultTmpSync } from './default-tmp.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport {\n lstatSync,\n promises,\n renameSync,\n rmdirSync,\n unlinkSync,\n} from './fs.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { errorCode } from './error.js'\nconst { lstat, rename, unlink, rmdir } = promises\n\n// crypto.randomBytes is much slower, and Math.random() is enough here\nconst uniqueFilename = (path: string) =>\n `.${basename(path)}.${Math.random()}`\n\nconst unlinkFixEPERM = fixEPERM(unlink)\nconst unlinkFixEPERMSync = fixEPERMSync(unlinkSync)\n\nexport const rimrafMoveRemove = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nconst rimrafMoveRemoveDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDir(\n path,\n { ...opt, tmp: await defaultTmp(path) },\n ent,\n )\n }\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir))\n return true\n}\n\nconst tmpUnlink = async (\n path: string,\n tmp: string,\n rm: (p: string) => Promise,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n await rename(path, tmpFile)\n return await rm(tmpFile)\n}\n\nexport const rimrafMoveRemoveSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafMoveRemoveDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafMoveRemoveDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n if (!opt.tmp) {\n return rimrafMoveRemoveDirSync(\n path,\n { ...opt, tmp: defaultTmpSync(path) },\n ent,\n )\n }\n const tmp: string = opt.tmp\n\n if (path === opt.tmp && parse(path).root !== path) {\n throw new Error('cannot delete temp directory used for deletion')\n }\n\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll\n }\n if (!removedAll) {\n return false\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync))\n return true\n}\n\nconst tmpUnlinkSync = (\n path: string,\n tmp: string,\n rmSync: (p: string) => void,\n) => {\n const tmpFile = resolve(tmp, uniqueFilename(path))\n renameSync(path, tmpFile)\n return rmSync(tmpFile)\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts deleted file mode 100644 index cc84bf7..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafNative: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafNativeSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map deleted file mode 100644 index 6bb2a08..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-native.d.ts","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAIlE,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,KAAK,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,KAAK,iBAAiB,KACrB,OAOF,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js deleted file mode 100644 index 719161f..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js +++ /dev/null @@ -1,19 +0,0 @@ -import { promises, rmSync } from './fs.js'; -const { rm } = promises; -export const rimrafNative = async (path, opt) => { - await rm(path, { - ...opt, - force: true, - recursive: true, - }); - return true; -}; -export const rimrafNativeSync = (path, opt) => { - rmSync(path, { - ...opt, - force: true, - recursive: true, - }); - return true; -}; -//# sourceMappingURL=rimraf-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map deleted file mode 100644 index fde373b..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-native.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-native.js","sourceRoot":"","sources":["../../src/rimraf-native.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAC1C,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAY,EACZ,GAAuB,EACL,EAAE;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,GAAsB,EACb,EAAE;IACX,MAAM,CAAC,IAAI,EAAE;QACX,GAAG,GAAG;QACN,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { promises, rmSync } from './fs.js'\nconst { rm } = promises\n\nexport const rimrafNative = async (\n path: string,\n opt: RimrafAsyncOptions,\n): Promise => {\n await rm(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n\nexport const rimrafNativeSync = (\n path: string,\n opt: RimrafSyncOptions,\n): boolean => {\n rmSync(path, {\n ...opt,\n force: true,\n recursive: true,\n })\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts deleted file mode 100644 index 8e532ef..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafPosix: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafPosixSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-posix.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map deleted file mode 100644 index c7b1b6a..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-posix.d.ts","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKlE,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAK,iBAAiB,YAOnE,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js deleted file mode 100644 index b850aed..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js +++ /dev/null @@ -1,97 +0,0 @@ -// the simple recursive removal, where unlink and rmdir are atomic -// Note that this approach does NOT work on Windows! -// We stat first and only unlink if the Dirent isn't a directory, -// because sunos will let root unlink a directory, and some -// SUPER weird breakage happens as a result. -import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'; -import { parse, resolve } from 'path'; -import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; -import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; -import { errorCode } from './error.js'; -const { lstat, rmdir, unlink } = promises; -export const rimrafPosix = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await ignoreENOENT(lstat(path).then(stat => rimrafPosixDir(path, opt, stat)))) ?? true); -}; -export const rimrafPosixSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return (ignoreENOENTSync(() => rimrafPosixDirSync(path, opt, lstatSync(path))) ?? true); -}; -const rimrafPosixDir = async (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? await readdirOrError(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await ignoreENOENT(unlink(path)); - return true; - } - const removedAll = (await Promise.all(entries.map(ent => rimrafPosixDir(resolve(path, ent.name), opt, ent)))).every(v => v === true); - if (!removedAll) { - return false; - } - // we don't ever ACTUALLY try to unlink /, because that can never work - // but when preserveRoot is false, we could be operating on it. - // No need to check if preserveRoot is not false. - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await ignoreENOENT(rmdir(path)); - return true; -}; -const rimrafPosixDirSync = (path, opt, ent) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - ignoreENOENTSync(() => unlinkSync(path)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const p = resolve(path, ent.name); - removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll; - } - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - ignoreENOENTSync(() => rmdirSync(path)); - return true; -}; -//# sourceMappingURL=rimraf-posix.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map deleted file mode 100644 index afcfefa..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-posix.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-posix.js","sourceRoot":"","sources":["../../src/rimraf-posix.ts"],"names":[],"mappings":"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","sourcesContent":["// the simple recursive removal, where unlink and rmdir are atomic\n// Note that this approach does NOT work on Windows!\n// We stat first and only unlink if the Dirent isn't a directory,\n// because sunos will let root unlink a directory, and some\n// SUPER weird breakage happens as a result.\n\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { parse, resolve } from 'path'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { Dirent, Stats } from 'fs'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { errorCode } from './error.js'\nconst { lstat, rmdir, unlink } = promises\n\nexport const rimrafPosix = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafPosixDir(path, opt, stat)),\n )) ?? true\n )\n}\n\nexport const rimrafPosixSync = (path: string, opt: RimrafSyncOptions) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafPosixDirSync(path, opt, lstatSync(path)),\n ) ?? true\n )\n}\n\nconst rimrafPosixDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n): Promise => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(unlink(path))\n return true\n }\n\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafPosixDir(resolve(path, ent.name), opt, ent),\n ),\n )\n ).every(v => v === true)\n\n if (!removedAll) {\n return false\n }\n\n // we don't ever ACTUALLY try to unlink /, because that can never work\n // but when preserveRoot is false, we could be operating on it.\n // No need to check if preserveRoot is not false.\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n\n await ignoreENOENT(rmdir(path))\n return true\n}\n\nconst rimrafPosixDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n): boolean => {\n opt?.signal?.throwIfAborted()\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() => unlinkSync(path))\n return true\n }\n let removedAll: boolean = true\n for (const ent of entries) {\n const p = resolve(path, ent.name)\n removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll\n }\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n\n if (!removedAll) {\n return false\n }\n\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n\n ignoreENOENTSync(() => rmdirSync(path))\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts deleted file mode 100644 index 5556890..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'; -export declare const rimrafWindows: (path: string, opt: RimrafAsyncOptions) => Promise; -export declare const rimrafWindowsSync: (path: string, opt: RimrafSyncOptions) => boolean; -//# sourceMappingURL=rimraf-windows.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map deleted file mode 100644 index bcca3f3..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-windows.d.ts","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AA2DlE,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,KAAK,kBAAkB,qBAQxB,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,KAAK,iBAAiB,YAQvB,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js deleted file mode 100644 index 1563ba4..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js +++ /dev/null @@ -1,154 +0,0 @@ -// This is the same as rimrafPosix, with the following changes: -// -// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff -// 2. All non-directories are removed first and then all directories are -// removed in a second sweep. -// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on -// the that folder. -// -// Note: "move then remove" is 2-10 times slower, and just as unreliable. -import { parse, resolve } from 'path'; -import { fixEPERM, fixEPERMSync } from './fix-eperm.js'; -import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'; -import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'; -import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'; -import { retryBusy, retryBusySync } from './retry-busy.js'; -import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; -import { errorCode } from './error.js'; -const { unlink, rmdir, lstat } = promises; -const rimrafWindowsFile = retryBusy(fixEPERM(unlink)); -const rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync)); -const rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir)); -const rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync)); -const rimrafWindowsDirMoveRemoveFallback = async (path, -// already filtered, remove from options so we don't call unnecessarily -// eslint-disable-next-line @typescript-eslint/no-unused-vars -{ filter, ...opt }) => { - /* c8 ignore next */ - opt?.signal?.throwIfAborted(); - try { - await rimrafWindowsDirRetry(path, opt); - return true; - } - catch (er) { - if (errorCode(er) === 'ENOTEMPTY') { - return rimrafMoveRemove(path, opt); - } - throw er; - } -}; -const rimrafWindowsDirMoveRemoveFallbackSync = (path, -// already filtered, remove from options so we don't call unnecessarily -// eslint-disable-next-line @typescript-eslint/no-unused-vars -{ filter, ...opt }) => { - opt?.signal?.throwIfAborted(); - try { - rimrafWindowsDirRetrySync(path, opt); - return true; - } - catch (er) { - if (errorCode(er) === 'ENOTEMPTY') { - return rimrafMoveRemoveSync(path, opt); - } - throw er; - } -}; -const START = Symbol('start'); -const CHILD = Symbol('child'); -const FINISH = Symbol('finish'); -export const rimrafWindows = async (path, opt) => { - opt?.signal?.throwIfAborted(); - return ((await ignoreENOENT(lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)))) ?? true); -}; -export const rimrafWindowsSync = (path, opt) => { - opt?.signal?.throwIfAborted(); - return (ignoreENOENTSync(() => rimrafWindowsDirSync(path, opt, lstatSync(path), START)) ?? true); -}; -const rimrafWindowsDir = async (path, opt, ent, state = START) => { - opt?.signal?.throwIfAborted(); - const entries = ent.isDirectory() ? await readdirOrError(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - // is a file - await ignoreENOENT(rimrafWindowsFile(path, opt)); - return true; - } - const s = state === START ? CHILD : state; - const removedAll = (await Promise.all(entries.map(ent => rimrafWindowsDir(resolve(path, ent.name), opt, ent, s)))).every(v => v === true); - if (state === START) { - return rimrafWindowsDir(path, opt, ent, FINISH); - } - else if (state === FINISH) { - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !(await opt.filter(path, ent))) { - return false; - } - await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt)); - } - return true; -}; -const rimrafWindowsDirSync = (path, opt, ent, state = START) => { - const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null; - if (!Array.isArray(entries)) { - // this can only happen if lstat/readdir lied, or if the dir was - // swapped out with a file at just the right moment. - /* c8 ignore start */ - if (entries) { - if (errorCode(entries) === 'ENOENT') { - return true; - } - if (errorCode(entries) !== 'ENOTDIR') { - throw entries; - } - } - /* c8 ignore stop */ - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - // is a file - ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt)); - return true; - } - let removedAll = true; - for (const ent of entries) { - const s = state === START ? CHILD : state; - const p = resolve(path, ent.name); - removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll; - } - if (state === START) { - return rimrafWindowsDirSync(path, opt, ent, FINISH); - } - else if (state === FINISH) { - if (opt.preserveRoot === false && path === parse(path).root) { - return false; - } - if (!removedAll) { - return false; - } - if (opt.filter && !opt.filter(path, ent)) { - return false; - } - ignoreENOENTSync(() => rimrafWindowsDirMoveRemoveFallbackSync(path, opt)); - } - return true; -}; -//# sourceMappingURL=rimraf-windows.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map b/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map deleted file mode 100644 index 9a35cba..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/rimraf-windows.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rimraf-windows.js","sourceRoot":"","sources":["../../src/rimraf-windows.ts"],"names":[],"mappings":"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","sourcesContent":["// This is the same as rimrafPosix, with the following changes:\n//\n// 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff\n// 2. All non-directories are removed first and then all directories are\n// removed in a second sweep.\n// 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on\n// the that folder.\n//\n// Note: \"move then remove\" is 2-10 times slower, and just as unreliable.\n\nimport { Dirent, Stats } from 'fs'\nimport { parse, resolve } from 'path'\nimport { RimrafAsyncOptions, RimrafSyncOptions } from './index.js'\nimport { fixEPERM, fixEPERMSync } from './fix-eperm.js'\nimport { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js'\nimport { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js'\nimport { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js'\nimport { retryBusy, retryBusySync } from './retry-busy.js'\nimport {\n rimrafMoveRemove,\n rimrafMoveRemoveSync,\n} from './rimraf-move-remove.js'\nimport { errorCode } from './error.js'\nconst { unlink, rmdir, lstat } = promises\n\nconst rimrafWindowsFile = retryBusy(fixEPERM(unlink))\nconst rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync))\nconst rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir))\nconst rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync))\n\nconst rimrafWindowsDirMoveRemoveFallback = async (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafAsyncOptions,\n): Promise => {\n /* c8 ignore next */\n opt?.signal?.throwIfAborted()\n try {\n await rimrafWindowsDirRetry(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemove(path, opt)\n }\n throw er\n }\n}\n\nconst rimrafWindowsDirMoveRemoveFallbackSync = (\n path: string,\n // already filtered, remove from options so we don't call unnecessarily\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { filter, ...opt }: RimrafSyncOptions,\n): boolean => {\n opt?.signal?.throwIfAborted()\n try {\n rimrafWindowsDirRetrySync(path, opt)\n return true\n } catch (er) {\n if (errorCode(er) === 'ENOTEMPTY') {\n return rimrafMoveRemoveSync(path, opt)\n }\n throw er\n }\n}\n\nconst START = Symbol('start')\nconst CHILD = Symbol('child')\nconst FINISH = Symbol('finish')\n\nexport const rimrafWindows = async (\n path: string,\n opt: RimrafAsyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n (await ignoreENOENT(\n lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)),\n )) ?? true\n )\n}\n\nexport const rimrafWindowsSync = (\n path: string,\n opt: RimrafSyncOptions,\n) => {\n opt?.signal?.throwIfAborted()\n return (\n ignoreENOENTSync(() =>\n rimrafWindowsDirSync(path, opt, lstatSync(path), START),\n ) ?? true\n )\n}\n\nconst rimrafWindowsDir = async (\n path: string,\n opt: RimrafAsyncOptions,\n ent: Dirent | Stats,\n state = START,\n): Promise => {\n opt?.signal?.throwIfAborted()\n\n const entries = ent.isDirectory() ? await readdirOrError(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n // is a file\n await ignoreENOENT(rimrafWindowsFile(path, opt))\n return true\n }\n\n const s = state === START ? CHILD : state\n const removedAll = (\n await Promise.all(\n entries.map(ent =>\n rimrafWindowsDir(resolve(path, ent.name), opt, ent, s),\n ),\n )\n ).every(v => v === true)\n\n if (state === START) {\n return rimrafWindowsDir(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !(await opt.filter(path, ent))) {\n return false\n }\n await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt))\n }\n return true\n}\n\nconst rimrafWindowsDirSync = (\n path: string,\n opt: RimrafSyncOptions,\n ent: Dirent | Stats,\n state = START,\n): boolean => {\n const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null\n if (!Array.isArray(entries)) {\n // this can only happen if lstat/readdir lied, or if the dir was\n // swapped out with a file at just the right moment.\n /* c8 ignore start */\n if (entries) {\n if (errorCode(entries) === 'ENOENT') {\n return true\n }\n if (errorCode(entries) !== 'ENOTDIR') {\n throw entries\n }\n }\n /* c8 ignore stop */\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n // is a file\n ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt))\n return true\n }\n\n let removedAll = true\n for (const ent of entries) {\n const s = state === START ? CHILD : state\n const p = resolve(path, ent.name)\n removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll\n }\n\n if (state === START) {\n return rimrafWindowsDirSync(path, opt, ent, FINISH)\n } else if (state === FINISH) {\n if (opt.preserveRoot === false && path === parse(path).root) {\n return false\n }\n if (!removedAll) {\n return false\n }\n if (opt.filter && !opt.filter(path, ent)) {\n return false\n }\n ignoreENOENTSync(() =>\n rimrafWindowsDirMoveRemoveFallbackSync(path, opt),\n )\n }\n return true\n}\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts deleted file mode 100644 index e191fd9..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RimrafAsyncOptions, RimrafOptions } from './index.js'; -export declare const useNative: (opt?: RimrafAsyncOptions) => boolean; -export declare const useNativeSync: (opt?: RimrafOptions) => boolean; -//# sourceMappingURL=use-native.d.ts.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map b/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map deleted file mode 100644 index be687c1..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/use-native.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"use-native.d.ts","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW9D,eAAO,MAAM,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,kBAAkB,KAAK,OAGf,CAAA;AACvC,eAAO,MAAM,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,aAAa,KAAK,OAGd,CAAA"} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.js b/apps/extension/node_modules/rimraf/dist/esm/use-native.js deleted file mode 100644 index 08098d8..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/use-native.js +++ /dev/null @@ -1,15 +0,0 @@ -/* c8 ignore next */ -const [major = 0, minor = 0] = process.version - .replace(/^v/, '') - .split('.') - .map(v => parseInt(v, 10)); -const hasNative = major > 14 || (major === 14 && minor >= 14); -// we do NOT use native by default on Windows, because Node's native -// rm implementation is less advanced. Change this code if that changes. -export const useNative = !hasNative || process.platform === 'win32' ? - () => false - : opt => !opt?.signal && !opt?.filter; -export const useNativeSync = !hasNative || process.platform === 'win32' ? - () => false - : opt => !opt?.signal && !opt?.filter; -//# sourceMappingURL=use-native.js.map \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map b/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map deleted file mode 100644 index 5feb7d6..0000000 --- a/apps/extension/node_modules/rimraf/dist/esm/use-native.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"use-native.js","sourceRoot":"","sources":["../../src/use-native.ts"],"names":[],"mappings":"AAEA,oBAAoB;AACpB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO;KAC3C,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;KACjB,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5B,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAE7D,oEAAoE;AACpE,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA;AACvC,MAAM,CAAC,MAAM,aAAa,GACxB,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK;IACb,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA","sourcesContent":["import { RimrafAsyncOptions, RimrafOptions } from './index.js'\n\n/* c8 ignore next */\nconst [major = 0, minor = 0] = process.version\n .replace(/^v/, '')\n .split('.')\n .map(v => parseInt(v, 10))\nconst hasNative = major > 14 || (major === 14 && minor >= 14)\n\n// we do NOT use native by default on Windows, because Node's native\n// rm implementation is less advanced. Change this code if that changes.\nexport const useNative: (opt?: RimrafAsyncOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\nexport const useNativeSync: (opt?: RimrafOptions) => boolean =\n !hasNative || process.platform === 'win32' ?\n () => false\n : opt => !opt?.signal && !opt?.filter\n"]} \ No newline at end of file diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf deleted file mode 100644 index ce0aefc..0000000 --- a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*) basedir=`cygpath -w "$basedir"`;; -esac - -if [ -z "$NODE_PATH" ]; then - export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" -else - export NODE_PATH="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules:$NODE_PATH" -fi -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../../dist/esm/bin.mjs" "$@" -else - exec node "$basedir/../../dist/esm/bin.mjs" "$@" -fi diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD deleted file mode 100644 index 5a6ddd7..0000000 --- a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.CMD +++ /dev/null @@ -1,12 +0,0 @@ -@SETLOCAL -@IF NOT DEFINED NODE_PATH ( - @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" -) ELSE ( - @SET "NODE_PATH=D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules;%NODE_PATH%" -) -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" "%~dp0\..\..\dist\esm\bin.mjs" %* -) ELSE ( - @SET PATHEXT=%PATHEXT:;.JS;=;% - node "%~dp0\..\..\dist\esm\bin.mjs" %* -) diff --git a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 b/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 deleted file mode 100644 index f4911c8..0000000 --- a/apps/extension/node_modules/rimraf/node_modules/.bin/rimraf.ps1 +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -$pathsep=":" -$env_node_path=$env:NODE_PATH -$new_node_path="D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\esm\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\dist\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules\rimraf\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\rimraf@6.1.3\node_modules;D:\GitHub\data-recipe\node_modules\.pnpm\node_modules" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" - $pathsep=";" -} else { - $new_node_path="/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/esm/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/dist/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules/rimraf/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/rimraf@6.1.3/node_modules:/mnt/d/GitHub/data-recipe/node_modules/.pnpm/node_modules" -} -if ([string]::IsNullOrEmpty($env_node_path)) { - $env:NODE_PATH=$new_node_path -} else { - $env:NODE_PATH="$new_node_path$pathsep$env_node_path" -} - -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../../dist/esm/bin.mjs" $args - } else { - & "$basedir/node$exe" "$basedir/../../dist/esm/bin.mjs" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../../dist/esm/bin.mjs" $args - } else { - & "node$exe" "$basedir/../../dist/esm/bin.mjs" $args - } - $ret=$LASTEXITCODE -} -$env:NODE_PATH=$env_node_path -exit $ret diff --git a/apps/extension/node_modules/rimraf/package.json b/apps/extension/node_modules/rimraf/package.json deleted file mode 100644 index b00e93e..0000000 --- a/apps/extension/node_modules/rimraf/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "rimraf", - "version": "6.1.3", - "type": "module", - "tshy": { - "main": true, - "exports": { - "./package.json": "./package.json", - ".": "./src/index.ts" - } - }, - "bin": "./dist/esm/bin.mjs", - "main": "./dist/commonjs/index.js", - "types": "./dist/commonjs/index.d.ts", - "exports": { - "./package.json": "./package.json", - ".": { - "import": { - "types": "./dist/esm/index.d.ts", - "default": "./dist/esm/index.js" - }, - "require": { - "types": "./dist/commonjs/index.d.ts", - "default": "./dist/commonjs/index.js" - } - } - }, - "files": [ - "dist" - ], - "description": "A deep deletion module for node (like `rm -rf`)", - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "BlueOak-1.0.0", - "repository": "git@github.com:isaacs/rimraf.git", - "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "prepare": "tshy", - "pretest": "npm run prepare", - "presnap": "npm run prepare", - "test": "tap", - "snap": "tap", - "format": "prettier --write . --log-level warn", - "benchmark": "node benchmark/index.js", - "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" - }, - "devDependencies": { - "@types/node": "^25.2.0", - "mkdirp": "^3.0.1", - "prettier": "^3.6.2", - "tap": "^21.1.1", - "tshy": "^3.0.3", - "typedoc": "^0.28.14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "engines": { - "node": "20 || >=22" - }, - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "keywords": [ - "rm", - "rm -rf", - "rm -fr", - "remove", - "directory", - "cli", - "rmdir", - "recursive" - ], - "module": "./dist/esm/index.js" -} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/package.json b/packages/detector/node_modules/@data-recipe/recipe-core/package.json deleted file mode 100644 index e4538ee..0000000 --- a/packages/detector/node_modules/@data-recipe/recipe-core/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@data-recipe/recipe-core", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - } -} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts b/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts deleted file mode 100644 index 7cdb195..0000000 --- a/packages/detector/node_modules/@data-recipe/recipe-core/src/index.ts +++ /dev/null @@ -1,111 +0,0 @@ -export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; - -export type JsonObject = Record; - -export interface DataRecipe { - name: string; - displayName: string; - source: DataRecipeSource; - request: DataRecipeRequest; - response: DataRecipeResponse; - pagination: DataRecipePagination; - fields: DataRecipeField[]; -} - -export interface DataRecipeSource { - type: "web_api"; - pageUrl: string; - apiUrl: string; - method: HttpMethod; -} - -export interface DataRecipeRequest { - query: JsonObject; - body: unknown; -} - -export interface DataRecipeResponse { - type: "list" | "object" | "unknown"; - listPath: string; - totalPath: string; -} - -export interface DataRecipePagination { - type: "page_number" | "cursor" | "unknown"; - pageParam: string; - pageSizeParam: string; - totalPath: string; -} - -export interface DataRecipeField { - name: string; - path: string; - type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; - sample?: unknown; -} - -export interface CreateRecipeInput { - pageUrl: string; - apiUrl: string; - method: HttpMethod; - query: JsonObject; - body: unknown; - responseType: DataRecipeResponse["type"]; - listPath: string; - totalPath: string; - fields: DataRecipeField[]; -} - -export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { - const name = buildRecipeName(input.apiUrl); - - return { - name, - displayName: "数据来源", - source: { - type: "web_api", - pageUrl: input.pageUrl, - apiUrl: input.apiUrl, - method: input.method - }, - request: { - query: input.query, - body: input.body ?? {} - }, - response: { - type: input.responseType, - listPath: input.listPath, - totalPath: input.totalPath - }, - pagination: { - type: "page_number", - pageParam: "", - pageSizeParam: "", - totalPath: input.totalPath - }, - fields: input.fields - }; -} - -function buildRecipeName(apiUrl: string): string { - try { - const url = new URL(apiUrl); - const pathPart = url.pathname - .split("/") - .filter(Boolean) - .slice(-2) - .join("_"); - return normalizeName(pathPart || url.hostname); - } catch { - return normalizeName(apiUrl || "data_source"); - } -} - -function normalizeName(value: string): string { - const normalized = value - .toLowerCase() - .replace(/[^a-z0-9]+/g, "_") - .replace(/^_+|_+$/g, ""); - - return normalized || "data_source"; -} diff --git a/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json b/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json deleted file mode 100644 index c34ef95..0000000 --- a/packages/detector/node_modules/@data-recipe/recipe-core/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src"] -} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json deleted file mode 100644 index e4538ee..0000000 --- a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@data-recipe/recipe-core", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - } -} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts deleted file mode 100644 index 7cdb195..0000000 --- a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/src/index.ts +++ /dev/null @@ -1,111 +0,0 @@ -export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | string; - -export type JsonObject = Record; - -export interface DataRecipe { - name: string; - displayName: string; - source: DataRecipeSource; - request: DataRecipeRequest; - response: DataRecipeResponse; - pagination: DataRecipePagination; - fields: DataRecipeField[]; -} - -export interface DataRecipeSource { - type: "web_api"; - pageUrl: string; - apiUrl: string; - method: HttpMethod; -} - -export interface DataRecipeRequest { - query: JsonObject; - body: unknown; -} - -export interface DataRecipeResponse { - type: "list" | "object" | "unknown"; - listPath: string; - totalPath: string; -} - -export interface DataRecipePagination { - type: "page_number" | "cursor" | "unknown"; - pageParam: string; - pageSizeParam: string; - totalPath: string; -} - -export interface DataRecipeField { - name: string; - path: string; - type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; - sample?: unknown; -} - -export interface CreateRecipeInput { - pageUrl: string; - apiUrl: string; - method: HttpMethod; - query: JsonObject; - body: unknown; - responseType: DataRecipeResponse["type"]; - listPath: string; - totalPath: string; - fields: DataRecipeField[]; -} - -export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { - const name = buildRecipeName(input.apiUrl); - - return { - name, - displayName: "数据来源", - source: { - type: "web_api", - pageUrl: input.pageUrl, - apiUrl: input.apiUrl, - method: input.method - }, - request: { - query: input.query, - body: input.body ?? {} - }, - response: { - type: input.responseType, - listPath: input.listPath, - totalPath: input.totalPath - }, - pagination: { - type: "page_number", - pageParam: "", - pageSizeParam: "", - totalPath: input.totalPath - }, - fields: input.fields - }; -} - -function buildRecipeName(apiUrl: string): string { - try { - const url = new URL(apiUrl); - const pathPart = url.pathname - .split("/") - .filter(Boolean) - .slice(-2) - .join("_"); - return normalizeName(pathPart || url.hostname); - } catch { - return normalizeName(apiUrl || "data_source"); - } -} - -function normalizeName(value: string): string { - const normalized = value - .toLowerCase() - .replace(/[^a-z0-9]+/g, "_") - .replace(/^_+|_+$/g, ""); - - return normalized || "data_source"; -} diff --git a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json b/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json deleted file mode 100644 index c34ef95..0000000 --- a/packages/recipe-runner/node_modules/@data-recipe/recipe-core/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src"] -} From e07c089109e54a86f5c9644210ca652b13389f26 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:17:49 +0800 Subject: [PATCH 03/25] chore: make workspace buildable --- packages/detector/package.json | 10 +- packages/detector/tsconfig.json | 12 +- packages/detector/tsconfig.tsbuildinfo | 1 + packages/recipe-core/package.json | 10 +- packages/recipe-core/tsconfig.json | 7 +- packages/recipe-core/tsconfig.tsbuildinfo | 1 + packages/recipe-runner/package.json | 10 +- packages/recipe-runner/tsconfig.json | 12 +- packages/recipe-runner/tsconfig.tsbuildinfo | 1 + pnpm-lock.yaml | 1020 +++++++++++++++++++ pnpm-workspace.yaml | 6 + tsconfig.base.json | 20 +- 12 files changed, 1096 insertions(+), 14 deletions(-) create mode 100644 packages/detector/tsconfig.tsbuildinfo create mode 100644 packages/recipe-core/tsconfig.tsbuildinfo create mode 100644 packages/recipe-runner/tsconfig.tsbuildinfo create mode 100644 pnpm-lock.yaml diff --git a/packages/detector/package.json b/packages/detector/package.json index e7a9ca2..4c9ded6 100644 --- a/packages/detector/package.json +++ b/packages/detector/package.json @@ -6,10 +6,16 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" }, "dependencies": { "@data-recipe/recipe-core": "workspace:*" + }, + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } } } diff --git a/packages/detector/tsconfig.json b/packages/detector/tsconfig.json index c34ef95..97fb707 100644 --- a/packages/detector/tsconfig.json +++ b/packages/detector/tsconfig.json @@ -4,7 +4,15 @@ "declaration": true, "declarationMap": true, "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "composite": true }, - "include": ["src"] + "include": [ + "src" + ], + "references": [ + { + "path": "../recipe-core" + } + ] } diff --git a/packages/detector/tsconfig.tsbuildinfo b/packages/detector/tsconfig.tsbuildinfo new file mode 100644 index 0000000..284d190 --- /dev/null +++ b/packages/detector/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../recipe-core/dist/index.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[62],[63,64,66],[65],[60]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c",{"version":"5646d45c44272b6eb81cb427a3d2b924065b56a439f639f17902708c8fa28a1c","signature":"2443573fa626f56d4e6a750839930a21d474df743c0f701aedbd56aedfbabc4f"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[61],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[63,1],[67,2],[66,3],[61,4]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/recipe-core/package.json b/packages/recipe-core/package.json index e4538ee..a70786b 100644 --- a/packages/recipe-core/package.json +++ b/packages/recipe-core/package.json @@ -6,7 +6,13 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + }, + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } } } diff --git a/packages/recipe-core/tsconfig.json b/packages/recipe-core/tsconfig.json index c34ef95..8a1cac6 100644 --- a/packages/recipe-core/tsconfig.json +++ b/packages/recipe-core/tsconfig.json @@ -4,7 +4,10 @@ "declaration": true, "declarationMap": true, "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "composite": true }, - "include": ["src"] + "include": [ + "src" + ] } diff --git a/packages/recipe-core/tsconfig.tsbuildinfo b/packages/recipe-core/tsconfig.tsbuildinfo new file mode 100644 index 0000000..e336498 --- /dev/null +++ b/packages/recipe-core/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[61],[62,63,65],[64]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"557612ee5ec7f331992592d96d5af8399595802e6ad505e17620af2aaa7e8d2b","signature":"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[60],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[62,1],[66,2],[65,3]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/recipe-runner/package.json b/packages/recipe-runner/package.json index 0cc0225..ef5c684 100644 --- a/packages/recipe-runner/package.json +++ b/packages/recipe-runner/package.json @@ -6,10 +6,16 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" }, "dependencies": { "@data-recipe/recipe-core": "workspace:*" + }, + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } } } diff --git a/packages/recipe-runner/tsconfig.json b/packages/recipe-runner/tsconfig.json index c34ef95..97fb707 100644 --- a/packages/recipe-runner/tsconfig.json +++ b/packages/recipe-runner/tsconfig.json @@ -4,7 +4,15 @@ "declaration": true, "declarationMap": true, "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "composite": true }, - "include": ["src"] + "include": [ + "src" + ], + "references": [ + { + "path": "../recipe-core" + } + ] } diff --git a/packages/recipe-runner/tsconfig.tsbuildinfo b/packages/recipe-runner/tsconfig.tsbuildinfo new file mode 100644 index 0000000..5880ea4 --- /dev/null +++ b/packages/recipe-runner/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../recipe-core/dist/index.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[62],[63,64,66],[65],[60]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c",{"version":"6663b0ca3eb87144a3698e5f05879b9ba42c7d8059a860cce782a820b06cc096","signature":"c821788e13c67498643f72ee286ca2498a85896d55bb968d34a8213e591d26ec"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[61],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[63,1],[67,2],[66,3],[61,4]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..fb72fb8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1020 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/chrome': + specifier: ^0.0.268 + version: 0.0.268 + tsup: + specifier: ^8.2.4 + version: 8.5.1(typescript@5.9.3) + typescript: + specifier: ^5.5.4 + version: 5.9.3 + + apps/extension: + dependencies: + '@data-recipe/detector': + specifier: workspace:* + version: link:../../packages/detector + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../../packages/recipe-core + devDependencies: + rimraf: + specifier: ^6.0.1 + version: 6.1.3 + + packages/detector: + dependencies: + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../recipe-core + + packages/recipe-core: {} + + packages/recipe-runner: + dependencies: + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../recipe-core + +packages: + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@rollup/rollup-android-arm-eabi@4.62.2': + resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.62.2': + resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.62.2': + resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.62.2': + resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.62.2': + resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.62.2': + resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.62.2': + resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.62.2': + resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.62.2': + resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.62.2': + resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.62.2': + resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.62.2': + resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.62.2': + resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.62.2': + resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.62.2': + resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.62.2': + resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.62.2': + resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.62.2': + resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} + cpu: [x64] + os: [win32] + + '@types/chrome@0.0.268': + resolution: {integrity: sha512-7N1QH9buudSJ7sI8Pe4mBHJr5oZ48s0hcanI9w3wgijAlv1OZNUZve9JR4x42dn5lJ5Sm87V1JNfnoh10EnQlA==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/filesystem@0.0.36': + resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} + + '@types/filewriter@0.0.33': + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + + '@types/har-format@1.2.16': + resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} + engines: {node: 18 || 20 || >=22} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + engines: {node: 20 || >=22} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + rimraf@6.1.3: + resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==} + engines: {node: 20 || >=22} + hasBin: true + + rollup@4.62.2: + resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + +snapshots: + + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@rollup/rollup-android-arm-eabi@4.62.2': + optional: true + + '@rollup/rollup-android-arm64@4.62.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.62.2': + optional: true + + '@rollup/rollup-darwin-x64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.62.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.62.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.62.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.62.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.62.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.62.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.62.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.62.2': + optional: true + + '@types/chrome@0.0.268': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 + + '@types/estree@1.0.9': {} + + '@types/filesystem@0.0.36': + dependencies: + '@types/filewriter': 0.0.33 + + '@types/filewriter@0.0.33': {} + + '@types/har-format@1.2.16': {} + + acorn@8.17.0: {} + + any-promise@1.3.0: {} + + balanced-match@4.0.4: {} + + brace-expansion@5.0.7: + dependencies: + balanced-match: 4.0.4 + + bundle-require@5.1.0(esbuild@0.27.7): + dependencies: + esbuild: 0.27.7 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + commander@4.1.1: {} + + confbox@0.1.8: {} + + consola@3.4.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.62.2 + + fsevents@2.3.3: + optional: true + + glob@13.0.6: + dependencies: + minimatch: 10.2.5 + minipass: 7.1.3 + path-scurry: 2.0.2 + + joycon@3.1.1: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lru-cache@11.5.1: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.7 + + minipass@7.1.3: {} + + mlly@1.8.2: + dependencies: + acorn: 8.17.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + object-assign@4.1.1: {} + + package-json-from-dist@1.0.1: {} + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.5.1 + minipass: 7.1.3 + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + pirates@4.0.7: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + postcss-load-config@6.0.1: + dependencies: + lilconfig: 3.1.3 + + readdirp@4.1.2: {} + + resolve-from@5.0.0: {} + + rimraf@6.1.3: + dependencies: + glob: 13.0.6 + package-json-from-dist: 1.0.1 + + rollup@4.62.2: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.62.2 + '@rollup/rollup-android-arm64': 4.62.2 + '@rollup/rollup-darwin-arm64': 4.62.2 + '@rollup/rollup-darwin-x64': 4.62.2 + '@rollup/rollup-freebsd-arm64': 4.62.2 + '@rollup/rollup-freebsd-x64': 4.62.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 + '@rollup/rollup-linux-arm-musleabihf': 4.62.2 + '@rollup/rollup-linux-arm64-gnu': 4.62.2 + '@rollup/rollup-linux-arm64-musl': 4.62.2 + '@rollup/rollup-linux-loong64-gnu': 4.62.2 + '@rollup/rollup-linux-loong64-musl': 4.62.2 + '@rollup/rollup-linux-ppc64-gnu': 4.62.2 + '@rollup/rollup-linux-ppc64-musl': 4.62.2 + '@rollup/rollup-linux-riscv64-gnu': 4.62.2 + '@rollup/rollup-linux-riscv64-musl': 4.62.2 + '@rollup/rollup-linux-s390x-gnu': 4.62.2 + '@rollup/rollup-linux-x64-gnu': 4.62.2 + '@rollup/rollup-linux-x64-musl': 4.62.2 + '@rollup/rollup-openbsd-x64': 4.62.2 + '@rollup/rollup-openharmony-arm64': 4.62.2 + '@rollup/rollup-win32-arm64-msvc': 4.62.2 + '@rollup/rollup-win32-ia32-msvc': 4.62.2 + '@rollup/rollup-win32-x64-gnu': 4.62.2 + '@rollup/rollup-win32-x64-msvc': 4.62.2 + fsevents: 2.3.3 + + source-map@0.7.6: {} + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.17 + ts-interface-checker: 0.1.13 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.2: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsup@8.5.1(typescript@5.9.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.7) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.7 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1 + resolve-from: 5.0.0 + rollup: 4.62.2 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + typescript@5.9.3: {} + + ufo@1.6.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3ff5faa..3baf9ff 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,9 @@ packages: - "apps/*" - "packages/*" + +allowBuilds: + esbuild: true + +onlyBuiltDependencies: + - esbuild diff --git a/tsconfig.base.json b/tsconfig.base.json index 65996e7..35a0c58 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2022", - "lib": ["ES2022", "DOM"], + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], "module": "ESNext", "moduleResolution": "Bundler", "strict": true, @@ -9,6 +13,18 @@ "forceConsistentCasingInFileNames": true, "noUncheckedIndexedAccess": true, "resolveJsonModule": true, - "isolatedModules": true + "isolatedModules": true, + "baseUrl": ".", + "paths": { + "@data-recipe/recipe-core": [ + "packages/recipe-core/src/index.ts" + ], + "@data-recipe/detector": [ + "packages/detector/src/index.ts" + ], + "@data-recipe/recipe-runner": [ + "packages/recipe-runner/src/index.ts" + ] + } } } From 947995cfe81b14ebdf234a05ac7ad317f1c0577d Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:18:08 +0800 Subject: [PATCH 04/25] chore: ignore typescript build info --- .gitignore | 1 + packages/detector/tsconfig.tsbuildinfo | 1 - packages/recipe-core/tsconfig.tsbuildinfo | 1 - packages/recipe-runner/tsconfig.tsbuildinfo | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 packages/detector/tsconfig.tsbuildinfo delete mode 100644 packages/recipe-core/tsconfig.tsbuildinfo delete mode 100644 packages/recipe-runner/tsconfig.tsbuildinfo diff --git a/.gitignore b/.gitignore index 6fe0009..15a4b73 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/ .turbo/ .DS_Store *.log +*.tsbuildinfo diff --git a/packages/detector/tsconfig.tsbuildinfo b/packages/detector/tsconfig.tsbuildinfo deleted file mode 100644 index 284d190..0000000 --- a/packages/detector/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../recipe-core/dist/index.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[62],[63,64,66],[65],[60]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c",{"version":"5646d45c44272b6eb81cb427a3d2b924065b56a439f639f17902708c8fa28a1c","signature":"2443573fa626f56d4e6a750839930a21d474df743c0f701aedbd56aedfbabc4f"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[61],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[63,1],[67,2],[66,3],[61,4]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/recipe-core/tsconfig.tsbuildinfo b/packages/recipe-core/tsconfig.tsbuildinfo deleted file mode 100644 index e336498..0000000 --- a/packages/recipe-core/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[61],[62,63,65],[64]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"557612ee5ec7f331992592d96d5af8399595802e6ad505e17620af2aaa7e8d2b","signature":"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[60],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[62,1],[66,2],[65,3]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/recipe-runner/tsconfig.tsbuildinfo b/packages/recipe-runner/tsconfig.tsbuildinfo deleted file mode 100644 index 5880ea4..0000000 --- a/packages/recipe-runner/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../recipe-core/dist/index.d.ts","./src/index.ts","../../node_modules/.pnpm/@types+har-format@1.2.16/node_modules/@types/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/har-format/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/chrome-cast/index.d.ts","../../node_modules/.pnpm/@types+filewriter@0.0.33/node_modules/@types/filewriter/index.d.ts","../../node_modules/.pnpm/@types+filesystem@0.0.36/node_modules/@types/filesystem/index.d.ts","../../node_modules/.pnpm/@types+chrome@0.0.268/node_modules/@types/chrome/index.d.ts"],"fileIdsList":[[62],[63,64,66],[65],[60]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},"725bc07a431963b41d9f315fc76c79bb93e1cbffd4e96173e8d45821b5d0772c",{"version":"6663b0ca3eb87144a3698e5f05879b9ba42c7d8059a860cce782a820b06cc096","signature":"c821788e13c67498643f72ee286ca2498a85896d55bb968d34a8213e591d26ec"},{"version":"5574d520dabc450de6be799f1791d86d71da4fb236f16e6ca21b953788bb5154","impliedFormat":1},{"version":"5f877dfc985d1fd3ac8bf4a75cd77b06c42ca608809b324c44b4151758de7189","affectsGlobalScope":true,"impliedFormat":1},{"version":"9698d9513bbce8e33fded9b396243b917cd7544ab192c9ebaadce5ea298c31e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"14c2fd6220654a41c53836a62ba96d4b515ae1413b0ccb31c2445fb1ae1de5de","affectsGlobalScope":true,"impliedFormat":1},{"version":"4f29c38739500cd35a2ce41d15a35e34445ca755ebb991915b5f170985a49d21","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3a8593c2ccdd12de17752811a26ad28a4aa28334caf58011284c81b07bdda2","affectsGlobalScope":true,"impliedFormat":1}],"root":[61],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[63,1],[67,2],[66,3],[61,4]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file From 67c02e25bd9646f26c9a8c576e5767cb5f27812e Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:19:21 +0800 Subject: [PATCH 05/25] docs: add extension mvp runbook --- README.en.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ README.md | 9 +++++++++ README.zh-CN.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/README.en.md b/README.en.md index fafa4dd..2fa45de 100644 --- a/README.en.md +++ b/README.en.md @@ -145,3 +145,49 @@ data-recipe/ ## License TBD + +## Run the MVP locally + +### Install dependencies + +```bash +pnpm install +``` + +### Build the browser extension + +```bash +pnpm build:extension +``` + +The extension output is: + +```text +apps/extension/dist +``` + +### Load it in Chrome + +1. Open `chrome://extensions`; +2. Enable Developer mode; +3. Click "Load unpacked"; +4. Select `apps/extension/dist`; +5. Click the "AI 有数" extension icon to open the side panel. + +### Manual verification + +1. Open `docs/test-page.html`; +2. Click "开始发现" in the side panel; +3. Click the fetch or XHR test button on the test page; +4. The side panel should show the discovered data source count, URL, method, status, query data, and response preview; +5. Expand "高级信息" to inspect the minimal Data Recipe draft JSON. + +You can also start discovery on any page you are authorized to access and then trigger a page query. This MVP only performs low-frequency local detection. It does not bypass login, captchas, risk controls, or dynamic signatures. + +### Development mode + +```bash +pnpm dev:extension +``` + +This watches and rebuilds `apps/extension/dist`. Refresh the unpacked extension in Chrome before testing updated code. diff --git a/README.md b/README.md index 098ab72..73c51b8 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,12 @@ Turn web page queries and API responses into reusable data recipes for AI agents * [中文说明](./README.zh-CN.md) * [English README](./README.en.md) + +## MVP quick start + +```bash +pnpm install +pnpm build:extension +``` + +Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, open the DataRecipe side panel, click "开始发现", and trigger the fetch or XHR test request. diff --git a/README.zh-CN.md b/README.zh-CN.md index 03a60ce..2c688f7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -138,3 +138,49 @@ data-recipe/ ## License TBD + +## 本地运行 MVP + +### 安装依赖 + +```bash +pnpm install +``` + +### 构建浏览器插件 + +```bash +pnpm build:extension +``` + +构建产物在: + +```text +apps/extension/dist +``` + +### 在 Chrome 中加载插件 + +1. 打开 `chrome://extensions`; +2. 开启「开发者模式」; +3. 点击「加载已解压的扩展程序」; +4. 选择 `apps/extension/dist`; +5. 点击浏览器工具栏里的「AI 有数」图标打开侧边栏。 + +### 手动验证 + +1. 打开 `docs/test-page.html`; +2. 在 AI 有数侧边栏点击「开始发现」; +3. 在测试页点击「触发 fetch 查询」或「触发 XHR 查询」; +4. 侧边栏应显示发现的数据来源数量、URL、请求方式、状态、查询条件和返回预览; +5. 展开「高级信息」可以查看最小数据配方草稿 JSON。 + +也可以在任意你有权访问的网页上点击「开始发现」,然后触发页面查询。当前 MVP 只做低频本地探测,不会绕过登录、验证码、风控或动态签名。 + +### 开发模式 + +```bash +pnpm dev:extension +``` + +该命令会监听并重新构建 `apps/extension/dist`。Chrome 扩展页面中需要手动点击刷新插件后再验证最新代码。 From 5553acb82ae1a7d1b7efcd61290b8591406ba421 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:29:03 +0800 Subject: [PATCH 06/25] feat: copy data skill draft from side panel --- apps/extension/public/sidepanel.css | 9 +++++++ apps/extension/src/sidepanel.ts | 38 ++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 73ea911..6c98d85 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -221,3 +221,12 @@ summary { font-size: 13px; font-weight: 600; } + +.recipe-draft { + display: grid; + gap: 10px; +} + +.copy-button { + justify-self: start; +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index 28cd06c..e3bde67 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -127,10 +127,31 @@ function renderDetail(): void { ])), block("查询条件", pre(JSON.stringify({ query: capture.query, body: capture.requestBody ?? {} }, null, 2))), block("返回预览", pre(capture.responsePreview || "无可展示内容")), + recipeDraftBlock(recipe), advancedInfo(capture, recipe) ); } +function recipeDraftBlock(recipe: unknown): HTMLElement { + const wrapper = document.createElement("div"); + wrapper.className = "recipe-draft"; + + const summary = document.createElement("div"); + summary.className = "finding"; + summary.textContent = "已根据当前数据来源生成一份可复用的数据技能草稿。"; + + const copyButton = document.createElement("button"); + copyButton.type = "button"; + copyButton.className = "copy-button"; + copyButton.textContent = "复制 JSON"; + copyButton.addEventListener("click", () => { + void copyText(JSON.stringify(recipe, null, 2), copyButton); + }); + + wrapper.append(summary, copyButton); + return block("数据技能草稿", wrapper); +} + function advancedInfo(capture: CapturedRequest, recipe: unknown): HTMLElement { const details = document.createElement("details"); const summary = document.createElement("summary"); @@ -139,7 +160,7 @@ function advancedInfo(capture: CapturedRequest, recipe: unknown): HTMLElement { content.className = "detail-block"; content.append( block("传输方式", keyValues([["类型", capture.transport]])), - block("数据配方草稿", pre(JSON.stringify(recipe, null, 2))) + block("数据技能 JSON", pre(JSON.stringify(recipe, null, 2))) ); details.append(summary, content); return details; @@ -209,3 +230,18 @@ function getElement(id: string): T { } return element as T; } + +async function copyText(text: string, button: HTMLButtonElement): Promise { + const originalText = button.textContent ?? "复制 JSON"; + + try { + await navigator.clipboard.writeText(text); + button.textContent = "已复制"; + } catch { + button.textContent = "复制失败"; + } + + window.setTimeout(() => { + button.textContent = originalText; + }, 1600); +} From effac495fc83a2b79784320e92dc35a1b63560f4 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:33:27 +0800 Subject: [PATCH 07/25] feat: preview data skill run results --- apps/extension/package.json | 3 +- apps/extension/public/sidepanel.css | 5 +++ apps/extension/src/sidepanel.ts | 20 +++++++++ packages/recipe-runner/src/index.ts | 66 +++++++++++++++++++++++++++++ pnpm-lock.yaml | 16 +++++++ 5 files changed, 109 insertions(+), 1 deletion(-) diff --git a/apps/extension/package.json b/apps/extension/package.json index fd60ef2..b720d82 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -11,7 +11,8 @@ }, "dependencies": { "@data-recipe/detector": "workspace:*", - "@data-recipe/recipe-core": "workspace:*" + "@data-recipe/recipe-core": "workspace:*", + "@data-recipe/recipe-runner": "workspace:*" }, "devDependencies": { "rimraf": "^6.0.1" diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 6c98d85..6d5f484 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -230,3 +230,8 @@ summary { .copy-button { justify-self: start; } + +.run-preview { + display: grid; + gap: 10px; +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index e3bde67..f786c0f 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,4 +1,5 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; +import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import type { PanelEvent, PanelSnapshot } from "./messages"; const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); @@ -108,6 +109,7 @@ function renderDetail(): void { const detection = summarizeResponse(capture.responseBody); const recipe = buildRecipeFromCapture(capture); + const runResult = runRecipeOnSample(recipe, capture.responseBody); elements.requestDetail.className = ""; elements.requestDetail.innerHTML = ""; @@ -128,10 +130,27 @@ function renderDetail(): void { block("查询条件", pre(JSON.stringify({ query: capture.query, body: capture.requestBody ?? {} }, null, 2))), block("返回预览", pre(capture.responsePreview || "无可展示内容")), recipeDraftBlock(recipe), + runPreviewBlock(runResult), advancedInfo(capture, recipe) ); } +function runPreviewBlock(runResult: ReturnType): HTMLElement { + const wrapper = document.createElement("div"); + wrapper.className = "run-preview"; + + const summary = document.createElement("div"); + summary.className = "finding"; + summary.textContent = runResult.message; + wrapper.append(summary); + + if (runResult.previewRows.length > 0) { + wrapper.append(pre(JSON.stringify(runResult.previewRows, null, 2))); + } + + return block("试运行结果", wrapper); +} + function recipeDraftBlock(recipe: unknown): HTMLElement { const wrapper = document.createElement("div"); wrapper.className = "recipe-draft"; @@ -245,3 +264,4 @@ async function copyText(text: string, button: HTMLButtonElement): Promise button.textContent = originalText; }, 1600); } + diff --git a/packages/recipe-runner/src/index.ts b/packages/recipe-runner/src/index.ts index 3250f01..e924435 100644 --- a/packages/recipe-runner/src/index.ts +++ b/packages/recipe-runner/src/index.ts @@ -3,4 +3,70 @@ import type { DataRecipe } from "@data-recipe/recipe-core"; export interface RecipeRunResult { recipe: DataRecipe; rows: unknown[]; + rowCount: number; + previewRows: unknown[]; + status: "ok" | "empty" | "unsupported"; + message: string; +} + +export interface RunRecipeOnSampleOptions { + previewLimit?: number; +} + +export function runRecipeOnSample( + recipe: DataRecipe, + responseBody: unknown, + options: RunRecipeOnSampleOptions = {} +): RecipeRunResult { + const previewLimit = options.previewLimit ?? 5; + const listValue = getByPath(responseBody, recipe.response.listPath); + + if (!Array.isArray(listValue)) { + return { + recipe, + rows: [], + rowCount: 0, + previewRows: [], + status: recipe.response.type === "list" ? "empty" : "unsupported", + message: recipe.response.type === "list" ? "没有从当前响应中读取到列表数据。" : "当前数据来源暂不适合按列表预览。" + }; + } + + const rows = listValue; + + return { + recipe, + rows, + rowCount: rows.length, + previewRows: rows.slice(0, previewLimit), + status: rows.length > 0 ? "ok" : "empty", + message: rows.length > 0 ? `已读取 ${rows.length} 条数据,下面展示前 ${Math.min(rows.length, previewLimit)} 条。` : "当前列表没有数据。" + }; +} + +function getByPath(value: unknown, path: string): unknown { + if (!path || path === "$") { + return value; + } + + const parts = path + .replace(/^\$\.?/, "") + .split(".") + .filter(Boolean); + + return parts.reduce((current, part) => { + if (!current || typeof current !== "object") { + return undefined; + } + + const arrayMatch = part.match(/^(.*)\[(\d+)\]$/); + if (arrayMatch) { + const [, key, indexText] = arrayMatch; + const container = key ? (current as Record)[key] : current; + const index = Number(indexText); + return Array.isArray(container) ? container[index] : undefined; + } + + return (current as Record)[part]; + }, value); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb72fb8..1ecc830 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: '@data-recipe/recipe-core': specifier: workspace:* version: link:../../packages/recipe-core + '@data-recipe/recipe-runner': + specifier: workspace:* + version: link:../../packages/recipe-runner devDependencies: rimraf: specifier: ^6.0.1 @@ -250,66 +253,79 @@ packages: resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.62.2': resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.62.2': resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.62.2': resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.62.2': resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.62.2': resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.62.2': resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.62.2': resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.62.2': resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.62.2': resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.62.2': resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.62.2': resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.62.2': resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.62.2': resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} From debf69392a63b342c2796bf21d978916c776793d Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:37:56 +0800 Subject: [PATCH 08/25] feat: describe recipe inputs and fields --- apps/extension/src/sidepanel.ts | 35 ++++++++++++++++++ packages/detector/src/index.ts | 19 ++++------ packages/recipe-core/src/index.ts | 60 +++++++++++++++++++++++++++++-- 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index f786c0f..ea8e893 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -128,6 +128,8 @@ function renderDetail(): void { : "暂未发现 total / count / page / records / list 等字段" ])), block("查询条件", pre(JSON.stringify({ query: capture.query, body: capture.requestBody ?? {} }, null, 2))), + parameterPreviewBlock(recipe), + fieldPreviewBlock(recipe), block("返回预览", pre(capture.responsePreview || "无可展示内容")), recipeDraftBlock(recipe), runPreviewBlock(runResult), @@ -135,6 +137,30 @@ function renderDetail(): void { ); } +function parameterPreviewBlock(recipe: ReturnType): HTMLElement { + const parameters = [...recipe.request.queryFields, ...recipe.request.bodyFields]; + + if (parameters.length === 0) { + return block("查询条件说明", findingList(["暂未发现明确的查询条件。"])); + } + + return block( + "查询条件说明", + findingList(parameters.slice(0, 12).map((item) => `${item.displayName}:${item.type}${item.sample === undefined ? "" : `,样例 ${formatInlineValue(item.sample)}`}`)) + ); +} + +function fieldPreviewBlock(recipe: ReturnType): HTMLElement { + if (recipe.fields.length === 0) { + return block("返回字段", findingList(["暂未从当前数据中识别出稳定字段。"])); + } + + return block( + "返回字段", + findingList(recipe.fields.slice(0, 16).map((field) => `${field.displayName}:${field.type}${field.sample === undefined ? "" : `,样例 ${formatInlineValue(field.sample)}`}`)) + ); +} + function runPreviewBlock(runResult: ReturnType): HTMLElement { const wrapper = document.createElement("div"); wrapper.className = "run-preview"; @@ -242,6 +268,13 @@ function readableUrl(urlValue: string): string { } } +function formatInlineValue(value: unknown): string { + const text = typeof value === "string" ? value : JSON.stringify(value); + if (!text) { + return "空"; + } + return text.length > 48 ? `${text.slice(0, 48)}...` : text; +} function getElement(id: string): T { const element = document.getElementById(id); if (!element) { @@ -265,3 +298,5 @@ async function copyText(text: string, button: HTMLButtonElement): Promise }, 1600); } + + diff --git a/packages/detector/src/index.ts b/packages/detector/src/index.ts index 00145a3..a9f479c 100644 --- a/packages/detector/src/index.ts +++ b/packages/detector/src/index.ts @@ -1,6 +1,7 @@ import { createDataRecipeDraft, type DataRecipe, + inferDataValueType, type DataRecipeField, type JsonObject } from "@data-recipe/recipe-core"; @@ -151,9 +152,11 @@ function inferFieldsAtPath(responseBody: unknown, listPath: string): DataRecipeF return Object.entries(sample).map(([key, value]) => ({ name: key, + displayName: key, path: `${listPath}.${key}`, - type: inferJsonType(value), - sample: simplifySample(value) + type: inferDataValueType(value), + sample: simplifySample(value), + description: "待确认" })); } @@ -192,16 +195,6 @@ function walk(value: unknown, path: string, visit: (path: string, value: unknown }); } -function inferJsonType(value: unknown): DataRecipeField["type"] { - if (value === null) return "null"; - if (Array.isArray(value)) return "array"; - if (typeof value === "string") return "string"; - if (typeof value === "number") return "number"; - if (typeof value === "boolean") return "boolean"; - if (typeof value === "object") return "object"; - return "unknown"; -} - function simplifySample(value: unknown): unknown { if (Array.isArray(value)) { return value.slice(0, 2); @@ -213,3 +206,5 @@ function simplifySample(value: unknown): unknown { return value; } + + diff --git a/packages/recipe-core/src/index.ts b/packages/recipe-core/src/index.ts index 7cdb195..fcbf40a 100644 --- a/packages/recipe-core/src/index.ts +++ b/packages/recipe-core/src/index.ts @@ -2,6 +2,8 @@ export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | export type JsonObject = Record; +export type DataValueType = "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + export interface DataRecipe { name: string; displayName: string; @@ -22,6 +24,17 @@ export interface DataRecipeSource { export interface DataRecipeRequest { query: JsonObject; body: unknown; + queryFields: DataRecipeParameter[]; + bodyFields: DataRecipeParameter[]; +} + +export interface DataRecipeParameter { + name: string; + displayName: string; + path: string; + type: DataValueType; + required: boolean; + sample?: unknown; } export interface DataRecipeResponse { @@ -39,9 +52,11 @@ export interface DataRecipePagination { export interface DataRecipeField { name: string; + displayName: string; path: string; - type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown"; + type: DataValueType; sample?: unknown; + description: string; } export interface CreateRecipeInput { @@ -50,6 +65,8 @@ export interface CreateRecipeInput { method: HttpMethod; query: JsonObject; body: unknown; + queryFields?: DataRecipeParameter[]; + bodyFields?: DataRecipeParameter[]; responseType: DataRecipeResponse["type"]; listPath: string; totalPath: string; @@ -70,7 +87,9 @@ export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { }, request: { query: input.query, - body: input.body ?? {} + body: input.body ?? {}, + queryFields: input.queryFields ?? inferParameters(input.query, "query"), + bodyFields: input.bodyFields ?? inferParameters(input.body, "body") }, response: { type: input.responseType, @@ -87,6 +106,31 @@ export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { }; } +export function inferParameters(value: unknown, rootPath: "query" | "body"): DataRecipeParameter[] { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return []; + } + + return Object.entries(value).slice(0, 50).map(([name, sample]) => ({ + name, + displayName: name, + path: `${rootPath}.${name}`, + type: inferDataValueType(sample), + required: false, + sample: simplifySample(sample) + })); +} + +export function inferDataValueType(value: unknown): DataValueType { + if (value === null) return "null"; + if (Array.isArray(value)) return "array"; + if (typeof value === "string") return "string"; + if (typeof value === "number") return "number"; + if (typeof value === "boolean") return "boolean"; + if (typeof value === "object") return "object"; + return "unknown"; +} + function buildRecipeName(apiUrl: string): string { try { const url = new URL(apiUrl); @@ -109,3 +153,15 @@ function normalizeName(value: string): string { return normalized || "data_source"; } + +function simplifySample(value: unknown): unknown { + if (Array.isArray(value)) { + return value.slice(0, 2); + } + + if (value && typeof value === "object") { + return Object.fromEntries(Object.entries(value).slice(0, 5)); + } + + return value; +} From 127e829d97152abe02f4564deeee35d3d66dcc69 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:41:40 +0800 Subject: [PATCH 09/25] feat: edit detected field labels --- apps/extension/public/sidepanel.css | 25 +++++++++++++++ apps/extension/src/sidepanel.ts | 50 +++++++++++++++++++++++------ 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 6d5f484..7026262 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -235,3 +235,28 @@ summary { display: grid; gap: 10px; } + +.field-editor { + display: grid; + gap: 8px; +} + +.field-row { + display: grid; + gap: 4px; +} + +.field-row input { + border: 1px solid #c9cdd4; + border-radius: 6px; + font: inherit; + min-height: 34px; + padding: 6px 8px; + width: 100%; +} + +.field-row span { + color: #6b7280; + font-size: 12px; + overflow-wrap: anywhere; +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index ea8e893..e39ef68 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -7,13 +7,15 @@ const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); const state: { snapshot: PanelSnapshot; selectedId: string | null; + fieldLabels: Record>; } = { snapshot: { tabId: null, state: "idle", captures: [] }, - selectedId: null + selectedId: null, + fieldLabels: {} }; const elements = { @@ -108,7 +110,7 @@ function renderDetail(): void { } const detection = summarizeResponse(capture.responseBody); - const recipe = buildRecipeFromCapture(capture); + const recipe = applyFieldLabels(capture.id, buildRecipeFromCapture(capture)); const runResult = runRecipeOnSample(recipe, capture.responseBody); elements.requestDetail.className = ""; @@ -137,6 +139,17 @@ function renderDetail(): void { ); } +function applyFieldLabels(recipeId: string, recipe: ReturnType): ReturnType { + const labels = state.fieldLabels[recipeId] ?? {}; + return { + ...recipe, + fields: recipe.fields.map((field) => ({ + ...field, + displayName: labels[field.path] ?? field.displayName, + description: labels[field.path] ? "用户确认" : field.description + })) + }; +} function parameterPreviewBlock(recipe: ReturnType): HTMLElement { const parameters = [...recipe.request.queryFields, ...recipe.request.bodyFields]; @@ -151,14 +164,35 @@ function parameterPreviewBlock(recipe: ReturnType } function fieldPreviewBlock(recipe: ReturnType): HTMLElement { - if (recipe.fields.length === 0) { + if (recipe.fields.length === 0 || !state.selectedId) { return block("返回字段", findingList(["暂未从当前数据中识别出稳定字段。"])); } - return block( - "返回字段", - findingList(recipe.fields.slice(0, 16).map((field) => `${field.displayName}:${field.type}${field.sample === undefined ? "" : `,样例 ${formatInlineValue(field.sample)}`}`)) - ); + const wrapper = document.createElement("div"); + wrapper.className = "field-editor"; + + recipe.fields.slice(0, 16).forEach((field) => { + const row = document.createElement("label"); + row.className = "field-row"; + + const input = document.createElement("input"); + input.value = field.displayName; + input.placeholder = field.name; + input.addEventListener("input", () => { + if (!state.selectedId) return; + const labels = state.fieldLabels[state.selectedId] ?? {}; + labels[field.path] = input.value.trim() || field.name; + state.fieldLabels[state.selectedId] = labels; + }); + + const meta = document.createElement("span"); + meta.textContent = `${field.name} · ${field.type}${field.sample === undefined ? "" : ` · 样例 ${formatInlineValue(field.sample)}`}`; + + row.append(input, meta); + wrapper.append(row); + }); + + return block("返回字段", wrapper); } function runPreviewBlock(runResult: ReturnType): HTMLElement { @@ -298,5 +332,3 @@ async function copyText(text: string, button: HTMLButtonElement): Promise }, 1600); } - - From e562bb0621486aad1f48d639d8ac0d2182b78204 Mon Sep 17 00:00:00 2001 From: return null Date: Wed, 1 Jul 2026 23:45:32 +0800 Subject: [PATCH 10/25] feat: persist edited field labels --- apps/extension/public/manifest.json | 3 ++- apps/extension/src/sidepanel.ts | 38 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json index 7496e3a..42df91c 100644 --- a/apps/extension/public/manifest.json +++ b/apps/extension/public/manifest.json @@ -19,7 +19,7 @@ "side_panel": { "default_path": "sidepanel.html" }, - "permissions": ["activeTab", "sidePanel", "tabs", "scripting"], + "permissions": ["activeTab", "sidePanel", "tabs", "scripting", "storage"], "host_permissions": [""], "web_accessible_resources": [ { @@ -28,3 +28,4 @@ } ] } + diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index e39ef68..d587386 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -2,6 +2,8 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import type { PanelEvent, PanelSnapshot } from "./messages"; +const FIELD_LABELS_STORAGE_KEY = "dataRecipeFieldLabels"; + const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); const state: { @@ -43,6 +45,7 @@ port.onMessage.addListener((event: PanelEvent) => { } }); +void loadFieldLabels(); port.postMessage({ type: "get-snapshot" }); function applySnapshot(snapshot: PanelSnapshot): void { @@ -110,7 +113,7 @@ function renderDetail(): void { } const detection = summarizeResponse(capture.responseBody); - const recipe = applyFieldLabels(capture.id, buildRecipeFromCapture(capture)); + const recipe = applyFieldLabels(capture.url, buildRecipeFromCapture(capture)); const runResult = runRecipeOnSample(recipe, capture.responseBody); elements.requestDetail.className = ""; @@ -179,10 +182,14 @@ function fieldPreviewBlock(recipe: ReturnType): H input.value = field.displayName; input.placeholder = field.name; input.addEventListener("input", () => { - if (!state.selectedId) return; - const labels = state.fieldLabels[state.selectedId] ?? {}; - labels[field.path] = input.value.trim() || field.name; - state.fieldLabels[state.selectedId] = labels; + const sourceKey = recipe.source.apiUrl; + const labels = state.fieldLabels[sourceKey] ?? {}; + const label = input.value.trim() || field.name; + labels[field.path] = label; + state.fieldLabels[sourceKey] = labels; + field.displayName = label; + field.description = "用户确认"; + void saveFieldLabels(); }); const meta = document.createElement("span"); @@ -302,6 +309,26 @@ function readableUrl(urlValue: string): string { } } +async function loadFieldLabels(): Promise { + try { + const stored = await chrome.storage.local.get(FIELD_LABELS_STORAGE_KEY); + const labels = stored[FIELD_LABELS_STORAGE_KEY]; + if (labels && typeof labels === "object" && !Array.isArray(labels)) { + state.fieldLabels = labels as Record>; + render(); + } + } catch { + // Local edits remain usable even if extension storage is unavailable. + } +} + +async function saveFieldLabels(): Promise { + try { + await chrome.storage.local.set({ [FIELD_LABELS_STORAGE_KEY]: state.fieldLabels }); + } catch { + // The current in-memory edit is still reflected in the copied draft. + } +} function formatInlineValue(value: unknown): string { const text = typeof value === "string" ? value : JSON.stringify(value); if (!text) { @@ -332,3 +359,4 @@ async function copyText(text: string, button: HTMLButtonElement): Promise }, 1600); } + From 61ecb3f3acfe1b7d63d2ef5efd47e337cd642fa0 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:10:03 +0800 Subject: [PATCH 11/25] feat: edit data skill metadata --- apps/extension/public/sidepanel.css | 30 ++++++++++ apps/extension/src/sidepanel.ts | 90 +++++++++++++++++++++++++---- packages/recipe-core/src/index.ts | 5 ++ 3 files changed, 113 insertions(+), 12 deletions(-) diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 7026262..67b79e3 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -260,3 +260,33 @@ summary { font-size: 12px; overflow-wrap: anywhere; } + +.skill-editor { + display: grid; + gap: 10px; +} + +.skill-field { + display: grid; + gap: 5px; +} + +.skill-field span { + color: #6b7280; + font-size: 12px; + font-weight: 600; +} + +.skill-field input, +.skill-field textarea { + border: 1px solid #c9cdd4; + border-radius: 6px; + font: inherit; + padding: 7px 8px; + width: 100%; +} + +.skill-field textarea { + line-height: 1.45; + resize: vertical; +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index d587386..6e74d2c 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -2,7 +2,13 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import type { PanelEvent, PanelSnapshot } from "./messages"; +interface RecipeMetadata { + displayName?: string; + description?: string; + useCases?: string[]; +} const FIELD_LABELS_STORAGE_KEY = "dataRecipeFieldLabels"; +const RECIPE_META_STORAGE_KEY = "dataRecipeMetadata"; const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); @@ -10,6 +16,7 @@ const state: { snapshot: PanelSnapshot; selectedId: string | null; fieldLabels: Record>; + recipeMetadata: Record; } = { snapshot: { tabId: null, @@ -17,7 +24,8 @@ const state: { captures: [] }, selectedId: null, - fieldLabels: {} + fieldLabels: {}, + recipeMetadata: {} }; const elements = { @@ -45,7 +53,7 @@ port.onMessage.addListener((event: PanelEvent) => { } }); -void loadFieldLabels(); +void loadStoredEdits(); port.postMessage({ type: "get-snapshot" }); function applySnapshot(snapshot: PanelSnapshot): void { @@ -113,7 +121,7 @@ function renderDetail(): void { } const detection = summarizeResponse(capture.responseBody); - const recipe = applyFieldLabels(capture.url, buildRecipeFromCapture(capture)); + const recipe = applyRecipeEdits(capture.url, buildRecipeFromCapture(capture)); const runResult = runRecipeOnSample(recipe, capture.responseBody); elements.requestDetail.className = ""; @@ -136,16 +144,21 @@ function renderDetail(): void { parameterPreviewBlock(recipe), fieldPreviewBlock(recipe), block("返回预览", pre(capture.responsePreview || "无可展示内容")), + recipeMetadataBlock(recipe), recipeDraftBlock(recipe), runPreviewBlock(runResult), advancedInfo(capture, recipe) ); } -function applyFieldLabels(recipeId: string, recipe: ReturnType): ReturnType { - const labels = state.fieldLabels[recipeId] ?? {}; +function applyRecipeEdits(sourceKey: string, recipe: ReturnType): ReturnType { + const labels = state.fieldLabels[sourceKey] ?? {}; + const metadata = state.recipeMetadata[sourceKey]; return { ...recipe, + displayName: metadata?.displayName ?? recipe.displayName, + description: metadata?.description ?? recipe.description, + useCases: metadata?.useCases?.length ? metadata.useCases : recipe.useCases, fields: recipe.fields.map((field) => ({ ...field, displayName: labels[field.path] ?? field.displayName, @@ -189,7 +202,7 @@ function fieldPreviewBlock(recipe: ReturnType): H state.fieldLabels[sourceKey] = labels; field.displayName = label; field.description = "用户确认"; - void saveFieldLabels(); + void saveStoredEdits(); }); const meta = document.createElement("span"); @@ -202,6 +215,46 @@ function fieldPreviewBlock(recipe: ReturnType): H return block("返回字段", wrapper); } +function recipeMetadataBlock(recipe: ReturnType): HTMLElement { + const wrapper = document.createElement("div"); + wrapper.className = "skill-editor"; + + const nameLabel = document.createElement("label"); + nameLabel.className = "skill-field"; + const nameTitle = document.createElement("span"); + nameTitle.textContent = "数据技能名称"; + const nameInput = document.createElement("input"); + nameInput.value = recipe.displayName; + nameInput.addEventListener("input", () => { + const metadata = state.recipeMetadata[recipe.source.apiUrl] ?? {}; + metadata.displayName = nameInput.value.trim() || "数据来源"; + state.recipeMetadata[recipe.source.apiUrl] = metadata; + recipe.displayName = metadata.displayName; + void saveStoredEdits(); + }); + nameLabel.append(nameTitle, nameInput); + + const descriptionLabel = document.createElement("label"); + descriptionLabel.className = "skill-field"; + const descriptionTitle = document.createElement("span"); + descriptionTitle.textContent = "用途说明"; + const descriptionInput = document.createElement("textarea"); + descriptionInput.rows = 3; + descriptionInput.value = recipe.description; + descriptionInput.addEventListener("input", () => { + const metadata = state.recipeMetadata[recipe.source.apiUrl] ?? {}; + metadata.description = descriptionInput.value.trim(); + metadata.useCases = splitUseCases(descriptionInput.value); + state.recipeMetadata[recipe.source.apiUrl] = metadata; + recipe.description = metadata.description ?? ""; + recipe.useCases = metadata.useCases ?? []; + void saveStoredEdits(); + }); + descriptionLabel.append(descriptionTitle, descriptionInput); + + wrapper.append(nameLabel, descriptionLabel); + return block("数据技能信息", wrapper); +} function runPreviewBlock(runResult: ReturnType): HTMLElement { const wrapper = document.createElement("div"); wrapper.className = "run-preview"; @@ -309,26 +362,40 @@ function readableUrl(urlValue: string): string { } } -async function loadFieldLabels(): Promise { +async function loadStoredEdits(): Promise { try { - const stored = await chrome.storage.local.get(FIELD_LABELS_STORAGE_KEY); + const stored = await chrome.storage.local.get([FIELD_LABELS_STORAGE_KEY, RECIPE_META_STORAGE_KEY]); const labels = stored[FIELD_LABELS_STORAGE_KEY]; + const metadata = stored[RECIPE_META_STORAGE_KEY]; if (labels && typeof labels === "object" && !Array.isArray(labels)) { state.fieldLabels = labels as Record>; - render(); } + if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) { + state.recipeMetadata = metadata as Record; + } + render(); } catch { // Local edits remain usable even if extension storage is unavailable. } } -async function saveFieldLabels(): Promise { +async function saveStoredEdits(): Promise { try { - await chrome.storage.local.set({ [FIELD_LABELS_STORAGE_KEY]: state.fieldLabels }); + await chrome.storage.local.set({ + [FIELD_LABELS_STORAGE_KEY]: state.fieldLabels, + [RECIPE_META_STORAGE_KEY]: state.recipeMetadata + }); } catch { // The current in-memory edit is still reflected in the copied draft. } } +function splitUseCases(value: string): string[] { + return value + .split(/[\n,,;;]+/) + .map((item) => item.trim()) + .filter(Boolean) + .slice(0, 8); +} function formatInlineValue(value: unknown): string { const text = typeof value === "string" ? value : JSON.stringify(value); if (!text) { @@ -359,4 +426,3 @@ async function copyText(text: string, button: HTMLButtonElement): Promise }, 1600); } - diff --git a/packages/recipe-core/src/index.ts b/packages/recipe-core/src/index.ts index fcbf40a..ec2de60 100644 --- a/packages/recipe-core/src/index.ts +++ b/packages/recipe-core/src/index.ts @@ -7,6 +7,8 @@ export type DataValueType = "string" | "number" | "boolean" | "object" | "array" export interface DataRecipe { name: string; displayName: string; + description: string; + useCases: string[]; source: DataRecipeSource; request: DataRecipeRequest; response: DataRecipeResponse; @@ -79,6 +81,8 @@ export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { return { name, displayName: "数据来源", + description: "用于获取和预览这个数据来源中的列表数据。", + useCases: ["查看数据明细", "汇总和分析列表数据"], source: { type: "web_api", pageUrl: input.pageUrl, @@ -165,3 +169,4 @@ function simplifySample(value: unknown): unknown { return value; } + From be560afaf4e3f86f1362643add8abb26d1aeee3f Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:10:15 +0800 Subject: [PATCH 12/25] feat: add data skill package builder --- packages/skill-builder/package.json | 21 +++++++++++ packages/skill-builder/src/index.ts | 53 ++++++++++++++++++++++++++++ packages/skill-builder/tsconfig.json | 12 +++++++ pnpm-lock.yaml | 6 ++++ 4 files changed, 92 insertions(+) create mode 100644 packages/skill-builder/package.json create mode 100644 packages/skill-builder/src/index.ts create mode 100644 packages/skill-builder/tsconfig.json diff --git a/packages/skill-builder/package.json b/packages/skill-builder/package.json new file mode 100644 index 0000000..d4bd030 --- /dev/null +++ b/packages/skill-builder/package.json @@ -0,0 +1,21 @@ +{ + "name": "@data-recipe/skill-builder", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + }, + "scripts": { + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + }, + "dependencies": { + "@data-recipe/recipe-core": "workspace:*" + } +} diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts new file mode 100644 index 0000000..26eded1 --- /dev/null +++ b/packages/skill-builder/src/index.ts @@ -0,0 +1,53 @@ +import type { DataRecipe } from "@data-recipe/recipe-core"; + +export interface DataSkillPackage { + packageName: string; + files: DataSkillPackageFile[]; +} + +export interface DataSkillPackageFile { + path: "SKILL.md" | "recipe.json" | "examples.md" | "README.md"; + content: string; +} + +export interface BuildDataSkillPackageInput { + recipe: DataRecipe; + userGoal?: string; +} + +export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSkillPackage { + const packageName = input.recipe.name || "data-skill"; + const goal = input.userGoal?.trim() || input.recipe.description; + + return { + packageName, + files: [ + { path: "SKILL.md", content: buildSkillMarkdown(input.recipe, goal) }, + { path: "recipe.json", content: `${JSON.stringify(input.recipe, null, 2)}\n` }, + { path: "examples.md", content: buildExamplesMarkdown(input.recipe, goal) }, + { path: "README.md", content: buildReadmeMarkdown(input.recipe, goal) } + ] + }; +} + +function buildSkillMarkdown(recipe: DataRecipe, goal: string): string { + const fields = recipe.fields.length + ? recipe.fields.map((field) => `- ${field.displayName} (${field.name}): ${field.description}`).join("\n") + : "- 暂未确认返回字段。"; + const queryFields = [...recipe.request.queryFields, ...recipe.request.bodyFields]; + const queries = queryFields.length + ? queryFields.map((field) => `- ${field.displayName} (${field.name})`).join("\n") + : "- 当前数据来源没有明确的查询条件。"; + + return `# ${recipe.displayName}\n\n## 适合完成的任务\n\n${goal}\n\n## 数据来源\n\n这个技能会从用户已授权访问的页面数据来源读取数据。\n\n## 查询条件\n\n${queries}\n\n## 返回字段\n\n${fields}\n\n## 使用限制\n\n- 只用于用户有权访问的数据。\n- 不用于绕过登录、验证码、风控或访问限制。\n- 运行前应先用 recipe.json 测试数据预览是否正常。\n`; +} + +function buildExamplesMarkdown(recipe: DataRecipe, goal: string): string { + const firstUseCase = recipe.useCases[0] ?? goal; + + return `# 示例\n\n## 示例问题\n\n- 请根据「${recipe.displayName}」查看最新数据。\n- 请基于这些数据完成:${firstUseCase}\n\n## 示例输出\n\n系统会先测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。\n`; +} + +function buildReadmeMarkdown(recipe: DataRecipe, goal: string): string { + return `# ${recipe.displayName}\n\n${goal}\n\n## 包含文件\n\n- SKILL.md: 给 AI Agent 使用的技能说明。\n- recipe.json: 可测试运行的数据配方。\n- examples.md: 示例问题和示例输出。\n- README.md: 给人看的说明。\n\n## 验证方式\n\n用 recipe.json 进行测试运行,并确认可以读取预期数据。\n`; +} diff --git a/packages/skill-builder/tsconfig.json b/packages/skill-builder/tsconfig.json new file mode 100644 index 0000000..334c4e4 --- /dev/null +++ b/packages/skill-builder/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"], + "references": [{ "path": "../recipe-core" }] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ecc830..581da6b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,12 @@ importers: specifier: workspace:* version: link:../recipe-core + packages/skill-builder: + dependencies: + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../recipe-core + packages: '@esbuild/aix-ppc64@0.27.7': From 8ab19fe9dc9aee9282625ff3812f93631742f3f1 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:13:35 +0800 Subject: [PATCH 13/25] feat: preview data skill package in side panel --- apps/extension/package.json | 3 +- apps/extension/public/sidepanel.css | 11 ++++++++ apps/extension/src/sidepanel.ts | 43 +++++++++++++++++++++++++++++ pnpm-lock.yaml | 3 ++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/apps/extension/package.json b/apps/extension/package.json index b720d82..463aa86 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -12,7 +12,8 @@ "dependencies": { "@data-recipe/detector": "workspace:*", "@data-recipe/recipe-core": "workspace:*", - "@data-recipe/recipe-runner": "workspace:*" + "@data-recipe/recipe-runner": "workspace:*", + "@data-recipe/skill-builder": "workspace:*" }, "devDependencies": { "rimraf": "^6.0.1" diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 67b79e3..742f00e 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -290,3 +290,14 @@ summary { line-height: 1.45; resize: vertical; } + +.skill-package { + display: grid; + gap: 10px; +} + +.package-actions { + display: flex; + flex-wrap: wrap; + gap: 8px; +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index 6e74d2c..fde8dd8 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,5 +1,6 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; import { runRecipeOnSample } from "@data-recipe/recipe-runner"; +import { buildDataSkillPackage, type DataSkillPackage } from "@data-recipe/skill-builder"; import type { PanelEvent, PanelSnapshot } from "./messages"; interface RecipeMetadata { @@ -123,6 +124,7 @@ function renderDetail(): void { const detection = summarizeResponse(capture.responseBody); const recipe = applyRecipeEdits(capture.url, buildRecipeFromCapture(capture)); const runResult = runRecipeOnSample(recipe, capture.responseBody); + const skillPackage = buildDataSkillPackage({ recipe, userGoal: recipe.description }); elements.requestDetail.className = ""; elements.requestDetail.innerHTML = ""; @@ -146,6 +148,7 @@ function renderDetail(): void { block("返回预览", pre(capture.responsePreview || "无可展示内容")), recipeMetadataBlock(recipe), recipeDraftBlock(recipe), + skillPackageBlock(skillPackage), runPreviewBlock(runResult), advancedInfo(capture, recipe) ); @@ -255,6 +258,46 @@ function recipeMetadataBlock(recipe: ReturnType): wrapper.append(nameLabel, descriptionLabel); return block("数据技能信息", wrapper); } +function skillPackageBlock(skillPackage: DataSkillPackage): HTMLElement { + const wrapper = document.createElement("div"); + wrapper.className = "skill-package"; + + const summary = document.createElement("div"); + summary.className = "finding"; + summary.textContent = `已生成 ${skillPackage.files.length} 个文件:${skillPackage.files.map((file) => file.path).join("、")}`; + + const actions = document.createElement("div"); + actions.className = "package-actions"; + + const skillFile = skillPackage.files.find((file) => file.path === "SKILL.md"); + const recipeFile = skillPackage.files.find((file) => file.path === "recipe.json"); + + if (skillFile) { + actions.append(copyContentButton("复制 SKILL.md", skillFile.content)); + } + if (recipeFile) { + actions.append(copyContentButton("复制 recipe.json", recipeFile.content)); + } + + const details = document.createElement("details"); + const detailsSummary = document.createElement("summary"); + detailsSummary.textContent = "预览 SKILL.md"; + details.append(detailsSummary, pre(skillFile?.content ?? "暂未生成 SKILL.md")); + + wrapper.append(summary, actions, details); + return block("技能包预览", wrapper); +} + +function copyContentButton(label: string, content: string): HTMLButtonElement { + const button = document.createElement("button"); + button.type = "button"; + button.className = "copy-button"; + button.textContent = label; + button.addEventListener("click", () => { + void copyText(content, button); + }); + return button; +} function runPreviewBlock(runResult: ReturnType): HTMLElement { const wrapper = document.createElement("div"); wrapper.className = "run-preview"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 581da6b..80c59bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@data-recipe/recipe-runner': specifier: workspace:* version: link:../../packages/recipe-runner + '@data-recipe/skill-builder': + specifier: workspace:* + version: link:../../packages/skill-builder devDependencies: rimraf: specifier: ^6.0.1 From 658a65226109740094963b57438751af83fece2f Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:16:57 +0800 Subject: [PATCH 14/25] feat: add data skill package exporter --- packages/skill-exporter/package.json | 21 +++++++++++++++++++++ packages/skill-exporter/src/index.ts | 25 +++++++++++++++++++++++++ packages/skill-exporter/tsconfig.json | 12 ++++++++++++ pnpm-lock.yaml | 9 +++++++++ 4 files changed, 67 insertions(+) create mode 100644 packages/skill-exporter/package.json create mode 100644 packages/skill-exporter/src/index.ts create mode 100644 packages/skill-exporter/tsconfig.json diff --git a/packages/skill-exporter/package.json b/packages/skill-exporter/package.json new file mode 100644 index 0000000..789ae50 --- /dev/null +++ b/packages/skill-exporter/package.json @@ -0,0 +1,21 @@ +{ + "name": "@data-recipe/skill-exporter", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + }, + "scripts": { + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + }, + "dependencies": { + "@data-recipe/skill-builder": "workspace:*" + } +} diff --git a/packages/skill-exporter/src/index.ts b/packages/skill-exporter/src/index.ts new file mode 100644 index 0000000..b6e86e0 --- /dev/null +++ b/packages/skill-exporter/src/index.ts @@ -0,0 +1,25 @@ +import type { DataSkillPackage } from "@data-recipe/skill-builder"; + +export interface ExportedDataSkillPackage { + fileName: string; + mimeType: "application/json"; + content: string; +} + +export function exportDataSkillPackageAsJson(skillPackage: DataSkillPackage): ExportedDataSkillPackage { + const safeName = normalizeFileName(skillPackage.packageName || "data-skill"); + return { + fileName: `${safeName}.data-skill.json`, + mimeType: "application/json", + content: `${JSON.stringify(skillPackage, null, 2)}\n` + }; +} + +function normalizeFileName(value: string): string { + const normalized = value + .toLowerCase() + .replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-") + .replace(/^-+|-+$/g, ""); + + return normalized || "data-skill"; +} diff --git a/packages/skill-exporter/tsconfig.json b/packages/skill-exporter/tsconfig.json new file mode 100644 index 0000000..ead34fc --- /dev/null +++ b/packages/skill-exporter/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"], + "references": [{ "path": "../skill-builder" }] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80c59bf..4bad535 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: '@data-recipe/skill-builder': specifier: workspace:* version: link:../../packages/skill-builder + '@data-recipe/skill-exporter': + specifier: workspace:* + version: link:../../packages/skill-exporter devDependencies: rimraf: specifier: ^6.0.1 @@ -57,6 +60,12 @@ importers: specifier: workspace:* version: link:../recipe-core + packages/skill-exporter: + dependencies: + '@data-recipe/skill-builder': + specifier: workspace:* + version: link:../skill-builder + packages: '@esbuild/aix-ppc64@0.27.7': From 252a997ffa398bb610b65af994fe1f1ab39be3de Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:17:14 +0800 Subject: [PATCH 15/25] feat: export data skill package from side panel --- apps/extension/package.json | 3 ++- apps/extension/src/sidepanel.ts | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/extension/package.json b/apps/extension/package.json index 463aa86..b83205c 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -13,7 +13,8 @@ "@data-recipe/detector": "workspace:*", "@data-recipe/recipe-core": "workspace:*", "@data-recipe/recipe-runner": "workspace:*", - "@data-recipe/skill-builder": "workspace:*" + "@data-recipe/skill-builder": "workspace:*", + "@data-recipe/skill-exporter": "workspace:*" }, "devDependencies": { "rimraf": "^6.0.1" diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index fde8dd8..a3a18b7 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,6 +1,7 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import { buildDataSkillPackage, type DataSkillPackage } from "@data-recipe/skill-builder"; +import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; import type { PanelEvent, PanelSnapshot } from "./messages"; interface RecipeMetadata { @@ -288,6 +289,26 @@ function skillPackageBlock(skillPackage: DataSkillPackage): HTMLElement { return block("技能包预览", wrapper); } +function exportPackageButton(skillPackage: DataSkillPackage): HTMLButtonElement { + const button = document.createElement("button"); + button.type = "button"; + button.className = "primary"; + button.textContent = "导出技能包"; + button.addEventListener("click", () => { + downloadTextFile(exportDataSkillPackageAsJson(skillPackage)); + }); + return button; +} + +function downloadTextFile(file: ReturnType): void { + const blob = new Blob([file.content], { type: file.mimeType }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = file.fileName; + link.click(); + URL.revokeObjectURL(url); +} function copyContentButton(label: string, content: string): HTMLButtonElement { const button = document.createElement("button"); button.type = "button"; From fc64a04e5ea5833f4cb14c3c11daa2f1324cdc9d Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:29:01 +0800 Subject: [PATCH 16/25] feat: validate exported data skill packages --- apps/extension/src/sidepanel.ts | 9 +++++++-- packages/skill-exporter/src/index.ts | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index a3a18b7..3ff6fb4 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,7 +1,7 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import { buildDataSkillPackage, type DataSkillPackage } from "@data-recipe/skill-builder"; -import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; +import { exportDataSkillPackageAsJson, validateDataSkillPackage } from "@data-recipe/skill-exporter"; import type { PanelEvent, PanelSnapshot } from "./messages"; interface RecipeMetadata { @@ -263,9 +263,12 @@ function skillPackageBlock(skillPackage: DataSkillPackage): HTMLElement { const wrapper = document.createElement("div"); wrapper.className = "skill-package"; + const validation = validateDataSkillPackage(skillPackage); const summary = document.createElement("div"); summary.className = "finding"; - summary.textContent = `已生成 ${skillPackage.files.length} 个文件:${skillPackage.files.map((file) => file.path).join("、")}`; + summary.textContent = validation.ok + ? `已生成 ${skillPackage.files.length} 个文件,技能包可以导出。` + : `技能包还缺少:${validation.missingFiles.join("、")}`; const actions = document.createElement("div"); actions.className = "package-actions"; @@ -273,6 +276,8 @@ function skillPackageBlock(skillPackage: DataSkillPackage): HTMLElement { const skillFile = skillPackage.files.find((file) => file.path === "SKILL.md"); const recipeFile = skillPackage.files.find((file) => file.path === "recipe.json"); + actions.append(exportPackageButton(skillPackage)); + if (skillFile) { actions.append(copyContentButton("复制 SKILL.md", skillFile.content)); } diff --git a/packages/skill-exporter/src/index.ts b/packages/skill-exporter/src/index.ts index b6e86e0..b37a1ea 100644 --- a/packages/skill-exporter/src/index.ts +++ b/packages/skill-exporter/src/index.ts @@ -1,5 +1,21 @@ import type { DataSkillPackage } from "@data-recipe/skill-builder"; +export interface DataSkillPackageValidation { + ok: boolean; + missingFiles: string[]; +} + +const REQUIRED_FILES = ["SKILL.md", "recipe.json", "examples.md", "README.md"] as const; + +export function validateDataSkillPackage(skillPackage: DataSkillPackage): DataSkillPackageValidation { + const existing = new Set(skillPackage.files.map((file) => file.path)); + const missingFiles = REQUIRED_FILES.filter((file) => !existing.has(file)); + + return { + ok: missingFiles.length === 0, + missingFiles + }; +} export interface ExportedDataSkillPackage { fileName: string; mimeType: "application/json"; @@ -23,3 +39,4 @@ function normalizeFileName(value: string): string { return normalized || "data-skill"; } + From db9881be0d73e33977127b448c275e14eee9c272 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 00:31:49 +0800 Subject: [PATCH 17/25] docs: document data skill package export --- README.en.md | 33 +++++++++++++++++++++++++++++++++ README.md | 3 ++- README.zh-CN.md | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/README.en.md b/README.en.md index 2fa45de..bef73ba 100644 --- a/README.en.md +++ b/README.en.md @@ -191,3 +191,36 @@ pnpm dev:extension ``` This watches and rebuilds `apps/extension/dist`. Refresh the unpacked extension in Chrome before testing updated code. + +### Export a Data Skill Package + +After one discovery flow, use the side panel to: + +1. Fill in the data skill name and purpose; +2. Confirm or rename returned fields; +3. Check "试运行结果" to confirm data can be read; +4. Check "技能包预览" to confirm required files are present; +5. Click "导出技能包". + +The current MVP downloads a `.data-skill.json` file. This is a temporary text package format containing: + +```text +packageName +files[] + SKILL.md + recipe.json + examples.md + README.md +``` + +A later version can export a real folder or zip. For now, the JSON text package validates the generate, test, and export loop. + +### Data Skill Package acceptance checks + +An exported package should at least: + +* Include `SKILL.md`, `recipe.json`, `examples.md`, and `README.md`; +* Use `SKILL.md` to explain what the data skill is useful for; +* Use `recipe.json` to hold the data source, query inputs, returned fields, and test-run information; +* Show a data preview in the side panel test-run result; +* Show no missing required files before export. diff --git a/README.md b/README.md index 73c51b8..87b19af 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,5 @@ pnpm install pnpm build:extension ``` -Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, open the DataRecipe side panel, click "开始发现", and trigger the fetch or XHR test request. +Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, open the DataRecipe side panel, click "开始发现", trigger the fetch or XHR test request, then confirm the generated Data Skill Package and export the `.data-skill.json` file. + diff --git a/README.zh-CN.md b/README.zh-CN.md index 2c688f7..d4bc3b8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -184,3 +184,36 @@ pnpm dev:extension ``` 该命令会监听并重新构建 `apps/extension/dist`。Chrome 扩展页面中需要手动点击刷新插件后再验证最新代码。 + +### 导出 Data Skill Package + +完成一次发现后,可以在侧边栏中: + +1. 为数据技能填写名称和用途说明; +2. 确认或修改返回字段名称; +3. 查看「试运行结果」确认能读取数据; +4. 在「技能包预览」中确认已包含必需文件; +5. 点击「导出技能包」。 + +当前 MVP 会下载一个 `.data-skill.json` 文件。它是临时的文本包格式,里面包含: + +```text +packageName +files[] + SKILL.md + recipe.json + examples.md + README.md +``` + +后续会把这个导出格式升级为真实文件夹或 zip。当前阶段先用 JSON 文本包验证「可生成、可测试、可导出」的闭环。 + +### Data Skill Package 验收点 + +导出的技能包至少应满足: + +* 包含 `SKILL.md`、`recipe.json`、`examples.md`、`README.md`; +* `SKILL.md` 能说明这个数据技能适合完成什么任务; +* `recipe.json` 包含数据来源、查询条件、返回字段和测试运行所需信息; +* 侧边栏「试运行结果」可以展示数据预览; +* 导出前没有提示缺少必需文件。 From 31572386507520218434be6e03cbdddbed29b5ad Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 2 Jul 2026 07:53:37 +0800 Subject: [PATCH 18/25] feat: validate exported skill packages --- README.en.md | 10 +++++ README.md | 6 +++ README.zh-CN.md | 10 +++++ package.json | 3 +- packages/skill-exporter/src/index.ts | 49 +++++++++++++++++++++---- scripts/validate-data-skill-package.mjs | 42 +++++++++++++++++++++ 6 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 scripts/validate-data-skill-package.mjs diff --git a/README.en.md b/README.en.md index bef73ba..e9f96eb 100644 --- a/README.en.md +++ b/README.en.md @@ -224,3 +224,13 @@ An exported package should at least: * Use `recipe.json` to hold the data source, query inputs, returned fields, and test-run information; * Show a data preview in the side panel test-run result; * Show no missing required files before export. + +### Validate an exported skill package + +After exporting a `.data-skill.json` file, run: + +```bash +pnpm validate:skill-package path/to/your.data-skill.json +``` + +The command checks that all four required files are present and non-empty. It exits with a non-zero status when the package is invalid, so it can be used in later automated checks. diff --git a/README.md b/README.md index 87b19af..6ba2d69 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,9 @@ pnpm build:extension Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, open the DataRecipe side panel, click "开始发现", trigger the fetch or XHR test request, then confirm the generated Data Skill Package and export the `.data-skill.json` file. + +## Validate an exported skill package + +```bash +pnpm validate:skill-package path/to/your.data-skill.json +``` diff --git a/README.zh-CN.md b/README.zh-CN.md index d4bc3b8..d54a4c2 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -217,3 +217,13 @@ files[] * `recipe.json` 包含数据来源、查询条件、返回字段和测试运行所需信息; * 侧边栏「试运行结果」可以展示数据预览; * 导出前没有提示缺少必需文件。 + +### 校验导出的技能包 + +导出 `.data-skill.json` 后,可以用下面的命令检查它是否包含四个必需文件,并确认文件内容不为空: + +```bash +pnpm validate:skill-package path/to/your.data-skill.json +``` + +校验通过时会输出技能包名称和文件列表;缺少文件或文件为空时会返回非零退出码,便于后续接入自动化验收。 diff --git a/package.json b/package.json index 0a5a26f..ba199e6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "pnpm -r build", "typecheck": "pnpm -r typecheck", "dev:extension": "pnpm --filter @data-recipe/extension dev", - "build:extension": "pnpm --filter @data-recipe/extension build" + "build:extension": "pnpm --filter @data-recipe/extension build", + "validate:skill-package": "node scripts/validate-data-skill-package.mjs" }, "devDependencies": { "@types/chrome": "^0.0.268", diff --git a/packages/skill-exporter/src/index.ts b/packages/skill-exporter/src/index.ts index b37a1ea..0f02b00 100644 --- a/packages/skill-exporter/src/index.ts +++ b/packages/skill-exporter/src/index.ts @@ -3,6 +3,13 @@ import type { DataSkillPackage } from "@data-recipe/skill-builder"; export interface DataSkillPackageValidation { ok: boolean; missingFiles: string[]; + errors: string[]; +} + +export interface ExportedDataSkillPackage { + fileName: string; + mimeType: "application/json"; + content: string; } const REQUIRED_FILES = ["SKILL.md", "recipe.json", "examples.md", "README.md"] as const; @@ -10,16 +17,45 @@ const REQUIRED_FILES = ["SKILL.md", "recipe.json", "examples.md", "README.md"] a export function validateDataSkillPackage(skillPackage: DataSkillPackage): DataSkillPackageValidation { const existing = new Set(skillPackage.files.map((file) => file.path)); const missingFiles = REQUIRED_FILES.filter((file) => !existing.has(file)); + const errors: string[] = []; + + if (!skillPackage.packageName.trim()) { + errors.push("packageName is required"); + } + + skillPackage.files.forEach((file) => { + if (!file.content.trim()) { + errors.push(`${file.path} is empty`); + } + }); return { - ok: missingFiles.length === 0, - missingFiles + ok: missingFiles.length === 0 && errors.length === 0, + missingFiles, + errors }; } -export interface ExportedDataSkillPackage { - fileName: string; - mimeType: "application/json"; - content: string; + +export function validateExportedDataSkillPackageJson(content: string): DataSkillPackageValidation { + try { + const parsed = JSON.parse(content) as DataSkillPackage; + + if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.files)) { + return { + ok: false, + missingFiles: [...REQUIRED_FILES], + errors: ["exported package must contain a files array"] + }; + } + + return validateDataSkillPackage(parsed); + } catch { + return { + ok: false, + missingFiles: [...REQUIRED_FILES], + errors: ["exported package is not valid JSON"] + }; + } } export function exportDataSkillPackageAsJson(skillPackage: DataSkillPackage): ExportedDataSkillPackage { @@ -39,4 +75,3 @@ function normalizeFileName(value: string): string { return normalized || "data-skill"; } - diff --git a/scripts/validate-data-skill-package.mjs b/scripts/validate-data-skill-package.mjs new file mode 100644 index 0000000..9b49d50 --- /dev/null +++ b/scripts/validate-data-skill-package.mjs @@ -0,0 +1,42 @@ +import { readFile } from "node:fs/promises"; + +const requiredFiles = ["SKILL.md", "recipe.json", "examples.md", "README.md"]; +const filePath = process.argv[2]; + +if (!filePath) { + console.error("Usage: pnpm validate:skill-package "); + process.exit(1); +} + +let parsed; +try { + parsed = JSON.parse(await readFile(filePath, "utf8")); +} catch (error) { + console.error(`Invalid JSON package: ${error instanceof Error ? error.message : String(error)}`); + process.exit(1); +} + +const files = Array.isArray(parsed.files) ? parsed.files : []; +const existing = new Set(files.map((file) => file?.path)); +const missing = requiredFiles.filter((file) => !existing.has(file)); +const empty = files + .filter((file) => typeof file?.content !== "string" || file.content.trim() === "") + .map((file) => file?.path ?? "(unknown)"); + +if (typeof parsed.packageName !== "string" || parsed.packageName.trim() === "") { + console.error("Invalid package: packageName is required."); + process.exit(1); +} + +if (missing.length > 0 || empty.length > 0) { + if (missing.length > 0) { + console.error(`Missing files: ${missing.join(", ")}`); + } + if (empty.length > 0) { + console.error(`Empty files: ${empty.join(", ")}`); + } + process.exit(1); +} + +console.log(`Valid Data Skill Package: ${parsed.packageName}`); +console.log(`Files: ${requiredFiles.join(", ")}`); From 03e32376605bb30cdb08d872ad10f5ec02985912 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 9 Jul 2026 22:50:04 +0800 Subject: [PATCH 19/25] feat: add browser RPC core package and enhance runtime architecture documentation --- README.en.md | 23 +++++- README.md | 9 +++ README.zh-CN.md | 23 +++++- packages/browser-rpc-core/package.json | 21 ++++++ packages/browser-rpc-core/src/index.ts | 96 +++++++++++++++++++++++++ packages/browser-rpc-core/tsconfig.json | 14 ++++ packages/detector/src/index.ts | 32 +++++++-- packages/recipe-core/src/index.ts | 47 ++++++++++-- packages/skill-builder/src/index.ts | 18 ++++- pnpm-lock.yaml | 24 ++++--- tsconfig.base.json | 3 + 11 files changed, 285 insertions(+), 25 deletions(-) create mode 100644 packages/browser-rpc-core/package.json create mode 100644 packages/browser-rpc-core/src/index.ts create mode 100644 packages/browser-rpc-core/tsconfig.json diff --git a/README.en.md b/README.en.md index e9f96eb..ebb503d 100644 --- a/README.en.md +++ b/README.en.md @@ -129,10 +129,12 @@ data-recipe/ ├── apps/ │ └── extension/ # Browser sidebar extension ├── packages/ +│ ├── browser-rpc-core/ # Browser RPC Bridge protocol types │ ├── detector/ # API request detection │ ├── recipe-core/ # Core Data Recipe model │ ├── recipe-runner/ # Recipe runtime -│ └── recipe-exporter/ # MCP / OpenAPI / JSON exporter +│ ├── skill-builder/ # Data Skill Package generation +│ └── skill-exporter/ # Data Skill Package export ├── docs/ │ ├── vision.md │ ├── data-recipe-spec.md @@ -234,3 +236,22 @@ pnpm validate:skill-package path/to/your.data-skill.json ``` The command checks that all four required files are present and non-empty. It exits with a non-zero status when the package is invalid, so it can be used in later automated checks. + +## Long-term Runtime Architecture + +DataRecipe's long-term execution path is: + +```text +Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +``` + +Meaning: + +* `Data Skill Package` stores the recipe, skill instructions, and examples; +* `recipe-runner` interprets the recipe and does not hold user login credentials; +* `Browser RPC Bridge` is a constrained protocol layer that forwards explicit run requests to the browser extension; +* `Chrome Extension` executes requests inside the user's authorized browser session; +* `authorized browser session` means a page session the user has already logged into and is allowed to access. + +This architecture does not expose Cookie, Authorization header, or other sensitive credentials to AI agents, and it is not an arbitrary request proxy. The project will not implement bypasses for login, captchas, risk controls, dynamic signatures, or anti-bot systems. + diff --git a/README.md b/README.md index 6ba2d69..390ef34 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,12 @@ Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-p ```bash pnpm validate:skill-package path/to/your.data-skill.json ``` + +## Runtime architecture + +```text +Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +``` + +The Browser RPC Bridge is a constrained runtime protocol for running a recipe inside the user's authorized Chrome session. It must not expose Cookie or Authorization headers to AI agents, must not become an arbitrary request proxy, and must not bypass login, captchas, risk controls, dynamic signatures, or anti-bot systems. + diff --git a/README.zh-CN.md b/README.zh-CN.md index d54a4c2..48c857d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -122,10 +122,12 @@ data-recipe/ ├── apps/ │ └── extension/ # 浏览器侧边栏插件 ├── packages/ +│ ├── browser-rpc-core/ # Browser RPC Bridge 协议类型 │ ├── detector/ # API 请求探测 │ ├── recipe-core/ # 数据配方核心结构 │ ├── recipe-runner/ # 数据配方执行器 -│ └── recipe-exporter/ # MCP / OpenAPI / JSON 导出 +│ ├── skill-builder/ # Data Skill Package 生成 +│ └── skill-exporter/ # Data Skill Package 导出 ├── docs/ │ ├── vision.md │ ├── data-recipe-spec.md @@ -227,3 +229,22 @@ pnpm validate:skill-package path/to/your.data-skill.json ``` 校验通过时会输出技能包名称和文件列表;缺少文件或文件为空时会返回非零退出码,便于后续接入自动化验收。 + +## 长期 Runtime 架构 + +DataRecipe 的长期执行链路是: + +```text +Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +``` + +含义: + +* `Data Skill Package` 保存数据配方、技能说明和示例; +* `recipe-runner` 负责解释 recipe,不直接持有用户登录凭证; +* `Browser RPC Bridge` 是受限协议层,只把明确的运行请求转交给浏览器插件; +* `Chrome Extension` 在用户授权的当前浏览器会话中执行请求; +* `authorized browser session` 指用户已经正常登录并有权访问的页面会话。 + +这个架构不会把 Cookie、Authorization header 或其它敏感凭证暴露给 AI Agent,也不会提供任意请求代理。项目不会实现绕过登录、验证码、风控、动态签名或反爬的能力。 + diff --git a/packages/browser-rpc-core/package.json b/packages/browser-rpc-core/package.json new file mode 100644 index 0000000..3973c2b --- /dev/null +++ b/packages/browser-rpc-core/package.json @@ -0,0 +1,21 @@ +{ + "name": "@data-recipe/browser-rpc-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + }, + "dependencies": { + "@data-recipe/recipe-core": "workspace:*" + }, + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + } +} diff --git a/packages/browser-rpc-core/src/index.ts b/packages/browser-rpc-core/src/index.ts new file mode 100644 index 0000000..f7e373c --- /dev/null +++ b/packages/browser-rpc-core/src/index.ts @@ -0,0 +1,96 @@ +import type { DataRecipe, HttpMethod, JsonObject } from "@data-recipe/recipe-core"; + +export type BrowserRpcMethod = + | "browser.getBridgeStatus" + | "browser.getActiveTab" + | "browser.runRecipe" + | "browser.fetchWithSession"; + +export type BrowserRpcBridgeState = "unavailable" | "disconnected" | "permission_required" | "ready"; + +export interface BrowserRpcBridgeStatus { + state: BrowserRpcBridgeState; + extensionVersion?: string; + activeTab?: BrowserRpcTabSummary; + message?: string; +} + +export interface BrowserRpcTabSummary { + tabId: number; + url: string; + title?: string; + origin: string; + active: boolean; +} + +export interface BrowserRpcRequestMap { + "browser.getBridgeStatus": undefined; + "browser.getActiveTab": undefined; + "browser.runRecipe": BrowserRunRecipeParams; + "browser.fetchWithSession": BrowserFetchWithSessionParams; +} + +export interface BrowserRpcResponseMap { + "browser.getBridgeStatus": BrowserRpcBridgeStatus; + "browser.getActiveTab": BrowserRpcTabSummary | null; + "browser.runRecipe": BrowserRunRecipeResult; + "browser.fetchWithSession": BrowserFetchWithSessionResult; +} + +export interface BrowserRunRecipeParams { + recipe: DataRecipe; + variables?: JsonObject; + requireUserConfirmation?: boolean; +} + +export interface BrowserRunRecipeResult { + recipeName: string; + status: "ok" | "empty" | "blocked" | "error"; + rows?: unknown[]; + rowCount?: number; + responsePreview?: unknown; + message?: string; +} + +export interface BrowserFetchWithSessionParams { + url: string; + method: HttpMethod; + query?: JsonObject; + body?: unknown; + requiredOrigin: string; + requireUserConfirmation?: boolean; +} + +export interface BrowserFetchWithSessionResult { + url: string; + status: number; + ok: boolean; + contentType?: string; + bodyPreview?: unknown; +} + +export type BrowserRpcRequest = { + id: string; + method: TMethod; + params: BrowserRpcRequestMap[TMethod]; +}; + +export type BrowserRpcResponse = + | { + id: string; + method: TMethod; + ok: true; + result: BrowserRpcResponseMap[TMethod]; + } + | { + id: string; + method: TMethod; + ok: false; + error: BrowserRpcError; + }; + +export interface BrowserRpcError { + code: "BRIDGE_UNAVAILABLE" | "PERMISSION_DENIED" | "ORIGIN_MISMATCH" | "ACTIVE_SESSION_REQUIRED" | "REQUEST_FAILED" | "INVALID_REQUEST"; + message: string; + details?: JsonObject; +} diff --git a/packages/browser-rpc-core/tsconfig.json b/packages/browser-rpc-core/tsconfig.json new file mode 100644 index 0000000..21fc57b --- /dev/null +++ b/packages/browser-rpc-core/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src", + "composite": true + }, + "include": [ + "src" + ], + "references": [{ "path": "../recipe-core" }] +} diff --git a/packages/detector/src/index.ts b/packages/detector/src/index.ts index a9f479c..0446e9a 100644 --- a/packages/detector/src/index.ts +++ b/packages/detector/src/index.ts @@ -1,8 +1,12 @@ import { createDataRecipeDraft, + createUnknownPagination, type DataRecipe, + type DataRecipePagination, inferDataValueType, + inferParameters, type DataRecipeField, + type DataRecipeParameter, type JsonObject } from "@data-recipe/recipe-core"; @@ -33,7 +37,8 @@ export interface ResponseDetection { const TOTAL_KEYS = new Set(["total", "count", "totalCount", "total_count", "recordCount", "record_count"]); const LIST_KEYS = new Set(["records", "list", "items", "rows", "data", "result"]); -const PAGE_KEYS = new Set(["page", "pageNo", "pageNum", "page_number", "current", "currentPage", "pageSize"]); +const PAGE_KEYS = new Set(["page", "pageNo", "pageNum", "page_number", "current", "currentPage"]); +const PAGE_SIZE_KEYS = new Set(["pageSize", "page_size", "size", "limit", "perPage", "per_page"]); export function parseQueryFromUrl(urlValue: string): JsonObject { try { @@ -78,7 +83,7 @@ export function summarizeResponse(responseBody: unknown): ResponseDetection { arrayPaths.push(path); } - if (key && (TOTAL_KEYS.has(key) || LIST_KEYS.has(key) || PAGE_KEYS.has(key))) { + if (key && (TOTAL_KEYS.has(key) || LIST_KEYS.has(key) || PAGE_KEYS.has(key) || PAGE_SIZE_KEYS.has(key))) { keywordPaths.push(path); } @@ -105,6 +110,8 @@ export function summarizeResponse(responseBody: unknown): ResponseDetection { export function buildRecipeFromCapture(capture: CapturedRequest): DataRecipe { const detection = summarizeResponse(capture.responseBody); + const queryFields = inferParameters(capture.query, "query"); + const bodyFields = inferParameters(capture.requestBody, "body"); return createDataRecipeDraft({ pageUrl: capture.pageUrl, @@ -112,9 +119,12 @@ export function buildRecipeFromCapture(capture: CapturedRequest): DataRecipe { method: capture.method, query: capture.query, body: capture.requestBody ?? {}, + queryFields, + bodyFields, responseType: detection.looksLikeList ? "list" : detection.isJson ? "object" : "unknown", listPath: detection.listPath, totalPath: detection.totalPath, + pagination: detectPageNumberPagination([...queryFields, ...bodyFields], detection.totalPath), fields: detection.fields }); } @@ -129,6 +139,22 @@ export function formatPreview(value: unknown, maxLength = 1800): string { return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; } +function detectPageNumberPagination(parameters: DataRecipeParameter[], totalPath: string): DataRecipePagination { + const pageParam = parameters.find((field) => PAGE_KEYS.has(field.name))?.path ?? ""; + const pageSizeParam = parameters.find((field) => PAGE_SIZE_KEYS.has(field.name))?.path ?? ""; + + if (!pageParam && !pageSizeParam) { + return createUnknownPagination(totalPath); + } + + return { + type: "page_number", + pageParam, + pageSizeParam, + totalPath + }; +} + function pickListPath(responseBody: unknown, arrayPaths: string[]): string { if (arrayPaths.length === 0) { return ""; @@ -206,5 +232,3 @@ function simplifySample(value: unknown): unknown { return value; } - - diff --git a/packages/recipe-core/src/index.ts b/packages/recipe-core/src/index.ts index ec2de60..b586c2a 100644 --- a/packages/recipe-core/src/index.ts +++ b/packages/recipe-core/src/index.ts @@ -10,6 +10,7 @@ export interface DataRecipe { description: string; useCases: string[]; source: DataRecipeSource; + runtime: DataRecipeRuntime; request: DataRecipeRequest; response: DataRecipeResponse; pagination: DataRecipePagination; @@ -23,6 +24,14 @@ export interface DataRecipeSource { method: HttpMethod; } +export interface DataRecipeRuntime { + type: "browser_rpc" | "direct_fetch" | "manual"; + requiredOrigin: string; + requiresActiveSession: boolean; + requiresUserConfirmation: boolean; + permissionNote: string; +} + export interface DataRecipeRequest { query: JsonObject; body: unknown; @@ -72,6 +81,8 @@ export interface CreateRecipeInput { responseType: DataRecipeResponse["type"]; listPath: string; totalPath: string; + pagination?: DataRecipePagination; + runtime?: DataRecipeRuntime; fields: DataRecipeField[]; } @@ -89,6 +100,7 @@ export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { apiUrl: input.apiUrl, method: input.method }, + runtime: input.runtime ?? createDefaultRuntime(input.pageUrl, input.apiUrl), request: { query: input.query, body: input.body ?? {}, @@ -100,16 +112,20 @@ export function createDataRecipeDraft(input: CreateRecipeInput): DataRecipe { listPath: input.listPath, totalPath: input.totalPath }, - pagination: { - type: "page_number", - pageParam: "", - pageSizeParam: "", - totalPath: input.totalPath - }, + pagination: input.pagination ?? createUnknownPagination(input.totalPath), fields: input.fields }; } +export function createUnknownPagination(totalPath = ""): DataRecipePagination { + return { + type: "unknown", + pageParam: "", + pageSizeParam: "", + totalPath + }; +} + export function inferParameters(value: unknown, rootPath: "query" | "body"): DataRecipeParameter[] { if (!value || typeof value !== "object" || Array.isArray(value)) { return []; @@ -135,6 +151,16 @@ export function inferDataValueType(value: unknown): DataValueType { return "unknown"; } +function createDefaultRuntime(pageUrl: string, apiUrl: string): DataRecipeRuntime { + return { + type: "browser_rpc", + requiredOrigin: inferOrigin(pageUrl) || inferOrigin(apiUrl), + requiresActiveSession: true, + requiresUserConfirmation: true, + permissionNote: "需要在用户已授权访问的浏览器会话中运行,不直接暴露 Cookie 或 Authorization header。" + }; +} + function buildRecipeName(apiUrl: string): string { try { const url = new URL(apiUrl); @@ -158,6 +184,14 @@ function normalizeName(value: string): string { return normalized || "data_source"; } +function inferOrigin(urlValue: string): string { + try { + return new URL(urlValue).origin; + } catch { + return ""; + } +} + function simplifySample(value: unknown): unknown { if (Array.isArray(value)) { return value.slice(0, 2); @@ -169,4 +203,3 @@ function simplifySample(value: unknown): unknown { return value; } - diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts index 26eded1..5e329aa 100644 --- a/packages/skill-builder/src/index.ts +++ b/packages/skill-builder/src/index.ts @@ -38,16 +38,28 @@ function buildSkillMarkdown(recipe: DataRecipe, goal: string): string { const queries = queryFields.length ? queryFields.map((field) => `- ${field.displayName} (${field.name})`).join("\n") : "- 当前数据来源没有明确的查询条件。"; + const runtime = buildRuntimeMarkdown(recipe); - return `# ${recipe.displayName}\n\n## 适合完成的任务\n\n${goal}\n\n## 数据来源\n\n这个技能会从用户已授权访问的页面数据来源读取数据。\n\n## 查询条件\n\n${queries}\n\n## 返回字段\n\n${fields}\n\n## 使用限制\n\n- 只用于用户有权访问的数据。\n- 不用于绕过登录、验证码、风控或访问限制。\n- 运行前应先用 recipe.json 测试数据预览是否正常。\n`; + return `# ${recipe.displayName}\n\n## 适合完成的任务\n\n${goal}\n\n## 数据来源\n\n这个技能会从用户已授权访问的页面数据来源读取数据。\n\n## Runtime\n\n${runtime}\n\n## 查询条件\n\n${queries}\n\n## 返回字段\n\n${fields}\n\n## 使用限制\n\n- 只用于用户有权访问的数据。\n- 不用于绕过登录、验证码、风控、动态签名、反爬或访问限制。\n- 不要直接调用 recipe.json 中记录的数据来源地址。\n- 不要要求用户提供 Cookie、Authorization header 或其它登录凭证。\n- 运行前应先用 Browser RPC Bridge 测试数据预览是否正常。\n`; +} + +function buildRuntimeMarkdown(recipe: DataRecipe): string { + if (recipe.runtime.type !== "browser_rpc") { + return `- 运行方式:${recipe.runtime.type}\n- 权限说明:${recipe.runtime.permissionNote || "按 recipe.json 中的 runtime 配置执行。"}`; + } + + const confirmation = recipe.runtime.requiresUserConfirmation ? "需要用户确认" : "不需要额外确认"; + const session = recipe.runtime.requiresActiveSession ? "需要用户当前浏览器中已有授权会话" : "不要求已有授权会话"; + + return `- 运行方式:Browser RPC Bridge。\n- 执行位置:用户授权的 Chrome 会话,通过浏览器插件完成请求。\n- 站点范围:${recipe.runtime.requiredOrigin || "未限定,请在运行前确认来源页面"}。\n- 会话要求:${session},${confirmation}。\n- Agent 不应直接调用数据来源地址,应把运行请求交给 Browser RPC Bridge。\n- Browser RPC Bridge 不向 Agent 暴露 Cookie、Authorization header 或其它敏感凭证。\n- 权限说明:${recipe.runtime.permissionNote}`; } function buildExamplesMarkdown(recipe: DataRecipe, goal: string): string { const firstUseCase = recipe.useCases[0] ?? goal; - return `# 示例\n\n## 示例问题\n\n- 请根据「${recipe.displayName}」查看最新数据。\n- 请基于这些数据完成:${firstUseCase}\n\n## 示例输出\n\n系统会先测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。\n`; + return `# 示例\n\n## 示例问题\n\n- 请根据「${recipe.displayName}」查看最新数据。\n- 请基于这些数据完成:${firstUseCase}\n\n## 示例输出\n\n系统会先通过 Browser RPC Bridge 在用户授权的浏览器会话中测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。\n`; } function buildReadmeMarkdown(recipe: DataRecipe, goal: string): string { - return `# ${recipe.displayName}\n\n${goal}\n\n## 包含文件\n\n- SKILL.md: 给 AI Agent 使用的技能说明。\n- recipe.json: 可测试运行的数据配方。\n- examples.md: 示例问题和示例输出。\n- README.md: 给人看的说明。\n\n## 验证方式\n\n用 recipe.json 进行测试运行,并确认可以读取预期数据。\n`; + return `# ${recipe.displayName}\n\n${goal}\n\n## 包含文件\n\n- SKILL.md: 给 AI Agent 使用的技能说明。\n- recipe.json: 可测试运行的数据配方。\n- examples.md: 示例问题和示例输出。\n- README.md: 给人看的说明。\n\n## 运行方式\n\n这个技能默认通过 Browser RPC Bridge 在用户授权的 Chrome 会话中运行,不直接暴露 Cookie 或 Authorization header。\n\n## 验证方式\n\n用 recipe.json 通过 Browser RPC Bridge 进行测试运行,并确认可以读取预期数据。\n`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bad535..c7ac343 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,10 +12,10 @@ importers: specifier: ^0.0.268 version: 0.0.268 tsup: - specifier: ^8.2.4 + specifier: ^8.5.1 version: 8.5.1(typescript@5.9.3) typescript: - specifier: ^5.5.4 + specifier: ^5.9.3 version: 5.9.3 apps/extension: @@ -40,6 +40,12 @@ importers: specifier: ^6.0.1 version: 6.1.3 + packages/browser-rpc-core: + dependencies: + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../recipe-core + packages/detector: dependencies: '@data-recipe/recipe-core': @@ -522,8 +528,8 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pirates@4.0.7: @@ -870,9 +876,9 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 fix-dts-default-cjs-exports@1.0.1: dependencies: @@ -937,7 +943,7 @@ snapshots: picocolors@1.1.1: {} - picomatch@4.0.4: {} + picomatch@4.0.5: {} pirates@4.0.7: {} @@ -1015,8 +1021,8 @@ snapshots: tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tree-kill@1.2.2: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 35a0c58..38cc17c 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -19,6 +19,9 @@ "@data-recipe/recipe-core": [ "packages/recipe-core/src/index.ts" ], + "@data-recipe/browser-rpc-core": [ + "packages/browser-rpc-core/src/index.ts" + ], "@data-recipe/detector": [ "packages/detector/src/index.ts" ], From 1b560346a4d015729c00294c9232658ba56f5869 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 9 Jul 2026 22:50:19 +0800 Subject: [PATCH 20/25] feat: update devDependencies for tsup and typescript versions --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index ba199e6..87eea19 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,7 @@ }, "devDependencies": { "@types/chrome": "^0.0.268", - "tsup": "^8.2.4", - "typescript": "^5.5.4" - }, - "packageManager": "pnpm@9.7.0" + "tsup": "^8.5.1", + "typescript": "^5.9.3" + } } From 7830040512369ee31bb868fa9fc80d611ba75db3 Mon Sep 17 00:00:00 2001 From: return null Date: Thu, 9 Jul 2026 23:21:07 +0800 Subject: [PATCH 21/25] feat: enhance documentation and implement Browser RPC interface for Data Skill Package --- PR_TESTING.md | 99 +++++++++++++ README.en.md | 12 ++ README.md | 5 + README.zh-CN.md | 12 ++ packages/detector/src/index.ts | 5 +- packages/recipe-runner/package.json | 1 + packages/recipe-runner/src/index.ts | 60 +++++++- packages/recipe-runner/tsconfig.json | 3 + packages/skill-builder/src/index.ts | 211 +++++++++++++++++++++++++-- pnpm-lock.yaml | 3 + 10 files changed, 396 insertions(+), 15 deletions(-) create mode 100644 PR_TESTING.md diff --git a/PR_TESTING.md b/PR_TESTING.md new file mode 100644 index 0000000..5eec2ea --- /dev/null +++ b/PR_TESTING.md @@ -0,0 +1,99 @@ +# PR Testing — Data Skill Package + Browser RPC Bridge Runtime + +This document records what was tested for the current PR. The branch direction +is **Data Skill Package + Browser RPC Bridge Runtime**. This round intentionally +does NOT include complex UI, MCP, OpenAPI, cross-page composition, or a real +LLM API connection. + +## Scope of this round + +1. Restructure `SKILL.md` into a standard Skill file (YAML frontmatter + structured sections). +2. Add `LLMProvider` interface + `MockLLMProvider`. +3. Fix pagination detection logic. +4. Add `runRecipeWithBrowserRpc` interface to `recipe-runner`. +5. Update architecture docs in the READMEs. +6. Keep the whole monorepo type-clean and the extension buildable. + +## Automated checks (required, all green) + +```bash +pnpm install +pnpm typecheck # must exit 0 across all packages + the extension +pnpm build:extension # must produce apps/extension/dist/*.global.js +``` + +Run result on this PR: + +- `pnpm typecheck` → all 7 packages + extension typecheck pass. +- `pnpm build:extension` → builds `content.global.js`, `background.global.js`, `sidepanel.global.js`, `page-hook.global.js`. + +## Manual verification — Skill package export loop + +These checks reproduce the end-to-end flow on `docs/test-page.html`. + +1. `pnpm build:extension`, load `apps/extension/dist` as an unpacked extension. +2. Open `docs/test-page.html`, open the side panel, click **开始发现**. +3. Click **触发 fetch 查询** / **触发 XHR 查询**. +4. Confirm the side panel shows the discovered source, the query fields, the sample preview, and a minimal recipe draft. + +### SKILL.md structure (this round's focus) + +Export the Data Skill Package and open the generated `SKILL.md`. Confirm: + +- **YAML frontmatter present** at the very top of the file, delimited by `---`, containing `name` and `description`: + ```yaml + --- + name: + description: "" + ``` +- **Sections present**, in this order: `# `, `## Runtime`, `## Inputs`, `## Outputs`, `## Execution`, `## Safety`, `## Examples`. +- **Inputs** lists each query/body field with type, required/optional, and source path. +- **Outputs** lists each return field with type and path, plus the list-path and total-path hints. +- **Execution** describes the Browser RPC Bridge flow and pagination behavior (page / cursor / unknown). +- **Safety** includes the "only authorized data / no credential harvesting / dry-run first" rules. + +### MockLLMProvider (this round's focus) + +- `buildDataSkillPackage({ recipe })` with **no provider** still produces the full `SKILL.md` via the default `MockLLMProvider`. +- Passing a custom `LLMProvider` in `buildDataSkillPackage({ recipe, provider })` swaps in that provider's output — this is the extension point for a real LLM later. +- The default template is deterministic; the prose is identical to the structure above. + +## Manual verification — pagination fix (this round's focus) + +Build a recipe draft from a captured request and inspect `recipe.json#pagination` (or +inspect the SKILL.md `## Execution` pagination note). Expect: + +- A request with a `page` / `pageNo` / `pageNum` / `current` / `currentPage` parameter → `pagination.type === "page_number"`, and the matching field is recorded as `pageParam`. +- A request with **only** `pageSize` / `limit` / `size` (no page parameter) → `pagination.type === "unknown"`. Previously this was incorrectly marked `page_number`; it should NOT be. +- A request with neither → `pagination.type === "unknown"`. + +You can verify quickly by capturing a request whose query is `?limit=20` (no `page`): +the generated SKILL.md `## Execution` step 8 should read "Pagination behavior is unknown". + +## Manual verification — recipe-runner Browser RPC interface (this round's focus) + +This is a **type-level wiring** change. The real bridge transport is NOT implemented +this round. Verify the contract: + +- `recipe-runner` exports `runRecipeWithBrowserRpc(input: { recipe, variables? })`. +- Its return type is `BrowserRunRecipeResult` from `@data-recipe/browser-rpc-core` (status `ok | empty | blocked | error`, plus `recipeName`, optional `rows`/`rowCount`/`responsePreview`/`message`). +- For a `browser_rpc` recipe it currently **returns `blocked`** (placeholder) rather than throwing. +- For a non-`browser_rpc` recipe it returns `blocked` with a localized message. +- `recipe-runner` also exports `createBrowserRpcError` to construct `BrowserRpcError` values — used later when the real transport lands. + +Because the real round-trip is deferred, this is verified via `pnpm typecheck` (the +surface compiles against `browser-rpc-core`'s types) rather than live execution. + +## Out of scope this round (deferred to follow-up PRs) + +- Complex side-panel UI changes. +- MCP / OpenAPI integration. +- Cross-page recipe composition. +- Real LLM API connection (OpenAI / Claude). `LLMProvider` is ready as an interface; only `MockLLMProvider` is wired. +- Real browser RPC execution: `recipe.runRecipe()` inside the extension's authorized session. `runRecipeWithBrowserRpc` returns `blocked` until then. + +## Regression notes + +- `skill-exporter.validateDataSkillPackage` still expects `SKILL.md` (content non-empty); the YAML frontmatter + structured body satisfy this. +- The `LLMProvider` interface keeps `buildDataSkillPackage` backwards compatible — no callers need to change because the mock provider is the default. +- Adding `@data-recipe/browser-rpc-core` to `recipe-runner`'s dependencies does not change the public API of `recipe-runner` for existing consumers; `runRecipeOnSample` is unchanged. diff --git a/README.en.md b/README.en.md index ebb503d..fa5fcc5 100644 --- a/README.en.md +++ b/README.en.md @@ -237,6 +237,12 @@ pnpm validate:skill-package path/to/your.data-skill.json The command checks that all four required files are present and non-empty. It exits with a non-zero status when the package is invalid, so it can be used in later automated checks. +## Artifact Hierarchy + +* **SKILL.md is the artifact an AI agent actually reads.** It is a standard Skill file: a YAML frontmatter block carries `name` and `description`, and the body covers Runtime / Inputs / Outputs / Execution / Safety / Examples. +* **recipe.json is the low-level execution config.** It records the data source, query/body parameters, response shape, pagination rules, and field meanings. The agent should follow SKILL.md and let the runtime execute recipe.json rather than fetching the data source URL directly. +* **Browser RPC Bridge is the future runtime**, responsible for executing the recipe safely inside the user's authorized browser session without exposing Cookie / Authorization headers to the agent. + ## Long-term Runtime Architecture DataRecipe's long-term execution path is: @@ -255,3 +261,9 @@ Meaning: This architecture does not expose Cookie, Authorization header, or other sensitive credentials to AI agents, and it is not an arbitrary request proxy. The project will not implement bypasses for login, captchas, risk controls, dynamic signatures, or anti-bot systems. +## Current MVP Status + +* Done: API detection / recipe draft generation / local sample preview / Data Skill Package export. +* Done: `recipe-runner.runRecipeWithBrowserRpc` is defined, with its types wired to `BrowserRunRecipeResult` from `@data-recipe/browser-rpc-core`. +* Not yet implemented: real browser RPC execution. The MVP only completes the wire protocol and the skill package draft; `runRecipeWithBrowserRpc` currently returns `blocked` until the bridge transport is connected in a follow-up PR. + diff --git a/README.md b/README.md index 390ef34..94cdca6 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,8 @@ Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension The Browser RPC Bridge is a constrained runtime protocol for running a recipe inside the user's authorized Chrome session. It must not expose Cookie or Authorization headers to AI agents, must not become an arbitrary request proxy, and must not bypass login, captchas, risk controls, dynamic signatures, or anti-bot systems. +- **SKILL.md is the artifact an AI agent actually reads.** It describes the skill's goal, runtime, inputs, outputs, execution flow, safety rules, and examples. It carries a YAML frontmatter block with `name` and `description` so it works as a standard Skill file. +- **recipe.json is the low-level execution config.** It records the data source, query/body parameters, response shape, pagination rules, and field meanings. The agent should follow SKILL.md and let the runtime execute recipe.json rather than fetching the data source URL directly. +- **Browser RPC Bridge is the future runtime.** Today the bridge exists only as the wire-protocol types in `@data-recipe/browser-rpc-core`; the real `browser.runRecipe` round-trip is not wired up yet. +- **Current MVP status:** discovery + recipe-draft + local sample preview + skill package export all work end-to-end. Real browser RPC execution (the Chrome extension actually running `browser.runRecipe` inside an authorized session) is NOT implemented yet. `recipe-runner.runRecipeWithBrowserRpc` returns `blocked` until the bridge transport is connected in a follow-up PR. + diff --git a/README.zh-CN.md b/README.zh-CN.md index 48c857d..23c54dc 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -230,6 +230,12 @@ pnpm validate:skill-package path/to/your.data-skill.json 校验通过时会输出技能包名称和文件列表;缺少文件或文件为空时会返回非零退出码,便于后续接入自动化验收。 +## 产物层级 + +* **SKILL.md 是核心产物**,是 AI Agent 真正阅读的技能文件。它用 YAML frontmatter 记录 `name` 和 `description`,并包含 Runtime / Inputs / Outputs / Execution / Safety / Examples 结构。 +* **recipe.json 是底层执行配置**,记录数据来源、查询参数、响应结构、分页规则和字段含义。Agent 应按 SKILL.md 的说明,由运行时执行 recipe.json,而不是直接请求数据来源地址。 +* **Browser RPC Bridge 是未来运行时**,负责在用户授权的浏览器会话里安全执行 recipe,不会把 Cookie / Authorization header 暴露给 Agent。 + ## 长期 Runtime 架构 DataRecipe 的长期执行链路是: @@ -248,3 +254,9 @@ Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension 这个架构不会把 Cookie、Authorization header 或其它敏感凭证暴露给 AI Agent,也不会提供任意请求代理。项目不会实现绕过登录、验证码、风控、动态签名或反爬的能力。 +## 当前 MVP 状态 + +* 已完成:API 探测 / recipe 草稿生成 / 本地试运行预览 / Data Skill Package 导出; +* 已完成:`recipe-runner.runRecipeWithBrowserRpc` 接口定形,类型已接上 `@data-recipe/browser-rpc-core` 的 `BrowserRunRecipeResult`; +* 尚未实现:真实浏览器 RPC 执行。当前 MVP 只完成协议和技能包草稿,`runRecipeWithBrowserRpc` 暂时返回 `blocked`,真实执行会在后续 PR 接入。 + diff --git a/packages/detector/src/index.ts b/packages/detector/src/index.ts index 0446e9a..f976603 100644 --- a/packages/detector/src/index.ts +++ b/packages/detector/src/index.ts @@ -143,7 +143,10 @@ function detectPageNumberPagination(parameters: DataRecipeParameter[], totalPath const pageParam = parameters.find((field) => PAGE_KEYS.has(field.name))?.path ?? ""; const pageSizeParam = parameters.find((field) => PAGE_SIZE_KEYS.has(field.name))?.path ?? ""; - if (!pageParam && !pageSizeParam) { + // Only mark page_number when an explicit page parameter is detected. + // Detecting only a page size / limit parameter is not enough — many + // single-page APIs take `limit` or `size` without supporting pagination. + if (!pageParam) { return createUnknownPagination(totalPath); } diff --git a/packages/recipe-runner/package.json b/packages/recipe-runner/package.json index ef5c684..751feed 100644 --- a/packages/recipe-runner/package.json +++ b/packages/recipe-runner/package.json @@ -10,6 +10,7 @@ "typecheck": "tsc -b tsconfig.json" }, "dependencies": { + "@data-recipe/browser-rpc-core": "workspace:*", "@data-recipe/recipe-core": "workspace:*" }, "exports": { diff --git a/packages/recipe-runner/src/index.ts b/packages/recipe-runner/src/index.ts index e924435..9c8de01 100644 --- a/packages/recipe-runner/src/index.ts +++ b/packages/recipe-runner/src/index.ts @@ -1,4 +1,8 @@ -import type { DataRecipe } from "@data-recipe/recipe-core"; +import type { DataRecipe, JsonObject } from "@data-recipe/recipe-core"; +import type { + BrowserRunRecipeResult, + BrowserRpcError +} from "@data-recipe/browser-rpc-core"; export interface RecipeRunResult { recipe: DataRecipe; @@ -44,6 +48,60 @@ export function runRecipeOnSample( }; } +/** + * Input for running a recipe through the Browser RPC Bridge. The contract + * mirrors `BrowserRunRecipeParams` in `@data-recipe/browser-rpc-core` but + * keeps recipe-runner free of a hard dependency on any particular transport. + */ +export interface BrowserRunRecipeInput { + recipe: DataRecipe; + variables?: JsonObject; +} + +/** + * Run a recipe through the Browser RPC Bridge inside the user's authorized + * Chrome session. + * + * Current status (MVP): the bridge executor is not implemented yet. The + * browser extension only exposes the `browser-rpc-core` wire types; the + * actual `browser.runRecipe` round-trip lands in a future PR. Until then + * this returns a `blocked` result rather than throwing, so callers can be + * wired end-to-end against the real `BrowserRunRecipeResult` shape and swap + * in a transport later without changing the surface. + */ +export function runRecipeWithBrowserRpc(input: BrowserRunRecipeInput): BrowserRunRecipeResult { + if (input.recipe.runtime.type !== "browser_rpc") { + return { + recipeName: input.recipe.name, + status: "blocked", + message: `运行方式 「${input.recipe.runtime.type}」 不通过 Browser RPC Bridge 执行。` + }; + } + + // MVP placeholder: the bridge transport is not connected yet. + return blockedResult( + input.recipe.name, + "Browser RPC Bridge 执行器尚未实现。当前 MVP 只完成协议和技能包草稿,尚未实现真实浏览器 RPC 执行。" + ); +} + +/** + * Build a `BrowserRpcError` for a failed bridge call. Handy once a real + * transport is wired up; kept here so the error vocabulary lives next to + * the runner that produces it. + */ +export function createBrowserRpcError( + code: BrowserRpcError["code"], + message: string, + details?: JsonObject +): BrowserRpcError { + return { code, message, details }; +} + +function blockedResult(recipeName: string, message: string): BrowserRunRecipeResult { + return { recipeName, status: "blocked", message }; +} + function getByPath(value: unknown, path: string): unknown { if (!path || path === "$") { return value; diff --git a/packages/recipe-runner/tsconfig.json b/packages/recipe-runner/tsconfig.json index 97fb707..23412fb 100644 --- a/packages/recipe-runner/tsconfig.json +++ b/packages/recipe-runner/tsconfig.json @@ -11,6 +11,9 @@ "src" ], "references": [ + { + "path": "../browser-rpc-core" + }, { "path": "../recipe-core" } diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts index 5e329aa..6e723ea 100644 --- a/packages/skill-builder/src/index.ts +++ b/packages/skill-builder/src/index.ts @@ -13,16 +13,40 @@ export interface DataSkillPackageFile { export interface BuildDataSkillPackageInput { recipe: DataRecipe; userGoal?: string; + provider?: LLMProvider; +} + +/** + * LLMProvider turns a DataRecipe into the agent-facing SKILL.md document. + * + * The shipped MockLLMProvider uses a deterministic template. A real provider + * (OpenAI / Claude / local model) can improve the prose, restate the goal in + * the user's language, and sharpen field descriptions without changing the + * underlying recipe.json contract. + */ +export interface LLMProvider { + // Returns the SKILL.md body synchronously. Real network-backed providers + // (OpenAI / Claude) are deferred to a later PR that makes buildDataSkillPackage + // async end-to-end; MockLLMProvider uses the deterministic template. + generateSkillMarkdown(recipe: DataRecipe, goal: string): string; +} + +export class MockLLMProvider implements LLMProvider { + generateSkillMarkdown(recipe: DataRecipe, goal: string): string { + return buildSkillMarkdown(recipe, goal); + } } export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSkillPackage { const packageName = input.recipe.name || "data-skill"; const goal = input.userGoal?.trim() || input.recipe.description; + const provider = input.provider ?? new MockLLMProvider(); + const skillMarkdown = provider.generateSkillMarkdown(input.recipe, goal); return { packageName, files: [ - { path: "SKILL.md", content: buildSkillMarkdown(input.recipe, goal) }, + { path: "SKILL.md", content: skillMarkdown }, { path: "recipe.json", content: `${JSON.stringify(input.recipe, null, 2)}\n` }, { path: "examples.md", content: buildExamplesMarkdown(input.recipe, goal) }, { path: "README.md", content: buildReadmeMarkdown(input.recipe, goal) } @@ -31,35 +55,196 @@ export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSk } function buildSkillMarkdown(recipe: DataRecipe, goal: string): string { - const fields = recipe.fields.length - ? recipe.fields.map((field) => `- ${field.displayName} (${field.name}): ${field.description}`).join("\n") - : "- 暂未确认返回字段。"; - const queryFields = [...recipe.request.queryFields, ...recipe.request.bodyFields]; - const queries = queryFields.length - ? queryFields.map((field) => `- ${field.displayName} (${field.name})`).join("\n") - : "- 当前数据来源没有明确的查询条件。"; + const frontmatterName = recipe.name || "data-skill"; + const frontmatterDescription = escapeYamlValue(goal || recipe.description); + + const inputs = buildInputsMarkdown(recipe); + const outputs = buildOutputsMarkdown(recipe); + const execution = buildExecutionMarkdown(recipe); const runtime = buildRuntimeMarkdown(recipe); + const examples = buildSkillExamplesMarkdown(recipe, goal); + + return `--- +name: ${frontmatterName} +description: ${frontmatterDescription} +--- + +# ${recipe.displayName} + +${goal || recipe.description} + +## Runtime + +${runtime} + +## Inputs + +${inputs} + +## Outputs + +${outputs} - return `# ${recipe.displayName}\n\n## 适合完成的任务\n\n${goal}\n\n## 数据来源\n\n这个技能会从用户已授权访问的页面数据来源读取数据。\n\n## Runtime\n\n${runtime}\n\n## 查询条件\n\n${queries}\n\n## 返回字段\n\n${fields}\n\n## 使用限制\n\n- 只用于用户有权访问的数据。\n- 不用于绕过登录、验证码、风控、动态签名、反爬或访问限制。\n- 不要直接调用 recipe.json 中记录的数据来源地址。\n- 不要要求用户提供 Cookie、Authorization header 或其它登录凭证。\n- 运行前应先用 Browser RPC Bridge 测试数据预览是否正常。\n`; +## Execution + +${execution} + +## Safety + +- Only use this skill for data the user is authorized to access. +- Do not use it to bypass login, captchas, risk controls, dynamic signatures, or anti-bot measures. +- Do not call the underlying data source URL recorded in recipe.json directly. +- Do not ask the user for cookies, Authorization headers, or other credentials. +- Dry-run the recipe through the Browser RPC Bridge first to confirm the data preview is healthy before drawing conclusions. +- ${recipe.runtime.permissionNote || "Follow the runtime configuration recorded in recipe.json."} + +## Examples + +${examples} +`; +} + +function escapeYamlValue(value: string): string { + // Quote the value so YAML special characters (colons, quotes, newlines) are safe. + const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n+/g, " ").trim(); + return `"${escaped}"`; +} + +function buildInputsMarkdown(recipe: DataRecipe): string { + const queryFields = [...recipe.request.queryFields, ...recipe.request.bodyFields]; + + if (queryFields.length === 0) { + return "- This data source has no confirmed query conditions yet.\n- Inspect the recipe.json `request.queryFields` and `request.bodyFields` before asking the user for parameters."; + } + + const items = queryFields + .map((field) => { + const required = field.required ? "required" : "optional"; + return `- \`${field.name}\` (${field.type}, ${required}) — ${field.displayName}. Path in source: \`${field.path}\`.`; + }) + .join("\n"); + + return `${items}\n- Only pass parameters the user explicitly provides or confirms; do not invent hidden query fields.`; +} + +function buildOutputsMarkdown(recipe: DataRecipe): string { + const listHint = recipe.response.type === "list" + ? `List payload root: \`${recipe.response.listPath || "$"}\`.` + : `Response shape: ${recipe.response.type}. List path: \`${recipe.response.listPath || "(none)"}\`.`; + + if (recipe.fields.length === 0) { + return `- No return fields confirmed yet.\n- ${listHint}`; + } + + const fields = recipe.fields + .map((field) => `- \`${field.name}\` (${field.type}) — ${field.description || field.displayName}. Path: \`${field.path}\`.`) + .join("\n"); + + return `${fields}\n- ${listHint}\n- Total count path (if any): \`${recipe.response.totalPath || "(none)"}\`.`; +} + +function buildExecutionMarkdown(recipe: DataRecipe): string { + if (recipe.runtime.type !== "browser_rpc") { + return `- Execution mode: \`${recipe.runtime.type}\`.\n- ${recipe.runtime.permissionNote || "使用即可。"}`; + } + + const confirmation = recipe.runtime.requiresUserConfirmation + ? "The agent MUST ask the user to confirm before each run." + : "No extra confirmation required, but still surface a preview first."; + const session = recipe.runtime.requiresActiveSession + ? "Requires an active, authorized browser session for the target origin." + : "Does not require a pre-existing session."; + const origin = recipe.runtime.requiredOrigin || "未限定,请在运行前确认来源页面"; + + const parts = [ + "1. Confirm the user's goal and which inputs they want to use.", + "2. Call the Browser RPC Bridge with the recipe recorded in recipe.json.", + `3. Site scope: \`${origin}\`. +4. ${session} +5. ${confirmation}`, + "6. Do not call the data source URL directly. Do not surface cookies or Authorization headers to the agent.", + "7. Preview the returned rows before summarizing or analyzing." + ]; + + if (recipe.pagination.type === "page_number") { + parts.push( + `8. Pagination is page-number based. Page parameter: \`${recipe.pagination.pageParam || "(none)"}\`; page-size parameter: \`${recipe.pagination.pageSizeParam || "(none)"}\`.` + ); + } else if (recipe.pagination.type === "cursor") { + parts.push(`8. Pagination is cursor based. Pagination cursor path: \`${recipe.pagination.pageParam || "(none)"}\`.`); + } else { + parts.push("8. Pagination behavior is unknown; do not assume the data can be paginated unless verified."); + } + + return parts.join("\n"); +} + +function buildSkillExamplesMarkdown(recipe: DataRecipe, goal: string): string { + const firstUseCase = recipe.useCases[0] ?? goal; + const fieldList = recipe.fields.map((f) => `\`${f.name}\``).join(", ") || "(fields pending confirmation)"; + + return `### Example queries + +- "Use '${recipe.displayName}' to pull the latest data." +- "Based on this data, help me with: ${firstUseCase}." + +### Expected flow + +The agent first asks the Browser RPC Bridge for a dry-run preview of recipe.json, confirms the data looks healthy, then organizes and analyzes the returned fields: ${fieldList}.`; } function buildRuntimeMarkdown(recipe: DataRecipe): string { if (recipe.runtime.type !== "browser_rpc") { - return `- 运行方式:${recipe.runtime.type}\n- 权限说明:${recipe.runtime.permissionNote || "按 recipe.json 中的 runtime 配置执行。"}`; + return `- Execution mode: \`${recipe.runtime.type}\`. +- Permission note: ${recipe.runtime.permissionNote || "使用即可。"}`; } const confirmation = recipe.runtime.requiresUserConfirmation ? "需要用户确认" : "不需要额外确认"; const session = recipe.runtime.requiresActiveSession ? "需要用户当前浏览器中已有授权会话" : "不要求已有授权会话"; - return `- 运行方式:Browser RPC Bridge。\n- 执行位置:用户授权的 Chrome 会话,通过浏览器插件完成请求。\n- 站点范围:${recipe.runtime.requiredOrigin || "未限定,请在运行前确认来源页面"}。\n- 会话要求:${session},${confirmation}。\n- Agent 不应直接调用数据来源地址,应把运行请求交给 Browser RPC Bridge。\n- Browser RPC Bridge 不向 Agent 暴露 Cookie、Authorization header 或其它敏感凭证。\n- 权限说明:${recipe.runtime.permissionNote}`; + return `- **Execution mode**: Browser RPC Bridge. Runs inside the user's authorized Chrome session via the browser extension. +- **Site scope**: ${recipe.runtime.requiredOrigin || "未限定,请在运行前确认来源页面"}. +- **Session requirement**: ${session};${confirmation}. +- The agent must NOT call the data source URL directly; hand execution to the Browser RPC Bridge. +- The Browser RPC Bridge does NOT expose cookies, Authorization headers, or other sensitive credentials to the agent. +- **Permission note**: ${recipe.runtime.permissionNote}. +- This is a draft skill package. The real browser RPC executor is not wired up yet — dry-run confirmations currently return \`blocked\`.`; } function buildExamplesMarkdown(recipe: DataRecipe, goal: string): string { const firstUseCase = recipe.useCases[0] ?? goal; - return `# 示例\n\n## 示例问题\n\n- 请根据「${recipe.displayName}」查看最新数据。\n- 请基于这些数据完成:${firstUseCase}\n\n## 示例输出\n\n系统会先通过 Browser RPC Bridge 在用户授权的浏览器会话中测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。\n`; + return `# 示例 + +## 示例问题 + +- 请根据「${recipe.displayName}」查看最新数据。 +- 请基于这些数据完成:${firstUseCase} + +## 示例输出 + +系统会先通过 Browser RPC Bridge 在用户授权的浏览器会话中测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。 +`; } function buildReadmeMarkdown(recipe: DataRecipe, goal: string): string { - return `# ${recipe.displayName}\n\n${goal}\n\n## 包含文件\n\n- SKILL.md: 给 AI Agent 使用的技能说明。\n- recipe.json: 可测试运行的数据配方。\n- examples.md: 示例问题和示例输出。\n- README.md: 给人看的说明。\n\n## 运行方式\n\n这个技能默认通过 Browser RPC Bridge 在用户授权的 Chrome 会话中运行,不直接暴露 Cookie 或 Authorization header。\n\n## 验证方式\n\n用 recipe.json 通过 Browser RPC Bridge 进行测试运行,并确认可以读取预期数据。\n`; + return `# ${recipe.displayName} + +${goal} + +## 包含文件 + +- SKILL.md: 给 AI Agent 使用的技能说明。 +- recipe.json: 可测试运行的数据配方。 +- examples.md: 示例问题和示例输出。 +- README.md: 给人看的说明。 + +## 运行方式 + +这个技能默认通过 Browser RPC Bridge 在用户授权的 Chrome 会话中运行,不直接暴露 Cookie 或 Authorization header。 + +## 验证方式 + +用 recipe.json 通过 Browser RPC Bridge 进行测试运行,并确认可以读取预期数据。 +`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7ac343..638e784 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: packages/recipe-runner: dependencies: + '@data-recipe/browser-rpc-core': + specifier: workspace:* + version: link:../browser-rpc-core '@data-recipe/recipe-core': specifier: workspace:* version: link:../recipe-core From ac14cc1d54bc3adf39aacafac86b8816ca46e463 Mon Sep 17 00:00:00 2001 From: null_object_0000 Date: Fri, 10 Jul 2026 14:22:50 +0800 Subject: [PATCH 22/25] feat: implement Agent Tool Layer with enhanced documentation and new interfaces for skill package generation --- AGENTS.md | 27 ++++++ PR_TESTING.md | 15 ++-- README.en.md | 28 +++--- README.md | 21 +++-- README.zh-CN.md | 30 ++++--- docs/agent-tool-architecture.md | 60 +++++++++++++ packages/agent-tools-core/package.json | 23 +++++ packages/agent-tools-core/src/index.ts | 110 ++++++++++++++++++++++++ packages/agent-tools-core/tsconfig.json | 16 ++++ packages/skill-builder/src/index.ts | 56 ++++++++---- pnpm-lock.yaml | 12 +++ tsconfig.base.json | 6 ++ 12 files changed, 350 insertions(+), 54 deletions(-) create mode 100644 AGENTS.md create mode 100644 docs/agent-tool-architecture.md create mode 100644 packages/agent-tools-core/package.json create mode 100644 packages/agent-tools-core/src/index.ts create mode 100644 packages/agent-tools-core/tsconfig.json diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0f42d80 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,27 @@ +# DataRecipe Agent Architecture + +DataRecipe is an **Agent Tool Layer**, not a fixed-flow Skill generator. + +## Responsibility boundaries + +- The browser extension captures authorized page/API activity and exposes bounded tools. +- The AI Agent decides which captures to inspect, how much content to read, how to refine a recipe, and how to write `SKILL.md` for the user's actual goal. +- The user authorizes browser access and confirms sensitive execution/export actions. +- The final artifact is a **Data Skill Package** containing `SKILL.md`, `recipe.json`, examples, and human-readable documentation. + +## Agent-facing tools + +Keep these names and responsibilities stable: + +- `listCapturedSources`: discover captured sources without loading every response. +- `readCapture`: read request/response content using preview, page, range, or full mode. +- `inspectResponse`: inspect response structure and selected content using the same bounded read modes. +- `buildRecipe`: produce a rule-derived `recipe.json` draft, optionally applying Agent edits. +- `runRecipe`: execute or dry-run a recipe through the Browser RPC Bridge. +- `exportSkillPackage`: package the Agent-authored `SKILL.md` and reviewed recipe. + +Never silently expand a bounded read to a full read. Never expose Cookie, Authorization headers, or equivalent browser credentials to the Agent. + +## Artifact policy + +`recipe.json` is machine-oriented execution configuration. Rules and tools generate the initial draft; the Agent may inspect and modify it. `SKILL.md` is authored by the Agent from tool results and user intent, and must not be constrained to a deterministic template. A deterministic Mock template may remain for demos, offline operation, and non-Agent fallback only. diff --git a/PR_TESTING.md b/PR_TESTING.md index 5eec2ea..ecf3763 100644 --- a/PR_TESTING.md +++ b/PR_TESTING.md @@ -3,12 +3,12 @@ This document records what was tested for the current PR. The branch direction is **Data Skill Package + Browser RPC Bridge Runtime**. This round intentionally does NOT include complex UI, MCP, OpenAPI, cross-page composition, or a real -LLM API connection. +Agent host/tool transport integration. ## Scope of this round 1. Restructure `SKILL.md` into a standard Skill file (YAML frontmatter + structured sections). -2. Add `LLMProvider` interface + `MockLLMProvider`. +2. Add Agent-facing tool contracts and retain a deterministic `MockSkillMarkdownFallback` only for non-Agent fallback. 3. Fix pagination detection logic. 4. Add `runRecipeWithBrowserRpc` interface to `recipe-runner`. 5. Update architecture docs in the READMEs. @@ -52,10 +52,11 @@ Export the Data Skill Package and open the generated `SKILL.md`. Confirm: - **Execution** describes the Browser RPC Bridge flow and pagination behavior (page / cursor / unknown). - **Safety** includes the "only authorized data / no credential harvesting / dry-run first" rules. -### MockLLMProvider (this round's focus) +### Agent-authored SKILL.md and Mock fallback -- `buildDataSkillPackage({ recipe })` with **no provider** still produces the full `SKILL.md` via the default `MockLLMProvider`. -- Passing a custom `LLMProvider` in `buildDataSkillPackage({ recipe, provider })` swaps in that provider's output — this is the extension point for a real LLM later. +- `buildDataSkillPackage({ recipe })` with no Agent-authored content still produces a full `SKILL.md` via `MockSkillMarkdownFallback`. +- Passing `skillMarkdown` uses the Agent-authored content verbatim (with a trailing newline) and does not invoke the fallback. +- The long-term integration point is the six-tool Agent Tool Layer, not an `LLMProvider.generateSkillMarkdown` call. - The default template is deterministic; the prose is identical to the structure above. ## Manual verification — pagination fix (this round's focus) @@ -89,11 +90,11 @@ surface compiles against `browser-rpc-core`'s types) rather than live execution. - Complex side-panel UI changes. - MCP / OpenAPI integration. - Cross-page recipe composition. -- Real LLM API connection (OpenAI / Claude). `LLMProvider` is ready as an interface; only `MockLLMProvider` is wired. +- Agent host integration that exposes the six tool contracts and supplies Agent-authored `SKILL.md`. - Real browser RPC execution: `recipe.runRecipe()` inside the extension's authorized session. `runRecipeWithBrowserRpc` returns `blocked` until then. ## Regression notes - `skill-exporter.validateDataSkillPackage` still expects `SKILL.md` (content non-empty); the YAML frontmatter + structured body satisfy this. -- The `LLMProvider` interface keeps `buildDataSkillPackage` backwards compatible — no callers need to change because the mock provider is the default. +- The default Mock fallback keeps the current side-panel flow working while Agent-authored `skillMarkdown` is the preferred package path. - Adding `@data-recipe/browser-rpc-core` to `recipe-runner`'s dependencies does not change the public API of `recipe-runner` for existing consumers; `runRecipeOnSample` is unchanged. diff --git a/README.en.md b/README.en.md index fa5fcc5..9ff3947 100644 --- a/README.en.md +++ b/README.en.md @@ -4,8 +4,7 @@ Operate once. Generate reusable data recipes for AI agents. -DataRecipe turns web page queries, API responses, query parameters, pagination rules, and field meanings into reusable data recipes. -Any AI agent can later use these recipes to collect, organize, and analyze data. +DataRecipe is a browser-resident tool layer for AI agents. It turns authorized page queries, API responses, parameters, pagination rules, and field meanings into reusable recipes while letting the Agent decide what to read and how to build the final package. ## Why DataRecipe @@ -130,6 +129,7 @@ data-recipe/ │ └── extension/ # Browser sidebar extension ├── packages/ │ ├── browser-rpc-core/ # Browser RPC Bridge protocol types +│ ├── agent-tools-core/ # Agent-facing tool contracts │ ├── detector/ # API request detection │ ├── recipe-core/ # Core Data Recipe model │ ├── recipe-runner/ # Recipe runtime @@ -239,31 +239,39 @@ The command checks that all four required files are present and non-empty. It ex ## Artifact Hierarchy -* **SKILL.md is the artifact an AI agent actually reads.** It is a standard Skill file: a YAML frontmatter block carries `name` and `description`, and the body covers Runtime / Inputs / Outputs / Execution / Safety / Examples. -* **recipe.json is the low-level execution config.** It records the data source, query/body parameters, response shape, pagination rules, and field meanings. The agent should follow SKILL.md and let the runtime execute recipe.json rather than fetching the data source URL directly. -* **Browser RPC Bridge is the future runtime**, responsible for executing the recipe safely inside the user's authorized browser session without exposing Cookie / Authorization headers to the agent. +* **The plugin provides tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Read tools support preview, page, range, and explicit full modes. +* **The Agent makes judgments:** it selects sources, decides how much to read, reviews and edits the recipe, and freely authors `SKILL.md` from tool evidence and the user's goal. +* **The user authorizes and confirms:** browser-session access, origin permissions, recipe runs, and protected export actions remain user-controlled. +* **recipe.json remains the low-level config:** rules and tools generate its draft; the Agent may inspect and modify it before runtime validation. +* **The Mock template is fallback only:** it supports the current non-Agent side panel, offline use, and degraded flows, but is not the long-term generation strategy. +* **The final deliverable is a Data Skill Package:** Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and documentation. ## Long-term Runtime Architecture DataRecipe's long-term execution path is: ```text -Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +User ↔ AI Agent → Agent-facing tools → Browser RPC Bridge → authorized Chrome session + ↓ + Data Skill Package ``` Meaning: -* `Data Skill Package` stores the recipe, skill instructions, and examples; -* `recipe-runner` interprets the recipe and does not hold user login credentials; -* `Browser RPC Bridge` is a constrained protocol layer that forwards explicit run requests to the browser extension; +* `AI Agent` is the controller: it plans tool calls, reads progressively, edits the recipe, and authors SKILL.md for the user goal; +* `Agent-facing tools` expose capture discovery, bounded reads, response inspection, recipe build/run, and package export; +* `Browser RPC Bridge` is the runtime behind `runRecipe`, forwarding only validated recipe runs to the extension; * `Chrome Extension` executes requests inside the user's authorized browser session; * `authorized browser session` means a page session the user has already logged into and is allowed to access. This architecture does not expose Cookie, Authorization header, or other sensitive credentials to AI agents, and it is not an arbitrary request proxy. The project will not implement bypasses for login, captchas, risk controls, dynamic signatures, or anti-bot systems. +See [`docs/agent-tool-architecture.md`](./docs/agent-tool-architecture.md) and [`AGENTS.md`](./AGENTS.md) for the detailed responsibility, tool, and phase design. + ## Current MVP Status -* Done: API detection / recipe draft generation / local sample preview / Data Skill Package export. +* Done: API detection / recipe draft generation / local sample preview / Mock fallback Data Skill Package export / Agent tool type contracts. +* Planned: an Agent host using the six tools to read selectively, inspect/edit recipes, and author SKILL.md. * Done: `recipe-runner.runRecipeWithBrowserRpc` is defined, with its types wired to `BrowserRunRecipeResult` from `@data-recipe/browser-rpc-core`. * Not yet implemented: real browser RPC execution. The MVP only completes the wire protocol and the skill package draft; `runRecipeWithBrowserRpc` currently returns `blocked` until the bridge transport is connected in a follow-up PR. diff --git a/README.md b/README.md index 94cdca6..5ba4b51 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ **中文名:AI 有数** -Turn web page queries and API responses into reusable data recipes for AI agents. +Provide a browser-resident Agent Tool Layer that turns authorized page/API activity into reusable data capabilities. -将网页查询和 API 响应沉淀为 AI Agent 可复用的数据配方。 +为 AI Agent 提供浏览器驻留工具层,将用户授权的网页查询和 API 响应沉淀为可复用的数据能力。 ## Languages @@ -27,16 +27,21 @@ Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-p pnpm validate:skill-package path/to/your.data-skill.json ``` -## Runtime architecture +## Long-term architecture ```text -Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +User ↔ AI Agent → Agent-facing tools → Browser RPC Bridge → authorized Chrome session + ↓ + Data Skill Package ``` -The Browser RPC Bridge is a constrained runtime protocol for running a recipe inside the user's authorized Chrome session. It must not expose Cookie or Authorization headers to AI agents, must not become an arbitrary request proxy, and must not bypass login, captchas, risk controls, dynamic signatures, or anti-bot systems. +The plugin provides tools; the AI Agent decides what to inspect, how much to read, how to edit the rule-generated recipe, and how to author `SKILL.md`; the user grants permission and confirms protected actions. The final deliverable is a Data Skill Package. -- **SKILL.md is the artifact an AI agent actually reads.** It describes the skill's goal, runtime, inputs, outputs, execution flow, safety rules, and examples. It carries a YAML frontmatter block with `name` and `description` so it works as a standard Skill file. -- **recipe.json is the low-level execution config.** It records the data source, query/body parameters, response shape, pagination rules, and field meanings. The agent should follow SKILL.md and let the runtime execute recipe.json rather than fetching the data source URL directly. -- **Browser RPC Bridge is the future runtime.** Today the bridge exists only as the wire-protocol types in `@data-recipe/browser-rpc-core`; the real `browser.runRecipe` round-trip is not wired up yet. +- **Agent-facing tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Reads support preview, page, range, and explicit full modes. +- **recipe.json is rule/tool generated and Agent-reviewable.** It remains the low-level execution config; the Agent may inspect and modify it before running or exporting. +- **SKILL.md is Agent-authored.** It is based on tool evidence and the user's goal, not constrained to a fixed provider/template strategy. The deterministic Mock template remains a fallback for the current MVP UI. +- **Browser RPC Bridge is the runtime tool.** It executes a reviewed recipe inside the user's authorized Chrome session without exposing browser credentials to the Agent. The real round-trip is not wired up yet. - **Current MVP status:** discovery + recipe-draft + local sample preview + skill package export all work end-to-end. Real browser RPC execution (the Chrome extension actually running `browser.runRecipe` inside an authorized session) is NOT implemented yet. `recipe-runner.runRecipeWithBrowserRpc` returns `blocked` until the bridge transport is connected in a follow-up PR. +See [Agent Tool Layer architecture](./docs/agent-tool-architecture.md) and [AGENTS.md](./AGENTS.md) for the detailed responsibility and type boundaries. + diff --git a/README.zh-CN.md b/README.zh-CN.md index 23c54dc..8666d4d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -2,8 +2,7 @@ **操作一次页面,生成 AI Agent 可复用的数据配方。** -AI 有数可以将网页查询、API 响应、查询条件、分页规则和字段含义沉淀为一份可复用的数据配方。 -以后无论在哪个 AI Agent 中,都可以复用这份配方来自动取数、整理和分析。 +AI 有数是供 AI Agent 使用的浏览器驻留工具层。它将网页查询、API 响应、查询条件、分页规则和字段含义沉淀为可复用的数据配方,并允许 Agent 按需读取、判断和生成最终技能包。 ## 为什么做这个项目 @@ -123,6 +122,7 @@ data-recipe/ │ └── extension/ # 浏览器侧边栏插件 ├── packages/ │ ├── browser-rpc-core/ # Browser RPC Bridge 协议类型 +│ ├── agent-tools-core/ # Agent-facing tools 类型契约 │ ├── detector/ # API 请求探测 │ ├── recipe-core/ # 数据配方核心结构 │ ├── recipe-runner/ # 数据配方执行器 @@ -232,31 +232,39 @@ pnpm validate:skill-package path/to/your.data-skill.json ## 产物层级 -* **SKILL.md 是核心产物**,是 AI Agent 真正阅读的技能文件。它用 YAML frontmatter 记录 `name` 和 `description`,并包含 Runtime / Inputs / Outputs / Execution / Safety / Examples 结构。 -* **recipe.json 是底层执行配置**,记录数据来源、查询参数、响应结构、分页规则和字段含义。Agent 应按 SKILL.md 的说明,由运行时执行 recipe.json,而不是直接请求数据来源地址。 -* **Browser RPC Bridge 是未来运行时**,负责在用户授权的浏览器会话里安全执行 recipe,不会把 Cookie / Authorization header 暴露给 Agent。 +* **插件提供工具**:`listCapturedSources`、`readCapture`、`inspectResponse`、`buildRecipe`、`runRecipe`、`exportSkillPackage`。读取工具支持预览、分页、范围和明确的完整读取。 +* **Agent 做判断**:选择数据来源、决定读取多少、检查并修改配方,并结合工具结果和用户目标自由编写 `SKILL.md`,不受固定模板策略限制。 +* **用户做授权和确认**:浏览器会话访问、来源权限、recipe 执行和导出等受保护动作由用户控制。 +* **recipe.json 是底层执行配置**:规则和工具先生成草稿,Agent 可以检查和修改,运行时仍会进行约束和校验。 +* **Mock 模板只作 fallback**:当前无 Agent 的侧边栏、离线或降级流程可以使用确定性模板,但它不是长期唯一生成路径。 +* **最终产物是 Data Skill Package**:包含 Agent 编写的 `SKILL.md`、审核后的 `recipe.json`、示例和说明文档。 ## 长期 Runtime 架构 DataRecipe 的长期执行链路是: ```text -Data Skill Package → recipe-runner → Browser RPC Bridge → Chrome Extension → authorized browser session +用户 ↔ AI Agent → Agent-facing tools → Browser RPC Bridge → 用户授权的 Chrome 会话 + ↓ + Data Skill Package ``` 含义: -* `Data Skill Package` 保存数据配方、技能说明和示例; -* `recipe-runner` 负责解释 recipe,不直接持有用户登录凭证; -* `Browser RPC Bridge` 是受限协议层,只把明确的运行请求转交给浏览器插件; -* `Chrome Extension` 在用户授权的当前浏览器会话中执行请求; +* `AI Agent` 是主控,按用户目标规划工具调用、渐进读取、修改 recipe 并生成 SKILL.md; +* `Agent-facing tools` 提供捕获列表、受限读取、响应检查、recipe 构建/执行和技能包导出; +* `Browser RPC Bridge` 是 `runRecipe` 背后的运行时工具,只把经过校验的 recipe 运行请求转交给浏览器插件; +* `Chrome Extension` 在用户授权并确认的当前浏览器会话中执行请求; * `authorized browser session` 指用户已经正常登录并有权访问的页面会话。 这个架构不会把 Cookie、Authorization header 或其它敏感凭证暴露给 AI Agent,也不会提供任意请求代理。项目不会实现绕过登录、验证码、风控、动态签名或反爬的能力。 +更完整的职责、工具和分期设计见 [`docs/agent-tool-architecture.md`](./docs/agent-tool-architecture.md) 与 [`AGENTS.md`](./AGENTS.md)。 + ## 当前 MVP 状态 -* 已完成:API 探测 / recipe 草稿生成 / 本地试运行预览 / Data Skill Package 导出; +* 已完成:API 探测 / recipe 草稿生成 / 本地试运行预览 / Mock fallback Data Skill Package 导出 / Agent 工具类型契约; +* 已规划:Agent 通过六个工具自主选择读取范围、检查/修改 recipe 并编写 SKILL.md; * 已完成:`recipe-runner.runRecipeWithBrowserRpc` 接口定形,类型已接上 `@data-recipe/browser-rpc-core` 的 `BrowserRunRecipeResult`; * 尚未实现:真实浏览器 RPC 执行。当前 MVP 只完成协议和技能包草稿,`runRecipeWithBrowserRpc` 暂时返回 `blocked`,真实执行会在后续 PR 接入。 diff --git a/docs/agent-tool-architecture.md b/docs/agent-tool-architecture.md new file mode 100644 index 0000000..e352a27 --- /dev/null +++ b/docs/agent-tool-architecture.md @@ -0,0 +1,60 @@ +# Agent Tool Layer architecture + +## Direction + +DataRecipe is a browser-resident tool layer used by an AI Agent. The extension does not own a fixed pipeline that turns one capture into one templated Skill. It exposes capabilities and constrained runtime access; the Agent owns planning and judgment. + +```text +User goal + ↓ +AI Agent (plans, reads selectively, edits, writes SKILL.md) + ↓ tool calls +DataRecipe Agent Tool Layer + ├─ capture catalog and bounded readers + ├─ rule-based response inspection / recipe drafting + ├─ Browser RPC Bridge runtime + └─ Data Skill Package exporter + ↓ authorization / confirmation +User-authorized Chrome session +``` + +The responsibility split is: + +1. **Plugin provides tools.** It captures eligible traffic, stores it locally, provides bounded reads, applies deterministic inference rules, validates recipes, runs approved recipes, and exports packages. +2. **Agent makes judgments.** It chooses a source, decides whether a preview is enough, requests further pages/ranges only when needed, checks and edits `recipe.json`, and writes `SKILL.md` based on evidence and the user's goal. +3. **User authorizes and confirms.** Browser-session access, origin permissions, recipe runs, and export confirmation remain visible user decisions where required. +4. **Data Skill Package is the deliverable.** It contains an Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and README. + +## Agent-facing tools + +The canonical TypeScript contracts live in `@data-recipe/agent-tools-core`. + +| Tool | Purpose | +| --- | --- | +| `listCapturedSources` | Paginate lightweight capture metadata so the Agent can select candidates without reading all bodies. | +| `readCapture` | Read request, response, or both with explicit `preview`, `page`, `range`, or `full` selection. | +| `inspectResponse` | Apply structural rules and return selected response content; supports JSON-path focus and bounded depth. | +| `buildRecipe` | Create a rule-generated recipe draft and apply Agent-provided edits. | +| `runRecipe` | Dry-run or execute the reviewed recipe in the authorized browser session. | +| `exportSkillPackage` | Validate and export the reviewed recipe with Agent-authored Skill content. | + +Bounded reads are a protocol guarantee. A tool must report truncation and continuation metadata and must not silently turn a preview, page, or range request into a full read. The Agent may explicitly request `full` when justified. + +## Recipe and Skill lifecycle + +`recipe.json` remains deterministic and machine-oriented. Detection rules can infer request parameters, response paths, fields, and pagination. The Agent reviews warnings and evidence, then may change the recipe before dry-run or export. Runtime validation remains authoritative even after Agent edits. + +`SKILL.md` is not generated through an `LLMProvider.generateSkillMarkdown` template call. The controlling Agent writes it freely after reading enough evidence and understanding the user's goal. `MockSkillMarkdownFallback` exists only for the current side panel, demos, offline flows, and failure recovery; it is not the long-term primary path. + +## Runtime and trust boundary + +`runRecipe` delegates execution to the Browser RPC Bridge. The Bridge is a constrained runtime tool operating inside a Chrome session the user has already authorized. It validates origin and confirmation requirements and returns data or bounded previews. It does not expose Cookie, Authorization headers, or comparable credentials to the Agent and must not become an arbitrary request proxy. + +The runtime does not bypass login, captchas, risk controls, dynamic signatures, anti-bot systems, or source authorization. + +## Delivery phases + +1. **Now:** capture discovery, deterministic recipe draft, local sample preview, Mock fallback package export, and Agent tool contracts. +2. **Next:** implement capture storage/read handlers and expose the six tool calls to an Agent host. +3. **Then:** connect `runRecipe` to the real Browser RPC Bridge with origin checks, user confirmation, pagination limits, and response bounding. +4. **Finally:** make Agent-authored package export the default UI path while retaining Mock fallback for degraded/offline use. diff --git a/packages/agent-tools-core/package.json b/packages/agent-tools-core/package.json new file mode 100644 index 0000000..437f055 --- /dev/null +++ b/packages/agent-tools-core/package.json @@ -0,0 +1,23 @@ +{ + "name": "@data-recipe/agent-tools-core", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + }, + "scripts": { + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + }, + "dependencies": { + "@data-recipe/browser-rpc-core": "workspace:*", + "@data-recipe/recipe-core": "workspace:*", + "@data-recipe/skill-builder": "workspace:*" + } +} diff --git a/packages/agent-tools-core/src/index.ts b/packages/agent-tools-core/src/index.ts new file mode 100644 index 0000000..e71de94 --- /dev/null +++ b/packages/agent-tools-core/src/index.ts @@ -0,0 +1,110 @@ +import type { BrowserRunRecipeResult } from "@data-recipe/browser-rpc-core"; +import type { DataRecipe, HttpMethod, JsonObject } from "@data-recipe/recipe-core"; +import type { DataSkillPackage } from "@data-recipe/skill-builder"; + +/** Reading is controlled by the Agent. Tools must never silently upgrade a + * bounded request to a full capture read. */ +export type AgentReadSelection = + | { mode: "preview"; maxChars?: number; maxItems?: number } + | { mode: "page"; cursor?: string; pageSize?: number } + | { mode: "range"; offset: number; length: number } + | { mode: "full" }; + +export interface CapturedSourceSummary { + captureId: string; + pageUrl: string; + apiUrl: string; + method: HttpMethod; + status: number; + capturedAt: number; + transport: "fetch" | "xhr"; + responseContentType?: string; + responseSize?: number; + preview?: unknown; +} + +export interface ReadResult { + value: T; + selection: AgentReadSelection; + truncated: boolean; + nextCursor?: string; + totalItems?: number; + totalChars?: number; +} + +export interface AgentToolInputMap { + listCapturedSources: { + cursor?: string; + pageSize?: number; + pageUrl?: string; + }; + readCapture: { + captureId: string; + section: "request" | "response" | "both"; + selection: AgentReadSelection; + }; + inspectResponse: { + captureId: string; + selection: AgentReadSelection; + jsonPath?: string; + maxDepth?: number; + }; + buildRecipe: { + captureId: string; + /** Rule-generated draft that the Agent may inspect and patch. */ + recipe?: DataRecipe; + patch?: Partial; + }; + runRecipe: { + recipe: DataRecipe; + variables?: JsonObject; + dryRun?: boolean; + previewLimit?: number; + requireUserConfirmation?: boolean; + }; + exportSkillPackage: { + recipe: DataRecipe; + /** Authored freely by the Agent from tool results and the user's goal. */ + skillMarkdown: string; + userGoal: string; + examplesMarkdown?: string; + readmeMarkdown?: string; + userConfirmed: boolean; + }; +} + +export interface ResponseInspection { + shape: "list" | "object" | "scalar" | "unknown"; + listPaths: string[]; + candidateTotalPaths: string[]; + candidateFields: Array<{ path: string; type: string; sample?: unknown }>; + content: ReadResult; +} + +export interface AgentToolOutputMap { + listCapturedSources: { + sources: CapturedSourceSummary[]; + nextCursor?: string; + }; + readCapture: ReadResult; + inspectResponse: ResponseInspection; + buildRecipe: { + recipe: DataRecipe; + warnings: string[]; + inferredByRules: boolean; + }; + runRecipe: BrowserRunRecipeResult; + exportSkillPackage: { + package: DataSkillPackage; + warnings: string[]; + }; +} + +export type AgentToolName = keyof AgentToolInputMap; + +export interface AgentToolLayer { + invoke( + name: TName, + input: AgentToolInputMap[TName] + ): Promise; +} diff --git a/packages/agent-tools-core/tsconfig.json b/packages/agent-tools-core/tsconfig.json new file mode 100644 index 0000000..03c2b5a --- /dev/null +++ b/packages/agent-tools-core/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src", + "composite": true + }, + "include": ["src"], + "references": [ + { "path": "../browser-rpc-core" }, + { "path": "../recipe-core" }, + { "path": "../skill-builder" } + ] +} diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts index 6e723ea..525df1b 100644 --- a/packages/skill-builder/src/index.ts +++ b/packages/skill-builder/src/index.ts @@ -13,26 +13,31 @@ export interface DataSkillPackageFile { export interface BuildDataSkillPackageInput { recipe: DataRecipe; userGoal?: string; - provider?: LLMProvider; + /** + * SKILL.md authored by the controlling AI Agent after it has inspected the + * captures and recipe through the Agent Tool Layer. + */ + skillMarkdown?: string; + examplesMarkdown?: string; + readmeMarkdown?: string; + /** + * Optional deterministic fallback for non-Agent surfaces such as the MVP + * side panel. This is deliberately not an LLM abstraction or the primary + * generation path. + */ + fallback?: SkillMarkdownFallback; } /** - * LLMProvider turns a DataRecipe into the agent-facing SKILL.md document. - * - * The shipped MockLLMProvider uses a deterministic template. A real provider - * (OpenAI / Claude / local model) can improve the prose, restate the goal in - * the user's language, and sharpen field descriptions without changing the - * underlying recipe.json contract. + * Last-resort SKILL.md generation for clients that do not host an Agent yet. + * Agent integrations should pass `skillMarkdown` instead. */ -export interface LLMProvider { - // Returns the SKILL.md body synchronously. Real network-backed providers - // (OpenAI / Claude) are deferred to a later PR that makes buildDataSkillPackage - // async end-to-end; MockLLMProvider uses the deterministic template. - generateSkillMarkdown(recipe: DataRecipe, goal: string): string; +export interface SkillMarkdownFallback { + buildFallbackSkillMarkdown(recipe: DataRecipe, goal: string): string; } -export class MockLLMProvider implements LLMProvider { - generateSkillMarkdown(recipe: DataRecipe, goal: string): string { +export class MockSkillMarkdownFallback implements SkillMarkdownFallback { + buildFallbackSkillMarkdown(recipe: DataRecipe, goal: string): string { return buildSkillMarkdown(recipe, goal); } } @@ -40,20 +45,35 @@ export class MockLLMProvider implements LLMProvider { export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSkillPackage { const packageName = input.recipe.name || "data-skill"; const goal = input.userGoal?.trim() || input.recipe.description; - const provider = input.provider ?? new MockLLMProvider(); - const skillMarkdown = provider.generateSkillMarkdown(input.recipe, goal); + const skillMarkdown = input.skillMarkdown?.trim() + ? ensureTrailingNewline(input.skillMarkdown) + : (input.fallback ?? new MockSkillMarkdownFallback()).buildFallbackSkillMarkdown(input.recipe, goal); return { packageName, files: [ { path: "SKILL.md", content: skillMarkdown }, { path: "recipe.json", content: `${JSON.stringify(input.recipe, null, 2)}\n` }, - { path: "examples.md", content: buildExamplesMarkdown(input.recipe, goal) }, - { path: "README.md", content: buildReadmeMarkdown(input.recipe, goal) } + { + path: "examples.md", + content: input.examplesMarkdown?.trim() + ? ensureTrailingNewline(input.examplesMarkdown) + : buildExamplesMarkdown(input.recipe, goal) + }, + { + path: "README.md", + content: input.readmeMarkdown?.trim() + ? ensureTrailingNewline(input.readmeMarkdown) + : buildReadmeMarkdown(input.recipe, goal) + } ] }; } +function ensureTrailingNewline(value: string): string { + return value.endsWith("\n") ? value : `${value}\n`; +} + function buildSkillMarkdown(recipe: DataRecipe, goal: string): string { const frontmatterName = recipe.name || "data-skill"; const frontmatterDescription = escapeYamlValue(goal || recipe.description); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 638e784..d7fc142 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,18 @@ importers: specifier: ^6.0.1 version: 6.1.3 + packages/agent-tools-core: + dependencies: + '@data-recipe/browser-rpc-core': + specifier: workspace:* + version: link:../browser-rpc-core + '@data-recipe/recipe-core': + specifier: workspace:* + version: link:../recipe-core + '@data-recipe/skill-builder': + specifier: workspace:* + version: link:../skill-builder + packages/browser-rpc-core: dependencies: '@data-recipe/recipe-core': diff --git a/tsconfig.base.json b/tsconfig.base.json index 38cc17c..d8e85f1 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -27,6 +27,12 @@ ], "@data-recipe/recipe-runner": [ "packages/recipe-runner/src/index.ts" + ], + "@data-recipe/skill-builder": [ + "packages/skill-builder/src/index.ts" + ], + "@data-recipe/agent-tools-core": [ + "packages/agent-tools-core/src/index.ts" ] } } From 4eada30cfa55bd81c6e914aff79c8525d26872c4 Mon Sep 17 00:00:00 2001 From: null_object_0000 Date: Fri, 10 Jul 2026 14:43:50 +0800 Subject: [PATCH 23/25] feat: Revamp sidepanel UI and enhance agent interaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated sidepanel layout to improve user experience with a new branding section and clearer action buttons. - Replaced "开始发现" with "开始学习页面" to better reflect the learning process. - Introduced a chat interface for user-agent interaction, allowing users to specify goals and receive feedback. - Implemented a structured plan for the agent's learning process, including steps for capturing data sources and generating recipes. - Enhanced messaging system to provide real-time updates and responses from the agent. - Added functionality for displaying captured data sources and their details in a more organized manner. - Updated documentation to reflect changes in the agent's architecture and interaction model. --- AGENTS.md | 4 +- README.en.md | 8 +- README.md | 4 +- README.zh-CN.md | 8 +- apps/extension/public/sidepanel.css | 400 +++++---------- apps/extension/public/sidepanel.html | 57 ++- apps/extension/src/sidepanel.ts | 695 ++++++++++++--------------- docs/agent-tool-architecture.md | 8 +- 8 files changed, 498 insertions(+), 686 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0f42d80..72ebfd1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,10 +2,12 @@ DataRecipe is an **Agent Tool Layer**, not a fixed-flow Skill generator. +The primary user experience is the browser side panel's built-in conversational Agent. Users state goals in natural language; the side-panel Agent plans and calls the same Agent Tool Layer that future external Agents can reuse. + ## Responsibility boundaries - The browser extension captures authorized page/API activity and exposes bounded tools. -- The AI Agent decides which captures to inspect, how much content to read, how to refine a recipe, and how to write `SKILL.md` for the user's actual goal. +- The side-panel Agent (or a future external Agent) decides which captures to inspect, how much content to read, how to refine a recipe, and how to write `SKILL.md` for the user's actual goal. - The user authorizes browser access and confirms sensitive execution/export actions. - The final artifact is a **Data Skill Package** containing `SKILL.md`, `recipe.json`, examples, and human-readable documentation. diff --git a/README.en.md b/README.en.md index 9ff3947..b361394 100644 --- a/README.en.md +++ b/README.en.md @@ -179,10 +179,12 @@ apps/extension/dist ### Manual verification 1. Open `docs/test-page.html`; -2. Click "开始发现" in the side panel; +2. Click "开始学习页面" in the conversational side panel; 3. Click the fetch or XHR test button on the test page; -4. The side panel should show the discovered data source count, URL, method, status, query data, and response preview; -5. Expand "高级信息" to inspect the minimal Data Recipe draft JSON. +4. State a goal in natural language; the side-panel Agent should create a plan and call the local tools; +5. Tool results remain collapsed, while "高级信息" contains data-source details and the recipe draft. + +The side panel is the primary workspace for ordinary users: conversation is the main UI, while sources, recipes, test output, and tool traces are secondary. The MVP uses a deterministic local Agent Loop; a real LLM can replace it later without changing the shared Agent Tool Layer used by future external Agents. You can also start discovery on any page you are authorized to access and then trigger a page query. This MVP only performs low-frequency local detection. It does not bypass login, captchas, risk controls, or dynamic signatures. diff --git a/README.md b/README.md index 5ba4b51..a475842 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ pnpm install pnpm build:extension ``` -Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, open the DataRecipe side panel, click "开始发现", trigger the fetch or XHR test request, then confirm the generated Data Skill Package and export the `.data-skill.json` file. +Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, and use the DataRecipe side-panel chat. Click “开始学习页面”, trigger a fetch/XHR query, then describe your goal in natural language. The local Agent Loop will show a plan, call the existing tools, test the recipe, and prepare a fallback Data Skill Package. ## Validate an exported skill package @@ -37,6 +37,8 @@ User ↔ AI Agent → Agent-facing tools → Browser RPC Bridge → authorized C The plugin provides tools; the AI Agent decides what to inspect, how much to read, how to edit the rule-generated recipe, and how to author `SKILL.md`; the user grants permission and confirms protected actions. The final deliverable is a Data Skill Package. +The side panel is the primary conversational Agent workspace. Tool calls and data-source details are secondary, collapsed information; the same Agent Tool Layer remains reusable by future external Agents. + - **Agent-facing tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Reads support preview, page, range, and explicit full modes. - **recipe.json is rule/tool generated and Agent-reviewable.** It remains the low-level execution config; the Agent may inspect and modify it before running or exporting. - **SKILL.md is Agent-authored.** It is based on tool evidence and the user's goal, not constrained to a fixed provider/template strategy. The deterministic Mock template remains a fallback for the current MVP UI. diff --git a/README.zh-CN.md b/README.zh-CN.md index 8666d4d..7701ec2 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -172,10 +172,12 @@ apps/extension/dist ### 手动验证 1. 打开 `docs/test-page.html`; -2. 在 AI 有数侧边栏点击「开始发现」; +2. 在 AI 有数对话侧边栏点击「开始学习页面」; 3. 在测试页点击「触发 fetch 查询」或「触发 XHR 查询」; -4. 侧边栏应显示发现的数据来源数量、URL、请求方式、状态、查询条件和返回预览; -5. 展开「高级信息」可以查看最小数据配方草稿 JSON。 +4. 在输入框中用自然语言说明目标,侧边栏 Agent 应生成执行计划并调用本地工具; +5. 工具结果默认折叠,展开「高级信息」可以查看数据来源和 recipe 草稿。 + +侧边栏是普通用户的主要工作台:对话是主界面,数据源列表、recipe、测试结果和工具调用记录都是辅助信息。当前使用确定性本地 Agent Loop,后续可以替换为真实 LLM,而 Agent Tool Layer 保持不变并可供外部 Agent 复用。 也可以在任意你有权访问的网页上点击「开始发现」,然后触发页面查询。当前 MVP 只做低频本地探测,不会绕过登录、验证码、风控或动态签名。 diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 742f00e..7c071fe 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -1,303 +1,167 @@ :root { color-scheme: light; - font-family: - Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", - sans-serif; - color: #202124; - background: #f7f8fa; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + color: #1f2937; + background: #f7f7f5; } -* { - box-sizing: border-box; -} - -body { - margin: 0; - min-width: 360px; -} - -button { - border: 1px solid #c9cdd4; - border-radius: 6px; - background: #ffffff; - color: #202124; - cursor: pointer; - font: inherit; - min-height: 36px; - padding: 0 12px; -} - -button:disabled { - cursor: not-allowed; - opacity: 0.55; -} - -button.primary { - border-color: #0f766e; - background: #0f766e; - color: #ffffff; -} +* { box-sizing: border-box; } +body { margin: 0; min-width: 340px; } +button, textarea { font: inherit; } +button { cursor: pointer; } +button:disabled { cursor: not-allowed; opacity: .55; } .app { display: flex; flex-direction: column; gap: 14px; min-height: 100vh; - padding: 16px; + padding: 14px; } -.header { +.header, .brand, .learn-actions, .message-head, .artifact-actions, .workspace summary { align-items: center; display: flex; - justify-content: space-between; - gap: 12px; -} - -.eyebrow { - color: #5f6368; - font-size: 12px; - margin: 0 0 4px; -} - -h1 { - font-size: 22px; - line-height: 1.2; - margin: 0; } +.header { justify-content: space-between; } +.brand { gap: 10px; } +.brand-mark { + align-items: center; + background: linear-gradient(145deg, #0f766e, #115e59); + border-radius: 10px; + color: white; + display: flex; + font-size: 15px; + font-weight: 700; + height: 34px; + justify-content: center; + width: 34px; +} +h1 { font-size: 16px; line-height: 1.2; margin: 0; } +.brand p { color: #7c827f; font-size: 11px; margin: 2px 0 0; } .status { - border: 1px solid #d7dae0; + align-items: center; + background: #eeefec; border-radius: 999px; - color: #5f6368; - font-size: 12px; - padding: 4px 9px; - white-space: nowrap; -} - -.status.active { - border-color: #14b8a6; - color: #0f766e; -} - -.toolbar { - display: grid; - gap: 8px; - grid-template-columns: 1fr 1fr; -} - -.summary { - align-items: baseline; - background: #ffffff; - border: 1px solid #e1e4e8; - border-radius: 8px; - display: flex; - gap: 6px; - padding: 12px; -} - -.summary strong { - font-size: 24px; + color: #6b706d; + display: inline-flex; + font-size: 11px; + gap: 5px; + padding: 5px 8px; } +.status span { background: #9ca3af; border-radius: 50%; height: 6px; width: 6px; } +.status.active { background: #e3f4ef; color: #0f766e; } +.status.active span { background: #10b981; box-shadow: 0 0 0 3px #c8eee2; } -.layout { +.learn-card { + background: linear-gradient(135deg, #ecf7f4, #f3f8f4); + border: 1px solid #cde7df; + border-radius: 12px; display: grid; gap: 12px; + padding: 13px; } - -.request-list, -.detail { - background: #ffffff; - border: 1px solid #e1e4e8; +.learn-card strong { color: #164e47; font-size: 13px; } +.learn-card p { color: #52706a; font-size: 12px; line-height: 1.45; margin: 4px 0 0; } +.learn-actions { gap: 8px; } +.primary, .quiet, .artifact-actions button { + border: 1px solid #b8d8cf; border-radius: 8px; - min-width: 0; - padding: 12px; -} - -.section-title { - color: #5f6368; - font-size: 12px; - font-weight: 600; - margin-bottom: 10px; -} - -.list-empty, -.empty-detail { - color: #6b7280; - font-size: 13px; - line-height: 1.5; -} - -.request-item { - border: 1px solid #e5e7eb; - border-radius: 6px; - cursor: pointer; - display: grid; - gap: 5px; - margin-bottom: 8px; - padding: 10px; - text-align: left; - width: 100%; -} - -.request-item.active { - border-color: #0f766e; - box-shadow: 0 0 0 1px #0f766e inset; -} - -.request-title { - color: #111827; - font-size: 13px; - font-weight: 650; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + min-height: 34px; + padding: 0 11px; } +.primary { background: #0f766e; border-color: #0f766e; color: #fff; } +.quiet, .artifact-actions button { background: rgba(255,255,255,.7); color: #315e58; } -.meta { - color: #6b7280; +.messages { display: flex; flex: 1; flex-direction: column; gap: 14px; min-height: 220px; } +.message { display: flex; gap: 8px; max-width: 94%; } +.message.user { align-self: flex-end; flex-direction: row-reverse; } +.avatar { + align-items: center; + background: #dceee9; + border-radius: 8px; + color: #0f766e; display: flex; - flex-wrap: wrap; - font-size: 12px; - gap: 6px; -} - -.pill { - background: #eef2f7; - border-radius: 999px; - padding: 2px 7px; -} - -.finding { - color: #374151; - font-size: 13px; - line-height: 1.5; -} - -.detail-block { - margin-bottom: 14px; -} - -.detail-block h2 { - font-size: 14px; - margin: 0 0 8px; -} - -.key-value { - display: grid; - gap: 8px; -} - -.key-value dt { - color: #6b7280; - font-size: 12px; -} - -.key-value dd { - font-size: 13px; - margin: 2px 0 0; - overflow-wrap: anywhere; -} - -pre { - background: #111827; - border-radius: 6px; - color: #f9fafb; - font-size: 12px; + flex: 0 0 auto; + font-size: 11px; + font-weight: 700; + height: 26px; + justify-content: center; + margin-top: 2px; + width: 26px; +} +.user .avatar { background: #e5e7eb; color: #4b5563; } +.bubble { + background: #fff; + border: 1px solid #e5e7e2; + border-radius: 4px 12px 12px 12px; + box-shadow: 0 1px 2px rgba(25, 40, 35, .04); + min-width: 0; + padding: 10px 11px; +} +.user .bubble { background: #0f766e; border-color: #0f766e; border-radius: 12px 4px 12px 12px; color: #fff; } +.message-head { color: #6b7280; font-size: 10px; justify-content: space-between; margin-bottom: 5px; } +.message-text { font-size: 13px; line-height: 1.55; white-space: pre-wrap; } + +.plan { border-top: 1px solid #eceeea; margin: 9px 0 0; padding: 8px 0 0 20px; } +.plan li { color: #58615e; font-size: 12px; line-height: 1.5; padding: 2px 0 2px 2px; } +.plan li.done::marker { color: #0f9f78; content: "✓ "; } +.plan li.running::marker { color: #d58a18; content: "● "; } + +.tool-call { border-top: 1px solid #eceeea; margin-top: 8px; padding-top: 8px; } +.tool-call summary { color: #6b7280; cursor: pointer; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 11px; } +.tool-call pre, .source-detail pre { + background: #202522; + border-radius: 7px; + color: #e6eee9; + font-size: 10px; line-height: 1.45; - margin: 0; - max-height: 260px; + margin: 8px 0 0; + max-height: 220px; overflow: auto; - padding: 10px; + padding: 9px; white-space: pre-wrap; } +.artifact-actions { flex-wrap: wrap; gap: 7px; margin-top: 10px; } +.artifact-actions button { font-size: 11px; min-height: 30px; } -details { - border-top: 1px solid #e5e7eb; - padding-top: 10px; -} - -summary { - cursor: pointer; - font-size: 13px; - font-weight: 600; -} - -.recipe-draft { - display: grid; - gap: 10px; -} - -.copy-button { - justify-self: start; -} - -.run-preview { - display: grid; - gap: 10px; -} - -.field-editor { - display: grid; - gap: 8px; -} - -.field-row { - display: grid; - gap: 4px; -} - -.field-row input { - border: 1px solid #c9cdd4; - border-radius: 6px; - font: inherit; - min-height: 34px; - padding: 6px 8px; - width: 100%; -} - -.field-row span { - color: #6b7280; - font-size: 12px; - overflow-wrap: anywhere; -} - -.skill-editor { - display: grid; - gap: 10px; -} - -.skill-field { - display: grid; - gap: 5px; -} - -.skill-field span { - color: #6b7280; - font-size: 12px; - font-weight: 600; -} - -.skill-field input, -.skill-field textarea { - border: 1px solid #c9cdd4; - border-radius: 6px; - font: inherit; - padding: 7px 8px; - width: 100%; -} - -.skill-field textarea { - line-height: 1.45; - resize: vertical; -} - -.skill-package { - display: grid; - gap: 10px; +.suggestions { display: flex; gap: 7px; overflow-x: auto; } +.suggestions button { + background: #fff; + border: 1px solid #dde1dc; + border-radius: 999px; + color: #59625f; + font-size: 11px; + padding: 7px 10px; + white-space: nowrap; } - -.package-actions { +.composer { + align-items: flex-end; + background: #fff; + border: 1px solid #d9ddd8; + border-radius: 12px; + box-shadow: 0 4px 16px rgba(24, 45, 38, .07); display: flex; - flex-wrap: wrap; gap: 8px; -} + padding: 8px; + position: sticky; + bottom: 8px; +} +.composer:focus-within { border-color: #68aa9d; box-shadow: 0 0 0 3px #dceee9; } +.composer textarea { border: 0; color: #1f2937; line-height: 1.45; max-height: 120px; outline: 0; padding: 5px; resize: none; width: 100%; } +.send { background: #0f766e; border: 0; border-radius: 8px; color: #fff; flex: 0 0 auto; font-size: 19px; height: 34px; width: 34px; } + +.workspace { border-top: 1px solid #dcdfda; margin-top: 2px; padding-top: 10px; } +.workspace summary { color: #686f6c; cursor: pointer; font-size: 12px; justify-content: space-between; } +.count { background: #e9ebe8; border-radius: 999px; font-size: 10px; padding: 3px 7px; } +.workspace-body { display: grid; gap: 10px; padding-top: 10px; } +.source-list, .source-detail { background: #fff; border: 1px solid #e3e5e1; border-radius: 9px; padding: 9px; } +.empty { color: #8a918e; font-size: 12px; } +.source-item { background: #fff; border: 1px solid #e5e7e3; border-radius: 7px; display: block; margin-bottom: 6px; padding: 8px; text-align: left; width: 100%; } +.source-item.active { border-color: #4f9a8c; } +.source-title { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.source-meta { color: #858b88; font-size: 10px; margin-top: 3px; } +.source-detail dl { display: grid; gap: 7px; margin: 0; } +.source-detail dt { color: #858b88; font-size: 10px; } +.source-detail dd { font-size: 11px; margin: 1px 0 0; overflow-wrap: anywhere; } diff --git a/apps/extension/public/sidepanel.html b/apps/extension/public/sidepanel.html index 23bf639..c47a748 100644 --- a/apps/extension/public/sidepanel.html +++ b/apps/extension/public/sidepanel.html @@ -9,34 +9,49 @@
-
-

DataRecipe

-

AI 有数

+
+ +
+

AI 有数

+

页面数据 Agent

+
- 未开始 + 待命
-
- - +
+
+ 让 AI 先认识这个页面 +

开启后,请在页面里完成一次查询或翻页。

+
+
+ + +
-
- 0 - 个数据来源 -
+
-
-
-
发现的数据来源
-
还没有发现数据来源
-
+
+ + +
-
-
详情
-
点击「开始发现」,然后在页面里触发一次查询。
-
-
+
+ + +
+ +
+ + 高级信息 + 0 个数据源 + +
+
学习页面后,数据源会显示在这里。
+
尚未选择数据源。
+
+
diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index 3ff6fb4..cd826fe 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,46 +1,81 @@ import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; import { runRecipeOnSample } from "@data-recipe/recipe-runner"; import { buildDataSkillPackage, type DataSkillPackage } from "@data-recipe/skill-builder"; -import { exportDataSkillPackageAsJson, validateDataSkillPackage } from "@data-recipe/skill-exporter"; +import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; +import type { DataRecipe } from "@data-recipe/recipe-core"; import type { PanelEvent, PanelSnapshot } from "./messages"; -interface RecipeMetadata { - displayName?: string; - description?: string; - useCases?: string[]; +type PlanStatus = "pending" | "running" | "done"; + +interface AgentPlanStep { + label: string; + status: PlanStatus; +} + +interface ToolCallView { + name: "listCapturedSources" | "buildRecipe" | "runRecipe" | "exportSkillPackage"; + summary: string; + output: unknown; +} + +interface ChatMessage { + id: string; + role: "assistant" | "user"; + text: string; + plan?: AgentPlanStep[]; + tools?: ToolCallView[]; + skillPackage?: DataSkillPackage; } -const FIELD_LABELS_STORAGE_KEY = "dataRecipeFieldLabels"; -const RECIPE_META_STORAGE_KEY = "dataRecipeMetadata"; const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); const state: { snapshot: PanelSnapshot; selectedId: string | null; - fieldLabels: Record>; - recipeMetadata: Record; + running: boolean; + messages: ChatMessage[]; } = { - snapshot: { - tabId: null, - state: "idle", - captures: [] - }, + snapshot: { tabId: null, state: "idle", captures: [] }, selectedId: null, - fieldLabels: {}, - recipeMetadata: {} + running: false, + messages: [{ + id: createId(), + role: "assistant", + text: "你好,我是 AI 有数。告诉我你想从当前页面了解什么,我会先学习页面,再帮你读取数据、生成配方并测试。" + }] }; const elements = { statusBadge: getElement("statusBadge"), startButton: getElement("startButton"), stopButton: getElement("stopButton"), + learnHint: getElement("learnHint"), + messageList: getElement("messageList"), + composer: getElement("composer"), + chatInput: getElement("chatInput"), + sendButton: getElement("sendButton"), + suggestions: getElement("suggestions"), captureCount: getElement("captureCount"), requestList: getElement("requestList"), requestDetail: getElement("requestDetail") }; -elements.startButton.addEventListener("click", () => port.postMessage({ type: "start-discovery" })); +elements.startButton.addEventListener("click", startLearning); elements.stopButton.addEventListener("click", () => port.postMessage({ type: "stop-discovery" })); +elements.composer.addEventListener("submit", (event) => { + event.preventDefault(); + void submitGoal(elements.chatInput.value); +}); +elements.chatInput.addEventListener("keydown", (event) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + elements.composer.requestSubmit(); + } +}); +elements.chatInput.addEventListener("input", resizeComposer); +elements.suggestions.querySelectorAll("[data-prompt]").forEach((button) => { + button.addEventListener("click", () => void submitGoal(button.dataset.prompt ?? "")); +}); port.onMessage.addListener((event: PanelEvent) => { if (event.type === "snapshot") { @@ -49,377 +84,295 @@ port.onMessage.addListener((event: PanelEvent) => { } if (event.type === "capture-added") { - applySnapshot(event.snapshot); + const wasEmpty = state.snapshot.captures.length === 0; + state.snapshot = event.snapshot; state.selectedId = event.capture.id; + if (wasEmpty) { + addMessage("assistant", "我已经捕获到第一个数据来源。你现在可以直接告诉我想分析什么。", false); + } render(); } }); -void loadStoredEdits(); port.postMessage({ type: "get-snapshot" }); +render(); -function applySnapshot(snapshot: PanelSnapshot): void { - state.snapshot = snapshot; - if (!state.selectedId && snapshot.captures[0]) { - state.selectedId = snapshot.captures[0].id; - } - render(); +function startLearning(): void { + port.postMessage({ type: "start-discovery" }); + addMessage("assistant", "已开始学习当前页面。请回到页面执行一次查询、筛选或翻页,我会观察相关数据请求。", true); } -function render(): void { - const isActive = state.snapshot.state === "active"; - elements.statusBadge.textContent = isActive ? "发现中" : "未开始"; - elements.statusBadge.classList.toggle("active", isActive); - elements.startButton.disabled = isActive; - elements.stopButton.disabled = !isActive; - elements.captureCount.textContent = String(state.snapshot.captures.length); - - renderList(); - renderDetail(); -} - -function renderList(): void { - const captures = state.snapshot.captures; - elements.requestList.innerHTML = ""; +async function submitGoal(rawGoal: string): Promise { + const goal = rawGoal.trim(); + if (!goal || state.running) return; + + elements.chatInput.value = ""; + resizeComposer(); + addMessage("user", goal, false); + + const agentMessage: ChatMessage = { + id: createId(), + role: "assistant", + text: "我先制定一个本地执行计划。", + plan: [ + { label: "列出已学习的数据来源", status: "pending" }, + { label: "选择来源并生成 recipe 草稿", status: "pending" }, + { label: "用已捕获响应进行本地测试", status: "pending" }, + { label: "生成 fallback Data Skill Package", status: "pending" } + ], + tools: [] + }; + state.messages.push(agentMessage); + state.running = true; + renderChat(); + scrollToLatest(); - if (captures.length === 0) { - elements.requestList.className = "list-empty"; - elements.requestList.textContent = "还没有发现数据来源"; - return; + try { + await executeLocalAgentLoop(agentMessage, goal); + } finally { + state.running = false; + render(); } - - elements.requestList.className = ""; - - captures.forEach((capture) => { - const detection = summarizeResponse(capture.responseBody); - const button = document.createElement("button"); - button.type = "button"; - button.className = `request-item${capture.id === state.selectedId ? " active" : ""}`; - button.addEventListener("click", () => { - state.selectedId = capture.id; - render(); - }); - - const title = document.createElement("div"); - title.className = "request-title"; - title.textContent = readableUrl(capture.url); - - const meta = document.createElement("div"); - meta.className = "meta"; - meta.append(pill(capture.method), pill(String(capture.status)), pill(detection.looksLikeList ? "像列表数据" : "普通数据")); - - button.append(title, meta); - elements.requestList.append(button); - }); } -function renderDetail(): void { - const capture = state.snapshot.captures.find((item) => item.id === state.selectedId); +async function executeLocalAgentLoop(message: ChatMessage, goal: string): Promise { + await runPlanStep(message, 0, () => ({ + name: "listCapturedSources", + summary: `发现 ${state.snapshot.captures.length} 个候选数据源`, + output: state.snapshot.captures.map((capture) => ({ + id: capture.id, + url: capture.url, + method: capture.method, + status: capture.status, + capturedAt: new Date(capture.capturedAt).toISOString() + })) + })); + const capture = getSelectedCapture(); if (!capture) { - elements.requestDetail.className = "empty-detail"; - elements.requestDetail.textContent = "点击「开始发现」,然后在页面里触发一次查询。"; + message.text = "当前还没有可用的数据来源。请点击「开始学习页面」,然后在页面中完成一次查询,再把目标发给我。"; + message.plan?.slice(1).forEach((step) => { step.status = "pending"; }); return; } - const detection = summarizeResponse(capture.responseBody); - const recipe = applyRecipeEdits(capture.url, buildRecipeFromCapture(capture)); - const runResult = runRecipeOnSample(recipe, capture.responseBody); - const skillPackage = buildDataSkillPackage({ recipe, userGoal: recipe.description }); - - elements.requestDetail.className = ""; - elements.requestDetail.innerHTML = ""; - elements.requestDetail.append( - block("基础信息", keyValues([ - ["数据来源", capture.url], - ["请求方式", capture.method], - ["状态", String(capture.status)], - ["发现时间", new Date(capture.capturedAt).toLocaleString()] - ])), - block("智能判断", findingList([ - detection.looksLikeList ? "看起来像列表数据" : "暂未判断为列表数据", - detection.hasArray ? `包含数组:${detection.arrayPaths.join(", ")}` : "暂未发现数组", - detection.keywordPaths.length > 0 - ? `可能包含总数、页码或列表字段:${detection.keywordPaths.join(", ")}` - : "暂未发现 total / count / page / records / list 等字段" - ])), - block("查询条件", pre(JSON.stringify({ query: capture.query, body: capture.requestBody ?? {} }, null, 2))), - parameterPreviewBlock(recipe), - fieldPreviewBlock(recipe), - block("返回预览", pre(capture.responsePreview || "无可展示内容")), - recipeMetadataBlock(recipe), - recipeDraftBlock(recipe), - skillPackageBlock(skillPackage), - runPreviewBlock(runResult), - advancedInfo(capture, recipe) - ); -} - -function applyRecipeEdits(sourceKey: string, recipe: ReturnType): ReturnType { - const labels = state.fieldLabels[sourceKey] ?? {}; - const metadata = state.recipeMetadata[sourceKey]; - return { - ...recipe, - displayName: metadata?.displayName ?? recipe.displayName, - description: metadata?.description ?? recipe.description, - useCases: metadata?.useCases?.length ? metadata.useCases : recipe.useCases, - fields: recipe.fields.map((field) => ({ - ...field, - displayName: labels[field.path] ?? field.displayName, - description: labels[field.path] ? "用户确认" : field.description - })) - }; -} -function parameterPreviewBlock(recipe: ReturnType): HTMLElement { - const parameters = [...recipe.request.queryFields, ...recipe.request.bodyFields]; - - if (parameters.length === 0) { - return block("查询条件说明", findingList(["暂未发现明确的查询条件。"])); - } - - return block( - "查询条件说明", - findingList(parameters.slice(0, 12).map((item) => `${item.displayName}:${item.type}${item.sample === undefined ? "" : `,样例 ${formatInlineValue(item.sample)}`}`)) - ); -} - -function fieldPreviewBlock(recipe: ReturnType): HTMLElement { - if (recipe.fields.length === 0 || !state.selectedId) { - return block("返回字段", findingList(["暂未从当前数据中识别出稳定字段。"])); - } - - const wrapper = document.createElement("div"); - wrapper.className = "field-editor"; - - recipe.fields.slice(0, 16).forEach((field) => { - const row = document.createElement("label"); - row.className = "field-row"; - - const input = document.createElement("input"); - input.value = field.displayName; - input.placeholder = field.name; - input.addEventListener("input", () => { - const sourceKey = recipe.source.apiUrl; - const labels = state.fieldLabels[sourceKey] ?? {}; - const label = input.value.trim() || field.name; - labels[field.path] = label; - state.fieldLabels[sourceKey] = labels; - field.displayName = label; - field.description = "用户确认"; - void saveStoredEdits(); - }); - - const meta = document.createElement("span"); - meta.textContent = `${field.name} · ${field.type}${field.sample === undefined ? "" : ` · 样例 ${formatInlineValue(field.sample)}`}`; - - row.append(input, meta); - wrapper.append(row); + let recipe: DataRecipe | undefined; + await runPlanStep(message, 1, () => { + recipe = buildRecipeFromCapture(capture); + return { + name: "buildRecipe", + summary: `已从 ${readableUrl(capture.url)} 生成规则草稿`, + output: recipe + }; }); - return block("返回字段", wrapper); -} - -function recipeMetadataBlock(recipe: ReturnType): HTMLElement { - const wrapper = document.createElement("div"); - wrapper.className = "skill-editor"; - - const nameLabel = document.createElement("label"); - nameLabel.className = "skill-field"; - const nameTitle = document.createElement("span"); - nameTitle.textContent = "数据技能名称"; - const nameInput = document.createElement("input"); - nameInput.value = recipe.displayName; - nameInput.addEventListener("input", () => { - const metadata = state.recipeMetadata[recipe.source.apiUrl] ?? {}; - metadata.displayName = nameInput.value.trim() || "数据来源"; - state.recipeMetadata[recipe.source.apiUrl] = metadata; - recipe.displayName = metadata.displayName; - void saveStoredEdits(); + if (!recipe) return; + const finalRecipe = recipe; + await runPlanStep(message, 2, () => { + const result = runRecipeOnSample(finalRecipe, capture.responseBody); + return { + name: "runRecipe", + summary: result.message, + output: { status: result.status, rowCount: result.rowCount, previewRows: result.previewRows } + }; }); - nameLabel.append(nameTitle, nameInput); - - const descriptionLabel = document.createElement("label"); - descriptionLabel.className = "skill-field"; - const descriptionTitle = document.createElement("span"); - descriptionTitle.textContent = "用途说明"; - const descriptionInput = document.createElement("textarea"); - descriptionInput.rows = 3; - descriptionInput.value = recipe.description; - descriptionInput.addEventListener("input", () => { - const metadata = state.recipeMetadata[recipe.source.apiUrl] ?? {}; - metadata.description = descriptionInput.value.trim(); - metadata.useCases = splitUseCases(descriptionInput.value); - state.recipeMetadata[recipe.source.apiUrl] = metadata; - recipe.description = metadata.description ?? ""; - recipe.useCases = metadata.useCases ?? []; - void saveStoredEdits(); + + await runPlanStep(message, 3, () => { + const skillPackage = buildDataSkillPackage({ recipe: finalRecipe, userGoal: goal }); + message.skillPackage = skillPackage; + return { + name: "exportSkillPackage", + summary: "已用 Mock 模板生成 fallback 技能包,等待用户检查或导出", + output: { packageName: skillPackage.packageName, files: skillPackage.files.map((file) => file.path), mode: "mock-fallback" } + }; }); - descriptionLabel.append(descriptionTitle, descriptionInput); - wrapper.append(nameLabel, descriptionLabel); - return block("数据技能信息", wrapper); + message.text = `已完成本地骨架流程:我选择了「${finalRecipe.displayName}」,生成 recipe、读取样例并完成测试,还准备了一份 fallback 技能包。真实 LLM 接入后,我会根据你的目标自主决定读取深度并编写 SKILL.md。`; } -function skillPackageBlock(skillPackage: DataSkillPackage): HTMLElement { - const wrapper = document.createElement("div"); - wrapper.className = "skill-package"; - - const validation = validateDataSkillPackage(skillPackage); - const summary = document.createElement("div"); - summary.className = "finding"; - summary.textContent = validation.ok - ? `已生成 ${skillPackage.files.length} 个文件,技能包可以导出。` - : `技能包还缺少:${validation.missingFiles.join("、")}`; - - const actions = document.createElement("div"); - actions.className = "package-actions"; - - const skillFile = skillPackage.files.find((file) => file.path === "SKILL.md"); - const recipeFile = skillPackage.files.find((file) => file.path === "recipe.json"); - - actions.append(exportPackageButton(skillPackage)); - if (skillFile) { - actions.append(copyContentButton("复制 SKILL.md", skillFile.content)); - } - if (recipeFile) { - actions.append(copyContentButton("复制 recipe.json", recipeFile.content)); - } - - const details = document.createElement("details"); - const detailsSummary = document.createElement("summary"); - detailsSummary.textContent = "预览 SKILL.md"; - details.append(detailsSummary, pre(skillFile?.content ?? "暂未生成 SKILL.md")); - - wrapper.append(summary, actions, details); - return block("技能包预览", wrapper); +async function runPlanStep(message: ChatMessage, index: number, run: () => ToolCallView): Promise { + const step = message.plan?.[index]; + if (!step) return; + step.status = "running"; + renderChat(); + scrollToLatest(); + await nextFrame(); + const result = run(); + message.tools?.push(result); + step.status = "done"; + renderChat(); + scrollToLatest(); } -function exportPackageButton(skillPackage: DataSkillPackage): HTMLButtonElement { - const button = document.createElement("button"); - button.type = "button"; - button.className = "primary"; - button.textContent = "导出技能包"; - button.addEventListener("click", () => { - downloadTextFile(exportDataSkillPackageAsJson(skillPackage)); - }); - return button; +function applySnapshot(snapshot: PanelSnapshot): void { + state.snapshot = snapshot; + if (!state.selectedId && snapshot.captures[0]) state.selectedId = snapshot.captures[0].id; + render(); } -function downloadTextFile(file: ReturnType): void { - const blob = new Blob([file.content], { type: file.mimeType }); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = file.fileName; - link.click(); - URL.revokeObjectURL(url); -} -function copyContentButton(label: string, content: string): HTMLButtonElement { - const button = document.createElement("button"); - button.type = "button"; - button.className = "copy-button"; - button.textContent = label; - button.addEventListener("click", () => { - void copyText(content, button); - }); - return button; +function render(): void { + const active = state.snapshot.state === "active"; + elements.statusBadge.classList.toggle("active", active); + elements.statusBadge.lastChild!.textContent = active ? "学习中" : "待命"; + elements.startButton.disabled = active; + elements.startButton.textContent = active ? "正在学习页面…" : "开始学习页面"; + elements.stopButton.hidden = !active; + elements.learnHint.textContent = active + ? `正在观察页面操作,已发现 ${state.snapshot.captures.length} 个数据来源。` + : "开启后,请在页面里完成一次查询或翻页。"; + elements.sendButton.disabled = state.running; + elements.captureCount.textContent = `${state.snapshot.captures.length} 个数据源`; + renderChat(); + renderWorkspace(); } -function runPreviewBlock(runResult: ReturnType): HTMLElement { - const wrapper = document.createElement("div"); - wrapper.className = "run-preview"; - const summary = document.createElement("div"); - summary.className = "finding"; - summary.textContent = runResult.message; - wrapper.append(summary); - - if (runResult.previewRows.length > 0) { - wrapper.append(pre(JSON.stringify(runResult.previewRows, null, 2))); - } - - return block("试运行结果", wrapper); +function renderChat(): void { + elements.messageList.innerHTML = ""; + state.messages.forEach((message) => elements.messageList.append(renderMessage(message))); } -function recipeDraftBlock(recipe: unknown): HTMLElement { - const wrapper = document.createElement("div"); - wrapper.className = "recipe-draft"; - - const summary = document.createElement("div"); - summary.className = "finding"; - summary.textContent = "已根据当前数据来源生成一份可复用的数据技能草稿。"; - - const copyButton = document.createElement("button"); - copyButton.type = "button"; - copyButton.className = "copy-button"; - copyButton.textContent = "复制 JSON"; - copyButton.addEventListener("click", () => { - void copyText(JSON.stringify(recipe, null, 2), copyButton); - }); +function renderMessage(message: ChatMessage): HTMLElement { + const article = document.createElement("article"); + article.className = `message ${message.role}`; + const avatar = document.createElement("div"); + avatar.className = "avatar"; + avatar.textContent = message.role === "assistant" ? "AI" : "我"; + const bubble = document.createElement("div"); + bubble.className = "bubble"; + + if (message.role === "assistant") { + const head = document.createElement("div"); + head.className = "message-head"; + head.textContent = "AI 有数"; + bubble.append(head); + } + const text = document.createElement("div"); + text.className = "message-text"; + text.textContent = message.text; + bubble.append(text); + + if (message.plan) { + const plan = document.createElement("ol"); + plan.className = "plan"; + message.plan.forEach((step) => { + const item = document.createElement("li"); + item.className = step.status; + item.textContent = step.label; + plan.append(item); + }); + bubble.append(plan); + } - wrapper.append(summary, copyButton); - return block("数据技能草稿", wrapper); + message.tools?.forEach((tool) => bubble.append(toolCallDetails(tool))); + if (message.skillPackage) bubble.append(packageActions(message.skillPackage)); + article.append(avatar, bubble); + return article; } -function advancedInfo(capture: CapturedRequest, recipe: unknown): HTMLElement { +function toolCallDetails(tool: ToolCallView): HTMLElement { const details = document.createElement("details"); + details.className = "tool-call"; const summary = document.createElement("summary"); - summary.textContent = "高级信息"; - const content = document.createElement("div"); - content.className = "detail-block"; - content.append( - block("传输方式", keyValues([["类型", capture.transport]])), - block("数据技能 JSON", pre(JSON.stringify(recipe, null, 2))) - ); - details.append(summary, content); + summary.textContent = `✓ ${tool.name} · ${tool.summary}`; + const output = document.createElement("pre"); + output.textContent = JSON.stringify(tool.output, null, 2); + details.append(summary, output); return details; } -function block(titleText: string, content: HTMLElement): HTMLElement { - const section = document.createElement("section"); - section.className = "detail-block"; - const title = document.createElement("h2"); - title.textContent = titleText; - section.append(title, content); - return section; +function packageActions(skillPackage: DataSkillPackage): HTMLElement { + const actions = document.createElement("div"); + actions.className = "artifact-actions"; + const exportButton = document.createElement("button"); + exportButton.type = "button"; + exportButton.textContent = "导出 fallback 技能包"; + exportButton.addEventListener("click", () => downloadTextFile(exportDataSkillPackageAsJson(skillPackage))); + const recipe = skillPackage.files.find((file) => file.path === "recipe.json"); + const copyButton = document.createElement("button"); + copyButton.type = "button"; + copyButton.textContent = "复制 recipe.json"; + copyButton.addEventListener("click", () => void copyText(recipe?.content ?? "", copyButton)); + actions.append(exportButton, copyButton); + return actions; } -function keyValues(items: Array<[string, string]>): HTMLElement { - const list = document.createElement("dl"); - list.className = "key-value"; - items.forEach(([key, value]) => { - const wrapper = document.createElement("div"); +function renderWorkspace(): void { + const captures = state.snapshot.captures; + elements.requestList.innerHTML = ""; + if (captures.length === 0) { + elements.requestList.className = "source-list empty"; + elements.requestList.textContent = "学习页面后,数据源会显示在这里。"; + } else { + elements.requestList.className = "source-list"; + captures.forEach((capture) => { + const button = document.createElement("button"); + button.type = "button"; + button.className = `source-item${capture.id === state.selectedId ? " active" : ""}`; + const title = document.createElement("div"); + title.className = "source-title"; + title.textContent = readableUrl(capture.url); + const meta = document.createElement("div"); + meta.className = "source-meta"; + meta.textContent = `${capture.method} · ${capture.status} · ${summarizeResponse(capture.responseBody).looksLikeList ? "列表" : "普通响应"}`; + button.append(title, meta); + button.addEventListener("click", () => { state.selectedId = capture.id; renderWorkspace(); }); + elements.requestList.append(button); + }); + } + + const capture = getSelectedCapture(); + elements.requestDetail.innerHTML = ""; + if (!capture) { + elements.requestDetail.className = "source-detail empty"; + elements.requestDetail.textContent = "尚未选择数据源。"; + return; + } + elements.requestDetail.className = "source-detail"; + const recipe = buildRecipeFromCapture(capture); + const info = document.createElement("dl"); + const sourceFacts: Array<[string, string]> = [ + ["接口", capture.url], + ["页面", capture.pageUrl], + ["请求", `${capture.method} · ${capture.status}`], + ["传输", capture.transport] + ]; + sourceFacts.forEach(([key, value]) => { + const row = document.createElement("div"); const dt = document.createElement("dt"); const dd = document.createElement("dd"); dt.textContent = key; dd.textContent = value; - wrapper.append(dt, dd); - list.append(wrapper); + row.append(dt, dd); + info.append(row); }); - return list; + const details = document.createElement("details"); + const summary = document.createElement("summary"); + summary.textContent = "查看 recipe 草稿与响应预览"; + const content = document.createElement("pre"); + content.textContent = JSON.stringify({ recipe, responsePreview: capture.responsePreview }, null, 2); + details.append(summary, content); + elements.requestDetail.append(info, details); } -function findingList(items: string[]): HTMLElement { - const container = document.createElement("div"); - container.className = "finding"; - items.forEach((item) => { - const line = document.createElement("div"); - line.textContent = item; - container.append(line); - }); - return container; +function getSelectedCapture(): CapturedRequest | undefined { + return state.snapshot.captures.find((capture) => capture.id === state.selectedId) ?? state.snapshot.captures[0]; +} + +function addMessage(role: ChatMessage["role"], text: string, dedupe: boolean): void { + if (dedupe && state.messages.at(-1)?.text === text) return; + state.messages.push({ id: createId(), role, text }); + renderChat(); + scrollToLatest(); } -function pre(text: string): HTMLElement { - const element = document.createElement("pre"); - element.textContent = text; - return element; +function scrollToLatest(): void { + window.requestAnimationFrame(() => { + window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" }); + }); } -function pill(text: string): HTMLElement { - const element = document.createElement("span"); - element.className = "pill"; - element.textContent = text; - return element; +function resizeComposer(): void { + elements.chatInput.style.height = "auto"; + elements.chatInput.style.height = `${Math.min(elements.chatInput.scrollHeight, 120)}px`; } function readableUrl(urlValue: string): string { @@ -431,67 +384,37 @@ function readableUrl(urlValue: string): string { } } -async function loadStoredEdits(): Promise { - try { - const stored = await chrome.storage.local.get([FIELD_LABELS_STORAGE_KEY, RECIPE_META_STORAGE_KEY]); - const labels = stored[FIELD_LABELS_STORAGE_KEY]; - const metadata = stored[RECIPE_META_STORAGE_KEY]; - if (labels && typeof labels === "object" && !Array.isArray(labels)) { - state.fieldLabels = labels as Record>; - } - if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) { - state.recipeMetadata = metadata as Record; - } - render(); - } catch { - // Local edits remain usable even if extension storage is unavailable. - } -} - -async function saveStoredEdits(): Promise { - try { - await chrome.storage.local.set({ - [FIELD_LABELS_STORAGE_KEY]: state.fieldLabels, - [RECIPE_META_STORAGE_KEY]: state.recipeMetadata - }); - } catch { - // The current in-memory edit is still reflected in the copied draft. - } -} -function splitUseCases(value: string): string[] { - return value - .split(/[\n,,;;]+/) - .map((item) => item.trim()) - .filter(Boolean) - .slice(0, 8); -} -function formatInlineValue(value: unknown): string { - const text = typeof value === "string" ? value : JSON.stringify(value); - if (!text) { - return "空"; - } - return text.length > 48 ? `${text.slice(0, 48)}...` : text; -} -function getElement(id: string): T { - const element = document.getElementById(id); - if (!element) { - throw new Error(`Missing element: ${id}`); - } - return element as T; +function downloadTextFile(file: ReturnType): void { + const blob = new Blob([file.content], { type: file.mimeType }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = file.fileName; + link.click(); + URL.revokeObjectURL(url); } async function copyText(text: string, button: HTMLButtonElement): Promise { - const originalText = button.textContent ?? "复制 JSON"; - + const original = button.textContent ?? "复制"; try { await navigator.clipboard.writeText(text); button.textContent = "已复制"; } catch { button.textContent = "复制失败"; } + window.setTimeout(() => { button.textContent = original; }, 1500); +} + +function nextFrame(): Promise { + return new Promise((resolve) => window.requestAnimationFrame(() => resolve())); +} - window.setTimeout(() => { - button.textContent = originalText; - }, 1600); +function createId(): string { + return `${Date.now()}-${Math.random().toString(36).slice(2)}`; } +function getElement(id: string): T { + const element = document.getElementById(id); + if (!element) throw new Error(`Missing element: ${id}`); + return element as T; +} diff --git a/docs/agent-tool-architecture.md b/docs/agent-tool-architecture.md index e352a27..bc0c100 100644 --- a/docs/agent-tool-architecture.md +++ b/docs/agent-tool-architecture.md @@ -2,12 +2,12 @@ ## Direction -DataRecipe is a browser-resident tool layer used by an AI Agent. The extension does not own a fixed pipeline that turns one capture into one templated Skill. It exposes capabilities and constrained runtime access; the Agent owns planning and judgment. +DataRecipe is a browser-resident tool layer used by an AI Agent. Its primary UI is a conversational side-panel Agent; future external Agents reuse the same tools. The extension does not own a fixed pipeline that turns one capture into one templated Skill. It exposes capabilities and constrained runtime access; the active Agent owns planning and judgment. ```text -User goal +User goal in side-panel chat ↓ -AI Agent (plans, reads selectively, edits, writes SKILL.md) +Built-in Agent (plans, reads selectively, edits, writes SKILL.md) ↓ tool calls DataRecipe Agent Tool Layer ├─ capture catalog and bounded readers @@ -25,6 +25,8 @@ The responsibility split is: 3. **User authorizes and confirms.** Browser-session access, origin permissions, recipe runs, and export confirmation remain visible user decisions where required. 4. **Data Skill Package is the deliverable.** It contains an Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and README. +The current MVP uses a deterministic local Agent Loop: it turns a natural-language goal into a visible plan, then calls capture listing, rule-based recipe building, local sample execution, and Mock fallback package generation. Tool results stay collapsed beneath the conversation. A real LLM planner can replace this loop later without changing the tool contracts. + ## Agent-facing tools The canonical TypeScript contracts live in `@data-recipe/agent-tools-core`. From ad0304a3a881f5020a4f793fd2fc99a384821b52 Mon Sep 17 00:00:00 2001 From: null_object_0000 Date: Fri, 10 Jul 2026 15:17:03 +0800 Subject: [PATCH 24/25] feat: implement OpenAI-compatible agent runtime with configurable provider - Added `@data-recipe/agent-runtime` package for handling agent interactions with OpenAI-compatible models. - Introduced `OpenAICompatibleProvider` for API communication and `ToolCallingAgentRuntime` for executing agent logic. - Updated sidepanel to utilize the new agent runtime, enabling real-time tool calls and user-configured settings. - Enhanced UI for model configuration and improved user prompts for agent interactions. - Refactored existing code to accommodate the new agent architecture and removed deprecated features. - Added tests for the agent runtime functionality to ensure reliability. --- AGENTS.md | 7 +- PR_TESTING.md | 119 ++---- README.en.md | 9 +- README.md | 10 +- README.zh-CN.md | 9 +- apps/extension/package.json | 2 + apps/extension/public/manifest.json | 2 +- apps/extension/public/sidepanel.css | 43 ++- apps/extension/public/sidepanel.html | 32 +- apps/extension/src/agent-tool-definitions.ts | 71 ++++ apps/extension/src/agent-tools.ts | 327 ++++++++++++++++ apps/extension/src/sidepanel.ts | 370 ++++++++++--------- docs/agent-tool-architecture.md | 15 +- package.json | 1 + packages/agent-runtime/package.json | 18 + packages/agent-runtime/src/index.ts | 237 ++++++++++++ packages/agent-runtime/tsconfig.json | 11 + packages/agent-tools-core/src/index.ts | 1 - packages/skill-builder/src/index.ts | 31 +- pnpm-lock.yaml | 8 + scripts/test-agent-runtime.mjs | 61 +++ tsconfig.base.json | 3 + 22 files changed, 1089 insertions(+), 298 deletions(-) create mode 100644 apps/extension/src/agent-tool-definitions.ts create mode 100644 apps/extension/src/agent-tools.ts create mode 100644 packages/agent-runtime/package.json create mode 100644 packages/agent-runtime/src/index.ts create mode 100644 packages/agent-runtime/tsconfig.json create mode 100644 scripts/test-agent-runtime.mjs diff --git a/AGENTS.md b/AGENTS.md index 72ebfd1..bc37161 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ DataRecipe is an **Agent Tool Layer**, not a fixed-flow Skill generator. -The primary user experience is the browser side panel's built-in conversational Agent. Users state goals in natural language; the side-panel Agent plans and calls the same Agent Tool Layer that future external Agents can reuse. +The primary user experience is the browser side panel's real conversational Agent. Users configure an OpenAI-compatible Provider and state goals in natural language; the side-panel Agent plans through `/v1/chat/completions` tool calls and uses the same Agent Tool Layer that future external Agents can reuse. ## Responsibility boundaries @@ -10,6 +10,7 @@ The primary user experience is the browser side panel's built-in conversational - The side-panel Agent (or a future external Agent) decides which captures to inspect, how much content to read, how to refine a recipe, and how to write `SKILL.md` for the user's actual goal. - The user authorizes browser access and confirms sensitive execution/export actions. - The final artifact is a **Data Skill Package** containing `SKILL.md`, `recipe.json`, examples, and human-readable documentation. +- Provider credentials stay in `chrome.storage.local`; never pass them to a tool, model message, capture, recipe, or package. ## Agent-facing tools @@ -24,6 +25,8 @@ Keep these names and responsibilities stable: Never silently expand a bounded read to a full read. Never expose Cookie, Authorization headers, or equivalent browser credentials to the Agent. +`readCapture` / `inspectResponse` full reads, every `runRecipe`, and every `exportSkillPackage` require action-time user confirmation. Model-provided flags do not count as user confirmation. + ## Artifact policy -`recipe.json` is machine-oriented execution configuration. Rules and tools generate the initial draft; the Agent may inspect and modify it. `SKILL.md` is authored by the Agent from tool results and user intent, and must not be constrained to a deterministic template. A deterministic Mock template may remain for demos, offline operation, and non-Agent fallback only. +`recipe.json` is machine-oriented execution configuration. Rules and tools generate the initial draft; the Agent may inspect and modify it. `SKILL.md` is authored by the configured model from tool results and user intent, and must not be constrained to a deterministic template. Mock generation is test/development-only and must never appear in the user-facing path. diff --git a/PR_TESTING.md b/PR_TESTING.md index ecf3763..9451d2e 100644 --- a/PR_TESTING.md +++ b/PR_TESTING.md @@ -1,100 +1,55 @@ -# PR Testing — Data Skill Package + Browser RPC Bridge Runtime +# PR Testing — Real side-panel Agent Runtime -This document records what was tested for the current PR. The branch direction -is **Data Skill Package + Browser RPC Bridge Runtime**. This round intentionally -does NOT include complex UI, MCP, OpenAPI, cross-page composition, or a real -Agent host/tool transport integration. +This round makes the real OpenAI-compatible Agent the only user-facing chat path. -## Scope of this round - -1. Restructure `SKILL.md` into a standard Skill file (YAML frontmatter + structured sections). -2. Add Agent-facing tool contracts and retain a deterministic `MockSkillMarkdownFallback` only for non-Agent fallback. -3. Fix pagination detection logic. -4. Add `runRecipeWithBrowserRpc` interface to `recipe-runner`. -5. Update architecture docs in the READMEs. -6. Keep the whole monorepo type-clean and the extension buildable. - -## Automated checks (required, all green) +## Automated checks ```bash -pnpm install -pnpm typecheck # must exit 0 across all packages + the extension -pnpm build:extension # must produce apps/extension/dist/*.global.js +pnpm typecheck +pnpm build:extension ``` -Run result on this PR: - -- `pnpm typecheck` → all 7 packages + extension typecheck pass. -- `pnpm build:extension` → builds `content.global.js`, `background.global.js`, `sidepanel.global.js`, `page-hook.global.js`. - -## Manual verification — Skill package export loop - -These checks reproduce the end-to-end flow on `docs/test-page.html`. - -1. `pnpm build:extension`, load `apps/extension/dist` as an unpacked extension. -2. Open `docs/test-page.html`, open the side panel, click **开始发现**. -3. Click **触发 fetch 查询** / **触发 XHR 查询**. -4. Confirm the side panel shows the discovered source, the query fields, the sample preview, and a minimal recipe draft. - -### SKILL.md structure (this round's focus) - -Export the Data Skill Package and open the generated `SKILL.md`. Confirm: - -- **YAML frontmatter present** at the very top of the file, delimited by `---`, containing `name` and `description`: - ```yaml - --- - name: - description: "" - ``` -- **Sections present**, in this order: `# `, `## Runtime`, `## Inputs`, `## Outputs`, `## Execution`, `## Safety`, `## Examples`. -- **Inputs** lists each query/body field with type, required/optional, and source path. -- **Outputs** lists each return field with type and path, plus the list-path and total-path hints. -- **Execution** describes the Browser RPC Bridge flow and pagination behavior (page / cursor / unknown). -- **Safety** includes the "only authorized data / no credential harvesting / dry-run first" rules. - -### Agent-authored SKILL.md and Mock fallback - -- `buildDataSkillPackage({ recipe })` with no Agent-authored content still produces a full `SKILL.md` via `MockSkillMarkdownFallback`. -- Passing `skillMarkdown` uses the Agent-authored content verbatim (with a trailing newline) and does not invoke the fallback. -- The long-term integration point is the six-tool Agent Tool Layer, not an `LLMProvider.generateSkillMarkdown` call. -- The default template is deterministic; the prose is identical to the structure above. +The following packages and surfaces must compile: -## Manual verification — pagination fix (this round's focus) +- `@data-recipe/agent-runtime` +- `@data-recipe/agent-tools-core` +- `@data-recipe/skill-builder` +- the Chrome side panel and its six tool handlers -Build a recipe draft from a captured request and inspect `recipe.json#pagination` (or -inspect the SKILL.md `## Execution` pagination note). Expect: +## Manual verification -- A request with a `page` / `pageNo` / `pageNum` / `current` / `currentPage` parameter → `pagination.type === "page_number"`, and the matching field is recorded as `pageParam`. -- A request with **only** `pageSize` / `limit` / `size` (no page parameter) → `pagination.type === "unknown"`. Previously this was incorrectly marked `page_number`; it should NOT be. -- A request with neither → `pagination.type === "unknown"`. +### Provider settings -You can verify quickly by capturing a request whose query is `?limit=20` (no `page`): -the generated SKILL.md `## Execution` step 8 should read "Pagination behavior is unknown". +1. Open the side panel with no saved configuration. +2. Confirm the chat input is disabled and asks the user to configure a model. +3. Open “模型设置” and save `baseUrl`, `apiKey`, and a tool-capable `model`. +4. Reopen the side panel and confirm the configuration was restored from `chrome.storage.local`. -## Manual verification — recipe-runner Browser RPC interface (this round's focus) +### Agent tool loop -This is a **type-level wiring** change. The real bridge transport is NOT implemented -this round. Verify the contract: +1. Open `docs/test-page.html` and click “开始学习页面”. +2. Trigger a fetch or XHR request. +3. Ask the Agent to create a data skill. +4. Confirm the configured provider receives `/v1/chat/completions` requests with messages and function tools. +5. Confirm returned `tool_calls` execute locally and collapsed tool results are sent back as `role: tool` messages with matching `tool_call_id`. +6. Confirm the loop ends only when the model returns final assistant text or reaches the iteration limit. -- `recipe-runner` exports `runRecipeWithBrowserRpc(input: { recipe, variables? })`. -- Its return type is `BrowserRunRecipeResult` from `@data-recipe/browser-rpc-core` (status `ok | empty | blocked | error`, plus `recipeName`, optional `rows`/`rowCount`/`responsePreview`/`message`). -- For a `browser_rpc` recipe it currently **returns `blocked`** (placeholder) rather than throwing. -- For a non-`browser_rpc` recipe it returns `blocked` with a localized message. -- `recipe-runner` also exports `createBrowserRpcError` to construct `BrowserRpcError` values — used later when the real transport lands. +### Safety confirmations -Because the real round-trip is deferred, this is verified via `pnpm typecheck` (the -surface compiles against `browser-rpc-core`'s types) rather than live execution. +- `readCapture` and `inspectResponse` preview/page/range modes do not silently expand to full reads. +- Full capture/response reads require a visible user confirmation. +- Every `runRecipe` requires a visible user confirmation. +- Every `exportSkillPackage` requires a visible user confirmation. +- A recipe whose API URL is not present in current captures is rejected. +- Cookie, Authorization, API key, password, secret, and token-shaped captured fields are redacted before model exposure. +- Provider credentials are never included in tool inputs, tool results, recipes, or exported packages. -## Out of scope this round (deferred to follow-up PRs) +### Skill package path -- Complex side-panel UI changes. -- MCP / OpenAPI integration. -- Cross-page recipe composition. -- Agent host integration that exposes the six tool contracts and supplies Agent-authored `SKILL.md`. -- Real browser RPC execution: `recipe.runRecipe()` inside the extension's authorized session. `runRecipeWithBrowserRpc` returns `blocked` until then. +- `buildDataSkillPackage` rejects empty Agent-authored `skillMarkdown`. +- The side panel does not call the Mock development helper. +- Export uses the `SKILL.md` supplied by the model to `exportSkillPackage`. -## Regression notes +## Known limitation -- `skill-exporter.validateDataSkillPackage` still expects `SKILL.md` (content non-empty); the YAML frontmatter + structured body satisfy this. -- The default Mock fallback keeps the current side-panel flow working while Agent-authored `skillMarkdown` is the preferred package path. -- Adding `@data-recipe/browser-rpc-core` to `recipe-runner`'s dependencies does not change the public API of `recipe-runner` for existing consumers; `runRecipeOnSample` is unchanged. +Non-dry-run Browser RPC execution remains a typed placeholder and returns `blocked` until the real bridge transport is connected. Streaming is intentionally not implemented in this round. diff --git a/README.en.md b/README.en.md index b361394..534517f 100644 --- a/README.en.md +++ b/README.en.md @@ -129,6 +129,7 @@ data-recipe/ │ └── extension/ # Browser sidebar extension ├── packages/ │ ├── browser-rpc-core/ # Browser RPC Bridge protocol types +│ ├── agent-runtime/ # OpenAI-compatible Agent Runtime │ ├── agent-tools-core/ # Agent-facing tool contracts │ ├── detector/ # API request detection │ ├── recipe-core/ # Core Data Recipe model @@ -184,7 +185,7 @@ apps/extension/dist 4. State a goal in natural language; the side-panel Agent should create a plan and call the local tools; 5. Tool results remain collapsed, while "高级信息" contains data-source details and the recipe draft. -The side panel is the primary workspace for ordinary users: conversation is the main UI, while sources, recipes, test output, and tool traces are secondary. The MVP uses a deterministic local Agent Loop; a real LLM can replace it later without changing the shared Agent Tool Layer used by future external Agents. +The side panel is the primary workspace for ordinary users: conversation is the main UI, while sources, recipes, test output, and tool traces are secondary. Users first configure an OpenAI-compatible Provider (`baseUrl`, `apiKey`, and a tool-capable `model`). The side panel then runs a real Agent through `/v1/chat/completions`; future external Agents can reuse the same Agent Tool Layer. You can also start discovery on any page you are authorized to access and then trigger a page query. This MVP only performs low-frequency local detection. It does not bypass login, captchas, risk controls, or dynamic signatures. @@ -245,7 +246,7 @@ The command checks that all four required files are present and non-empty. It ex * **The Agent makes judgments:** it selects sources, decides how much to read, reviews and edits the recipe, and freely authors `SKILL.md` from tool evidence and the user's goal. * **The user authorizes and confirms:** browser-session access, origin permissions, recipe runs, and protected export actions remain user-controlled. * **recipe.json remains the low-level config:** rules and tools generate its draft; the Agent may inspect and modify it before runtime validation. -* **The Mock template is fallback only:** it supports the current non-Agent side panel, offline use, and degraded flows, but is not the long-term generation strategy. +* **Mock is not a production path:** the configured model must author `SKILL.md` in the user flow. Mock helpers are restricted to tests and development support. * **The final deliverable is a Data Skill Package:** Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and documentation. ## Long-term Runtime Architecture @@ -272,8 +273,8 @@ See [`docs/agent-tool-architecture.md`](./docs/agent-tool-architecture.md) and [ ## Current MVP Status -* Done: API detection / recipe draft generation / local sample preview / Mock fallback Data Skill Package export / Agent tool type contracts. -* Planned: an Agent host using the six tools to read selectively, inspect/edit recipes, and author SKILL.md. +* Done: API detection / Agent tool contracts / OpenAI-compatible Agent Runtime / side-panel model settings / six local tool handlers. +* Done: the Agent uses tool calls to read selectively, inspect/edit recipes, test runs, and author SKILL.md. * Done: `recipe-runner.runRecipeWithBrowserRpc` is defined, with its types wired to `BrowserRunRecipeResult` from `@data-recipe/browser-rpc-core`. * Not yet implemented: real browser RPC execution. The MVP only completes the wire protocol and the skill package draft; `runRecipeWithBrowserRpc` currently returns `blocked` until the bridge transport is connected in a follow-up PR. diff --git a/README.md b/README.md index a475842..db2b17b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ pnpm install pnpm build:extension ``` -Load `apps/extension/dist` as an unpacked extension in Chrome, open `docs/test-page.html`, and use the DataRecipe side-panel chat. Click “开始学习页面”, trigger a fetch/XHR query, then describe your goal in natural language. The local Agent Loop will show a plan, call the existing tools, test the recipe, and prepare a fallback Data Skill Package. +Load `apps/extension/dist` as an unpacked extension in Chrome, open the side-panel “模型设置”, and configure an OpenAI-compatible `baseUrl`, `apiKey`, and tool-capable `model`. Then open `docs/test-page.html`, click “开始学习页面”, trigger a fetch/XHR query, and describe your goal in natural language. The real Agent will call the local tools, test the recipe, author `SKILL.md`, and ask before exporting a Data Skill Package. ## Validate an exported skill package @@ -30,7 +30,9 @@ pnpm validate:skill-package path/to/your.data-skill.json ## Long-term architecture ```text -User ↔ AI Agent → Agent-facing tools → Browser RPC Bridge → authorized Chrome session +User ↔ Side-panel Agent → OpenAI-compatible /v1/chat/completions + ↓ tool_calls + Agent-facing tools → Browser RPC Bridge → authorized Chrome session ↓ Data Skill Package ``` @@ -39,9 +41,11 @@ The plugin provides tools; the AI Agent decides what to inspect, how much to rea The side panel is the primary conversational Agent workspace. Tool calls and data-source details are secondary, collapsed information; the same Agent Tool Layer remains reusable by future external Agents. +Provider configuration is stored in `chrome.storage.local`. The API key is used only for the configured model request and is never exposed to Agent tools or included in a Data Skill Package. + - **Agent-facing tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Reads support preview, page, range, and explicit full modes. - **recipe.json is rule/tool generated and Agent-reviewable.** It remains the low-level execution config; the Agent may inspect and modify it before running or exporting. -- **SKILL.md is Agent-authored.** It is based on tool evidence and the user's goal, not constrained to a fixed provider/template strategy. The deterministic Mock template remains a fallback for the current MVP UI. +- **SKILL.md is Agent-authored.** It is based on tool evidence and the user's goal. The user-facing flow never auto-generates it from a Mock template; Mock helpers are test/development only. - **Browser RPC Bridge is the runtime tool.** It executes a reviewed recipe inside the user's authorized Chrome session without exposing browser credentials to the Agent. The real round-trip is not wired up yet. - **Current MVP status:** discovery + recipe-draft + local sample preview + skill package export all work end-to-end. Real browser RPC execution (the Chrome extension actually running `browser.runRecipe` inside an authorized session) is NOT implemented yet. `recipe-runner.runRecipeWithBrowserRpc` returns `blocked` until the bridge transport is connected in a follow-up PR. diff --git a/README.zh-CN.md b/README.zh-CN.md index 7701ec2..79b2517 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -122,6 +122,7 @@ data-recipe/ │ └── extension/ # 浏览器侧边栏插件 ├── packages/ │ ├── browser-rpc-core/ # Browser RPC Bridge 协议类型 +│ ├── agent-runtime/ # OpenAI-compatible Agent Runtime │ ├── agent-tools-core/ # Agent-facing tools 类型契约 │ ├── detector/ # API 请求探测 │ ├── recipe-core/ # 数据配方核心结构 @@ -177,7 +178,7 @@ apps/extension/dist 4. 在输入框中用自然语言说明目标,侧边栏 Agent 应生成执行计划并调用本地工具; 5. 工具结果默认折叠,展开「高级信息」可以查看数据来源和 recipe 草稿。 -侧边栏是普通用户的主要工作台:对话是主界面,数据源列表、recipe、测试结果和工具调用记录都是辅助信息。当前使用确定性本地 Agent Loop,后续可以替换为真实 LLM,而 Agent Tool Layer 保持不变并可供外部 Agent 复用。 +侧边栏是普通用户的主要工作台:对话是主界面,数据源列表、recipe、测试结果和工具调用记录都是辅助信息。用户需要先在「模型设置」中配置 OpenAI-compatible Provider 的 `baseUrl`、`apiKey` 和支持 tools 的 `model`。侧边栏随后通过 `/v1/chat/completions` 运行真实 Agent,Agent Tool Layer 同时可供未来外部 Agent 复用。 也可以在任意你有权访问的网页上点击「开始发现」,然后触发页面查询。当前 MVP 只做低频本地探测,不会绕过登录、验证码、风控或动态签名。 @@ -238,7 +239,7 @@ pnpm validate:skill-package path/to/your.data-skill.json * **Agent 做判断**:选择数据来源、决定读取多少、检查并修改配方,并结合工具结果和用户目标自由编写 `SKILL.md`,不受固定模板策略限制。 * **用户做授权和确认**:浏览器会话访问、来源权限、recipe 执行和导出等受保护动作由用户控制。 * **recipe.json 是底层执行配置**:规则和工具先生成草稿,Agent 可以检查和修改,运行时仍会进行约束和校验。 -* **Mock 模板只作 fallback**:当前无 Agent 的侧边栏、离线或降级流程可以使用确定性模板,但它不是长期唯一生成路径。 +* **Mock 不在正式主路径**:用户流程必须由已配置模型编写 `SKILL.md`;Mock helper 只允许用于测试和开发辅助。 * **最终产物是 Data Skill Package**:包含 Agent 编写的 `SKILL.md`、审核后的 `recipe.json`、示例和说明文档。 ## 长期 Runtime 架构 @@ -265,8 +266,8 @@ DataRecipe 的长期执行链路是: ## 当前 MVP 状态 -* 已完成:API 探测 / recipe 草稿生成 / 本地试运行预览 / Mock fallback Data Skill Package 导出 / Agent 工具类型契约; -* 已规划:Agent 通过六个工具自主选择读取范围、检查/修改 recipe 并编写 SKILL.md; +* 已完成:API 探测 / Agent 工具类型契约 / OpenAI-compatible Agent Runtime / 侧边栏模型配置 / 六个本地工具 handler; +* 已完成:Agent 通过 tool calls 自主选择读取范围、检查/修改 recipe、测试运行并编写 SKILL.md; * 已完成:`recipe-runner.runRecipeWithBrowserRpc` 接口定形,类型已接上 `@data-recipe/browser-rpc-core` 的 `BrowserRunRecipeResult`; * 尚未实现:真实浏览器 RPC 执行。当前 MVP 只完成协议和技能包草稿,`runRecipeWithBrowserRpc` 暂时返回 `blocked`,真实执行会在后续 PR 接入。 diff --git a/apps/extension/package.json b/apps/extension/package.json index b83205c..594e11b 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -10,6 +10,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { + "@data-recipe/agent-runtime": "workspace:*", + "@data-recipe/agent-tools-core": "workspace:*", "@data-recipe/detector": "workspace:*", "@data-recipe/recipe-core": "workspace:*", "@data-recipe/recipe-runner": "workspace:*", diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json index 42df91c..1df2fa3 100644 --- a/apps/extension/public/manifest.json +++ b/apps/extension/public/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "DataRecipe / AI 有数", - "description": "发现网页背后的数据来源,并生成可复用的数据配方草稿。", + "description": "内置真实 AI Agent,通过用户配置的 OpenAI-compatible 模型学习页面并生成数据技能。", "version": "0.1.0", "action": { "default_title": "AI 有数" diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 7c071fe..42ac4a9 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -19,12 +19,13 @@ button:disabled { cursor: not-allowed; opacity: .55; } padding: 14px; } -.header, .brand, .learn-actions, .message-head, .artifact-actions, .workspace summary { +.header, .brand, .header-actions, .learn-actions, .message-head, .artifact-actions, .workspace summary, .dialog-head { align-items: center; display: flex; } .header { justify-content: space-between; } +.header-actions { gap: 7px; } .brand { gap: 10px; } .brand-mark { align-items: center; @@ -48,11 +49,22 @@ h1 { font-size: 16px; line-height: 1.2; margin: 0; } display: inline-flex; font-size: 11px; gap: 5px; + max-width: 128px; + overflow: hidden; padding: 5px 8px; + text-overflow: ellipsis; + white-space: nowrap; } .status span { background: #9ca3af; border-radius: 50%; height: 6px; width: 6px; } .status.active { background: #e3f4ef; color: #0f766e; } .status.active span { background: #10b981; box-shadow: 0 0 0 3px #c8eee2; } +.settings-button, .icon-button { + background: transparent; + border: 0; + color: #66706c; + font-size: 11px; + padding: 5px; +} .learn-card { background: linear-gradient(135deg, #ecf7f4, #f3f8f4); @@ -165,3 +177,32 @@ h1 { font-size: 16px; line-height: 1.2; margin: 0; } .source-detail dl { display: grid; gap: 7px; margin: 0; } .source-detail dt { color: #858b88; font-size: 10px; } .source-detail dd { font-size: 11px; margin: 1px 0 0; overflow-wrap: anywhere; } + +.model-dialog { + border: 0; + border-radius: 14px; + box-shadow: 0 18px 60px rgba(15, 35, 29, .22); + max-width: 390px; + padding: 0; + width: calc(100% - 28px); +} +.model-dialog::backdrop { background: rgba(20, 30, 27, .38); } +.model-form { display: grid; gap: 13px; padding: 18px; } +.dialog-head { align-items: flex-start; justify-content: space-between; } +.dialog-head h2 { font-size: 16px; margin: 0; } +.dialog-head p { color: #737b78; font-size: 11px; line-height: 1.45; margin: 4px 0 0; } +.icon-button { font-size: 22px; line-height: 1; } +.model-form label { display: grid; gap: 5px; } +.model-form label span { color: #59625f; font-size: 11px; font-weight: 600; } +.model-form input { + border: 1px solid #d4d9d4; + border-radius: 8px; + min-height: 38px; + outline: 0; + padding: 7px 9px; + width: 100%; +} +.model-form input:focus { border-color: #55988b; box-shadow: 0 0 0 3px #e1f0ec; } +.storage-note { color: #7b827f; font-size: 10px; line-height: 1.5; margin: 0; } +.model-error { color: #b42318; font-size: 11px; margin: 0; min-height: 16px; } +.save-model { width: 100%; } diff --git a/apps/extension/public/sidepanel.html b/apps/extension/public/sidepanel.html index c47a748..19aa357 100644 --- a/apps/extension/public/sidepanel.html +++ b/apps/extension/public/sidepanel.html @@ -16,7 +16,10 @@

AI 有数

页面数据 Agent

- 待命 +
+ + 待命 +
@@ -53,6 +56,33 @@

AI 有数

+ + +
+
+
+

模型设置

+

配置支持 Chat Completions 与 function tools 的 OpenAI-compatible Provider。

+
+ +
+ + + +

配置仅保存到浏览器扩展的本地存储。API Key 不会发送给 Agent 工具或写入技能包。

+ + +
+
diff --git a/apps/extension/src/agent-tool-definitions.ts b/apps/extension/src/agent-tool-definitions.ts new file mode 100644 index 0000000..193c47c --- /dev/null +++ b/apps/extension/src/agent-tool-definitions.ts @@ -0,0 +1,71 @@ +import type { AgentFunctionTool } from "@data-recipe/agent-runtime"; + +const selectionSchema = { + type: "object", + oneOf: [ + { properties: { mode: { const: "preview" }, maxChars: { type: "integer" }, maxItems: { type: "integer" } }, required: ["mode"] }, + { properties: { mode: { const: "page" }, cursor: { type: "string" }, pageSize: { type: "integer" } }, required: ["mode"] }, + { properties: { mode: { const: "range" }, offset: { type: "integer" }, length: { type: "integer" } }, required: ["mode", "offset", "length"] }, + { properties: { mode: { const: "full" } }, required: ["mode"] } + ] +}; + +export const AGENT_TOOL_DEFINITIONS: AgentFunctionTool[] = [ + tool("listCapturedSources", "分页列出插件已捕获的数据来源元信息,不读取完整响应。", { + type: "object", + properties: { cursor: { type: "string" }, pageSize: { type: "integer" }, pageUrl: { type: "string" } } + }), + tool("readCapture", "按预览、分页、范围或完整模式读取某个捕获。full 模式会触发用户确认。", { + type: "object", + properties: { + captureId: { type: "string" }, + section: { enum: ["request", "response", "both"] }, + selection: selectionSchema + }, + required: ["captureId", "section", "selection"] + }), + tool("inspectResponse", "检查响应结构、候选列表路径和字段,并按 bounded read 返回内容。", { + type: "object", + properties: { + captureId: { type: "string" }, + selection: selectionSchema, + jsonPath: { type: "string" }, + maxDepth: { type: "integer" } + }, + required: ["captureId", "selection"] + }), + tool("buildRecipe", "从捕获按规则生成 recipe.json 草稿;可提交检查后的完整 recipe 或 patch。", { + type: "object", + properties: { + captureId: { type: "string" }, + recipe: { type: "object" }, + patch: { type: "object" } + }, + required: ["captureId"] + }), + tool("runRecipe", "测试或运行已检查的 recipe。每次调用都会触发用户确认。", { + type: "object", + properties: { + recipe: { type: "object" }, + variables: { type: "object" }, + dryRun: { type: "boolean" }, + previewLimit: { type: "integer" } + }, + required: ["recipe"] + }), + tool("exportSkillPackage", "导出 Data Skill Package。必须提供 Agent 编写的完整 SKILL.md,并触发用户确认。", { + type: "object", + properties: { + recipe: { type: "object" }, + skillMarkdown: { type: "string" }, + userGoal: { type: "string" }, + examplesMarkdown: { type: "string" }, + readmeMarkdown: { type: "string" } + }, + required: ["recipe", "skillMarkdown", "userGoal"] + }) +]; + +function tool(name: string, description: string, parameters: Record): AgentFunctionTool { + return { type: "function", function: { name, description, parameters } }; +} diff --git a/apps/extension/src/agent-tools.ts b/apps/extension/src/agent-tools.ts new file mode 100644 index 0000000..3781c4b --- /dev/null +++ b/apps/extension/src/agent-tools.ts @@ -0,0 +1,327 @@ +import type { + AgentReadSelection, + AgentToolInputMap, + AgentToolLayer, + AgentToolName, + AgentToolOutputMap, + ReadResult +} from "@data-recipe/agent-tools-core"; +import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; +import type { DataRecipe } from "@data-recipe/recipe-core"; +import { runRecipeOnSample, runRecipeWithBrowserRpc } from "@data-recipe/recipe-runner"; +import { buildDataSkillPackage } from "@data-recipe/skill-builder"; +import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; + +export interface SidepanelAgentToolsOptions { + getCaptures(): CapturedRequest[]; + confirmAction(message: string): Promise; + download(file: { fileName: string; mimeType: string; content: string }): void; +} + +export class SidepanelAgentToolLayer implements AgentToolLayer { + constructor(private readonly options: SidepanelAgentToolsOptions) {} + + async invoke( + name: TName, + input: AgentToolInputMap[TName] + ): Promise { + let output: AgentToolOutputMap[AgentToolName]; + switch (name) { + case "listCapturedSources": + output = this.listCapturedSources(input as AgentToolInputMap["listCapturedSources"]); + break; + case "readCapture": + output = await this.readCapture(input as AgentToolInputMap["readCapture"]); + break; + case "inspectResponse": + output = await this.inspectResponse(input as AgentToolInputMap["inspectResponse"]); + break; + case "buildRecipe": + output = this.buildRecipe(input as AgentToolInputMap["buildRecipe"]); + break; + case "runRecipe": + output = await this.runRecipe(input as AgentToolInputMap["runRecipe"]); + break; + case "exportSkillPackage": + output = await this.exportSkillPackage(input as AgentToolInputMap["exportSkillPackage"]); + break; + default: + throw new Error(`不支持的工具:${String(name)}`); + } + return output as AgentToolOutputMap[TName]; + } + + private listCapturedSources(input: AgentToolInputMap["listCapturedSources"]): AgentToolOutputMap["listCapturedSources"] { + const pageSize = clampInteger(input.pageSize, 1, 50, 20); + const offset = parseCursor(input.cursor); + const filtered = this.options.getCaptures().filter((capture) => !input.pageUrl || capture.pageUrl === input.pageUrl); + const page = filtered.slice(offset, offset + pageSize); + const nextOffset = offset + page.length; + return { + sources: page.map((capture) => ({ + captureId: capture.id, + pageUrl: redactUrl(capture.pageUrl), + apiUrl: redactUrl(capture.url), + method: capture.method, + status: capture.status, + capturedAt: capture.capturedAt, + transport: capture.transport, + responseSize: safeJson(capture.responseBody).length, + preview: selectReadContent(redactSecrets(capture.responseBody), { mode: "preview", maxChars: 500 }).value + })), + nextCursor: nextOffset < filtered.length ? String(nextOffset) : undefined + }; + } + + private async readCapture(input: AgentToolInputMap["readCapture"]): Promise { + const capture = this.requireCapture(input.captureId); + validateSelection(input.selection); + if (input.selection.mode === "full") { + await this.requireConfirmation("Agent 请求完整读取当前捕获内容。完整内容可能较大,是否允许?"); + } + const request = { url: redactUrl(capture.url), method: capture.method, query: capture.query, body: capture.requestBody }; + const raw = input.section === "request" + ? request + : input.section === "response" + ? capture.responseBody + : { request, response: capture.responseBody }; + return selectReadContent(redactSecrets(raw), input.selection); + } + + private async inspectResponse(input: AgentToolInputMap["inspectResponse"]): Promise { + const capture = this.requireCapture(input.captureId); + validateSelection(input.selection); + if (input.selection.mode === "full") { + await this.requireConfirmation("Agent 请求完整读取响应内容以检查结构,是否允许?"); + } + const detection = summarizeResponse(capture.responseBody); + const focused = input.jsonPath ? getByPath(capture.responseBody, input.jsonPath) : capture.responseBody; + const shape = Array.isArray(focused) + ? "list" + : focused && typeof focused === "object" + ? "object" + : focused === undefined + ? "unknown" + : "scalar"; + return { + shape, + listPaths: detection.arrayPaths, + candidateTotalPaths: detection.totalPath ? [detection.totalPath] : [], + candidateFields: detection.fields.map((field) => ({ + path: field.path, + type: field.type, + sample: isSensitiveName(field.path) ? "[REDACTED]" : redactSecrets(field.sample) + })), + content: selectReadContent(redactSecrets(limitDepth(focused, input.maxDepth ?? 8)), input.selection) + }; + } + + private buildRecipe(input: AgentToolInputMap["buildRecipe"]): AgentToolOutputMap["buildRecipe"] { + const capture = this.requireCapture(input.captureId); + const draft = sanitizeRecipe(buildRecipeFromCapture(capture)); + const candidate = input.recipe ?? draft; + const patch = input.patch ?? {}; + const recipe = sanitizeRecipe({ + ...candidate, + ...patch, + source: draft.source, + runtime: draft.runtime, + request: patch.request ? { ...candidate.request, ...patch.request } : candidate.request, + response: patch.response ? { ...candidate.response, ...patch.response } : candidate.response, + pagination: patch.pagination ? { ...candidate.pagination, ...patch.pagination } : candidate.pagination + }); + return { + recipe, + inferredByRules: !input.recipe, + warnings: recipe.fields.length ? [] : ["尚未识别出稳定返回字段,请先 inspectResponse。"] + }; + } + + private async runRecipe(input: AgentToolInputMap["runRecipe"]): Promise { + const recipe = sanitizeRecipe(input.recipe); + const capture = this.requireRecipeCapture(recipe); + await this.requireConfirmation(`Agent 请求运行配方「${recipe.displayName}」,是否允许?`); + if (input.dryRun !== false) { + const result = runRecipeOnSample(recipe, capture.responseBody, { previewLimit: clampInteger(input.previewLimit, 1, 20, 5) }); + return { + recipeName: recipe.name, + status: result.status === "unsupported" ? "error" : result.status, + rows: result.previewRows, + rowCount: result.rowCount, + responsePreview: result.previewRows, + message: result.message + }; + } + return runRecipeWithBrowserRpc({ recipe, variables: redactSecrets(input.variables) as DataRecipe["request"]["query"] }); + } + + private async exportSkillPackage( + input: AgentToolInputMap["exportSkillPackage"] + ): Promise { + this.requireRecipeCapture(input.recipe); + if (!input.skillMarkdown.trim()) throw new Error("Agent 必须先编写 SKILL.md。 "); + await this.requireConfirmation(`Agent 已准备好 Data Skill Package「${input.recipe.displayName}」,是否导出?`); + const skillPackage = buildDataSkillPackage({ + recipe: sanitizeRecipe(input.recipe), + userGoal: input.userGoal, + skillMarkdown: input.skillMarkdown, + examplesMarkdown: input.examplesMarkdown, + readmeMarkdown: input.readmeMarkdown + }); + this.options.download(exportDataSkillPackageAsJson(skillPackage)); + return { package: skillPackage, warnings: [] }; + } + + private requireCapture(id: string): CapturedRequest { + const capture = this.options.getCaptures().find((item) => item.id === id); + if (!capture) throw new Error(`找不到 capture:${id}`); + return capture; + } + + private requireRecipeCapture(recipe: DataRecipe): CapturedRequest { + const capture = this.options.getCaptures().find((item) => redactUrl(item.url) === recipe.source.apiUrl); + if (!capture) throw new Error("recipe 的数据来源不在当前已捕获列表中,拒绝执行。"); + return capture; + } + + private async requireConfirmation(message: string): Promise { + if (!await this.options.confirmAction(message)) throw new Error("用户拒绝了本次操作。"); + } +} + +function selectReadContent(value: unknown, selection: AgentReadSelection): ReadResult { + const text = safeJson(value); + if (selection.mode === "full") { + return { value, selection, truncated: false, totalChars: text.length }; + } + if (selection.mode === "preview") { + const maxChars = clampInteger(selection.maxChars, 100, 8000, 1800); + const previewValue = Array.isArray(value) + ? value.slice(0, clampInteger(selection.maxItems, 1, 100, 10)) + : text.slice(0, maxChars); + return { + value: previewValue, + selection, + truncated: Array.isArray(value) ? previewValue.length < value.length : text.length > maxChars, + totalItems: Array.isArray(value) ? value.length : undefined, + totalChars: text.length + }; + } + if (selection.mode === "range") { + const offset = clampInteger(selection.offset, 0, text.length, 0); + const length = clampInteger(selection.length, 1, 8000, 1800); + return { + value: text.slice(offset, offset + length), + selection, + truncated: offset > 0 || offset + length < text.length, + totalChars: text.length + }; + } + const offset = parseCursor(selection.cursor); + const pageSize = clampInteger(selection.pageSize, 100, 8000, 1800); + const end = Math.min(text.length, offset + pageSize); + return { + value: text.slice(offset, end), + selection, + truncated: end < text.length, + nextCursor: end < text.length ? String(end) : undefined, + totalChars: text.length + }; +} + +function validateSelection(value: AgentReadSelection): void { + if (!value || !["preview", "page", "range", "full"].includes(value.mode)) { + throw new Error("selection.mode 必须是 preview、page、range 或 full。"); + } +} + +function redactSecrets(value: unknown, seen = new WeakSet()): unknown { + if (!value || typeof value !== "object") return value; + if (seen.has(value)) return "[Circular]"; + seen.add(value); + if (Array.isArray(value)) return value.map((item) => redactSecrets(item, seen)); + return Object.fromEntries(Object.entries(value).map(([key, child]) => [ + key, + isSensitiveName(key) + ? "[REDACTED]" + : redactSecrets(child, seen) + ])); +} + +function sanitizeRecipe(recipe: DataRecipe): DataRecipe { + return { + ...recipe, + source: { + ...recipe.source, + pageUrl: redactUrl(recipe.source.pageUrl), + apiUrl: redactUrl(recipe.source.apiUrl) + }, + request: { + ...recipe.request, + query: redactSecrets(recipe.request.query) as DataRecipe["request"]["query"], + body: redactSecrets(recipe.request.body), + queryFields: recipe.request.queryFields.map((field) => ({ + ...field, + sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) + })), + bodyFields: recipe.request.bodyFields.map((field) => ({ + ...field, + sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) + })) + }, + fields: recipe.fields.map((field) => ({ + ...field, + sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) + })) + }; +} + +function redactUrl(value: string): string { + try { + const url = new URL(value); + Array.from(url.searchParams.keys()).forEach((key) => { + if (isSensitiveName(key)) url.searchParams.set(key, "[REDACTED]"); + }); + return url.toString(); + } catch { + return value; + } +} + +function isSensitiveName(value: string): boolean { + return /authorization|cookie|set-cookie|api[-_]?key|access[-_]?token|refresh[-_]?token|password|secret/i.test(value); +} + +function limitDepth(value: unknown, depth: number): unknown { + if (depth <= 0 && value && typeof value === "object") return "[Max depth reached]"; + if (Array.isArray(value)) return value.slice(0, 100).map((item) => limitDepth(item, depth - 1)); + if (value && typeof value === "object") { + return Object.fromEntries(Object.entries(value).slice(0, 100).map(([key, child]) => [key, limitDepth(child, depth - 1)])); + } + return value; +} + +function getByPath(value: unknown, path: string): unknown { + if (!path || path === "$") return value; + return path.replace(/^\$\.?/, "").split(".").filter(Boolean).reduce((current, part) => { + if (!current || typeof current !== "object") return undefined; + return (current as Record)[part]; + }, value); +} + +function clampInteger(value: number | undefined, min: number, max: number, fallback: number): number { + return Number.isFinite(value) ? Math.min(max, Math.max(min, Math.floor(value!))) : fallback; +} + +function parseCursor(cursor: string | undefined): number { + const value = Number(cursor ?? 0); + return Number.isInteger(value) && value >= 0 ? value : 0; +} + +function safeJson(value: unknown): string { + try { + return JSON.stringify(value, null, 2) ?? "null"; + } catch { + return "[Unserializable]"; + } +} diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index cd826fe..008fc33 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,52 +1,74 @@ +import { + OpenAICompatibleProvider, + ToolCallingAgentRuntime, + type AgentChatMessage, + type AgentToolExecutionEvent, + type OpenAICompatibleProviderConfig +} from "@data-recipe/agent-runtime"; +import type { AgentToolInputMap, AgentToolName } from "@data-recipe/agent-tools-core"; import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; -import { runRecipeOnSample } from "@data-recipe/recipe-runner"; -import { buildDataSkillPackage, type DataSkillPackage } from "@data-recipe/skill-builder"; -import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; -import type { DataRecipe } from "@data-recipe/recipe-core"; import type { PanelEvent, PanelSnapshot } from "./messages"; - -type PlanStatus = "pending" | "running" | "done"; - -interface AgentPlanStep { - label: string; - status: PlanStatus; -} +import { AGENT_TOOL_DEFINITIONS } from "./agent-tool-definitions"; +import { SidepanelAgentToolLayer } from "./agent-tools"; interface ToolCallView { - name: "listCapturedSources" | "buildRecipe" | "runRecipe" | "exportSkillPackage"; + name: string; summary: string; + input: unknown; output: unknown; + error?: string; } interface ChatMessage { id: string; role: "assistant" | "user"; text: string; - plan?: AgentPlanStep[]; + pending?: boolean; tools?: ToolCallView[]; - skillPackage?: DataSkillPackage; } +const MODEL_CONFIG_STORAGE_KEY = "dataRecipeOpenAICompatibleProvider"; +const SYSTEM_PROMPT = `你是 AI 有数的数据技能生成 Agent。 + +你可以调用插件提供的工具观察当前页面捕获的数据来源,并根据用户目标生成可复用的 Data Skill Package。 + +工作规则: +- 先用 listCapturedSources 了解可用来源,再按需要调用 readCapture 或 inspectResponse。读多少由你决定,但必须遵守 bounded read;优先 preview/page/range,只有确有必要才请求 full。 +- readCapture full、runRecipe、exportSkillPackage 会要求用户确认。用户拒绝后应尊重决定并调整计划。 +- 不要要求用户提供 Cookie、Authorization header、API token 或其它浏览器凭证。 +- 不要尝试绕过登录、验证码、风控、动态签名、反爬或来源权限。 +- recipe.json 由 buildRecipe 基于规则生成。你必须检查其来源、参数、响应结构、分页和字段,必要时再用 buildRecipe 提交修订。 +- SKILL.md 必须由你根据工具读取结果和用户目标独立编写,不得依赖固定模板。应包含合法 YAML frontmatter、用途、输入、输出、执行方式和安全约束。 +- 在导出前应调用 runRecipe 做一次用户确认的测试。 +- 最终目标是调用 exportSkillPackage 生成 Data Skill Package,并向用户说明结果。`; + const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); const state: { snapshot: PanelSnapshot; selectedId: string | null; running: boolean; + configLoaded: boolean; + providerConfig: OpenAICompatibleProviderConfig | null; messages: ChatMessage[]; + agentMessages: AgentChatMessage[]; } = { snapshot: { tabId: null, state: "idle", captures: [] }, selectedId: null, running: false, + configLoaded: false, + providerConfig: null, messages: [{ id: createId(), role: "assistant", - text: "你好,我是 AI 有数。告诉我你想从当前页面了解什么,我会先学习页面,再帮你读取数据、生成配方并测试。" - }] + text: "你好,我是 AI 有数。配置模型后,告诉我你想从当前页面了解什么,我会调用页面工具生成并测试数据技能。" + }], + agentMessages: [] }; const elements = { statusBadge: getElement("statusBadge"), + settingsButton: getElement("settingsButton"), startButton: getElement("startButton"), stopButton: getElement("stopButton"), learnHint: getElement("learnHint"), @@ -57,15 +79,28 @@ const elements = { suggestions: getElement("suggestions"), captureCount: getElement("captureCount"), requestList: getElement("requestList"), - requestDetail: getElement("requestDetail") + requestDetail: getElement("requestDetail"), + modelDialog: getElement("modelDialog"), + modelForm: getElement("modelForm"), + closeSettingsButton: getElement("closeSettingsButton"), + baseUrlInput: getElement("baseUrlInput"), + apiKeyInput: getElement("apiKeyInput"), + modelInput: getElement("modelInput"), + modelError: getElement("modelError") }; +const toolLayer = new SidepanelAgentToolLayer({ + getCaptures: () => state.snapshot.captures, + confirmAction: async (message) => window.confirm(message), + download: downloadTextFile +}); + +elements.settingsButton.addEventListener("click", openModelSettings); +elements.closeSettingsButton.addEventListener("click", () => elements.modelDialog.close()); +elements.modelForm.addEventListener("submit", (event) => { event.preventDefault(); void saveModelSettings(); }); elements.startButton.addEventListener("click", startLearning); elements.stopButton.addEventListener("click", () => port.postMessage({ type: "stop-discovery" })); -elements.composer.addEventListener("submit", (event) => { - event.preventDefault(); - void submitGoal(elements.chatInput.value); -}); +elements.composer.addEventListener("submit", (event) => { event.preventDefault(); void submitGoal(elements.chatInput.value); }); elements.chatInput.addEventListener("keydown", (event) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); @@ -82,18 +117,16 @@ port.onMessage.addListener((event: PanelEvent) => { applySnapshot(event.snapshot); return; } - if (event.type === "capture-added") { const wasEmpty = state.snapshot.captures.length === 0; state.snapshot = event.snapshot; state.selectedId = event.capture.id; - if (wasEmpty) { - addMessage("assistant", "我已经捕获到第一个数据来源。你现在可以直接告诉我想分析什么。", false); - } + if (wasEmpty) addMessage("assistant", "我已经捕获到第一个数据来源。现在可以告诉我你想生成什么数据技能。", false); render(); } }); +void loadModelSettings(); port.postMessage({ type: "get-snapshot" }); render(); @@ -105,100 +138,64 @@ function startLearning(): void { async function submitGoal(rawGoal: string): Promise { const goal = rawGoal.trim(); if (!goal || state.running) return; + if (!state.providerConfig) { + addMessage("assistant", "请先在「模型设置」中配置 OpenAI-compatible Provider,配置完成后我才能运行真实 Agent。", true); + openModelSettings(); + return; + } elements.chatInput.value = ""; resizeComposer(); addMessage("user", goal, false); - - const agentMessage: ChatMessage = { + const pending: ChatMessage = { id: createId(), role: "assistant", - text: "我先制定一个本地执行计划。", - plan: [ - { label: "列出已学习的数据来源", status: "pending" }, - { label: "选择来源并生成 recipe 草稿", status: "pending" }, - { label: "用已捕获响应进行本地测试", status: "pending" }, - { label: "生成 fallback Data Skill Package", status: "pending" } - ], + text: `正在连接 ${state.providerConfig.model},由模型规划下一步…`, + pending: true, tools: [] }; - state.messages.push(agentMessage); + state.messages.push(pending); state.running = true; - renderChat(); + render(); scrollToLatest(); try { - await executeLocalAgentLoop(agentMessage, goal); + const runtime = new ToolCallingAgentRuntime(new OpenAICompatibleProvider(state.providerConfig)); + const runMessages: AgentChatMessage[] = [...state.agentMessages, { role: "user", content: goal }]; + const result = await runtime.run({ + systemPrompt: SYSTEM_PROMPT, + messages: runMessages, + tools: AGENT_TOOL_DEFINITIONS, + executeTool: invokeAgentTool, + onToolExecution: (event) => showToolExecution(pending, event) + }); + state.agentMessages = result.messages.filter((message) => message.role !== "system"); + pending.text = result.finalText; + pending.pending = false; + } catch (error) { + pending.text = error instanceof Error ? `Agent 运行失败:${error.message}` : "Agent 运行失败。"; + pending.pending = false; } finally { state.running = false; render(); + scrollToLatest(); } } -async function executeLocalAgentLoop(message: ChatMessage, goal: string): Promise { - await runPlanStep(message, 0, () => ({ - name: "listCapturedSources", - summary: `发现 ${state.snapshot.captures.length} 个候选数据源`, - output: state.snapshot.captures.map((capture) => ({ - id: capture.id, - url: capture.url, - method: capture.method, - status: capture.status, - capturedAt: new Date(capture.capturedAt).toISOString() - })) - })); - - const capture = getSelectedCapture(); - if (!capture) { - message.text = "当前还没有可用的数据来源。请点击「开始学习页面」,然后在页面中完成一次查询,再把目标发给我。"; - message.plan?.slice(1).forEach((step) => { step.status = "pending"; }); - return; - } - - let recipe: DataRecipe | undefined; - await runPlanStep(message, 1, () => { - recipe = buildRecipeFromCapture(capture); - return { - name: "buildRecipe", - summary: `已从 ${readableUrl(capture.url)} 生成规则草稿`, - output: recipe - }; - }); - - if (!recipe) return; - const finalRecipe = recipe; - await runPlanStep(message, 2, () => { - const result = runRecipeOnSample(finalRecipe, capture.responseBody); - return { - name: "runRecipe", - summary: result.message, - output: { status: result.status, rowCount: result.rowCount, previewRows: result.previewRows } - }; - }); - - await runPlanStep(message, 3, () => { - const skillPackage = buildDataSkillPackage({ recipe: finalRecipe, userGoal: goal }); - message.skillPackage = skillPackage; - return { - name: "exportSkillPackage", - summary: "已用 Mock 模板生成 fallback 技能包,等待用户检查或导出", - output: { packageName: skillPackage.packageName, files: skillPackage.files.map((file) => file.path), mode: "mock-fallback" } - }; - }); - - message.text = `已完成本地骨架流程:我选择了「${finalRecipe.displayName}」,生成 recipe、读取样例并完成测试,还准备了一份 fallback 技能包。真实 LLM 接入后,我会根据你的目标自主决定读取深度并编写 SKILL.md。`; +async function invokeAgentTool(name: string, input: unknown): Promise { + if (!isAgentToolName(name)) throw new Error(`模型请求了未知工具:${name}`); + return toolLayer.invoke(name, input as never); } -async function runPlanStep(message: ChatMessage, index: number, run: () => ToolCallView): Promise { - const step = message.plan?.[index]; - if (!step) return; - step.status = "running"; - renderChat(); - scrollToLatest(); - await nextFrame(); - const result = run(); - message.tools?.push(result); - step.status = "done"; +function showToolExecution(message: ChatMessage, event: AgentToolExecutionEvent): void { + message.text = event.error ? `工具 ${event.toolCall.function.name} 未完成,模型正在调整计划…` : "模型正在根据工具结果继续工作…"; + message.tools?.push({ + name: event.toolCall.function.name, + summary: event.error ?? summarizeToolResult(event.result), + input: event.arguments, + output: event.result, + error: event.error + }); renderChat(); scrollToLatest(); } @@ -209,17 +206,64 @@ function applySnapshot(snapshot: PanelSnapshot): void { render(); } +async function loadModelSettings(): Promise { + try { + const stored = await chrome.storage.local.get(MODEL_CONFIG_STORAGE_KEY); + const candidate = stored[MODEL_CONFIG_STORAGE_KEY]; + if (isProviderConfig(candidate)) state.providerConfig = candidate; + } finally { + state.configLoaded = true; + render(); + } +} + +function openModelSettings(): void { + elements.baseUrlInput.value = state.providerConfig?.baseUrl ?? "https://api.openai.com"; + elements.apiKeyInput.value = state.providerConfig?.apiKey ?? ""; + elements.modelInput.value = state.providerConfig?.model ?? ""; + elements.modelError.textContent = ""; + elements.modelDialog.showModal(); +} + +async function saveModelSettings(): Promise { + try { + const config: OpenAICompatibleProviderConfig = { + baseUrl: elements.baseUrlInput.value.trim(), + apiKey: elements.apiKeyInput.value.trim(), + model: elements.modelInput.value.trim() + }; + new OpenAICompatibleProvider(config); + const url = new URL(config.baseUrl); + if (!/^https?:$/.test(url.protocol)) throw new Error("Base URL 必须使用 http 或 https。 "); + await chrome.storage.local.set({ [MODEL_CONFIG_STORAGE_KEY]: config }); + state.providerConfig = config; + state.agentMessages = []; + elements.modelDialog.close(); + addMessage("assistant", `模型已配置为 ${config.model}。现在可以开始真实 Agent 对话。`, false); + render(); + } catch (error) { + elements.modelError.textContent = error instanceof Error ? error.message : "模型配置无效。"; + } +} + function render(): void { const active = state.snapshot.state === "active"; - elements.statusBadge.classList.toggle("active", active); - elements.statusBadge.lastChild!.textContent = active ? "学习中" : "待命"; + elements.statusBadge.classList.toggle("active", active || !!state.providerConfig); + elements.statusBadge.lastChild!.textContent = active ? "学习中" : state.providerConfig ? state.providerConfig.model : "未配置"; elements.startButton.disabled = active; elements.startButton.textContent = active ? "正在学习页面…" : "开始学习页面"; elements.stopButton.hidden = !active; elements.learnHint.textContent = active ? `正在观察页面操作,已发现 ${state.snapshot.captures.length} 个数据来源。` : "开启后,请在页面里完成一次查询或翻页。"; - elements.sendButton.disabled = state.running; + const configured = state.configLoaded && !!state.providerConfig; + elements.chatInput.disabled = state.running || !configured; + elements.chatInput.placeholder = !state.configLoaded + ? "正在读取模型配置…" + : configured + ? "告诉 AI 你想用页面数据完成什么…" + : "请先点击“模型设置”配置 Provider"; + elements.sendButton.disabled = state.running || !configured; elements.captureCount.textContent = `${state.snapshot.captures.length} 个数据源`; renderChat(); renderWorkspace(); @@ -238,32 +282,17 @@ function renderMessage(message: ChatMessage): HTMLElement { avatar.textContent = message.role === "assistant" ? "AI" : "我"; const bubble = document.createElement("div"); bubble.className = "bubble"; - if (message.role === "assistant") { const head = document.createElement("div"); head.className = "message-head"; - head.textContent = "AI 有数"; + head.textContent = message.pending ? "AI 有数 · 运行中" : "AI 有数"; bubble.append(head); } const text = document.createElement("div"); text.className = "message-text"; text.textContent = message.text; bubble.append(text); - - if (message.plan) { - const plan = document.createElement("ol"); - plan.className = "plan"; - message.plan.forEach((step) => { - const item = document.createElement("li"); - item.className = step.status; - item.textContent = step.label; - plan.append(item); - }); - bubble.append(plan); - } - message.tools?.forEach((tool) => bubble.append(toolCallDetails(tool))); - if (message.skillPackage) bubble.append(packageActions(message.skillPackage)); article.append(avatar, bubble); return article; } @@ -272,29 +301,13 @@ function toolCallDetails(tool: ToolCallView): HTMLElement { const details = document.createElement("details"); details.className = "tool-call"; const summary = document.createElement("summary"); - summary.textContent = `✓ ${tool.name} · ${tool.summary}`; + summary.textContent = `${tool.error ? "!" : "✓"} ${tool.name} · ${tool.summary}`; const output = document.createElement("pre"); - output.textContent = JSON.stringify(tool.output, null, 2); + output.textContent = JSON.stringify({ input: tool.input, output: tool.output }, null, 2); details.append(summary, output); return details; } -function packageActions(skillPackage: DataSkillPackage): HTMLElement { - const actions = document.createElement("div"); - actions.className = "artifact-actions"; - const exportButton = document.createElement("button"); - exportButton.type = "button"; - exportButton.textContent = "导出 fallback 技能包"; - exportButton.addEventListener("click", () => downloadTextFile(exportDataSkillPackageAsJson(skillPackage))); - const recipe = skillPackage.files.find((file) => file.path === "recipe.json"); - const copyButton = document.createElement("button"); - copyButton.type = "button"; - copyButton.textContent = "复制 recipe.json"; - copyButton.addEventListener("click", () => void copyText(recipe?.content ?? "", copyButton)); - actions.append(exportButton, copyButton); - return actions; -} - function renderWorkspace(): void { const captures = state.snapshot.captures; elements.requestList.innerHTML = ""; @@ -303,22 +316,8 @@ function renderWorkspace(): void { elements.requestList.textContent = "学习页面后,数据源会显示在这里。"; } else { elements.requestList.className = "source-list"; - captures.forEach((capture) => { - const button = document.createElement("button"); - button.type = "button"; - button.className = `source-item${capture.id === state.selectedId ? " active" : ""}`; - const title = document.createElement("div"); - title.className = "source-title"; - title.textContent = readableUrl(capture.url); - const meta = document.createElement("div"); - meta.className = "source-meta"; - meta.textContent = `${capture.method} · ${capture.status} · ${summarizeResponse(capture.responseBody).looksLikeList ? "列表" : "普通响应"}`; - button.append(title, meta); - button.addEventListener("click", () => { state.selectedId = capture.id; renderWorkspace(); }); - elements.requestList.append(button); - }); + captures.forEach((capture) => elements.requestList.append(sourceButton(capture))); } - const capture = getSelectedCapture(); elements.requestDetail.innerHTML = ""; if (!capture) { @@ -329,13 +328,8 @@ function renderWorkspace(): void { elements.requestDetail.className = "source-detail"; const recipe = buildRecipeFromCapture(capture); const info = document.createElement("dl"); - const sourceFacts: Array<[string, string]> = [ - ["接口", capture.url], - ["页面", capture.pageUrl], - ["请求", `${capture.method} · ${capture.status}`], - ["传输", capture.transport] - ]; - sourceFacts.forEach(([key, value]) => { + const facts: Array<[string, string]> = [["接口", capture.url], ["页面", capture.pageUrl], ["请求", `${capture.method} · ${capture.status}`], ["传输", capture.transport]]; + facts.forEach(([key, value]) => { const row = document.createElement("div"); const dt = document.createElement("dt"); const dd = document.createElement("dd"); @@ -353,6 +347,21 @@ function renderWorkspace(): void { elements.requestDetail.append(info, details); } +function sourceButton(capture: CapturedRequest): HTMLButtonElement { + const button = document.createElement("button"); + button.type = "button"; + button.className = `source-item${capture.id === state.selectedId ? " active" : ""}`; + const title = document.createElement("div"); + title.className = "source-title"; + title.textContent = readableUrl(capture.url); + const meta = document.createElement("div"); + meta.className = "source-meta"; + meta.textContent = `${capture.method} · ${capture.status} · ${summarizeResponse(capture.responseBody).looksLikeList ? "列表" : "普通响应"}`; + button.append(title, meta); + button.addEventListener("click", () => { state.selectedId = capture.id; renderWorkspace(); }); + return button; +} + function getSelectedCapture(): CapturedRequest | undefined { return state.snapshot.captures.find((capture) => capture.id === state.selectedId) ?? state.snapshot.captures[0]; } @@ -364,10 +373,26 @@ function addMessage(role: ChatMessage["role"], text: string, dedupe: boolean): v scrollToLatest(); } -function scrollToLatest(): void { - window.requestAnimationFrame(() => { - window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" }); - }); +function summarizeToolResult(result: unknown): string { + if (!result || typeof result !== "object") return "已完成"; + const record = result as Record; + if (Array.isArray(record.sources)) return `返回 ${record.sources.length} 个数据来源`; + if (record.recipe) return "已生成或更新 recipe"; + if (record.package) return "已确认并导出 Data Skill Package"; + if (typeof record.message === "string") return record.message; + return "已完成"; +} + +function isAgentToolName(name: string): name is AgentToolName { + return ["listCapturedSources", "readCapture", "inspectResponse", "buildRecipe", "runRecipe", "exportSkillPackage"].includes(name); +} + +function isProviderConfig(value: unknown): value is OpenAICompatibleProviderConfig { + if (!value || typeof value !== "object") return false; + const record = value as Record; + return typeof record.baseUrl === "string" && !!record.baseUrl + && typeof record.apiKey === "string" && !!record.apiKey + && typeof record.model === "string" && !!record.model; } function resizeComposer(): void { @@ -375,6 +400,10 @@ function resizeComposer(): void { elements.chatInput.style.height = `${Math.min(elements.chatInput.scrollHeight, 120)}px`; } +function scrollToLatest(): void { + window.requestAnimationFrame(() => window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" })); +} + function readableUrl(urlValue: string): string { try { const url = new URL(urlValue); @@ -384,7 +413,7 @@ function readableUrl(urlValue: string): string { } } -function downloadTextFile(file: ReturnType): void { +function downloadTextFile(file: { fileName: string; mimeType: string; content: string }): void { const blob = new Blob([file.content], { type: file.mimeType }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); @@ -394,21 +423,6 @@ function downloadTextFile(file: ReturnType) URL.revokeObjectURL(url); } -async function copyText(text: string, button: HTMLButtonElement): Promise { - const original = button.textContent ?? "复制"; - try { - await navigator.clipboard.writeText(text); - button.textContent = "已复制"; - } catch { - button.textContent = "复制失败"; - } - window.setTimeout(() => { button.textContent = original; }, 1500); -} - -function nextFrame(): Promise { - return new Promise((resolve) => window.requestAnimationFrame(() => resolve())); -} - function createId(): string { return `${Date.now()}-${Math.random().toString(36).slice(2)}`; } diff --git a/docs/agent-tool-architecture.md b/docs/agent-tool-architecture.md index bc0c100..57a76ac 100644 --- a/docs/agent-tool-architecture.md +++ b/docs/agent-tool-architecture.md @@ -7,7 +7,9 @@ DataRecipe is a browser-resident tool layer used by an AI Agent. Its primary UI ```text User goal in side-panel chat ↓ -Built-in Agent (plans, reads selectively, edits, writes SKILL.md) +Built-in Agent Runtime → user-configured OpenAI-compatible Provider + ↓ /v1/chat/completions + tool_calls +Agent (plans, reads selectively, edits, writes SKILL.md) ↓ tool calls DataRecipe Agent Tool Layer ├─ capture catalog and bounded readers @@ -25,7 +27,7 @@ The responsibility split is: 3. **User authorizes and confirms.** Browser-session access, origin permissions, recipe runs, and export confirmation remain visible user decisions where required. 4. **Data Skill Package is the deliverable.** It contains an Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and README. -The current MVP uses a deterministic local Agent Loop: it turns a natural-language goal into a visible plan, then calls capture listing, rule-based recipe building, local sample execution, and Mock fallback package generation. Tool results stay collapsed beneath the conversation. A real LLM planner can replace this loop later without changing the tool contracts. +The side panel runs a real non-streaming Agent Loop. Users configure `baseUrl`, `apiKey`, and `model`; the Runtime sends the system prompt, messages, and function tools to `/v1/chat/completions`, executes returned `tool_calls`, appends `role: tool` results, and continues until the model returns final text. Tool results stay collapsed beneath the conversation. ## Agent-facing tools @@ -46,7 +48,7 @@ Bounded reads are a protocol guarantee. A tool must report truncation and contin `recipe.json` remains deterministic and machine-oriented. Detection rules can infer request parameters, response paths, fields, and pagination. The Agent reviews warnings and evidence, then may change the recipe before dry-run or export. Runtime validation remains authoritative even after Agent edits. -`SKILL.md` is not generated through an `LLMProvider.generateSkillMarkdown` template call. The controlling Agent writes it freely after reading enough evidence and understanding the user's goal. `MockSkillMarkdownFallback` exists only for the current side panel, demos, offline flows, and failure recovery; it is not the long-term primary path. +`SKILL.md` is not generated through a fixed template call. The configured model writes it freely after reading enough evidence and understanding the user's goal. `buildDataSkillPackage` requires non-empty Agent-authored Markdown. Any Mock builder is restricted to tests and development support. ## Runtime and trust boundary @@ -56,7 +58,6 @@ The runtime does not bypass login, captchas, risk controls, dynamic signatures, ## Delivery phases -1. **Now:** capture discovery, deterministic recipe draft, local sample preview, Mock fallback package export, and Agent tool contracts. -2. **Next:** implement capture storage/read handlers and expose the six tool calls to an Agent host. -3. **Then:** connect `runRecipe` to the real Browser RPC Bridge with origin checks, user confirmation, pagination limits, and response bounding. -4. **Finally:** make Agent-authored package export the default UI path while retaining Mock fallback for degraded/offline use. +1. **Now:** real OpenAI-compatible Agent Runtime, local provider settings, capture/read/inspect/build/run/export handlers, and Agent-authored package export. +2. **Next:** connect non-dry-run `runRecipe` to the real Browser RPC Bridge with origin checks, user confirmation, pagination limits, and response bounding. +3. **Then:** add streaming, richer confirmation UI, persistent conversation state, and external Agent transports without changing tool contracts. diff --git a/package.json b/package.json index 87eea19..2e7fda0 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "typecheck": "pnpm -r typecheck", "dev:extension": "pnpm --filter @data-recipe/extension dev", "build:extension": "pnpm --filter @data-recipe/extension build", + "test:agent-runtime": "node scripts/test-agent-runtime.mjs", "validate:skill-package": "node scripts/validate-data-skill-package.mjs" }, "devDependencies": { diff --git a/packages/agent-runtime/package.json b/packages/agent-runtime/package.json new file mode 100644 index 0000000..99e4d74 --- /dev/null +++ b/packages/agent-runtime/package.json @@ -0,0 +1,18 @@ +{ + "name": "@data-recipe/agent-runtime", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + }, + "scripts": { + "build": "tsc -b tsconfig.json", + "typecheck": "tsc -b tsconfig.json" + } +} diff --git a/packages/agent-runtime/src/index.ts b/packages/agent-runtime/src/index.ts new file mode 100644 index 0000000..6e29f5b --- /dev/null +++ b/packages/agent-runtime/src/index.ts @@ -0,0 +1,237 @@ +export interface OpenAICompatibleProviderConfig { + baseUrl: string; + apiKey: string; + model: string; +} + +export interface AgentFunctionTool { + type: "function"; + function: { + name: string; + description: string; + parameters: Record; + }; +} + +export interface AgentToolCall { + id: string; + type: "function"; + function: { + name: string; + arguments: string; + }; +} + +export type AgentChatMessage = + | { role: "system" | "user"; content: string } + | { role: "assistant"; content: string | null; tool_calls?: AgentToolCall[] } + | { role: "tool"; content: string; tool_call_id: string }; + +export interface AgentCompletionRequest { + messages: AgentChatMessage[]; + tools?: AgentFunctionTool[]; + toolChoice?: "auto" | "none" | "required"; +} + +export interface AgentCompletion { + message: Extract; + finishReason?: string; +} + +export interface AgentModelProvider { + complete(input: AgentCompletionRequest): Promise; +} + +export class OpenAICompatibleProvider implements AgentModelProvider { + readonly config: OpenAICompatibleProviderConfig; + + constructor(config: OpenAICompatibleProviderConfig) { + const baseUrl = config.baseUrl.trim().replace(/\/+$/, ""); + const model = config.model.trim(); + const apiKey = config.apiKey.trim(); + if (!baseUrl || !model || !apiKey) { + throw new Error("baseUrl、apiKey 和 model 都必须配置。"); + } + this.config = { baseUrl, model, apiKey }; + } + + async complete(input: AgentCompletionRequest): Promise { + const response = await fetch(buildChatCompletionsUrl(this.config.baseUrl), { + method: "POST", + headers: { + "content-type": "application/json", + authorization: `Bearer ${this.config.apiKey}` + }, + body: JSON.stringify({ + model: this.config.model, + messages: input.messages, + tools: input.tools?.length ? input.tools : undefined, + tool_choice: input.tools?.length ? (input.toolChoice ?? "auto") : undefined, + stream: false + }) + }); + + const body = await readResponseBody(response); + if (!response.ok) { + throw new Error(`模型请求失败(HTTP ${response.status}):${extractErrorMessage(body)}`); + } + + const parsed = body as ChatCompletionsResponse; + const choice = parsed.choices?.[0]; + if (!choice?.message || choice.message.role !== "assistant") { + throw new Error("模型响应中缺少 assistant message。"); + } + + return { + message: { + role: "assistant", + content: typeof choice.message.content === "string" ? choice.message.content : null, + tool_calls: normalizeToolCalls(choice.message.tool_calls) + }, + finishReason: choice.finish_reason + }; + } +} + +export interface AgentToolExecutionEvent { + toolCall: AgentToolCall; + arguments: unknown; + result: unknown; + error?: string; +} + +export interface AgentRunInput { + systemPrompt: string; + messages: AgentChatMessage[]; + tools: AgentFunctionTool[]; + executeTool(name: string, input: unknown): Promise; + maxIterations?: number; + onToolExecution?: (event: AgentToolExecutionEvent) => void | Promise; +} + +export interface AgentRunResult { + finalText: string; + messages: AgentChatMessage[]; + iterations: number; +} + +export interface AgentRuntime { + run(input: AgentRunInput): Promise; +} + +export class ToolCallingAgentRuntime implements AgentRuntime { + constructor(private readonly provider: AgentModelProvider) {} + + async run(input: AgentRunInput): Promise { + const maxIterations = input.maxIterations ?? 12; + const messages: AgentChatMessage[] = [ + { role: "system", content: input.systemPrompt }, + ...input.messages.filter((message) => message.role !== "system") + ]; + + for (let iteration = 1; iteration <= maxIterations; iteration += 1) { + const completion = await this.provider.complete({ messages, tools: input.tools, toolChoice: "auto" }); + const assistantMessage = completion.message; + messages.push(assistantMessage); + + const toolCalls = assistantMessage.tool_calls ?? []; + if (toolCalls.length === 0) { + const finalText = assistantMessage.content?.trim(); + if (!finalText) throw new Error("模型没有返回最终文本或工具调用。"); + return { finalText, messages, iterations: iteration }; + } + + for (const toolCall of toolCalls) { + let args: unknown = {}; + let result: unknown; + let error: string | undefined; + try { + args = parseToolArguments(toolCall.function.arguments); + result = await input.executeTool(toolCall.function.name, args); + } catch (caught) { + error = caught instanceof Error ? caught.message : "工具执行失败。"; + result = { ok: false, error }; + } + + await input.onToolExecution?.({ toolCall, arguments: args, result, error }); + messages.push({ + role: "tool", + tool_call_id: toolCall.id, + content: safeStringify(result) + }); + } + } + + throw new Error(`Agent 超过最大工具循环次数(${maxIterations})。`); + } +} + +function buildChatCompletionsUrl(baseUrl: string): string { + if (/\/v1\/chat\/completions$/i.test(baseUrl)) return baseUrl; + return /\/v1$/i.test(baseUrl) ? `${baseUrl}/chat/completions` : `${baseUrl}/v1/chat/completions`; +} + +function parseToolArguments(value: string): unknown { + if (!value.trim()) return {}; + try { + return JSON.parse(value); + } catch { + throw new Error("模型返回了无效的工具参数 JSON。"); + } +} + +function normalizeToolCalls(value: unknown): AgentToolCall[] | undefined { + if (!Array.isArray(value)) return undefined; + const calls = value.filter(isAgentToolCall); + return calls.length ? calls : undefined; +} + +function isAgentToolCall(value: unknown): value is AgentToolCall { + if (!value || typeof value !== "object") return false; + const call = value as Partial; + return call.type === "function" + && typeof call.id === "string" + && !!call.function + && typeof call.function.name === "string" + && typeof call.function.arguments === "string"; +} + +async function readResponseBody(response: Response): Promise { + const text = await response.text(); + if (!text) return {}; + try { + return JSON.parse(text); + } catch { + return { message: text.slice(0, 1000) }; + } +} + +function extractErrorMessage(body: unknown): string { + if (!body || typeof body !== "object") return "未知错误"; + const record = body as Record; + const error = record.error; + if (error && typeof error === "object") { + const message = (error as Record).message; + if (typeof message === "string") return message; + } + return typeof record.message === "string" ? record.message : "未知错误"; +} + +function safeStringify(value: unknown): string { + try { + return JSON.stringify(value); + } catch { + return JSON.stringify({ ok: false, error: "工具结果无法序列化。" }); + } +} + +interface ChatCompletionsResponse { + choices?: Array<{ + finish_reason?: string; + message?: { + role?: string; + content?: unknown; + tool_calls?: unknown; + }; + }>; +} diff --git a/packages/agent-runtime/tsconfig.json b/packages/agent-runtime/tsconfig.json new file mode 100644 index 0000000..46f5ba2 --- /dev/null +++ b/packages/agent-runtime/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src", + "composite": true + }, + "include": ["src"] +} diff --git a/packages/agent-tools-core/src/index.ts b/packages/agent-tools-core/src/index.ts index e71de94..9f2ebe8 100644 --- a/packages/agent-tools-core/src/index.ts +++ b/packages/agent-tools-core/src/index.ts @@ -69,7 +69,6 @@ export interface AgentToolInputMap { userGoal: string; examplesMarkdown?: string; readmeMarkdown?: string; - userConfirmed: boolean; }; } diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts index 525df1b..20f3c29 100644 --- a/packages/skill-builder/src/index.ts +++ b/packages/skill-builder/src/index.ts @@ -17,21 +17,12 @@ export interface BuildDataSkillPackageInput { * SKILL.md authored by the controlling AI Agent after it has inspected the * captures and recipe through the Agent Tool Layer. */ - skillMarkdown?: string; + skillMarkdown: string; examplesMarkdown?: string; readmeMarkdown?: string; - /** - * Optional deterministic fallback for non-Agent surfaces such as the MVP - * side panel. This is deliberately not an LLM abstraction or the primary - * generation path. - */ - fallback?: SkillMarkdownFallback; } -/** - * Last-resort SKILL.md generation for clients that do not host an Agent yet. - * Agent integrations should pass `skillMarkdown` instead. - */ +/** Test/development-only deterministic Markdown helper. */ export interface SkillMarkdownFallback { buildFallbackSkillMarkdown(recipe: DataRecipe, goal: string): string; } @@ -45,9 +36,10 @@ export class MockSkillMarkdownFallback implements SkillMarkdownFallback { export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSkillPackage { const packageName = input.recipe.name || "data-skill"; const goal = input.userGoal?.trim() || input.recipe.description; - const skillMarkdown = input.skillMarkdown?.trim() - ? ensureTrailingNewline(input.skillMarkdown) - : (input.fallback ?? new MockSkillMarkdownFallback()).buildFallbackSkillMarkdown(input.recipe, goal); + if (!input.skillMarkdown.trim()) { + throw new Error("skillMarkdown must be authored by the Agent before export."); + } + const skillMarkdown = ensureTrailingNewline(input.skillMarkdown); return { packageName, @@ -70,6 +62,17 @@ export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSk }; } +/** Test/development helper only. Never use this in the user-facing flow. */ +export function buildMockDataSkillPackageForDevelopment( + input: Omit +): DataSkillPackage { + const goal = input.userGoal?.trim() || input.recipe.description; + return buildDataSkillPackage({ + ...input, + skillMarkdown: new MockSkillMarkdownFallback().buildFallbackSkillMarkdown(input.recipe, goal) + }); +} + function ensureTrailingNewline(value: string): string { return value.endsWith("\n") ? value : `${value}\n`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7fc142..77c4b75 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,12 @@ importers: apps/extension: dependencies: + '@data-recipe/agent-runtime': + specifier: workspace:* + version: link:../../packages/agent-runtime + '@data-recipe/agent-tools-core': + specifier: workspace:* + version: link:../../packages/agent-tools-core '@data-recipe/detector': specifier: workspace:* version: link:../../packages/detector @@ -40,6 +46,8 @@ importers: specifier: ^6.0.1 version: 6.1.3 + packages/agent-runtime: {} + packages/agent-tools-core: dependencies: '@data-recipe/browser-rpc-core': diff --git a/scripts/test-agent-runtime.mjs b/scripts/test-agent-runtime.mjs new file mode 100644 index 0000000..f986716 --- /dev/null +++ b/scripts/test-agent-runtime.mjs @@ -0,0 +1,61 @@ +import assert from "node:assert/strict"; +import { + OpenAICompatibleProvider, + ToolCallingAgentRuntime +} from "../packages/agent-runtime/dist/index.js"; + +const originalFetch = globalThis.fetch; +let requestedUrl = ""; +let requestedBody; +globalThis.fetch = async (url, init) => { + requestedUrl = String(url); + requestedBody = JSON.parse(String(init.body)); + assert.equal(init.headers.authorization, "Bearer test-key"); + return new Response(JSON.stringify({ + choices: [{ + finish_reason: "tool_calls", + message: { + role: "assistant", + content: null, + tool_calls: [{ id: "call-1", type: "function", function: { name: "echo", arguments: "{\"value\":42}" } }] + } + }] + }), { status: 200, headers: { "content-type": "application/json" } }); +}; + +const provider = new OpenAICompatibleProvider({ baseUrl: "https://provider.example", apiKey: "test-key", model: "tool-model" }); +const completion = await provider.complete({ + messages: [{ role: "user", content: "test" }], + tools: [{ type: "function", function: { name: "echo", description: "echo", parameters: { type: "object" } } }] +}); +assert.equal(requestedUrl, "https://provider.example/v1/chat/completions"); +assert.equal(requestedBody.stream, false); +assert.equal(completion.message.tool_calls?.[0]?.function.name, "echo"); +globalThis.fetch = originalFetch; + +let providerTurn = 0; +const runtime = new ToolCallingAgentRuntime({ + async complete() { + providerTurn += 1; + if (providerTurn === 1) { + return { + message: { + role: "assistant", + content: null, + tool_calls: [{ id: "call-2", type: "function", function: { name: "echo", arguments: "{\"value\":7}" } }] + } + }; + } + return { message: { role: "assistant", content: "完成" } }; + } +}); + +const result = await runtime.run({ + systemPrompt: "system", + messages: [{ role: "user", content: "run" }], + tools: [{ type: "function", function: { name: "echo", description: "echo", parameters: { type: "object" } } }], + executeTool: async (name, input) => ({ name, input }) +}); +assert.equal(result.finalText, "完成"); +assert.equal(result.messages.find((message) => message.role === "tool")?.tool_call_id, "call-2"); +console.log("agent-runtime tests passed"); diff --git a/tsconfig.base.json b/tsconfig.base.json index d8e85f1..5151f16 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -33,6 +33,9 @@ ], "@data-recipe/agent-tools-core": [ "packages/agent-tools-core/src/index.ts" + ], + "@data-recipe/agent-runtime": [ + "packages/agent-runtime/src/index.ts" ] } } From 584b04002e23e068d13884821d63a3d23930354e Mon Sep 17 00:00:00 2001 From: null_object_0000 Date: Fri, 10 Jul 2026 17:26:44 +0800 Subject: [PATCH 25/25] feat(skill-exporter): add fflate dependency and implement ZIP export functionality - Added fflate as a dependency for handling ZIP file creation. - Introduced exportDataSkillPackageAsZip function to export skill packages as ZIP files. - Updated validation logic to include workflow.json and handle recipe references. - Enhanced validateDataSkillPackage function to check for required files and validate workflow structure. - Implemented inspectDataSkillPackageZip function to inspect contents of exported ZIP files. - Updated validate-data-skill-package script to support validation of both ZIP and JSON formats. - Added comprehensive tests for new functionality in test-agent-runtime script. --- .pnpm-store/v11/index.db | Bin 0 -> 8192 bytes AGENTS.md | 22 +- PR_TESTING.md | 35 +- README.en.md | 37 +- README.md | 9 +- README.zh-CN.md | 35 +- apps/extension/package.json | 4 +- apps/extension/public/sidepanel.css | 59 ++ apps/extension/public/sidepanel.html | 1 + apps/extension/src/agent-tool-definitions.ts | 104 +++- apps/extension/src/agent-tools.ts | 449 +++++++++------ apps/extension/src/sidepanel.ts | 562 +++++++++++++------ docs/agent-tool-architecture.md | 28 +- package.json | 2 +- packages/agent-runtime/src/index.ts | 554 +++++++++++++++--- packages/agent-tools-core/src/index.ts | 226 ++++++-- packages/skill-builder/src/index.ts | 198 ++++++- packages/skill-exporter/package.json | 3 +- packages/skill-exporter/src/index.ts | 113 ++-- pnpm-lock.yaml | 34 ++ scripts/test-agent-runtime.mjs | 481 ++++++++++++++-- scripts/validate-data-skill-package.mjs | 42 +- 22 files changed, 2313 insertions(+), 685 deletions(-) create mode 100644 .pnpm-store/v11/index.db diff --git a/.pnpm-store/v11/index.db b/.pnpm-store/v11/index.db new file mode 100644 index 0000000000000000000000000000000000000000..044636a65ff67410fad601f0c39978108fefcea0 GIT binary patch literal 8192 zcmeIuzpBD86bA4#2p0s=&GDX11#$5OY&BppTCFMSqD0LV@%|C%po4=C;0rt5R!Xsx zd-*<+oFpepe$$EEhlalXPCq)NHmfksS%-)*#*-P9XRK%~B>T9;=Xc?(b$^tiS5|q+ zqJcmF0uX=z1Rwwb2tWV=5P$##awu^7v_7h}nsvK|di`yVdUMb_v)cb|%{g=6U0>Kr zkg^>qDAS^Pkk?+mi kUUFZI)hjuq$Cn@g0SG_<0uX=z1Rwwb2tWV=5J(070rxR8{{R30 literal 0 HcmV?d00001 diff --git a/AGENTS.md b/AGENTS.md index bc37161..4a7cdb1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ The primary user experience is the browser side panel's real conversational Agen - The browser extension captures authorized page/API activity and exposes bounded tools. - The side-panel Agent (or a future external Agent) decides which captures to inspect, how much content to read, how to refine a recipe, and how to write `SKILL.md` for the user's actual goal. - The user authorizes browser access and confirms sensitive execution/export actions. -- The final artifact is a **Data Skill Package** containing `SKILL.md`, `recipe.json`, examples, and human-readable documentation. +- The final artifact is a ZIP **Data Skill Package** containing `SKILL.md`, `workflow.json`, one or more `recipes/*.json`, examples, and human-readable documentation. `.data-skill.json` is development/import interchange only. - Provider credentials stay in `chrome.storage.local`; never pass them to a tool, model message, capture, recipe, or package. ## Agent-facing tools @@ -19,14 +19,26 @@ Keep these names and responsibilities stable: - `listCapturedSources`: discover captured sources without loading every response. - `readCapture`: read request/response content using preview, page, range, or full mode. - `inspectResponse`: inspect response structure and selected content using the same bounded read modes. -- `buildRecipe`: produce a rule-derived `recipe.json` draft, optionally applying Agent edits. -- `runRecipe`: execute or dry-run a recipe through the Browser RPC Bridge. -- `exportSkillPackage`: package the Agent-authored `SKILL.md` and reviewed recipe. +- `buildRecipe`: produce a rule-derived recipe draft in RecipeStore, optionally applying Agent edits by `recipeId`. +- `runRecipe`: execute or dry-run a stored recipe by `recipeId` through the Browser RPC Bridge. +- `exportSkillPackage`: package Agent-authored `SKILL.md`, all referenced `recipeIds`, and `workflow.json` as a real ZIP. Never silently expand a bounded read to a full read. Never expose Cookie, Authorization headers, or equivalent browser credentials to the Agent. `readCapture` / `inspectResponse` full reads, every `runRecipe`, and every `exportSkillPackage` require action-time user confirmation. Model-provided flags do not count as user confirmation. +## Runtime durability + +- Prefer streaming Chat Completions and aggregate incremental text and `tool_calls`; fall back to non-streaming only when the Provider explicitly rejects streaming. +- Checkpoint conversation messages immediately after every assistant message and tool result. +- Store active conversation history and RecipeStore snapshots in `chrome.storage.session`, scoped by `tabId + conversationId`. +- Never clear history on model changes or failures. Only the explicit “新建对话” action clears the active conversation. +- The model never sends a complete recipe back to the plugin. `buildRecipe` creates a `recipeId`; patch, run, and export operations reference that ID. +- Validate every tool input and return structured errors with `code`, `message`, `retryable`, and `expectedInput`. +- Stop repeated identical failed calls, enforce per-tool budgets, and request a `tool_choice: none` failure summary instead of discarding history at the iteration limit. +- Persist UI history as ordered `ConversationEvent`s: user/assistant messages, tool calls, tool results, statuses, artifacts, and outcomes. Create a tool-call event before execution and update that event in place. +- Treat `AgentRunOutcome` as authoritative. Carry it into the next model turn; never let prose contradict structured tool errors. Budget pauses preserve pending steps and offer continuation. + ## Artifact policy -`recipe.json` is machine-oriented execution configuration. Rules and tools generate the initial draft; the Agent may inspect and modify it. `SKILL.md` is authored by the configured model from tool results and user intent, and must not be constrained to a deterministic template. Mock generation is test/development-only and must never appear in the user-facing path. +Files under `recipes/` are machine-oriented execution configurations. Rules and tools generate initial drafts; the Agent may inspect and modify them. `workflow.json` expresses ordered input/output dependencies across recipes, including list → filter → detail → optional diff flows. Never describe multiple interfaces in `SKILL.md` while exporting only one recipe. `SKILL.md` is authored by the configured model from tool results and user intent, and must not be constrained to a deterministic template. Mock generation is test/development-only and must never appear in the user-facing path. diff --git a/PR_TESTING.md b/PR_TESTING.md index 9451d2e..b87052b 100644 --- a/PR_TESTING.md +++ b/PR_TESTING.md @@ -6,6 +6,7 @@ This round makes the real OpenAI-compatible Agent the only user-facing chat path ```bash pnpm typecheck +pnpm test:agent-runtime pnpm build:extension ``` @@ -30,9 +31,33 @@ The following packages and surfaces must compile: 1. Open `docs/test-page.html` and click “开始学习页面”. 2. Trigger a fetch or XHR request. 3. Ask the Agent to create a data skill. -4. Confirm the configured provider receives `/v1/chat/completions` requests with messages and function tools. -5. Confirm returned `tool_calls` execute locally and collapsed tool results are sent back as `role: tool` messages with matching `tool_call_id`. -6. Confirm the loop ends only when the model returns final assistant text or reaches the iteration limit. +4. Confirm the configured provider receives streaming `/v1/chat/completions` requests with messages and function tools. +5. Confirm SSE text appears incrementally and incremental tool call arguments are aggregated before execution. +6. Confirm returned `tool_calls` execute locally and collapsed tool results are sent back as `role: tool` messages with matching `tool_call_id`. +7. Confirm the loop ends only when the model returns final assistant text or a protected termination generates a `tool_choice: none` summary. +8. Confirm each call appears in the timeline immediately, updates in place on completion, and its result follows it in actual occurrence order. +9. Confirm streamed Markdown headings, lists, tables, code blocks, quotes, and links refresh incrementally and unsafe HTML is removed. + +### Conversation recovery + +- Close and reopen the side panel after at least one tool result; history and recipe IDs should remain usable. +- Simulate a Provider failure after a tool result; the partial history must remain in the next request. +- Changing model settings must not clear history. +- Clicking “新建对话” must create a new conversation ID and clear the active history. + +### Automated regressions + +- streaming text delta aggregation; +- streaming `tool_calls` name/arguments aggregation; +- explicit streaming rejection fallback; +- partial recipe validation without undefined-property errors; +- `runRecipe` requiring `recipeId`; +- failed tool results present in the next model turn; +- `AgentRunError.partialMessages` after a later Provider failure; +- repeated identical failure termination; +- max-iteration fault summary with history retained. +- `AgentRunOutcome` fields and budget-pause continuation state; +- multi-recipe weekly-report workflow and valid standalone ZIP structure. ### Safety confirmations @@ -49,7 +74,9 @@ The following packages and surfaces must compile: - `buildDataSkillPackage` rejects empty Agent-authored `skillMarkdown`. - The side panel does not call the Mock development helper. - Export uses the `SKILL.md` supplied by the model to `exportSkillPackage`. +- Formal export has MIME `application/zip` and contains `workflow.json` plus every referenced `recipes/*.json` file. +- A weekly-report goal containing only “池佳 W25” resolves person/year/week dynamically, obtains `empCode`, `uid`, and `weekId` from prior step outputs, then reads detail and optional diff without hardcoded identities. ## Known limitation -Non-dry-run Browser RPC execution remains a typed placeholder and returns `blocked` until the real bridge transport is connected. Streaming is intentionally not implemented in this round. +Non-dry-run Browser RPC execution remains a typed placeholder and returns `blocked` until the real bridge transport is connected. diff --git a/README.en.md b/README.en.md index 534517f..34c5d90 100644 --- a/README.en.md +++ b/README.en.md @@ -207,47 +207,54 @@ After one discovery flow, use the side panel to: 4. Check "技能包预览" to confirm required files are present; 5. Click "导出技能包". -The current MVP downloads a `.data-skill.json` file. This is a temporary text package format containing: +Production export downloads a real ZIP with MIME type `application/zip` and real paths: ```text -packageName -files[] - SKILL.md - recipe.json - examples.md - README.md +SKILL.md +workflow.json +recipes/ + people-list.json + week-list.json + week-detail.json +examples.md +README.md ``` -A later version can export a real folder or zip. For now, the JSON text package validates the generate, test, and export loop. +`.data-skill.json` remains available only as a development/import interchange format, not the primary user export. ### Data Skill Package acceptance checks An exported package should at least: -* Include `SKILL.md`, `recipe.json`, `examples.md`, and `README.md`; +* Include `SKILL.md`, `workflow.json`, one or more `recipes/*.json`, `examples.md`, and `README.md`; * Use `SKILL.md` to explain what the data skill is useful for; -* Use `recipe.json` to hold the data source, query inputs, returned fields, and test-run information; +* Use each recipe to hold its data source, query inputs, returned fields, and test-run information; +* Use `workflow.json` to express list → filter → detail → optional diff dependencies, with one packaged recipe for every interface used; * Show a data preview in the side panel test-run result; * Show no missing required files before export. ### Validate an exported skill package -After exporting a `.data-skill.json` file, run: +After exporting a ZIP, run: ```bash -pnpm validate:skill-package path/to/your.data-skill.json +pnpm validate:skill-package path/to/your-data-skill.zip ``` -The command checks that all four required files are present and non-empty. It exits with a non-zero status when the package is invalid, so it can be used in later automated checks. +The command checks required files, the recipes directory, and workflow references. It exits with a non-zero status when the package is invalid. ## Artifact Hierarchy * **The plugin provides tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Read tools support preview, page, range, and explicit full modes. +* **Streaming and recovery:** the Runtime aggregates SSE text/tool deltas, checkpoints every assistant/tool message, and stores conversations in `chrome.storage.session` by tab and conversation ID. +* **A real conversation timeline:** user messages, AI messages, tool calls, tool results, statuses, outcomes, and ZIP artifacts are ordered `ConversationEvent`s. Markdown refreshes incrementally and is sanitized with DOMPurify. +* **recipeId protocol:** complete recipes stay inside the plugin RecipeStore; the model patches, runs, and exports by `recipeId` instead of retransmitting full recipes. * **The Agent makes judgments:** it selects sources, decides how much to read, reviews and edits the recipe, and freely authors `SKILL.md` from tool evidence and the user's goal. * **The user authorizes and confirms:** browser-session access, origin permissions, recipe runs, and protected export actions remain user-controlled. -* **recipe.json remains the low-level config:** rules and tools generate its draft; the Agent may inspect and modify it before runtime validation. +* **Multi-recipe workflow:** rules and tools generate `recipes/*.json`; the Agent reviews them, while `workflow.json` defines cross-recipe dependencies. Production export is ZIP. +* **Structured stopping:** `AgentRunOutcome` distinguishes completion, budget pause, tool failure, and user/safety blocking. Paused progress can be continued. * **Mock is not a production path:** the configured model must author `SKILL.md` in the user flow. Mock helpers are restricted to tests and development support. -* **The final deliverable is a Data Skill Package:** Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and documentation. +* **The final deliverable is a Data Skill Package:** Agent-authored `SKILL.md`, `workflow.json`, reviewed `recipes/`, examples, and documentation. ## Long-term Runtime Architecture diff --git a/README.md b/README.md index db2b17b..4374a5e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Load `apps/extension/dist` as an unpacked extension in Chrome, open the side-pan ## Validate an exported skill package ```bash -pnpm validate:skill-package path/to/your.data-skill.json +pnpm validate:skill-package path/to/your-data-skill.zip ``` ## Long-term architecture @@ -44,7 +44,12 @@ The side panel is the primary conversational Agent workspace. Tool calls and dat Provider configuration is stored in `chrome.storage.local`. The API key is used only for the configured model request and is never exposed to Agent tools or included in a Data Skill Package. - **Agent-facing tools:** `listCapturedSources`, `readCapture`, `inspectResponse`, `buildRecipe`, `runRecipe`, and `exportSkillPackage`. Reads support preview, page, range, and explicit full modes. -- **recipe.json is rule/tool generated and Agent-reviewable.** It remains the low-level execution config; the Agent may inspect and modify it before running or exporting. +- **Streaming and durable history:** the runtime parses SSE text/tool deltas, checkpoints after every assistant/tool message, and stores the active conversation in `chrome.storage.session` by tab and conversation ID. +- **Real conversation timeline:** user messages, model messages, tool calls, tool results, statuses, outcomes, and ZIP artifacts are independent `ConversationEvent`s rendered in occurrence order. Markdown is rendered with `marked` and sanitized with DOMPurify. +- **Stable recipe protocol:** complete recipes stay in RecipeStore; the model uses `recipeId` for patch, run, and export operations. +- **Multi-recipe packages:** production export is `application/zip`, with `SKILL.md`, `workflow.json`, `recipes/*.json`, examples, and README. `.data-skill.json` remains development/import interchange only. +- **Structured stopping:** `AgentRunOutcome` distinguishes completed, budget-paused, failed-tool, and user/safety-blocked runs. A paused run preserves pending work and exposes “继续任务”. +- **Recipe JSON is rule/tool generated and Agent-reviewable.** Each file under `recipes/` remains low-level execution config; the Agent may inspect and modify it before running or exporting. - **SKILL.md is Agent-authored.** It is based on tool evidence and the user's goal. The user-facing flow never auto-generates it from a Mock template; Mock helpers are test/development only. - **Browser RPC Bridge is the runtime tool.** It executes a reviewed recipe inside the user's authorized Chrome session without exposing browser credentials to the Agent. The real round-trip is not wired up yet. - **Current MVP status:** discovery + recipe-draft + local sample preview + skill package export all work end-to-end. Real browser RPC execution (the Chrome extension actually running `browser.runRecipe` inside an authorized session) is NOT implemented yet. `recipe-runner.runRecipeWithBrowserRpc` returns `blocked` until the bridge transport is connected in a follow-up PR. diff --git a/README.zh-CN.md b/README.zh-CN.md index 79b2517..c7cc669 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -200,35 +200,38 @@ pnpm dev:extension 4. 在「技能包预览」中确认已包含必需文件; 5. 点击「导出技能包」。 -当前 MVP 会下载一个 `.data-skill.json` 文件。它是临时的文本包格式,里面包含: +正式导出会下载一个 MIME 为 `application/zip` 的 ZIP,包含真实目录和文件: ```text -packageName -files[] - SKILL.md - recipe.json - examples.md - README.md +SKILL.md +workflow.json +recipes/ + people-list.json + week-list.json + week-detail.json +examples.md +README.md ``` -后续会把这个导出格式升级为真实文件夹或 zip。当前阶段先用 JSON 文本包验证「可生成、可测试、可导出」的闭环。 +`.data-skill.json` 只保留为开发和导入交换格式,不是用户主导出格式。 ### Data Skill Package 验收点 导出的技能包至少应满足: -* 包含 `SKILL.md`、`recipe.json`、`examples.md`、`README.md`; +* 包含 `SKILL.md`、`workflow.json`、一个或多个 `recipes/*.json`、`examples.md`、`README.md`; * `SKILL.md` 能说明这个数据技能适合完成什么任务; -* `recipe.json` 包含数据来源、查询条件、返回字段和测试运行所需信息; +* 每个 recipe 包含数据来源、查询条件、返回字段和测试运行所需信息; +* `workflow.json` 明确 list → filter → detail → 可选 diff 的输入输出依赖,涉及多个接口时必须包含对应的多个 recipe; * 侧边栏「试运行结果」可以展示数据预览; * 导出前没有提示缺少必需文件。 ### 校验导出的技能包 -导出 `.data-skill.json` 后,可以用下面的命令检查它是否包含四个必需文件,并确认文件内容不为空: +导出 ZIP 后,可以用下面的命令检查必需文件、recipe 目录和 workflow 引用: ```bash -pnpm validate:skill-package path/to/your.data-skill.json +pnpm validate:skill-package path/to/your-data-skill.zip ``` 校验通过时会输出技能包名称和文件列表;缺少文件或文件为空时会返回非零退出码,便于后续接入自动化验收。 @@ -236,11 +239,15 @@ pnpm validate:skill-package path/to/your.data-skill.json ## 产物层级 * **插件提供工具**:`listCapturedSources`、`readCapture`、`inspectResponse`、`buildRecipe`、`runRecipe`、`exportSkillPackage`。读取工具支持预览、分页、范围和明确的完整读取。 +* **支持流式与故障恢复**:Runtime 聚合 SSE 文本和工具参数增量,每条 assistant/tool 消息立即 checkpoint,并按 tab 与 conversation 保存到 `chrome.storage.session`。 +* **真实对话时间线**:用户消息、AI 消息、tool call、tool result、状态、运行结果和 ZIP 产物统一存为 `ConversationEvent`,按发生顺序显示;Markdown 增量渲染并用 DOMPurify 清洗。 +* **recipeId 协议**:完整 recipe 只保存在插件 RecipeStore;模型通过 `recipeId` 修改、测试和导出,不再重传完整 recipe。 * **Agent 做判断**:选择数据来源、决定读取多少、检查并修改配方,并结合工具结果和用户目标自由编写 `SKILL.md`,不受固定模板策略限制。 * **用户做授权和确认**:浏览器会话访问、来源权限、recipe 执行和导出等受保护动作由用户控制。 -* **recipe.json 是底层执行配置**:规则和工具先生成草稿,Agent 可以检查和修改,运行时仍会进行约束和校验。 +* **多 recipe 与 workflow**:规则和工具生成 `recipes/*.json`,Agent 检查并修改;`workflow.json` 描述跨 recipe 的依赖。正式导出是 ZIP。 +* **结构化停止状态**:`AgentRunOutcome` 区分完成、预算暂停、工具失败和用户/安全阻止;暂停时保留进度并提供“继续任务”。 * **Mock 不在正式主路径**:用户流程必须由已配置模型编写 `SKILL.md`;Mock helper 只允许用于测试和开发辅助。 -* **最终产物是 Data Skill Package**:包含 Agent 编写的 `SKILL.md`、审核后的 `recipe.json`、示例和说明文档。 +* **最终产物是 Data Skill Package**:包含 Agent 编写的 `SKILL.md`、`workflow.json`、审核后的 `recipes/`、示例和说明文档。 ## 长期 Runtime 架构 diff --git a/apps/extension/package.json b/apps/extension/package.json index 594e11b..a9211cf 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -16,7 +16,9 @@ "@data-recipe/recipe-core": "workspace:*", "@data-recipe/recipe-runner": "workspace:*", "@data-recipe/skill-builder": "workspace:*", - "@data-recipe/skill-exporter": "workspace:*" + "@data-recipe/skill-exporter": "workspace:*", + "dompurify": "^3.4.11", + "marked": "^18.0.5" }, "devDependencies": { "rimraf": "^6.0.1" diff --git a/apps/extension/public/sidepanel.css b/apps/extension/public/sidepanel.css index 42ac4a9..c476065 100644 --- a/apps/extension/public/sidepanel.css +++ b/apps/extension/public/sidepanel.css @@ -116,6 +116,24 @@ h1 { font-size: 16px; line-height: 1.2; margin: 0; } .message-head { color: #6b7280; font-size: 10px; justify-content: space-between; margin-bottom: 5px; } .message-text { font-size: 13px; line-height: 1.55; white-space: pre-wrap; } +.markdown-body { overflow-wrap: anywhere; white-space: normal; } +.markdown-body > :first-child { margin-top: 0; } +.markdown-body > :last-child { margin-bottom: 0; } +.markdown-body h1, .markdown-body h2, .markdown-body h3 { line-height: 1.3; margin: 14px 0 7px; } +.markdown-body h1 { font-size: 18px; } +.markdown-body h2 { font-size: 16px; } +.markdown-body h3 { font-size: 14px; } +.markdown-body p, .markdown-body ul, .markdown-body ol { margin: 7px 0; } +.markdown-body ul, .markdown-body ol { padding-left: 20px; } +.markdown-body blockquote { border-left: 3px solid #84b8ad; color: #5e6965; margin: 9px 0; padding: 2px 0 2px 10px; } +.markdown-body code { background: #edf1ee; border-radius: 4px; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: .9em; padding: 1px 4px; } +.markdown-body pre { margin: 9px 0; } +.markdown-body pre code { background: transparent; padding: 0; } +.markdown-body a { color: #0f766e; text-decoration: underline; } +.markdown-body table { border-collapse: collapse; display: block; margin: 9px 0; max-width: 100%; overflow-x: auto; } +.markdown-body th, .markdown-body td { border: 1px solid #dce2de; font-size: 11px; padding: 5px 7px; text-align: left; } +.markdown-body th { background: #f0f4f1; } + .plan { border-top: 1px solid #eceeea; margin: 9px 0 0; padding: 8px 0 0 20px; } .plan li { color: #58615e; font-size: 12px; line-height: 1.5; padding: 2px 0 2px 2px; } .plan li.done::marker { color: #0f9f78; content: "✓ "; } @@ -138,6 +156,47 @@ h1 { font-size: 16px; line-height: 1.2; margin: 0; } .artifact-actions { flex-wrap: wrap; gap: 7px; margin-top: 10px; } .artifact-actions button { font-size: 11px; min-height: 30px; } +.timeline-status { align-self: center; color: #858d89; font-size: 10px; padding: 1px 8px; } +.timeline-tool, .timeline-result { + align-self: stretch; + background: #f1f3f0; + border: 1px solid #e0e4df; + border-radius: 8px; + margin-left: 34px; + padding: 8px 9px; +} +.timeline-tool summary, .timeline-result summary { color: #626b67; cursor: pointer; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 10px; } +.timeline-tool.running { border-color: #d8c38d; } +.timeline-tool.success, .timeline-result.success { border-color: #bcded4; } +.timeline-tool.error, .timeline-result.error { border-color: #efc1bc; background: #fff5f4; } +.timeline-tool pre, .timeline-result pre { margin-top: 7px; } +.artifact-card { + align-self: stretch; + background: linear-gradient(135deg, #e6f4ef, #f2f8f5); + border: 1px solid #b9ddd2; + border-radius: 10px; + color: #195e54; + font-size: 12px; + font-weight: 650; + margin-left: 34px; + padding: 11px; +} +.outcome-card { + align-self: stretch; + background: #f0f2ef; + border: 1px solid #dde1dc; + border-radius: 10px; + display: grid; + gap: 5px; + margin-left: 34px; + padding: 10px; +} +.outcome-card strong { font-size: 12px; } +.outcome-card span { color: #707874; font-size: 10px; } +.outcome-card.paused_budget { background: #fff8e8; border-color: #ead59a; } +.outcome-card.failed_tool, .outcome-card.blocked_user { background: #fff3f1; border-color: #e9bbb5; } +.outcome-card button { background: #0f766e; border: 0; border-radius: 7px; color: white; font-size: 11px; justify-self: start; min-height: 30px; padding: 0 10px; } + .suggestions { display: flex; gap: 7px; overflow-x: auto; } .suggestions button { background: #fff; diff --git a/apps/extension/public/sidepanel.html b/apps/extension/public/sidepanel.html index 19aa357..98f2648 100644 --- a/apps/extension/public/sidepanel.html +++ b/apps/extension/public/sidepanel.html @@ -17,6 +17,7 @@

AI 有数

+ 待命
diff --git a/apps/extension/src/agent-tool-definitions.ts b/apps/extension/src/agent-tool-definitions.ts index 193c47c..adc8a12 100644 --- a/apps/extension/src/agent-tool-definitions.ts +++ b/apps/extension/src/agent-tool-definitions.ts @@ -3,13 +3,89 @@ import type { AgentFunctionTool } from "@data-recipe/agent-runtime"; const selectionSchema = { type: "object", oneOf: [ - { properties: { mode: { const: "preview" }, maxChars: { type: "integer" }, maxItems: { type: "integer" } }, required: ["mode"] }, - { properties: { mode: { const: "page" }, cursor: { type: "string" }, pageSize: { type: "integer" } }, required: ["mode"] }, - { properties: { mode: { const: "range" }, offset: { type: "integer" }, length: { type: "integer" } }, required: ["mode", "offset", "length"] }, - { properties: { mode: { const: "full" } }, required: ["mode"] } + { properties: { mode: { const: "preview" }, maxChars: { type: "integer" }, maxItems: { type: "integer" } }, required: ["mode"], additionalProperties: false }, + { properties: { mode: { const: "page" }, cursor: { type: "string" }, pageSize: { type: "integer" } }, required: ["mode"], additionalProperties: false }, + { properties: { mode: { const: "range" }, offset: { type: "integer" }, length: { type: "integer" } }, required: ["mode", "offset", "length"], additionalProperties: false }, + { properties: { mode: { const: "full" } }, required: ["mode"], additionalProperties: false } ] }; +const workflowValueSchema = { + oneOf: [ + { + type: "object", + properties: { type: { const: "user_input" }, name: { type: "string" }, path: { type: "string" } }, + required: ["type", "name"], + additionalProperties: false + }, + { + type: "object", + properties: { type: { const: "step_output" }, stepId: { type: "string" }, path: { type: "string" } }, + required: ["type", "stepId", "path"], + additionalProperties: false + }, + { + type: "object", + properties: { type: { const: "literal" }, value: {} }, + required: ["type", "value"], + additionalProperties: false + } + ] +}; + +const workflowSchema = { + type: "object", + properties: { + version: { const: 1 }, + description: { type: "string" }, + userInputs: { + type: "array", + items: { + type: "object", + properties: { + name: { type: "string" }, + type: { enum: ["string", "number", "boolean", "object"] }, + required: { type: "boolean" }, + description: { type: "string" }, + examples: { type: "array" }, + parsing: { type: "string" } + }, + required: ["name", "type", "required", "description"], + additionalProperties: false + } + }, + steps: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + id: { type: "string" }, + operation: { enum: ["list", "filter", "detail", "diff"] }, + recipeId: { type: "string" }, + optional: { type: "boolean" }, + dependsOn: { type: "array", items: { type: "string" } }, + inputs: { type: "object", additionalProperties: workflowValueSchema }, + outputs: { + type: "object", + additionalProperties: { + type: "object", + properties: { path: { type: "string" }, description: { type: "string" } }, + required: ["path"], + additionalProperties: false + } + } + }, + required: ["id", "operation", "inputs", "outputs"], + additionalProperties: false + } + }, + finalOutputs: { type: "object", additionalProperties: workflowValueSchema } + }, + required: ["version", "description", "userInputs", "steps", "finalOutputs"], + additionalProperties: false +}; + export const AGENT_TOOL_DEFINITIONS: AgentFunctionTool[] = [ tool("listCapturedSources", "分页列出插件已捕获的数据来源元信息,不读取完整响应。", { type: "object", @@ -34,38 +110,40 @@ export const AGENT_TOOL_DEFINITIONS: AgentFunctionTool[] = [ }, required: ["captureId", "selection"] }), - tool("buildRecipe", "从捕获按规则生成 recipe.json 草稿;可提交检查后的完整 recipe 或 patch。", { + tool("buildRecipe", "首次用 captureId 生成 recipeId;后续只用 recipeId + patch 修改,不要传完整 recipe。", { type: "object", properties: { captureId: { type: "string" }, - recipe: { type: "object" }, + recipeId: { type: "string" }, patch: { type: "object" } }, - required: ["captureId"] + oneOf: [{ required: ["captureId"] }, { required: ["recipeId", "patch"] }] }), tool("runRecipe", "测试或运行已检查的 recipe。每次调用都会触发用户确认。", { type: "object", properties: { - recipe: { type: "object" }, + recipeId: { type: "string" }, variables: { type: "object" }, dryRun: { type: "boolean" }, previewLimit: { type: "integer" } }, - required: ["recipe"] + required: ["recipeId"] }), - tool("exportSkillPackage", "导出 Data Skill Package。必须提供 Agent 编写的完整 SKILL.md,并触发用户确认。", { + tool("exportSkillPackage", "导出 ZIP Data Skill Package。提供全部 recipeIds、workflow 和 Agent 编写的完整 SKILL.md;多接口技能必须包含多个 recipe。", { type: "object", properties: { - recipe: { type: "object" }, + recipeIds: { type: "array", minItems: 1, items: { type: "string" } }, + workflow: workflowSchema, + packageName: { type: "string" }, skillMarkdown: { type: "string" }, userGoal: { type: "string" }, examplesMarkdown: { type: "string" }, readmeMarkdown: { type: "string" } }, - required: ["recipe", "skillMarkdown", "userGoal"] + required: ["recipeIds", "workflow", "skillMarkdown", "userGoal"] }) ]; function tool(name: string, description: string, parameters: Record): AgentFunctionTool { - return { type: "function", function: { name, description, parameters } }; + return { type: "function", function: { name, description, parameters: { additionalProperties: false, ...parameters } } }; } diff --git a/apps/extension/src/agent-tools.ts b/apps/extension/src/agent-tools.ts index 3781c4b..dc68415 100644 --- a/apps/extension/src/agent-tools.ts +++ b/apps/extension/src/agent-tools.ts @@ -1,60 +1,84 @@ -import type { - AgentReadSelection, - AgentToolInputMap, - AgentToolLayer, - AgentToolName, - AgentToolOutputMap, - ReadResult +import { + RecipeStore, + RecipeStoreError, + summarizeRecipe, + type AgentReadSelection, + type AgentToolDataMap, + type AgentToolError, + type AgentToolInputMap, + type AgentToolLayer, + type AgentToolName, + type AgentToolOutputMap, + type DataRecipePatch, + type ReadResult } from "@data-recipe/agent-tools-core"; import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; -import type { DataRecipe } from "@data-recipe/recipe-core"; +import type { DataRecipe, JsonObject } from "@data-recipe/recipe-core"; import { runRecipeOnSample, runRecipeWithBrowserRpc } from "@data-recipe/recipe-runner"; import { buildDataSkillPackage } from "@data-recipe/skill-builder"; -import { exportDataSkillPackageAsJson } from "@data-recipe/skill-exporter"; +import { exportDataSkillPackageAsZip } from "@data-recipe/skill-exporter"; export interface SidepanelAgentToolsOptions { getCaptures(): CapturedRequest[]; confirmAction(message: string): Promise; - download(file: { fileName: string; mimeType: string; content: string }): void; + download(file: { fileName: string; mimeType: string; content: string | Uint8Array }): void; + recipeStore?: RecipeStore; +} + +const EXPECTED: Record = { + listCapturedSources: { cursor: "string?", pageSize: "integer 1..50?", pageUrl: "string?" }, + readCapture: { captureId: "string", section: "request|response|both", selection: "preview|page|range|full object" }, + inspectResponse: { captureId: "string", selection: "preview|page|range|full object", jsonPath: "string?", maxDepth: "integer 1..20?" }, + buildRecipe: { firstCall: { captureId: "string", patch: "object?" }, update: { recipeId: "string", patch: "object" } }, + runRecipe: { recipeId: "string", variables: "object?", dryRun: "boolean?", previewLimit: "integer 1..20?" }, + exportSkillPackage: { recipeIds: "non-empty string[]", workflow: "workflow object", packageName: "string?", skillMarkdown: "non-empty string", userGoal: "non-empty string", examplesMarkdown: "string?", readmeMarkdown: "string?" } +}; + +class ToolInputError extends Error { + constructor(readonly code: string, message: string, readonly retryable = true) { + super(message); + this.name = "ToolInputError"; + } } export class SidepanelAgentToolLayer implements AgentToolLayer { - constructor(private readonly options: SidepanelAgentToolsOptions) {} + readonly recipeStore: RecipeStore; + + constructor(private readonly options: SidepanelAgentToolsOptions) { + this.recipeStore = options.recipeStore ?? new RecipeStore(); + } async invoke( name: TName, input: AgentToolInputMap[TName] ): Promise { - let output: AgentToolOutputMap[AgentToolName]; - switch (name) { - case "listCapturedSources": - output = this.listCapturedSources(input as AgentToolInputMap["listCapturedSources"]); - break; - case "readCapture": - output = await this.readCapture(input as AgentToolInputMap["readCapture"]); - break; - case "inspectResponse": - output = await this.inspectResponse(input as AgentToolInputMap["inspectResponse"]); - break; - case "buildRecipe": - output = this.buildRecipe(input as AgentToolInputMap["buildRecipe"]); - break; - case "runRecipe": - output = await this.runRecipe(input as AgentToolInputMap["runRecipe"]); - break; - case "exportSkillPackage": - output = await this.exportSkillPackage(input as AgentToolInputMap["exportSkillPackage"]); - break; - default: - throw new Error(`不支持的工具:${String(name)}`); + try { + let data: AgentToolDataMap[AgentToolName]; + switch (name) { + case "listCapturedSources": data = this.listCapturedSources(input); break; + case "readCapture": data = await this.readCapture(input); break; + case "inspectResponse": data = await this.inspectResponse(input); break; + case "buildRecipe": data = this.buildRecipe(input); break; + case "runRecipe": data = await this.runRecipe(input); break; + case "exportSkillPackage": data = await this.exportSkillPackage(input); break; + default: throw new ToolInputError("UNKNOWN_TOOL", `不支持的工具:${String(name)}`, false); + } + return { ok: true, data } as AgentToolOutputMap[TName]; + } catch (caught) { + return { ok: false, error: toToolError(name, caught) } as AgentToolOutputMap[TName]; } - return output as AgentToolOutputMap[TName]; } - private listCapturedSources(input: AgentToolInputMap["listCapturedSources"]): AgentToolOutputMap["listCapturedSources"] { - const pageSize = clampInteger(input.pageSize, 1, 50, 20); - const offset = parseCursor(input.cursor); - const filtered = this.options.getCaptures().filter((capture) => !input.pageUrl || capture.pageUrl === input.pageUrl); + private listCapturedSources(input: unknown): AgentToolDataMap["listCapturedSources"] { + const record = requireRecord(input); + rejectUnknownKeys(record, ["cursor", "pageSize", "pageUrl"]); + optionalString(record.cursor, "cursor"); + optionalString(record.pageUrl, "pageUrl"); + optionalInteger(record.pageSize, "pageSize", 1, 50); + const pageSize = clampInteger(record.pageSize as number | undefined, 1, 50, 20); + const offset = parseCursor(record.cursor as string | undefined); + const pageUrl = record.pageUrl as string | undefined; + const filtered = this.options.getCaptures().filter((capture) => !pageUrl || capture.pageUrl === pageUrl); const page = filtered.slice(offset, offset + pageSize); const nextOffset = offset + page.length; return { @@ -73,36 +97,32 @@ export class SidepanelAgentToolLayer implements AgentToolLayer { }; } - private async readCapture(input: AgentToolInputMap["readCapture"]): Promise { - const capture = this.requireCapture(input.captureId); - validateSelection(input.selection); - if (input.selection.mode === "full") { - await this.requireConfirmation("Agent 请求完整读取当前捕获内容。完整内容可能较大,是否允许?"); - } + private async readCapture(input: unknown): Promise { + const record = requireRecord(input); + rejectUnknownKeys(record, ["captureId", "section", "selection"]); + const captureId = requiredString(record.captureId, "captureId"); + const section = requiredEnum(record.section, "section", ["request", "response", "both"] as const); + const selection = parseSelection(record.selection); + const capture = this.requireCapture(captureId); + if (selection.mode === "full") await this.requireConfirmation("Agent 请求完整读取当前捕获内容。完整内容可能较大,是否允许?"); const request = { url: redactUrl(capture.url), method: capture.method, query: capture.query, body: capture.requestBody }; - const raw = input.section === "request" - ? request - : input.section === "response" - ? capture.responseBody - : { request, response: capture.responseBody }; - return selectReadContent(redactSecrets(raw), input.selection); + const raw = section === "request" ? request : section === "response" ? capture.responseBody : { request, response: capture.responseBody }; + return selectReadContent(redactSecrets(raw), selection); } - private async inspectResponse(input: AgentToolInputMap["inspectResponse"]): Promise { - const capture = this.requireCapture(input.captureId); - validateSelection(input.selection); - if (input.selection.mode === "full") { - await this.requireConfirmation("Agent 请求完整读取响应内容以检查结构,是否允许?"); - } + private async inspectResponse(input: unknown): Promise { + const record = requireRecord(input); + rejectUnknownKeys(record, ["captureId", "selection", "jsonPath", "maxDepth"]); + const captureId = requiredString(record.captureId, "captureId"); + const selection = parseSelection(record.selection); + optionalString(record.jsonPath, "jsonPath"); + optionalInteger(record.maxDepth, "maxDepth", 1, 20); + const capture = this.requireCapture(captureId); + if (selection.mode === "full") await this.requireConfirmation("Agent 请求完整读取响应内容以检查结构,是否允许?"); const detection = summarizeResponse(capture.responseBody); - const focused = input.jsonPath ? getByPath(capture.responseBody, input.jsonPath) : capture.responseBody; - const shape = Array.isArray(focused) - ? "list" - : focused && typeof focused === "object" - ? "object" - : focused === undefined - ? "unknown" - : "scalar"; + const jsonPath = record.jsonPath as string | undefined; + const focused = jsonPath ? getByPath(capture.responseBody, jsonPath) : capture.responseBody; + const shape = Array.isArray(focused) ? "list" : focused && typeof focused === "object" ? "object" : focused === undefined ? "unknown" : "scalar"; return { shape, listPaths: detection.arrayPaths, @@ -112,37 +132,49 @@ export class SidepanelAgentToolLayer implements AgentToolLayer { type: field.type, sample: isSensitiveName(field.path) ? "[REDACTED]" : redactSecrets(field.sample) })), - content: selectReadContent(redactSecrets(limitDepth(focused, input.maxDepth ?? 8)), input.selection) + content: selectReadContent(redactSecrets(limitDepth(focused, (record.maxDepth as number | undefined) ?? 8)), selection) }; } - private buildRecipe(input: AgentToolInputMap["buildRecipe"]): AgentToolOutputMap["buildRecipe"] { - const capture = this.requireCapture(input.captureId); - const draft = sanitizeRecipe(buildRecipeFromCapture(capture)); - const candidate = input.recipe ?? draft; - const patch = input.patch ?? {}; - const recipe = sanitizeRecipe({ - ...candidate, - ...patch, - source: draft.source, - runtime: draft.runtime, - request: patch.request ? { ...candidate.request, ...patch.request } : candidate.request, - response: patch.response ? { ...candidate.response, ...patch.response } : candidate.response, - pagination: patch.pagination ? { ...candidate.pagination, ...patch.pagination } : candidate.pagination - }); - return { - recipe, - inferredByRules: !input.recipe, - warnings: recipe.fields.length ? [] : ["尚未识别出稳定返回字段,请先 inspectResponse。"] - }; + private buildRecipe(input: unknown): AgentToolDataMap["buildRecipe"] { + const record = requireRecord(input); + rejectUnknownKeys(record, ["captureId", "recipeId", "patch"]); + optionalString(record.captureId, "captureId"); + optionalString(record.recipeId, "recipeId"); + if (record.patch !== undefined && !isRecord(record.patch)) throw new ToolInputError("INVALID_PATCH", "patch 必须是 object。"); + if (isRecord(record.patch)) { + rejectUnknownKeys(record.patch, ["name", "displayName", "description", "useCases", "request", "response", "pagination", "fields"]); + } + const patch = redactSecrets(record.patch) as DataRecipePatch | undefined; + const existingId = record.recipeId as string | undefined; + + if (existingId) { + if (record.captureId !== undefined) throw new ToolInputError("AMBIGUOUS_RECIPE_REFERENCE", "recipeId 更新模式不能同时提供 captureId。"); + if (!patch) throw new ToolInputError("PATCH_REQUIRED", "使用 recipeId 修改配方时必须提供 patch。"); + const updated = sanitizeRecipe(this.recipeStore.update(existingId, patch)); + this.recipeStore.update(existingId, recipeToPatch(updated)); + return { recipeId: existingId, summary: summarizeRecipe(existingId, updated), warnings: recipeWarnings(updated), inferredByRules: false }; + } + + const captureId = requiredString(record.captureId, "captureId"); + let recipe = sanitizeRecipe(buildRecipeFromCapture(this.requireCapture(captureId))); + const recipeId = this.recipeStore.create(recipe); + if (patch) recipe = sanitizeRecipe(this.recipeStore.update(recipeId, patch)); + return { recipeId, summary: summarizeRecipe(recipeId, recipe), warnings: recipeWarnings(recipe), inferredByRules: true }; } - private async runRecipe(input: AgentToolInputMap["runRecipe"]): Promise { - const recipe = sanitizeRecipe(input.recipe); + private async runRecipe(input: unknown): Promise { + const record = requireRecord(input); + rejectUnknownKeys(record, ["recipeId", "variables", "dryRun", "previewLimit"]); + const recipeId = requiredString(record.recipeId, "recipeId"); + if (record.variables !== undefined && !isRecord(record.variables)) throw new ToolInputError("INVALID_VARIABLES", "variables 必须是 object。"); + optionalBoolean(record.dryRun, "dryRun"); + optionalInteger(record.previewLimit, "previewLimit", 1, 20); + const recipe = sanitizeRecipe(this.recipeStore.get(recipeId)); const capture = this.requireRecipeCapture(recipe); await this.requireConfirmation(`Agent 请求运行配方「${recipe.displayName}」,是否允许?`); - if (input.dryRun !== false) { - const result = runRecipeOnSample(recipe, capture.responseBody, { previewLimit: clampInteger(input.previewLimit, 1, 20, 5) }); + if (record.dryRun !== false) { + const result = runRecipeOnSample(recipe, capture.responseBody, { previewLimit: clampInteger(record.previewLimit as number | undefined, 1, 20, 5) }); return { recipeName: recipe.name, status: result.status === "unsupported" ? "error" : result.status, @@ -152,87 +184,174 @@ export class SidepanelAgentToolLayer implements AgentToolLayer { message: result.message }; } - return runRecipeWithBrowserRpc({ recipe, variables: redactSecrets(input.variables) as DataRecipe["request"]["query"] }); + return runRecipeWithBrowserRpc({ recipe, variables: redactSecrets(record.variables) as JsonObject | undefined }); } - private async exportSkillPackage( - input: AgentToolInputMap["exportSkillPackage"] - ): Promise { - this.requireRecipeCapture(input.recipe); - if (!input.skillMarkdown.trim()) throw new Error("Agent 必须先编写 SKILL.md。 "); - await this.requireConfirmation(`Agent 已准备好 Data Skill Package「${input.recipe.displayName}」,是否导出?`); - const skillPackage = buildDataSkillPackage({ - recipe: sanitizeRecipe(input.recipe), - userGoal: input.userGoal, - skillMarkdown: input.skillMarkdown, - examplesMarkdown: input.examplesMarkdown, - readmeMarkdown: input.readmeMarkdown - }); - this.options.download(exportDataSkillPackageAsJson(skillPackage)); + private async exportSkillPackage(input: unknown): Promise { + const record = requireRecord(input); + rejectUnknownKeys(record, ["recipeIds", "workflow", "packageName", "skillMarkdown", "userGoal", "examplesMarkdown", "readmeMarkdown"]); + if (!Array.isArray(record.recipeIds) || record.recipeIds.length === 0 || !record.recipeIds.every((id) => typeof id === "string" && id.trim())) { + throw new ToolInputError("INVALID_INPUT", "recipeIds 必须是非空字符串数组。"); + } + if (!isRecord(record.workflow)) throw new ToolInputError("INVALID_INPUT", "workflow 必须是 object。"); + optionalString(record.packageName, "packageName"); + const skillMarkdown = requiredString(record.skillMarkdown, "skillMarkdown"); + const userGoal = requiredString(record.userGoal, "userGoal"); + optionalString(record.examplesMarkdown, "examplesMarkdown"); + optionalString(record.readmeMarkdown, "readmeMarkdown"); + const recipeIds = [...new Set((record.recipeIds as string[]).map((id) => id.trim()))]; + const recipes = recipeIds.map((recipeId) => ({ recipeId, recipe: sanitizeRecipe(this.recipeStore.get(recipeId)) })); + recipes.forEach(({ recipe }) => this.requireRecipeCapture(recipe)); + let skillPackage; + try { + skillPackage = buildDataSkillPackage({ + packageName: record.packageName as string | undefined, + recipes, + workflow: record.workflow as never, + userGoal, + skillMarkdown, + examplesMarkdown: record.examplesMarkdown as string | undefined, + readmeMarkdown: record.readmeMarkdown as string | undefined + }); + } catch (caught) { + throw new ToolInputError( + "INVALID_WORKFLOW", + caught instanceof Error ? caught.message : "workflow 或技能包结构无效。", + true + ); + } + await this.requireConfirmation(`Agent 已准备好包含 ${recipes.length} 个 recipe 的 Data Skill Package,是否导出 ZIP?`); + this.options.download(exportDataSkillPackageAsZip(skillPackage)); return { package: skillPackage, warnings: [] }; } private requireCapture(id: string): CapturedRequest { const capture = this.options.getCaptures().find((item) => item.id === id); - if (!capture) throw new Error(`找不到 capture:${id}`); + if (!capture) throw new ToolInputError("CAPTURE_NOT_FOUND", `找不到 capture:${id}`, false); return capture; } private requireRecipeCapture(recipe: DataRecipe): CapturedRequest { const capture = this.options.getCaptures().find((item) => redactUrl(item.url) === recipe.source.apiUrl); - if (!capture) throw new Error("recipe 的数据来源不在当前已捕获列表中,拒绝执行。"); + if (!capture) throw new ToolInputError("RECIPE_SOURCE_NOT_CAPTURED", "recipe 的数据来源不在当前已捕获列表中,拒绝执行。", false); return capture; } private async requireConfirmation(message: string): Promise { - if (!await this.options.confirmAction(message)) throw new Error("用户拒绝了本次操作。"); + if (!await this.options.confirmAction(message)) throw new ToolInputError("USER_DENIED", "用户拒绝了本次操作。", false); + } +} + +function toToolError(name: AgentToolName, caught: unknown): AgentToolError { + if (caught instanceof ToolInputError) { + return { code: caught.code, message: caught.message, retryable: caught.retryable, expectedInput: EXPECTED[name] }; } + if (caught instanceof RecipeStoreError) { + return { code: caught.code, message: caught.message, retryable: caught.code !== "RECIPE_NOT_FOUND", expectedInput: EXPECTED[name] }; + } + return { code: "INTERNAL_TOOL_ERROR", message: "工具内部执行失败,请检查输入或重新开始该步骤。", retryable: false, expectedInput: EXPECTED[name] }; +} + +function requireRecord(value: unknown): Record { + if (!isRecord(value)) throw new ToolInputError("INVALID_INPUT", "工具参数必须是 object。"); + return value; +} + +function rejectUnknownKeys(record: Record, allowed: string[]): void { + const unknown = Object.keys(record).filter((key) => !allowed.includes(key)); + if (unknown.length) throw new ToolInputError("UNKNOWN_INPUT_FIELDS", `不支持的参数字段:${unknown.join("、")}。`); +} + +function requiredString(value: unknown, field: string): string { + if (typeof value !== "string" || !value.trim()) throw new ToolInputError("INVALID_INPUT", `${field} 必须是非空字符串。`); + return value.trim(); +} + +function optionalString(value: unknown, field: string): void { + if (value !== undefined && typeof value !== "string") throw new ToolInputError("INVALID_INPUT", `${field} 必须是字符串。`); +} + +function optionalBoolean(value: unknown, field: string): void { + if (value !== undefined && typeof value !== "boolean") throw new ToolInputError("INVALID_INPUT", `${field} 必须是 boolean。`); +} + +function optionalInteger(value: unknown, field: string, min: number, max: number): void { + if (value !== undefined && (!Number.isInteger(value) || Number(value) < min || Number(value) > max)) { + throw new ToolInputError("INVALID_INPUT", `${field} 必须是 ${min}..${max} 的整数。`); + } +} + +function requiredEnum(value: unknown, field: string, allowed: T): T[number] { + if (typeof value !== "string" || !allowed.includes(value)) throw new ToolInputError("INVALID_INPUT", `${field} 必须是 ${allowed.join("、")}。`); + return value as T[number]; +} + +function parseSelection(value: unknown): AgentReadSelection { + const record = requireRecord(value); + const mode = requiredEnum(record.mode, "selection.mode", ["preview", "page", "range", "full"] as const); + if (mode === "preview") { + rejectUnknownKeys(record, ["mode", "maxChars", "maxItems"]); + optionalInteger(record.maxChars, "selection.maxChars", 100, 8000); + optionalInteger(record.maxItems, "selection.maxItems", 1, 100); + return { mode, maxChars: record.maxChars as number | undefined, maxItems: record.maxItems as number | undefined }; + } + if (mode === "page") { + rejectUnknownKeys(record, ["mode", "cursor", "pageSize"]); + optionalString(record.cursor, "selection.cursor"); + optionalInteger(record.pageSize, "selection.pageSize", 100, 8000); + return { mode, cursor: record.cursor as string | undefined, pageSize: record.pageSize as number | undefined }; + } + if (mode === "range") { + rejectUnknownKeys(record, ["mode", "offset", "length"]); + optionalInteger(record.offset, "selection.offset", 0, Number.MAX_SAFE_INTEGER); + optionalInteger(record.length, "selection.length", 1, 8000); + if (record.offset === undefined || record.length === undefined) throw new ToolInputError("INVALID_INPUT", "range 模式必须提供 offset 和 length。"); + return { mode, offset: record.offset as number, length: record.length as number }; + } + rejectUnknownKeys(record, ["mode"]); + return { mode }; } function selectReadContent(value: unknown, selection: AgentReadSelection): ReadResult { const text = safeJson(value); - if (selection.mode === "full") { - return { value, selection, truncated: false, totalChars: text.length }; - } + if (selection.mode === "full") return { value, selection, truncated: false, totalChars: text.length }; if (selection.mode === "preview") { const maxChars = clampInteger(selection.maxChars, 100, 8000, 1800); - const previewValue = Array.isArray(value) - ? value.slice(0, clampInteger(selection.maxItems, 1, 100, 10)) - : text.slice(0, maxChars); - return { - value: previewValue, - selection, - truncated: Array.isArray(value) ? previewValue.length < value.length : text.length > maxChars, - totalItems: Array.isArray(value) ? value.length : undefined, - totalChars: text.length - }; + const previewValue = Array.isArray(value) ? value.slice(0, clampInteger(selection.maxItems, 1, 100, 10)) : text.slice(0, maxChars); + return { value: previewValue, selection, truncated: Array.isArray(value) ? previewValue.length < value.length : text.length > maxChars, totalItems: Array.isArray(value) ? value.length : undefined, totalChars: text.length }; } if (selection.mode === "range") { const offset = clampInteger(selection.offset, 0, text.length, 0); const length = clampInteger(selection.length, 1, 8000, 1800); - return { - value: text.slice(offset, offset + length), - selection, - truncated: offset > 0 || offset + length < text.length, - totalChars: text.length - }; + return { value: text.slice(offset, offset + length), selection, truncated: offset > 0 || offset + length < text.length, totalChars: text.length }; } const offset = parseCursor(selection.cursor); const pageSize = clampInteger(selection.pageSize, 100, 8000, 1800); const end = Math.min(text.length, offset + pageSize); + return { value: text.slice(offset, end), selection, truncated: end < text.length, nextCursor: end < text.length ? String(end) : undefined, totalChars: text.length }; +} + +function sanitizeRecipe(recipe: DataRecipe): DataRecipe { return { - value: text.slice(offset, end), - selection, - truncated: end < text.length, - nextCursor: end < text.length ? String(end) : undefined, - totalChars: text.length + ...recipe, + source: { ...recipe.source, pageUrl: redactUrl(recipe.source.pageUrl), apiUrl: redactUrl(recipe.source.apiUrl) }, + request: { + ...recipe.request, + query: redactSecrets(recipe.request.query) as JsonObject, + body: redactSecrets(recipe.request.body), + queryFields: recipe.request.queryFields.map((field) => ({ ...field, sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) })), + bodyFields: recipe.request.bodyFields.map((field) => ({ ...field, sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) })) + }, + fields: recipe.fields.map((field) => ({ ...field, sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) })) }; } -function validateSelection(value: AgentReadSelection): void { - if (!value || !["preview", "page", "range", "full"].includes(value.mode)) { - throw new Error("selection.mode 必须是 preview、page、range 或 full。"); - } +function recipeToPatch(recipe: DataRecipe): DataRecipePatch { + return { name: recipe.name, displayName: recipe.displayName, description: recipe.description, useCases: recipe.useCases, request: recipe.request, response: recipe.response, pagination: recipe.pagination, fields: recipe.fields }; +} + +function recipeWarnings(recipe: DataRecipe): string[] { + return recipe.fields.length ? [] : ["尚未识别出稳定返回字段,请先 inspectResponse。"]; } function redactSecrets(value: unknown, seen = new WeakSet()): unknown { @@ -240,52 +359,15 @@ function redactSecrets(value: unknown, seen = new WeakSet()): unknown { if (seen.has(value)) return "[Circular]"; seen.add(value); if (Array.isArray(value)) return value.map((item) => redactSecrets(item, seen)); - return Object.fromEntries(Object.entries(value).map(([key, child]) => [ - key, - isSensitiveName(key) - ? "[REDACTED]" - : redactSecrets(child, seen) - ])); -} - -function sanitizeRecipe(recipe: DataRecipe): DataRecipe { - return { - ...recipe, - source: { - ...recipe.source, - pageUrl: redactUrl(recipe.source.pageUrl), - apiUrl: redactUrl(recipe.source.apiUrl) - }, - request: { - ...recipe.request, - query: redactSecrets(recipe.request.query) as DataRecipe["request"]["query"], - body: redactSecrets(recipe.request.body), - queryFields: recipe.request.queryFields.map((field) => ({ - ...field, - sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) - })), - bodyFields: recipe.request.bodyFields.map((field) => ({ - ...field, - sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) - })) - }, - fields: recipe.fields.map((field) => ({ - ...field, - sample: isSensitiveName(`${field.name}.${field.path}`) ? "[REDACTED]" : redactSecrets(field.sample) - })) - }; + return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, isSensitiveName(key) ? "[REDACTED]" : redactSecrets(child, seen)])); } function redactUrl(value: string): string { try { const url = new URL(value); - Array.from(url.searchParams.keys()).forEach((key) => { - if (isSensitiveName(key)) url.searchParams.set(key, "[REDACTED]"); - }); + Array.from(url.searchParams.keys()).forEach((key) => { if (isSensitiveName(key)) url.searchParams.set(key, "[REDACTED]"); }); return url.toString(); - } catch { - return value; - } + } catch { return value; } } function isSensitiveName(value: string): boolean { @@ -295,18 +377,13 @@ function isSensitiveName(value: string): boolean { function limitDepth(value: unknown, depth: number): unknown { if (depth <= 0 && value && typeof value === "object") return "[Max depth reached]"; if (Array.isArray(value)) return value.slice(0, 100).map((item) => limitDepth(item, depth - 1)); - if (value && typeof value === "object") { - return Object.fromEntries(Object.entries(value).slice(0, 100).map(([key, child]) => [key, limitDepth(child, depth - 1)])); - } + if (isRecord(value)) return Object.fromEntries(Object.entries(value).slice(0, 100).map(([key, child]) => [key, limitDepth(child, depth - 1)])); return value; } function getByPath(value: unknown, path: string): unknown { if (!path || path === "$") return value; - return path.replace(/^\$\.?/, "").split(".").filter(Boolean).reduce((current, part) => { - if (!current || typeof current !== "object") return undefined; - return (current as Record)[part]; - }, value); + return path.replace(/^\$\.?/, "").split(".").filter(Boolean).reduce((current, part) => isRecord(current) ? current[part] : undefined, value); } function clampInteger(value: number | undefined, min: number, max: number, fallback: number): number { @@ -318,10 +395,10 @@ function parseCursor(cursor: string | undefined): number { return Number.isInteger(value) && value >= 0 ? value : 0; } +function isRecord(value: unknown): value is Record { + return !!value && typeof value === "object" && !Array.isArray(value); +} + function safeJson(value: unknown): string { - try { - return JSON.stringify(value, null, 2) ?? "null"; - } catch { - return "[Unserializable]"; - } + try { return JSON.stringify(value, null, 2) ?? "null"; } catch { return "[Unserializable]"; } } diff --git a/apps/extension/src/sidepanel.ts b/apps/extension/src/sidepanel.ts index 008fc33..7e46fbf 100644 --- a/apps/extension/src/sidepanel.ts +++ b/apps/extension/src/sidepanel.ts @@ -1,73 +1,85 @@ +import DOMPurify from "dompurify"; +import { marked } from "marked"; import { + AgentRunError, OpenAICompatibleProvider, ToolCallingAgentRuntime, type AgentChatMessage, + type AgentRunOutcome, + type AgentStatus, + type AgentToolCallStartedEvent, type AgentToolExecutionEvent, type OpenAICompatibleProviderConfig } from "@data-recipe/agent-runtime"; -import type { AgentToolInputMap, AgentToolName } from "@data-recipe/agent-tools-core"; +import type { AgentToolName } from "@data-recipe/agent-tools-core"; import { buildRecipeFromCapture, summarizeResponse, type CapturedRequest } from "@data-recipe/detector"; import type { PanelEvent, PanelSnapshot } from "./messages"; import { AGENT_TOOL_DEFINITIONS } from "./agent-tool-definitions"; import { SidepanelAgentToolLayer } from "./agent-tools"; -interface ToolCallView { - name: string; - summary: string; - input: unknown; - output: unknown; - error?: string; -} - -interface ChatMessage { - id: string; - role: "assistant" | "user"; - text: string; - pending?: boolean; - tools?: ToolCallView[]; +type ConversationEvent = + | { id: string; at: number; type: "user_message"; content: string } + | { id: string; at: number; type: "assistant_message"; content: string; state: "streaming" | "complete" | "error" } + | { id: string; at: number; type: "tool_call"; toolCallId: string; name: string; arguments: unknown; status: "running" | "success" | "error" } + | { id: string; at: number; type: "tool_result"; toolCallId: string; name: string; result: unknown; success: boolean } + | { id: string; at: number; type: "status"; status: AgentStatus | "restored"; label: string } + | { id: string; at: number; type: "artifact"; name: string; mimeType: string; details: unknown } + | { id: string; at: number; type: "outcome"; outcome: AgentRunOutcome }; + +interface ConversationCheckpoint { + version: 2; + conversationId: string; + agentMessages: AgentChatMessage[]; + events: ConversationEvent[]; + recipes: unknown; + lastOutcome: AgentRunOutcome | null; } const MODEL_CONFIG_STORAGE_KEY = "dataRecipeOpenAICompatibleProvider"; +const CONVERSATION_INDEX_PREFIX = "dataRecipeConversationIndex"; +const CONVERSATION_PREFIX = "dataRecipeConversation"; const SYSTEM_PROMPT = `你是 AI 有数的数据技能生成 Agent。 -你可以调用插件提供的工具观察当前页面捕获的数据来源,并根据用户目标生成可复用的 Data Skill Package。 +你可以调用插件工具观察当前页面捕获的数据来源,并根据用户目标生成可独立运行的 Data Skill Package ZIP。 工作规则: -- 先用 listCapturedSources 了解可用来源,再按需要调用 readCapture 或 inspectResponse。读多少由你决定,但必须遵守 bounded read;优先 preview/page/range,只有确有必要才请求 full。 -- readCapture full、runRecipe、exportSkillPackage 会要求用户确认。用户拒绝后应尊重决定并调整计划。 -- 不要要求用户提供 Cookie、Authorization header、API token 或其它浏览器凭证。 -- 不要尝试绕过登录、验证码、风控、动态签名、反爬或来源权限。 -- recipe.json 由 buildRecipe 基于规则生成。你必须检查其来源、参数、响应结构、分页和字段,必要时再用 buildRecipe 提交修订。 -- SKILL.md 必须由你根据工具读取结果和用户目标独立编写,不得依赖固定模板。应包含合法 YAML frontmatter、用途、输入、输出、执行方式和安全约束。 -- 在导出前应调用 runRecipe 做一次用户确认的测试。 -- 最终目标是调用 exportSkillPackage 生成 Data Skill Package,并向用户说明结果。`; +- 先用 listCapturedSources 了解来源,再按需调用 readCapture/inspectResponse;优先 bounded preview/page/range,full 只在必要时请求。 +- 不要要求 Cookie、Authorization header、API token;不要绕过登录、验证码、风控、动态签名、反爬或来源权限。 +- 首次 buildRecipe 使用 captureId 获取 recipeId;后续只能用 recipeId + patch。runRecipe 只接收 recipeId。 +- 多接口技能必须为每个接口创建 recipe。exportSkillPackage 必须提交所有 recipeIds 和 workflow;workflow 要描述 list → filter → detail → diff 的输入输出依赖。 +- SKILL.md 由你基于工具结果和用户目标编写,包含 YAML frontmatter、用途、输入、输出、流程和安全约束。 +- 在导出前测试必要 recipe。exportSkillPackage 输出正式 ZIP。 +- 如果上一轮提供 AgentRunOutcome,必须继续其 pendingSteps,并如实承认 failedToolCalls;结构化状态存在错误时不得声称“没有报错”。 +- 用户输入如“池佳 W25”时,应解析人员、当前/明确年份与 ISO 周数;通过列表匹配动态获得 empCode、uid、weekId,禁止硬编码具体人员标识,再获取详情并按需 diff。`; const port = chrome.runtime.connect({ name: "data-recipe-sidepanel" }); - const state: { snapshot: PanelSnapshot; selectedId: string | null; running: boolean; configLoaded: boolean; providerConfig: OpenAICompatibleProviderConfig | null; - messages: ChatMessage[]; + events: ConversationEvent[]; agentMessages: AgentChatMessage[]; + conversationId: string; + loadedConversationTabId: number | null; + lastOutcome: AgentRunOutcome | null; } = { snapshot: { tabId: null, state: "idle", captures: [] }, selectedId: null, running: false, configLoaded: false, providerConfig: null, - messages: [{ - id: createId(), - role: "assistant", - text: "你好,我是 AI 有数。配置模型后,告诉我你想从当前页面了解什么,我会调用页面工具生成并测试数据技能。" - }], - agentMessages: [] + events: [assistantEvent("你好,我是 AI 有数。配置模型后,告诉我你想从当前页面完成什么数据技能。", "complete")], + agentMessages: [], + conversationId: createId(), + loadedConversationTabId: null, + lastOutcome: null }; const elements = { statusBadge: getElement("statusBadge"), + newConversationButton: getElement("newConversationButton"), settingsButton: getElement("settingsButton"), startButton: getElement("startButton"), stopButton: getElement("stopButton"), @@ -92,20 +104,18 @@ const elements = { const toolLayer = new SidepanelAgentToolLayer({ getCaptures: () => state.snapshot.captures, confirmAction: async (message) => window.confirm(message), - download: downloadTextFile + download: downloadFile }); elements.settingsButton.addEventListener("click", openModelSettings); +elements.newConversationButton.addEventListener("click", () => void startNewConversation()); elements.closeSettingsButton.addEventListener("click", () => elements.modelDialog.close()); elements.modelForm.addEventListener("submit", (event) => { event.preventDefault(); void saveModelSettings(); }); elements.startButton.addEventListener("click", startLearning); elements.stopButton.addEventListener("click", () => port.postMessage({ type: "stop-discovery" })); elements.composer.addEventListener("submit", (event) => { event.preventDefault(); void submitGoal(elements.chatInput.value); }); elements.chatInput.addEventListener("keydown", (event) => { - if (event.key === "Enter" && !event.shiftKey) { - event.preventDefault(); - elements.composer.requestSubmit(); - } + if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); elements.composer.requestSubmit(); } }); elements.chatInput.addEventListener("input", resizeComposer); elements.suggestions.querySelectorAll("[data-prompt]").forEach((button) => { @@ -113,104 +123,157 @@ elements.suggestions.querySelectorAll("[data-prompt]").forEac }); port.onMessage.addListener((event: PanelEvent) => { - if (event.type === "snapshot") { - applySnapshot(event.snapshot); - return; - } + if (event.type === "snapshot") return applySnapshot(event.snapshot); if (event.type === "capture-added") { const wasEmpty = state.snapshot.captures.length === 0; state.snapshot = event.snapshot; state.selectedId = event.capture.id; - if (wasEmpty) addMessage("assistant", "我已经捕获到第一个数据来源。现在可以告诉我你想生成什么数据技能。", false); + if (wasEmpty) appendEvent(assistantEvent("已捕获到第一个数据来源。现在可以告诉我你想生成什么技能。", "complete")); render(); } }); +marked.setOptions({ gfm: true, breaks: true }); void loadModelSettings(); port.postMessage({ type: "get-snapshot" }); render(); function startLearning(): void { port.postMessage({ type: "start-discovery" }); - addMessage("assistant", "已开始学习当前页面。请回到页面执行一次查询、筛选或翻页,我会观察相关数据请求。", true); + appendEvent(statusEvent("thinking", "已开始学习页面,请在页面中执行查询、筛选或翻页")); } async function submitGoal(rawGoal: string): Promise { const goal = rawGoal.trim(); if (!goal || state.running) return; if (!state.providerConfig) { - addMessage("assistant", "请先在「模型设置」中配置 OpenAI-compatible Provider,配置完成后我才能运行真实 Agent。", true); + appendEvent(assistantEvent("请先在“模型设置”中配置 OpenAI-compatible Provider。", "complete")); openModelSettings(); return; } elements.chatInput.value = ""; resizeComposer(); - addMessage("user", goal, false); - const pending: ChatMessage = { - id: createId(), - role: "assistant", - text: `正在连接 ${state.providerConfig.model},由模型规划下一步…`, - pending: true, - tools: [] - }; - state.messages.push(pending); + appendEvent(userEvent(goal)); + let currentAssistant: Extract | null = null; + const previousOutcome = state.lastOutcome; + state.lastOutcome = null; + const outcomeContext: AgentChatMessage[] = previousOutcome + ? [{ role: "user", content: `[Previous AgentRunOutcome]\n${JSON.stringify(previousOutcome)}` }] + : []; + const runMessages: AgentChatMessage[] = [...state.agentMessages, ...outcomeContext, { role: "user", content: goal }]; + state.agentMessages = runMessages; state.running = true; + await saveConversation(); render(); - scrollToLatest(); try { const runtime = new ToolCallingAgentRuntime(new OpenAICompatibleProvider(state.providerConfig)); - const runMessages: AgentChatMessage[] = [...state.agentMessages, { role: "user", content: goal }]; const result = await runtime.run({ systemPrompt: SYSTEM_PROMPT, messages: runMessages, tools: AGENT_TOOL_DEFINITIONS, executeTool: invokeAgentTool, - onToolExecution: (event) => showToolExecution(pending, event) + onTextDelta: (delta) => { + if (!currentAssistant) { + currentAssistant = assistantEvent("", "streaming"); + appendEvent(currentAssistant); + } + currentAssistant.content += delta; + renderTimeline(); + scheduleConversationSave(); + scrollToLatest(); + }, + onStatusChange: (status) => { + if (status === "thinking") { + finishAssistantEvent(currentAssistant); + currentAssistant = null; + } + appendEvent(statusEvent(status, statusLabel(status))); + }, + onToolCall: (event) => { + discardEmptyAssistantEvent(currentAssistant); + currentAssistant = null; + showToolCall(event); + }, + onToolExecution: (event) => showToolResult(event), + onMessagesUpdated: async (messages) => { + state.agentMessages = withoutSystem(messages); + await saveConversation(); + } }); - state.agentMessages = result.messages.filter((message) => message.role !== "system"); - pending.text = result.finalText; - pending.pending = false; - } catch (error) { - pending.text = error instanceof Error ? `Agent 运行失败:${error.message}` : "Agent 运行失败。"; - pending.pending = false; + state.agentMessages = withoutSystem(result.messages); + const completedAssistant = currentAssistant as Extract | null; + if (!completedAssistant) { + currentAssistant = assistantEvent(result.finalText, "complete"); + appendEvent(currentAssistant); + } else { + completedAssistant.state = "complete"; + if (!completedAssistant.content.trim()) completedAssistant.content = result.finalText; + } + state.lastOutcome = result.outcome; + appendEvent(outcomeEvent(result.outcome)); + } catch (caught) { + const outcome = caught instanceof AgentRunError ? caught.outcome : failedOutcome(caught); + if (caught instanceof AgentRunError) state.agentMessages = withoutSystem(caught.partialMessages); + let failedAssistant = currentAssistant as Extract | null; + if (!failedAssistant) { + currentAssistant = assistantEvent("", "error"); + appendEvent(currentAssistant); + failedAssistant = currentAssistant; + } + failedAssistant.state = "error"; + const failure = caught instanceof Error ? caught.message : "Agent 运行失败。"; + failedAssistant.content += `${failedAssistant.content ? "\n\n" : ""}**运行中断:** ${failure}`; + state.lastOutcome = outcome; + appendEvent(outcomeEvent(outcome)); } finally { state.running = false; + await saveConversation(); render(); scrollToLatest(); } } async function invokeAgentTool(name: string, input: unknown): Promise { - if (!isAgentToolName(name)) throw new Error(`模型请求了未知工具:${name}`); + if (!isAgentToolName(name)) { + return { ok: false, error: { code: "UNKNOWN_TOOL", message: `未知工具:${name}`, retryable: false, expectedInput: { availableTools: AGENT_TOOL_DEFINITIONS.map((item) => item.function.name) } } }; + } return toolLayer.invoke(name, input as never); } -function showToolExecution(message: ChatMessage, event: AgentToolExecutionEvent): void { - message.text = event.error ? `工具 ${event.toolCall.function.name} 未完成,模型正在调整计划…` : "模型正在根据工具结果继续工作…"; - message.tools?.push({ - name: event.toolCall.function.name, - summary: event.error ?? summarizeToolResult(event.result), - input: event.arguments, - output: event.result, - error: event.error - }); - renderChat(); - scrollToLatest(); +function showToolCall(event: AgentToolCallStartedEvent): void { + appendEvent({ id: createId(), at: Date.now(), type: "tool_call", toolCallId: event.toolCall.id, name: event.toolCall.function.name, arguments: event.arguments, status: "running" }); +} + +function showToolResult(event: AgentToolExecutionEvent): void { + const call = state.events.find((item): item is Extract => item.type === "tool_call" && item.toolCallId === event.toolCall.id); + if (call) call.status = event.failed ? "error" : "success"; + appendEvent({ id: createId(), at: Date.now(), type: "tool_result", toolCallId: event.toolCall.id, name: event.toolCall.function.name, result: event.result, success: !event.failed }); + if (event.toolCall.function.name === "exportSkillPackage" && !event.failed) { + const packageInfo = getSuccessfulToolData(event.result)?.package as { packageName?: string; files?: unknown[] } | undefined; + appendEvent({ + id: createId(), + at: Date.now(), + type: "artifact", + name: `${packageInfo?.packageName ?? "data-skill"}.zip`, + mimeType: "application/zip", + details: { files: packageInfo?.files?.length ?? 0 } + }); + } } function applySnapshot(snapshot: PanelSnapshot): void { state.snapshot = snapshot; if (!state.selectedId && snapshot.captures[0]) state.selectedId = snapshot.captures[0].id; + if (snapshot.tabId !== null && snapshot.tabId !== state.loadedConversationTabId) void loadConversation(snapshot.tabId); render(); } async function loadModelSettings(): Promise { try { const stored = await chrome.storage.local.get(MODEL_CONFIG_STORAGE_KEY); - const candidate = stored[MODEL_CONFIG_STORAGE_KEY]; - if (isProviderConfig(candidate)) state.providerConfig = candidate; + if (isProviderConfig(stored[MODEL_CONFIG_STORAGE_KEY])) state.providerConfig = stored[MODEL_CONFIG_STORAGE_KEY]; } finally { state.configLoaded = true; render(); @@ -233,16 +296,13 @@ async function saveModelSettings(): Promise { model: elements.modelInput.value.trim() }; new OpenAICompatibleProvider(config); - const url = new URL(config.baseUrl); - if (!/^https?:$/.test(url.protocol)) throw new Error("Base URL 必须使用 http 或 https。 "); + if (!/^https?:$/.test(new URL(config.baseUrl).protocol)) throw new Error("Base URL 必须使用 http 或 https。"); await chrome.storage.local.set({ [MODEL_CONFIG_STORAGE_KEY]: config }); state.providerConfig = config; - state.agentMessages = []; elements.modelDialog.close(); - addMessage("assistant", `模型已配置为 ${config.model}。现在可以开始真实 Agent 对话。`, false); - render(); - } catch (error) { - elements.modelError.textContent = error instanceof Error ? error.message : "模型配置无效。"; + appendEvent(assistantEvent(`模型已配置为 **${config.model}**。当前对话历史保持不变。`, "complete")); + } catch (caught) { + elements.modelError.textContent = caught instanceof Error ? caught.message : "模型配置无效。"; } } @@ -253,65 +313,113 @@ function render(): void { elements.startButton.disabled = active; elements.startButton.textContent = active ? "正在学习页面…" : "开始学习页面"; elements.stopButton.hidden = !active; - elements.learnHint.textContent = active - ? `正在观察页面操作,已发现 ${state.snapshot.captures.length} 个数据来源。` - : "开启后,请在页面里完成一次查询或翻页。"; + elements.learnHint.textContent = active ? `正在观察页面操作,已发现 ${state.snapshot.captures.length} 个数据来源。` : "开启后,请在页面里完成一次查询或翻页。"; const configured = state.configLoaded && !!state.providerConfig; elements.chatInput.disabled = state.running || !configured; - elements.chatInput.placeholder = !state.configLoaded - ? "正在读取模型配置…" - : configured - ? "告诉 AI 你想用页面数据完成什么…" - : "请先点击“模型设置”配置 Provider"; + elements.chatInput.placeholder = !state.configLoaded ? "正在读取模型配置…" : configured ? "告诉 AI 你想用页面数据完成什么…" : "请先点击“模型设置”配置 Provider"; elements.sendButton.disabled = state.running || !configured; + elements.newConversationButton.disabled = state.running; elements.captureCount.textContent = `${state.snapshot.captures.length} 个数据源`; - renderChat(); + renderTimeline(); renderWorkspace(); } -function renderChat(): void { +function renderTimeline(): void { elements.messageList.innerHTML = ""; - state.messages.forEach((message) => elements.messageList.append(renderMessage(message))); -} - -function renderMessage(message: ChatMessage): HTMLElement { - const article = document.createElement("article"); - article.className = `message ${message.role}`; - const avatar = document.createElement("div"); - avatar.className = "avatar"; - avatar.textContent = message.role === "assistant" ? "AI" : "我"; - const bubble = document.createElement("div"); - bubble.className = "bubble"; - if (message.role === "assistant") { - const head = document.createElement("div"); - head.className = "message-head"; - head.textContent = message.pending ? "AI 有数 · 运行中" : "AI 有数"; - bubble.append(head); + state.events.forEach((event) => elements.messageList.append(renderConversationEvent(event))); +} + +function renderConversationEvent(event: ConversationEvent): HTMLElement { + if (event.type === "user_message" || event.type === "assistant_message") { + const article = document.createElement("article"); + article.className = `message ${event.type === "user_message" ? "user" : "assistant"}`; + const avatar = document.createElement("div"); + avatar.className = "avatar"; + avatar.textContent = event.type === "user_message" ? "我" : "AI"; + const bubble = document.createElement("div"); + bubble.className = "bubble"; + if (event.type === "assistant_message") { + const head = document.createElement("div"); + head.className = "message-head"; + head.textContent = event.state === "streaming" ? "AI 有数 · 生成中" : event.state === "error" ? "AI 有数 · 已中断" : "AI 有数"; + bubble.append(head); + const markdown = document.createElement("div"); + markdown.className = "message-text markdown-body"; + renderMarkdown(markdown, event.content || "_正在思考…_"); + bubble.append(markdown); + } else { + const text = document.createElement("div"); + text.className = "message-text"; + text.textContent = event.content; + bubble.append(text); + } + article.append(avatar, bubble); + return article; + } + + if (event.type === "status") { + const row = document.createElement("div"); + row.className = "timeline-status"; + row.textContent = event.label; + return row; } - const text = document.createElement("div"); - text.className = "message-text"; - text.textContent = message.text; - bubble.append(text); - message.tools?.forEach((tool) => bubble.append(toolCallDetails(tool))); - article.append(avatar, bubble); - return article; + + if (event.type === "tool_call") { + const details = document.createElement("details"); + details.className = `timeline-tool ${event.status}`; + const summary = document.createElement("summary"); + summary.textContent = `${event.status === "running" ? "●" : event.status === "success" ? "✓" : "!"} ${event.name} · ${event.status === "running" ? "执行中" : event.status === "success" ? "已完成" : "失败"}`; + details.append(summary, jsonPre(event.arguments)); + return details; + } + + if (event.type === "tool_result") { + const details = document.createElement("details"); + details.className = `timeline-result ${event.success ? "success" : "error"}`; + const summary = document.createElement("summary"); + summary.textContent = `${event.success ? "↳" : "↳ !"} ${event.name} result`; + details.append(summary, jsonPre(event.result)); + return details; + } + + if (event.type === "artifact") { + const card = document.createElement("div"); + card.className = "artifact-card"; + card.textContent = `ZIP 产物 · ${event.name}`; + return card; + } + + const card = document.createElement("div"); + card.className = `outcome-card ${event.outcome.status}`; + const title = document.createElement("strong"); + title.textContent = outcomeTitle(event.outcome); + const detail = document.createElement("span"); + detail.textContent = `已完成 ${event.outcome.completedSteps.length} 步 · 待处理 ${event.outcome.pendingSteps.length} 步 · recipe ${event.outcome.recipeIds.length} 个`; + card.append(title, detail); + if (event.outcome.status === "paused_budget") { + const button = document.createElement("button"); + button.type = "button"; + button.textContent = "继续任务"; + button.disabled = state.running; + button.addEventListener("click", () => void submitGoal("继续任务")); + card.append(button); + } + return card; } -function toolCallDetails(tool: ToolCallView): HTMLElement { - const details = document.createElement("details"); - details.className = "tool-call"; - const summary = document.createElement("summary"); - summary.textContent = `${tool.error ? "!" : "✓"} ${tool.name} · ${tool.summary}`; - const output = document.createElement("pre"); - output.textContent = JSON.stringify({ input: tool.input, output: tool.output }, null, 2); - details.append(summary, output); - return details; +function renderMarkdown(target: HTMLElement, markdown: string): void { + const rendered = marked.parse(markdown, { async: false }) as string; + target.innerHTML = DOMPurify.sanitize(rendered, { USE_PROFILES: { html: true } }); + target.querySelectorAll("a").forEach((link) => { + link.target = "_blank"; + link.rel = "noopener noreferrer"; + }); } function renderWorkspace(): void { const captures = state.snapshot.captures; elements.requestList.innerHTML = ""; - if (captures.length === 0) { + if (!captures.length) { elements.requestList.className = "source-list empty"; elements.requestList.textContent = "学习页面后,数据源会显示在这里。"; } else { @@ -341,9 +449,7 @@ function renderWorkspace(): void { const details = document.createElement("details"); const summary = document.createElement("summary"); summary.textContent = "查看 recipe 草稿与响应预览"; - const content = document.createElement("pre"); - content.textContent = JSON.stringify({ recipe, responsePreview: capture.responsePreview }, null, 2); - details.append(summary, content); + details.append(summary, jsonPre({ recipe, responsePreview: capture.responsePreview })); elements.requestDetail.append(info, details); } @@ -362,39 +468,186 @@ function sourceButton(capture: CapturedRequest): HTMLButtonElement { return button; } -function getSelectedCapture(): CapturedRequest | undefined { - return state.snapshot.captures.find((capture) => capture.id === state.selectedId) ?? state.snapshot.captures[0]; +async function loadConversation(tabId: number): Promise { + state.loadedConversationTabId = tabId; + toolLayer.recipeStore.clear(); + try { + const indexKey = conversationIndexKey(tabId); + const index = await chrome.storage.session.get(indexKey); + const storedId = index[indexKey]; + state.conversationId = typeof storedId === "string" && storedId ? storedId : createId(); + let restored = false; + if (typeof storedId === "string" && storedId) { + const key = conversationStorageKey(tabId, storedId); + const checkpoint = (await chrome.storage.session.get(key))[key]; + if (isConversationCheckpoint(checkpoint)) { + state.agentMessages = checkpoint.agentMessages; + state.events = checkpoint.events; + state.lastOutcome = checkpoint.lastOutcome; + try { toolLayer.recipeStore.restore(checkpoint.recipes); } catch { toolLayer.recipeStore.clear(); } + restored = true; + } + } + if (!restored) { + state.agentMessages = []; + state.events = [assistantEvent("你好,我是 AI 有数。告诉我你想从当前页面完成什么数据技能。", "complete")]; + state.lastOutcome = null; + } else { + state.events.push(statusEvent("restored", "已恢复当前标签页的对话进度")); + } + await chrome.storage.session.set({ [indexKey]: state.conversationId }); + await saveConversation(); + } catch { /* in-memory history remains available */ } + render(); +} + +let saveTimer: number | undefined; +function scheduleConversationSave(): void { + if (saveTimer !== undefined) window.clearTimeout(saveTimer); + saveTimer = window.setTimeout(() => { saveTimer = undefined; void saveConversation(); }, 250); } -function addMessage(role: ChatMessage["role"], text: string, dedupe: boolean): void { - if (dedupe && state.messages.at(-1)?.text === text) return; - state.messages.push({ id: createId(), role, text }); - renderChat(); +async function saveConversation(): Promise { + const tabId = state.snapshot.tabId; + if (tabId === null || state.loadedConversationTabId !== tabId) return; + const checkpoint: ConversationCheckpoint = { + version: 2, + conversationId: state.conversationId, + agentMessages: state.agentMessages, + events: state.events, + recipes: toolLayer.recipeStore.snapshot(), + lastOutcome: state.lastOutcome + }; + try { + await chrome.storage.session.set({ + [conversationIndexKey(tabId)]: state.conversationId, + [conversationStorageKey(tabId, state.conversationId)]: checkpoint + }); + } catch { /* best effort */ } +} + +async function startNewConversation(): Promise { + if (state.running || state.snapshot.tabId === null) return; + const tabId = state.snapshot.tabId; + const oldKey = conversationStorageKey(tabId, state.conversationId); + state.conversationId = createId(); + state.agentMessages = []; + state.events = [assistantEvent("已新建对话。告诉我这次要完成什么数据技能。", "complete")]; + state.lastOutcome = null; + toolLayer.recipeStore.clear(); + try { await chrome.storage.session.remove(oldKey); } catch { /* no-op */ } + await saveConversation(); + render(); +} + +function appendEvent(event: ConversationEvent): void { + state.events.push(event); + scheduleConversationSave(); + renderTimeline(); scrollToLatest(); } -function summarizeToolResult(result: unknown): string { - if (!result || typeof result !== "object") return "已完成"; +function finishAssistantEvent(event: Extract | null): void { + if (event) event.state = "complete"; +} + +function discardEmptyAssistantEvent(event: Extract | null): void { + if (!event || event.content.trim()) { + finishAssistantEvent(event); + return; + } + const index = state.events.findIndex((item) => item.id === event.id); + if (index >= 0) state.events.splice(index, 1); +} + +function userEvent(content: string): Extract { + return { id: createId(), at: Date.now(), type: "user_message", content }; +} + +function assistantEvent(content: string, eventState: "streaming" | "complete" | "error"): Extract { + return { id: createId(), at: Date.now(), type: "assistant_message", content, state: eventState }; +} + +function statusEvent(status: AgentStatus | "restored", label: string): Extract { + return { id: createId(), at: Date.now(), type: "status", status, label }; +} + +function outcomeEvent(outcome: AgentRunOutcome): Extract { + return { id: createId(), at: Date.now(), type: "outcome", outcome }; +} + +function failedOutcome(caught: unknown): AgentRunOutcome { + return { + status: "failed_tool", + message: caught instanceof Error ? caught.message : "Agent 运行失败。", + failedToolCalls: [], + completedSteps: [], + pendingSteps: ["retry_or_adjust_task"], + recipeIds: [] + }; +} + +function outcomeTitle(outcome: AgentRunOutcome): string { + if (outcome.status === "paused_budget") return "本轮达到执行上限,进度已保存"; + if (outcome.status === "blocked_user") return "任务已因用户决定或安全限制停止"; + if (outcome.status === "failed_tool") return "任务因工具连续失败停止"; + return outcome.failedToolCalls.length ? "任务完成,但存在工具错误" : "任务完成"; +} + +function statusLabel(status: AgentStatus): string { + const labels: Record = { + connecting: "正在连接模型", + streaming: "正在接收流式回复", + fallback: "Provider 不支持流式,已回退非流式", + thinking: "模型正在规划", + executing_tool: "正在执行工具", + checkpointing: "进度已保存", + summarizing: "正在生成故障总结", + completed: "本轮运行完成" + }; + return labels[status]; +} + +function getSuccessfulToolData(result: unknown): Record | undefined { + if (!result || typeof result !== "object") return undefined; const record = result as Record; - if (Array.isArray(record.sources)) return `返回 ${record.sources.length} 个数据来源`; - if (record.recipe) return "已生成或更新 recipe"; - if (record.package) return "已确认并导出 Data Skill Package"; - if (typeof record.message === "string") return record.message; - return "已完成"; + return record.ok === true && record.data && typeof record.data === "object" ? record.data as Record : undefined; +} + +function jsonPre(value: unknown): HTMLPreElement { + const pre = document.createElement("pre"); + try { pre.textContent = JSON.stringify(value, null, 2); } catch { pre.textContent = "[Unserializable]"; } + return pre; +} + +function getSelectedCapture(): CapturedRequest | undefined { + return state.snapshot.captures.find((capture) => capture.id === state.selectedId) ?? state.snapshot.captures[0]; } function isAgentToolName(name: string): name is AgentToolName { - return ["listCapturedSources", "readCapture", "inspectResponse", "buildRecipe", "runRecipe", "exportSkillPackage"].includes(name); + return AGENT_TOOL_DEFINITIONS.some((tool) => tool.function.name === name); } function isProviderConfig(value: unknown): value is OpenAICompatibleProviderConfig { if (!value || typeof value !== "object") return false; const record = value as Record; - return typeof record.baseUrl === "string" && !!record.baseUrl - && typeof record.apiKey === "string" && !!record.apiKey - && typeof record.model === "string" && !!record.model; + return typeof record.baseUrl === "string" && !!record.baseUrl && typeof record.apiKey === "string" && !!record.apiKey && typeof record.model === "string" && !!record.model; } +function isConversationCheckpoint(value: unknown): value is ConversationCheckpoint { + if (!value || typeof value !== "object") return false; + const record = value as Record; + return record.version === 2 && typeof record.conversationId === "string" && Array.isArray(record.agentMessages) + && Array.isArray(record.events) && !!record.recipes && typeof record.recipes === "object"; +} + +function withoutSystem(messages: AgentChatMessage[]): AgentChatMessage[] { + return messages.filter((message) => message.role !== "system"); +} + +function conversationIndexKey(tabId: number): string { return `${CONVERSATION_INDEX_PREFIX}:${tabId}`; } +function conversationStorageKey(tabId: number, conversationId: string): string { return `${CONVERSATION_PREFIX}:${tabId}:${conversationId}`; } + function resizeComposer(): void { elements.chatInput.style.height = "auto"; elements.chatInput.style.height = `${Math.min(elements.chatInput.scrollHeight, 120)}px`; @@ -405,17 +658,12 @@ function scrollToLatest(): void { } function readableUrl(urlValue: string): string { - try { - const url = new URL(urlValue); - return `${url.hostname}${url.pathname}`; - } catch { - return urlValue; - } + try { const url = new URL(urlValue); return `${url.hostname}${url.pathname}`; } catch { return urlValue; } } -function downloadTextFile(file: { fileName: string; mimeType: string; content: string }): void { - const blob = new Blob([file.content], { type: file.mimeType }); - const url = URL.createObjectURL(blob); +function downloadFile(file: { fileName: string; mimeType: string; content: string | Uint8Array }): void { + const content = file.content instanceof Uint8Array ? file.content.slice().buffer : file.content; + const url = URL.createObjectURL(new Blob([content], { type: file.mimeType })); const link = document.createElement("a"); link.href = url; link.download = file.fileName; @@ -423,9 +671,7 @@ function downloadTextFile(file: { fileName: string; mimeType: string; content: s URL.revokeObjectURL(url); } -function createId(): string { - return `${Date.now()}-${Math.random().toString(36).slice(2)}`; -} +function createId(): string { return `${Date.now()}-${Math.random().toString(36).slice(2)}`; } function getElement(id: string): T { const element = document.getElementById(id); diff --git a/docs/agent-tool-architecture.md b/docs/agent-tool-architecture.md index 57a76ac..361ec9c 100644 --- a/docs/agent-tool-architecture.md +++ b/docs/agent-tool-architecture.md @@ -23,11 +23,13 @@ User-authorized Chrome session The responsibility split is: 1. **Plugin provides tools.** It captures eligible traffic, stores it locally, provides bounded reads, applies deterministic inference rules, validates recipes, runs approved recipes, and exports packages. -2. **Agent makes judgments.** It chooses a source, decides whether a preview is enough, requests further pages/ranges only when needed, checks and edits `recipe.json`, and writes `SKILL.md` based on evidence and the user's goal. +2. **Agent makes judgments.** It chooses sources, decides whether a preview is enough, requests further pages/ranges only when needed, checks and edits stored recipes, designs `workflow.json`, and writes `SKILL.md` based on evidence and the user's goal. 3. **User authorizes and confirms.** Browser-session access, origin permissions, recipe runs, and export confirmation remain visible user decisions where required. -4. **Data Skill Package is the deliverable.** It contains an Agent-authored `SKILL.md`, reviewed `recipe.json`, examples, and README. +4. **Data Skill Package is the deliverable.** It is a real ZIP containing Agent-authored `SKILL.md`, `workflow.json`, reviewed `recipes/*.json`, examples, and README. -The side panel runs a real non-streaming Agent Loop. Users configure `baseUrl`, `apiKey`, and `model`; the Runtime sends the system prompt, messages, and function tools to `/v1/chat/completions`, executes returned `tool_calls`, appends `role: tool` results, and continues until the model returns final text. Tool results stay collapsed beneath the conversation. +The side panel runs a streaming Agent Loop. Users configure `baseUrl`, `apiKey`, and `model`; the Runtime sends the system prompt, messages, and function tools to `/v1/chat/completions` with `stream: true`, parses SSE text/tool deltas, executes aggregated `tool_calls`, appends `role: tool` results, and continues until the model returns final text. Providers that explicitly reject streaming fall back to a non-streaming request. The UI stores user messages, AI messages, tool calls, tool results, statuses, outcomes, and artifacts as ordered `ConversationEvent`s. Tool calls appear before execution, update in place, and keep their results collapsed as secondary detail. Model Markdown is rendered incrementally, then sanitized with DOMPurify. + +Every completed assistant message and tool result is checkpointed immediately. The side panel stores model history, UI history, and RecipeStore state in `chrome.storage.session` under `tabId + conversationId`. Failures carry partial history through `AgentRunError`; only “新建对话” clears it. ## Agent-facing tools @@ -38,18 +40,26 @@ The canonical TypeScript contracts live in `@data-recipe/agent-tools-core`. | `listCapturedSources` | Paginate lightweight capture metadata so the Agent can select candidates without reading all bodies. | | `readCapture` | Read request, response, or both with explicit `preview`, `page`, `range`, or `full` selection. | | `inspectResponse` | Apply structural rules and return selected response content; supports JSON-path focus and bounded depth. | -| `buildRecipe` | Create a rule-generated recipe draft and apply Agent-provided edits. | -| `runRecipe` | Dry-run or execute the reviewed recipe in the authorized browser session. | -| `exportSkillPackage` | Validate and export the reviewed recipe with Agent-authored Skill content. | +| `buildRecipe` | Create a rule-generated recipe and return a `recipeId`; later edits use `recipeId + patch`. | +| `runRecipe` | Dry-run or execute a reviewed stored recipe by `recipeId`. | +| `exportSkillPackage` | Export Agent-authored Skill content with all referenced `recipeIds` and a checked workflow as ZIP. | Bounded reads are a protocol guarantee. A tool must report truncation and continuation metadata and must not silently turn a preview, page, or range request into a full read. The Agent may explicitly request `full` when justified. ## Recipe and Skill lifecycle -`recipe.json` remains deterministic and machine-oriented. Detection rules can infer request parameters, response paths, fields, and pagination. The Agent reviews warnings and evidence, then may change the recipe before dry-run or export. Runtime validation remains authoritative even after Agent edits. +Each file under `recipes/` remains deterministic and machine-oriented. Detection rules can infer request parameters, response paths, fields, and pagination. The Agent reviews warnings and evidence, then may change recipes before dry-run or export. `workflow.json` defines ordered inputs, step-output dependencies, and final outputs across list, filter, detail, and optional diff steps. Runtime validation remains authoritative even after Agent edits, and a multi-interface Skill cannot export only one recipe. + +Complete recipes live only inside RecipeStore. Models receive `recipeId` plus a bounded summary and cannot submit a partial object as a complete recipe. All tool arguments are validated before execution; failures use the structured `{ code, message, retryable, expectedInput }` contract. `SKILL.md` is not generated through a fixed template call. The configured model writes it freely after reading enough evidence and understanding the user's goal. `buildDataSkillPackage` requires non-empty Agent-authored Markdown. Any Mock builder is restricted to tests and development support. +Production export uses `application/zip` with real paths. `.data-skill.json` is retained only as a development/import interchange format. + +## Outcomes and continuation + +Every run returns an `AgentRunOutcome`: `completed`, `paused_budget`, `failed_tool`, or `blocked_user`. It records failed tool calls, completed and pending steps, and recipe IDs. The outcome is persisted and injected into the next model turn, so narrative text cannot erase structured failures. A budget pause displays “本轮达到执行上限,进度已保存” and offers “继续任务”; repeated identical failures, user refusal, and safety limits are true stops. + ## Runtime and trust boundary `runRecipe` delegates execution to the Browser RPC Bridge. The Bridge is a constrained runtime tool operating inside a Chrome session the user has already authorized. It validates origin and confirmation requirements and returns data or bounded previews. It does not expose Cookie, Authorization headers, or comparable credentials to the Agent and must not become an arbitrary request proxy. @@ -58,6 +68,6 @@ The runtime does not bypass login, captchas, risk controls, dynamic signatures, ## Delivery phases -1. **Now:** real OpenAI-compatible Agent Runtime, local provider settings, capture/read/inspect/build/run/export handlers, and Agent-authored package export. +1. **Now:** real OpenAI-compatible streaming Agent Runtime, ordered conversation events, durable outcomes, local provider settings, capture/read/inspect/build/run/export handlers, and multi-recipe ZIP export. 2. **Next:** connect non-dry-run `runRecipe` to the real Browser RPC Bridge with origin checks, user confirmation, pagination limits, and response bounding. -3. **Then:** add streaming, richer confirmation UI, persistent conversation state, and external Agent transports without changing tool contracts. +3. **Then:** add richer confirmation UI and external Agent transports without changing tool contracts. diff --git a/package.json b/package.json index 2e7fda0..c96f7ec 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "typecheck": "pnpm -r typecheck", "dev:extension": "pnpm --filter @data-recipe/extension dev", "build:extension": "pnpm --filter @data-recipe/extension build", - "test:agent-runtime": "node scripts/test-agent-runtime.mjs", + "test:agent-runtime": "node --experimental-transform-types scripts/test-agent-runtime.mjs", "validate:skill-package": "node scripts/validate-data-skill-package.mjs" }, "devDependencies": { diff --git a/packages/agent-runtime/src/index.ts b/packages/agent-runtime/src/index.ts index 6e29f5b..2a127c7 100644 --- a/packages/agent-runtime/src/index.ts +++ b/packages/agent-runtime/src/index.ts @@ -2,6 +2,7 @@ export interface OpenAICompatibleProviderConfig { baseUrl: string; apiKey: string; model: string; + allowNonStreamingFallback?: boolean; } export interface AgentFunctionTool { @@ -16,10 +17,7 @@ export interface AgentFunctionTool { export interface AgentToolCall { id: string; type: "function"; - function: { - name: string; - arguments: string; - }; + function: { name: string; arguments: string }; } export type AgentChatMessage = @@ -27,69 +25,93 @@ export type AgentChatMessage = | { role: "assistant"; content: string | null; tool_calls?: AgentToolCall[] } | { role: "tool"; content: string; tool_call_id: string }; +export type AgentStatus = + | "connecting" + | "streaming" + | "fallback" + | "thinking" + | "executing_tool" + | "checkpointing" + | "summarizing" + | "completed"; + export interface AgentCompletionRequest { messages: AgentChatMessage[]; tools?: AgentFunctionTool[]; toolChoice?: "auto" | "none" | "required"; + stream?: boolean; +} + +export interface AgentCompletionCallbacks { + onTextDelta?: (delta: string, accumulated: string) => void | Promise; + onStatusChange?: (status: AgentStatus) => void | Promise; } export interface AgentCompletion { message: Extract; finishReason?: string; + streamed: boolean; } export interface AgentModelProvider { - complete(input: AgentCompletionRequest): Promise; + complete(input: AgentCompletionRequest, callbacks?: AgentCompletionCallbacks): Promise; } export class OpenAICompatibleProvider implements AgentModelProvider { - readonly config: OpenAICompatibleProviderConfig; + readonly config: Required; constructor(config: OpenAICompatibleProviderConfig) { const baseUrl = config.baseUrl.trim().replace(/\/+$/, ""); const model = config.model.trim(); const apiKey = config.apiKey.trim(); - if (!baseUrl || !model || !apiKey) { - throw new Error("baseUrl、apiKey 和 model 都必须配置。"); + if (!baseUrl || !model || !apiKey) throw new Error("baseUrl、apiKey 和 model 都必须配置。"); + this.config = { baseUrl, model, apiKey, allowNonStreamingFallback: config.allowNonStreamingFallback ?? true }; + } + + async complete(input: AgentCompletionRequest, callbacks: AgentCompletionCallbacks = {}): Promise { + const wantsStream = input.stream !== false; + await callbacks.onStatusChange?.("connecting"); + const response = await this.request(input, wantsStream); + + if (!response.ok) { + const body = await readResponseBody(response); + if (wantsStream && this.config.allowNonStreamingFallback && isStreamingUnsupported(response.status, body)) { + await callbacks.onStatusChange?.("fallback"); + return this.completeNonStreaming(input, callbacks); + } + throw createProviderError(response.status, body); } - this.config = { baseUrl, model, apiKey }; + + const contentType = response.headers.get("content-type")?.toLowerCase() ?? ""; + if (wantsStream && response.body && contentType.includes("text/event-stream")) { + await callbacks.onStatusChange?.("streaming"); + return parseChatCompletionStream(response.body, callbacks); + } + + return parseNonStreamingResponse(response, callbacks, false); } - async complete(input: AgentCompletionRequest): Promise { - const response = await fetch(buildChatCompletionsUrl(this.config.baseUrl), { + private async completeNonStreaming( + input: AgentCompletionRequest, + callbacks: AgentCompletionCallbacks + ): Promise { + const response = await this.request(input, false); + if (!response.ok) throw createProviderError(response.status, await readResponseBody(response)); + return parseNonStreamingResponse(response, callbacks, false); + } + + private request(input: AgentCompletionRequest, stream: boolean): Promise { + return fetch(buildChatCompletionsUrl(this.config.baseUrl), { method: "POST", - headers: { - "content-type": "application/json", - authorization: `Bearer ${this.config.apiKey}` - }, + headers: { "content-type": "application/json", authorization: `Bearer ${this.config.apiKey}` }, body: JSON.stringify({ model: this.config.model, messages: input.messages, tools: input.tools?.length ? input.tools : undefined, tool_choice: input.tools?.length ? (input.toolChoice ?? "auto") : undefined, - stream: false + stream }) }); - - const body = await readResponseBody(response); - if (!response.ok) { - throw new Error(`模型请求失败(HTTP ${response.status}):${extractErrorMessage(body)}`); - } - - const parsed = body as ChatCompletionsResponse; - const choice = parsed.choices?.[0]; - if (!choice?.message || choice.message.role !== "assistant") { - throw new Error("模型响应中缺少 assistant message。"); - } - - return { - message: { - role: "assistant", - content: typeof choice.message.content === "string" ? choice.message.content : null, - tool_calls: normalizeToolCalls(choice.message.tool_calls) - }, - finishReason: choice.finish_reason - }; } } @@ -97,28 +119,71 @@ export interface AgentToolExecutionEvent { toolCall: AgentToolCall; arguments: unknown; result: unknown; - error?: string; + failed: boolean; +} + +export interface AgentToolCallStartedEvent { + toolCall: AgentToolCall; + arguments: unknown; } -export interface AgentRunInput { +export interface AgentRunOutcome { + status: "completed" | "paused_budget" | "failed_tool" | "blocked_user"; + message: string; + failedToolCalls: Array<{ + name: string; + arguments: unknown; + error: { code: string; message: string; retryable: boolean; expectedInput?: unknown }; + }>; + completedSteps: string[]; + pendingSteps: string[]; + recipeIds: string[]; +} + +export interface AgentRunInput extends AgentCompletionCallbacks { systemPrompt: string; messages: AgentChatMessage[]; tools: AgentFunctionTool[]; executeTool(name: string, input: unknown): Promise; maxIterations?: number; + toolBudgets?: Partial>; + onToolCall?: (event: AgentToolCallStartedEvent) => void | Promise; onToolExecution?: (event: AgentToolExecutionEvent) => void | Promise; + onMessagesUpdated?: (messages: AgentChatMessage[], iterations: number) => void | Promise; } export interface AgentRunResult { finalText: string; messages: AgentChatMessage[]; iterations: number; + terminationReason: "completed" | "max_iterations" | "repeated_failure" | "blocked_user"; + outcome: AgentRunOutcome; } export interface AgentRuntime { run(input: AgentRunInput): Promise; } +export class AgentRunError extends Error { + readonly partialMessages: AgentChatMessage[]; + readonly iterations: number; + readonly outcome: AgentRunOutcome; + + constructor(message: string, partialMessages: AgentChatMessage[], iterations: number, outcome: AgentRunOutcome, options?: ErrorOptions) { + super(message, options); + this.name = "AgentRunError"; + this.partialMessages = cloneMessages(partialMessages); + this.iterations = iterations; + this.outcome = outcome; + } +} + +const DEFAULT_TOOL_BUDGETS: Record = { + buildRecipe: 6, + runRecipe: 3, + exportSkillPackage: 2 +}; + export class ToolCallingAgentRuntime implements AgentRuntime { constructor(private readonly provider: AgentModelProvider) {} @@ -128,42 +193,256 @@ export class ToolCallingAgentRuntime implements AgentRuntime { { role: "system", content: input.systemPrompt }, ...input.messages.filter((message) => message.role !== "system") ]; + const budgets = { ...DEFAULT_TOOL_BUDGETS, ...input.toolBudgets }; + const callCounts = new Map(); + let lastFailureSignature = ""; + let consecutiveFailureCount = 0; + let iterations = 0; + const failedToolCalls: AgentRunOutcome["failedToolCalls"] = []; + const completedSteps: string[] = []; + const recipeIds = new Set(); - for (let iteration = 1; iteration <= maxIterations; iteration += 1) { - const completion = await this.provider.complete({ messages, tools: input.tools, toolChoice: "auto" }); - const assistantMessage = completion.message; - messages.push(assistantMessage); - - const toolCalls = assistantMessage.tool_calls ?? []; - if (toolCalls.length === 0) { - const finalText = assistantMessage.content?.trim(); - if (!finalText) throw new Error("模型没有返回最终文本或工具调用。"); - return { finalText, messages, iterations: iteration }; - } + try { + for (iterations = 1; iterations <= maxIterations; iterations += 1) { + await input.onStatusChange?.("thinking"); + const completion = await this.provider.complete( + { messages, tools: input.tools, toolChoice: "auto", stream: true }, + { onTextDelta: input.onTextDelta, onStatusChange: input.onStatusChange } + ); + const assistantMessage = completion.message; + messages.push(assistantMessage); + await checkpoint(input, messages, iterations); - for (const toolCall of toolCalls) { - let args: unknown = {}; - let result: unknown; - let error: string | undefined; - try { - args = parseToolArguments(toolCall.function.arguments); - result = await input.executeTool(toolCall.function.name, args); - } catch (caught) { - error = caught instanceof Error ? caught.message : "工具执行失败。"; - result = { ok: false, error }; + const toolCalls = assistantMessage.tool_calls ?? []; + if (toolCalls.length === 0) { + let finalText = assistantMessage.content?.trim(); + if (!finalText) throw new Error("模型没有返回最终文本或工具调用。"); + const consistentText = enforceOutcomeConsistency(finalText, failedToolCalls); + if (consistentText !== finalText) { + const suffix = consistentText.slice(finalText.length); + assistantMessage.content = consistentText; + messages[messages.length - 1] = assistantMessage; + await input.onTextDelta?.(suffix, consistentText); + await checkpoint(input, messages, iterations); + } + finalText = consistentText; + await input.onStatusChange?.("completed"); + const outcome = createOutcome("completed", failedToolCalls, completedSteps, [], recipeIds); + return { finalText, messages, iterations, terminationReason: "completed", outcome }; } - await input.onToolExecution?.({ toolCall, arguments: args, result, error }); - messages.push({ - role: "tool", - tool_call_id: toolCall.id, - content: safeStringify(result) + const preparedToolCalls = toolCalls.map((toolCall) => { + try { + return { toolCall, arguments: parseToolArguments(toolCall.function.arguments), argumentError: undefined }; + } catch (caught) { + return { + toolCall, + arguments: { invalidArguments: true }, + argumentError: caught instanceof Error ? caught : new ToolArgumentsError("模型返回了无效的工具参数 JSON。") + }; + } }); + for (const prepared of preparedToolCalls) { + await input.onToolCall?.({ toolCall: prepared.toolCall, arguments: prepared.arguments }); + } + + for (let toolIndex = 0; toolIndex < preparedToolCalls.length; toolIndex += 1) { + const prepared = preparedToolCalls[toolIndex]!; + const toolCall = prepared.toolCall; + await input.onStatusChange?.("executing_tool"); + const args = prepared.arguments; + let result: unknown; + try { + if (prepared.argumentError) { + result = toolFailure("INVALID_TOOL_ARGUMENTS", prepared.argumentError.message, true, { type: "object", tool: toolCall.function.name }); + } else { + const count = (callCounts.get(toolCall.function.name) ?? 0) + 1; + callCounts.set(toolCall.function.name, count); + const budget = budgets[toolCall.function.name]; + result = budget !== undefined && count > budget + ? toolFailure("TOOL_BUDGET_EXCEEDED", `工具 ${toolCall.function.name} 已达到本轮调用预算 ${budget}。`, false, { budget }) + : await input.executeTool(toolCall.function.name, args); + } + } catch (caught) { + result = toolFailure( + "TOOL_EXECUTION_FAILED", + caught instanceof Error ? caught.message : "工具执行失败。", + false + ); + } + + const failed = isFailedToolResult(result); + collectRecipeIds(args, recipeIds); + collectRecipeIds(result, recipeIds); + const structuredError = getStructuredToolError(result); + if (structuredError) { + failedToolCalls.push({ name: toolCall.function.name, arguments: args, error: structuredError }); + } else { + completedSteps.push(`${toolCall.function.name}:${toolCall.id}`); + } + const signature = `${toolCall.function.name}:${stableArguments(toolCall.function.arguments)}`; + if (failed) { + consecutiveFailureCount = signature === lastFailureSignature ? consecutiveFailureCount + 1 : 1; + lastFailureSignature = signature; + } else { + consecutiveFailureCount = 0; + lastFailureSignature = ""; + } + + await input.onToolExecution?.({ toolCall, arguments: args, result, failed }); + messages.push({ role: "tool", tool_call_id: toolCall.id, content: safeStringify(result) }); + await checkpoint(input, messages, iterations); + + if (structuredError && isBlockingToolError(structuredError)) { + const pending = preparedToolCalls.slice(toolIndex + 1).map(({ toolCall: call }) => `${call.function.name}:${call.id}`); + return summarizeTermination(this.provider, input, messages, iterations, "blocked_user", failedToolCalls, completedSteps, pending, recipeIds); + } + + if (failed && consecutiveFailureCount >= 2) { + const pending = preparedToolCalls.slice(toolIndex + 1).map(({ toolCall: call }) => `${call.function.name}:${call.id}`); + return summarizeTermination(this.provider, input, messages, iterations, "repeated_failure", failedToolCalls, completedSteps, pending, recipeIds); + } + } } + + return summarizeTermination(this.provider, input, messages, maxIterations, "max_iterations", failedToolCalls, completedSteps, ["continue_agent_loop"], recipeIds); + } catch (caught) { + if (caught instanceof AgentRunError) throw caught; + throw new AgentRunError( + caught instanceof Error ? caught.message : "Agent 运行失败。", + messages, + Math.min(iterations, maxIterations), + createOutcome("failed_tool", failedToolCalls, completedSteps, ["retry_or_adjust_task"], recipeIds, caught instanceof Error ? caught.message : "Agent 运行失败。"), + caught instanceof Error ? { cause: caught } : undefined + ); } + } +} - throw new Error(`Agent 超过最大工具循环次数(${maxIterations})。`); +async function summarizeTermination( + provider: AgentModelProvider, + input: AgentRunInput, + messages: AgentChatMessage[], + iterations: number, + reason: "max_iterations" | "repeated_failure" | "blocked_user", + failedToolCalls: AgentRunOutcome["failedToolCalls"], + completedSteps: string[], + pendingSteps: string[], + recipeIds: Set +): Promise { + await input.onStatusChange?.("summarizing"); + const instruction = reason === "max_iterations" + ? "工具循环已达到最大轮数。请不要再调用工具;总结已完成的工作、当前故障、保留的上下文和用户下一步可采取的操作。" + : reason === "blocked_user" + ? "用户拒绝了操作或安全策略阻止继续。请不要再调用工具;说明已完成进度、阻止原因和用户可以选择的下一步。" + : "相同工具调用已连续失败两次。请不要再调用工具;总结失败原因、已保留的上下文和可行的下一步建议。"; + const completion = await provider.complete( + { + messages: [...messages, { role: "user", content: instruction }], + tools: input.tools, + toolChoice: "none", + stream: true + }, + { onTextDelta: input.onTextDelta, onStatusChange: input.onStatusChange } + ); + const summary = completion.message.content?.trim(); + if (!summary) throw new Error("模型未能生成故障总结。"); + const consistentSummary = enforceOutcomeConsistency(summary, failedToolCalls); + if (consistentSummary !== summary) { + await input.onTextDelta?.(consistentSummary.slice(summary.length), consistentSummary); } + messages.push({ role: "assistant", content: consistentSummary }); + await checkpoint(input, messages, iterations); + await input.onStatusChange?.("completed"); + const status = reason === "max_iterations" ? "paused_budget" : reason === "blocked_user" ? "blocked_user" : "failed_tool"; + const outcome = createOutcome(status, failedToolCalls, completedSteps, pendingSteps, recipeIds); + return { finalText: consistentSummary, messages, iterations, terminationReason: reason, outcome }; +} + +async function checkpoint(input: AgentRunInput, messages: AgentChatMessage[], iterations: number): Promise { + await input.onStatusChange?.("checkpointing"); + await input.onMessagesUpdated?.(cloneMessages(messages), iterations); +} + +function toolFailure(code: string, message: string, retryable: boolean, expectedInput?: unknown): unknown { + return { ok: false, error: { code, message, retryable, expectedInput } }; +} + +function isFailedToolResult(value: unknown): boolean { + return !!value && typeof value === "object" && (value as Record).ok === false; +} + +function getStructuredToolError(value: unknown): AgentRunOutcome["failedToolCalls"][number]["error"] | undefined { + if (!value || typeof value !== "object") return undefined; + const record = value as Record; + if (record.ok !== false || !record.error || typeof record.error !== "object") return undefined; + const error = record.error as Record; + return { + code: typeof error.code === "string" ? error.code : "TOOL_FAILED", + message: typeof error.message === "string" ? error.message : "工具执行失败。", + retryable: error.retryable === true, + expectedInput: error.expectedInput + }; +} + +function isBlockingToolError(error: AgentRunOutcome["failedToolCalls"][number]["error"]): boolean { + return error.code === "USER_DENIED" || error.code === "PERMISSION_DENIED" + || error.code === "RECIPE_SOURCE_NOT_CAPTURED" || error.code.startsWith("SAFETY_"); +} + +function collectRecipeIds(value: unknown, target: Set, depth = 0): void { + if (depth > 5 || !value || typeof value !== "object") return; + if (Array.isArray(value)) { + value.slice(0, 50).forEach((item) => collectRecipeIds(item, target, depth + 1)); + return; + } + Object.entries(value as Record).forEach(([key, child]) => { + if (key === "recipeId" && typeof child === "string" && child) target.add(child); + if (key === "recipeIds" && Array.isArray(child)) child.forEach((id) => { if (typeof id === "string" && id) target.add(id); }); + collectRecipeIds(child, target, depth + 1); + }); +} + +function createOutcome( + status: AgentRunOutcome["status"], + failedToolCalls: AgentRunOutcome["failedToolCalls"], + completedSteps: string[], + pendingSteps: string[], + recipeIds: Set, + message?: string +): AgentRunOutcome { + const defaultMessages: Record = { + completed: failedToolCalls.length ? "任务已完成,但本轮存在已记录的工具错误。" : "任务已完成。", + paused_budget: "本轮达到执行上限,进度已保存。", + failed_tool: "工具连续失败,任务已停止并保留进度。", + blocked_user: "用户拒绝或安全限制阻止继续,进度已保存。" + }; + return { + status, + message: message ?? defaultMessages[status], + failedToolCalls: JSON.parse(JSON.stringify(failedToolCalls)) as AgentRunOutcome["failedToolCalls"], + completedSteps: [...completedSteps], + pendingSteps: [...pendingSteps], + recipeIds: [...recipeIds] + }; +} + +function enforceOutcomeConsistency(text: string, failedToolCalls: AgentRunOutcome["failedToolCalls"]): string { + if (!failedToolCalls.length) return text; + const codes = [...new Set(failedToolCalls.map((call) => call.error.code))].join("、"); + return `${text}\n\n> 运行状态:本轮记录到 ${failedToolCalls.length} 个工具错误(${codes}),请以上述结构化状态为准。`; +} + +function stableArguments(value: string): string { + try { + return JSON.stringify(JSON.parse(value)); + } catch { + return value.trim(); + } +} + +function cloneMessages(messages: AgentChatMessage[]): AgentChatMessage[] { + return JSON.parse(JSON.stringify(messages)) as AgentChatMessage[]; } function buildChatCompletionsUrl(baseUrl: string): string { @@ -174,12 +453,105 @@ function buildChatCompletionsUrl(baseUrl: string): string { function parseToolArguments(value: string): unknown { if (!value.trim()) return {}; try { - return JSON.parse(value); - } catch { - throw new Error("模型返回了无效的工具参数 JSON。"); + const parsed: unknown = JSON.parse(value); + if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { + throw new ToolArgumentsError("工具参数必须是 JSON object。"); + } + return parsed; + } catch (caught) { + throw new ToolArgumentsError(caught instanceof Error && caught.message === "工具参数必须是 JSON object。" + ? caught.message + : "模型返回了无效的工具参数 JSON。"); + } +} + +class ToolArgumentsError extends Error { + constructor(message: string) { + super(message); + this.name = "ToolArgumentsError"; } } +async function parseChatCompletionStream( + stream: ReadableStream, + callbacks: AgentCompletionCallbacks +): Promise { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + let text = ""; + let finishReason: string | undefined; + const toolCalls = new Map(); + + const processFrame = async (frame: string): Promise => { + const data = frame.split(/\r?\n/) + .filter((line) => line.startsWith("data:")) + .map((line) => line.slice(5).trimStart()) + .join("\n"); + if (!data) return false; + if (data.trim() === "[DONE]") return true; + const chunk = JSON.parse(data) as ChatCompletionChunk; + const choice = chunk.choices?.[0]; + if (!choice) return false; + if (typeof choice.delta?.content === "string") { + text += choice.delta.content; + await callbacks.onTextDelta?.(choice.delta.content, text); + } + choice.delta?.tool_calls?.forEach((delta) => { + if (!Number.isInteger(delta.index)) return; + const current = toolCalls.get(delta.index) ?? { id: "", name: "", arguments: "" }; + if (typeof delta.id === "string") current.id += delta.id; + if (typeof delta.function?.name === "string") current.name += delta.function.name; + if (typeof delta.function?.arguments === "string") current.arguments += delta.function.arguments; + toolCalls.set(delta.index, current); + }); + if (typeof choice.finish_reason === "string") finishReason = choice.finish_reason; + return false; + }; + + let done = false; + while (!done) { + const read = await reader.read(); + buffer += decoder.decode(read.value, { stream: !read.done }); + const frames = buffer.split(/\r?\n\r?\n/); + buffer = frames.pop() ?? ""; + for (const frame of frames) { + if (await processFrame(frame)) { done = true; break; } + } + if (read.done) { + if (buffer.trim()) await processFrame(buffer); + break; + } + } + + const aggregatedCalls = [...toolCalls.entries()] + .sort(([a], [b]) => a - b) + .map(([, call]) => ({ id: call.id, type: "function" as const, function: { name: call.name, arguments: call.arguments } })) + .filter((call) => call.id && call.function.name); + return { + message: { role: "assistant", content: text || null, tool_calls: aggregatedCalls.length ? aggregatedCalls : undefined }, + finishReason, + streamed: true + }; +} + +async function parseNonStreamingResponse( + response: Response, + callbacks: AgentCompletionCallbacks, + streamed: boolean +): Promise { + const body = await readResponseBody(response) as ChatCompletionsResponse; + const choice = body.choices?.[0]; + if (!choice?.message || choice.message.role !== "assistant") throw new Error("模型响应中缺少 assistant message。"); + const content = typeof choice.message.content === "string" ? choice.message.content : null; + if (content) await callbacks.onTextDelta?.(content, content); + return { + message: { role: "assistant", content, tool_calls: normalizeToolCalls(choice.message.tool_calls) }, + finishReason: choice.finish_reason, + streamed + }; +} + function normalizeToolCalls(value: unknown): AgentToolCall[] | undefined { if (!Array.isArray(value)) return undefined; const calls = value.filter(isAgentToolCall); @@ -189,49 +561,49 @@ function normalizeToolCalls(value: unknown): AgentToolCall[] | undefined { function isAgentToolCall(value: unknown): value is AgentToolCall { if (!value || typeof value !== "object") return false; const call = value as Partial; - return call.type === "function" - && typeof call.id === "string" - && !!call.function - && typeof call.function.name === "string" - && typeof call.function.arguments === "string"; + return call.type === "function" && typeof call.id === "string" && !!call.function + && typeof call.function.name === "string" && typeof call.function.arguments === "string"; +} + +function isStreamingUnsupported(status: number, body: unknown): boolean { + if (![400, 404, 405, 415, 422, 501].includes(status)) return false; + return /stream|streaming|unsupported|not supported/i.test(extractErrorMessage(body)); +} + +function createProviderError(status: number, body: unknown): Error { + return new Error(`模型请求失败(HTTP ${status}):${extractErrorMessage(body)}`); } async function readResponseBody(response: Response): Promise { const text = await response.text(); if (!text) return {}; - try { - return JSON.parse(text); - } catch { - return { message: text.slice(0, 1000) }; - } + try { return JSON.parse(text); } catch { return { message: text.slice(0, 1000) }; } } function extractErrorMessage(body: unknown): string { if (!body || typeof body !== "object") return "未知错误"; const record = body as Record; const error = record.error; - if (error && typeof error === "object") { - const message = (error as Record).message; - if (typeof message === "string") return message; + if (error && typeof error === "object" && typeof (error as Record).message === "string") { + return String((error as Record).message); } return typeof record.message === "string" ? record.message : "未知错误"; } function safeStringify(value: unknown): string { - try { - return JSON.stringify(value); - } catch { - return JSON.stringify({ ok: false, error: "工具结果无法序列化。" }); - } + try { return JSON.stringify(value) ?? "null"; } catch { return JSON.stringify(toolFailure("UNSERIALIZABLE_RESULT", "工具结果无法序列化。", false)); } } interface ChatCompletionsResponse { + choices?: Array<{ finish_reason?: string; message?: { role?: string; content?: unknown; tool_calls?: unknown } }>; +} + +interface ChatCompletionChunk { choices?: Array<{ - finish_reason?: string; - message?: { - role?: string; - content?: unknown; - tool_calls?: unknown; + finish_reason?: string | null; + delta?: { + content?: string | null; + tool_calls?: Array<{ index: number; id?: string; function?: { name?: string; arguments?: string } }>; }; }>; } diff --git a/packages/agent-tools-core/src/index.ts b/packages/agent-tools-core/src/index.ts index 9f2ebe8..ac4ac23 100644 --- a/packages/agent-tools-core/src/index.ts +++ b/packages/agent-tools-core/src/index.ts @@ -1,9 +1,16 @@ import type { BrowserRunRecipeResult } from "@data-recipe/browser-rpc-core"; -import type { DataRecipe, HttpMethod, JsonObject } from "@data-recipe/recipe-core"; -import type { DataSkillPackage } from "@data-recipe/skill-builder"; +import type { + DataRecipe, + DataRecipeField, + DataRecipePagination, + DataRecipeParameter, + DataRecipeRequest, + DataRecipeResponse, + HttpMethod, + JsonObject +} from "@data-recipe/recipe-core"; +import type { DataSkillPackage, DataSkillWorkflow } from "@data-recipe/skill-builder"; -/** Reading is controlled by the Agent. Tools must never silently upgrade a - * bounded request to a full capture read. */ export type AgentReadSelection = | { mode: "preview"; maxChars?: number; maxItems?: number } | { mode: "page"; cursor?: string; pageSize?: number } @@ -32,39 +39,39 @@ export interface ReadResult { totalChars?: number; } +export interface DataRecipePatch { + name?: string; + displayName?: string; + description?: string; + useCases?: string[]; + request?: Partial; + response?: Partial; + pagination?: Partial; + fields?: DataRecipeField[]; +} + +export interface DataRecipeSummary { + recipeId: string; + name: string; + displayName: string; + description: string; + source: { pageUrl: string; apiUrl: string; method: HttpMethod }; + parameters: Array>; + response: DataRecipeResponse; + pagination: DataRecipePagination; + fields: Array>; +} + export interface AgentToolInputMap { - listCapturedSources: { - cursor?: string; - pageSize?: number; - pageUrl?: string; - }; - readCapture: { - captureId: string; - section: "request" | "response" | "both"; - selection: AgentReadSelection; - }; - inspectResponse: { - captureId: string; - selection: AgentReadSelection; - jsonPath?: string; - maxDepth?: number; - }; - buildRecipe: { - captureId: string; - /** Rule-generated draft that the Agent may inspect and patch. */ - recipe?: DataRecipe; - patch?: Partial; - }; - runRecipe: { - recipe: DataRecipe; - variables?: JsonObject; - dryRun?: boolean; - previewLimit?: number; - requireUserConfirmation?: boolean; - }; + listCapturedSources: { cursor?: string; pageSize?: number; pageUrl?: string }; + readCapture: { captureId: string; section: "request" | "response" | "both"; selection: AgentReadSelection }; + inspectResponse: { captureId: string; selection: AgentReadSelection; jsonPath?: string; maxDepth?: number }; + buildRecipe: { captureId?: string; recipeId?: string; patch?: DataRecipePatch }; + runRecipe: { recipeId: string; variables?: JsonObject; dryRun?: boolean; previewLimit?: number }; exportSkillPackage: { - recipe: DataRecipe; - /** Authored freely by the Agent from tool results and the user's goal. */ + recipeIds: string[]; + workflow: DataSkillWorkflow; + packageName?: string; skillMarkdown: string; userGoal: string; examplesMarkdown?: string; @@ -80,25 +87,24 @@ export interface ResponseInspection { content: ReadResult; } -export interface AgentToolOutputMap { - listCapturedSources: { - sources: CapturedSourceSummary[]; - nextCursor?: string; - }; +export interface AgentToolDataMap { + listCapturedSources: { sources: CapturedSourceSummary[]; nextCursor?: string }; readCapture: ReadResult; inspectResponse: ResponseInspection; - buildRecipe: { - recipe: DataRecipe; - warnings: string[]; - inferredByRules: boolean; - }; + buildRecipe: { recipeId: string; summary: DataRecipeSummary; warnings: string[]; inferredByRules: boolean }; runRecipe: BrowserRunRecipeResult; - exportSkillPackage: { - package: DataSkillPackage; - warnings: string[]; - }; + exportSkillPackage: { package: DataSkillPackage; warnings: string[] }; +} + +export interface AgentToolError { + code: string; + message: string; + retryable: boolean; + expectedInput: unknown; } +export type AgentToolResult = { ok: true; data: T } | { ok: false; error: AgentToolError }; +export type AgentToolOutputMap = { [TName in keyof AgentToolDataMap]: AgentToolResult }; export type AgentToolName = keyof AgentToolInputMap; export interface AgentToolLayer { @@ -107,3 +113,125 @@ export interface AgentToolLayer { input: AgentToolInputMap[TName] ): Promise; } + +export class RecipeStoreError extends Error { + readonly code: string; + constructor(code: string, message: string) { + super(message); + this.name = "RecipeStoreError"; + this.code = code; + } +} + +export class RecipeStore { + private readonly recipes = new Map(); + + create(recipe: DataRecipe): string { + assertDataRecipe(recipe); + const recipeId = createRecipeId(); + this.recipes.set(recipeId, cloneRecipe(recipe)); + return recipeId; + } + + get(recipeId: string): DataRecipe { + if (!recipeId || typeof recipeId !== "string") throw new RecipeStoreError("INVALID_RECIPE_ID", "recipeId 必须是非空字符串。"); + const recipe = this.recipes.get(recipeId); + if (!recipe) throw new RecipeStoreError("RECIPE_NOT_FOUND", `找不到 recipeId:${recipeId}`); + return cloneRecipe(recipe); + } + + update(recipeId: string, patch: DataRecipePatch): DataRecipe { + if (!patch || typeof patch !== "object" || Array.isArray(patch)) { + throw new RecipeStoreError("INVALID_RECIPE_PATCH", "patch 必须是 object。"); + } + const current = this.get(recipeId); + const next: DataRecipe = { + ...current, + name: patch.name ?? current.name, + displayName: patch.displayName ?? current.displayName, + description: patch.description ?? current.description, + useCases: patch.useCases ?? current.useCases, + fields: patch.fields ?? current.fields, + request: patch.request ? { ...current.request, ...patch.request } : current.request, + response: patch.response ? { ...current.response, ...patch.response } : current.response, + pagination: patch.pagination ? { ...current.pagination, ...patch.pagination } : current.pagination + }; + assertDataRecipe(next); + this.recipes.set(recipeId, cloneRecipe(next)); + return cloneRecipe(next); + } + + clear(): void { + this.recipes.clear(); + } + + snapshot(): Record { + return Object.fromEntries([...this.recipes.entries()].map(([id, recipe]) => [id, cloneRecipe(recipe)])); + } + + restore(snapshot: unknown): void { + if (!isObject(snapshot)) throw new RecipeStoreError("INVALID_RECIPE_SNAPSHOT", "recipe snapshot 必须是 object。"); + const restored = new Map(); + Object.entries(snapshot).forEach(([id, recipe]) => { + if (!id) throw new RecipeStoreError("INVALID_RECIPE_SNAPSHOT", "recipe snapshot 包含空 id。"); + assertDataRecipe(recipe); + restored.set(id, cloneRecipe(recipe)); + }); + this.recipes.clear(); + restored.forEach((recipe, id) => this.recipes.set(id, recipe)); + } +} + +export function summarizeRecipe(recipeId: string, recipe: DataRecipe): DataRecipeSummary { + assertDataRecipe(recipe); + return { + recipeId, + name: recipe.name, + displayName: recipe.displayName, + description: recipe.description, + source: { ...recipe.source }, + parameters: [...recipe.request.queryFields, ...recipe.request.bodyFields].map(({ name, displayName, path, type, required }) => ({ + name, displayName, path, type, required + })), + response: { ...recipe.response }, + pagination: { ...recipe.pagination }, + fields: recipe.fields.map(({ name, displayName, path, type, description }) => ({ name, displayName, path, type, description })) + }; +} + +export function assertDataRecipe(value: unknown): asserts value is DataRecipe { + if (!isObject(value)) throw new RecipeStoreError("INVALID_RECIPE", "recipe 必须是完整 object。"); + const recipe = value as Partial; + if (!nonEmpty(recipe.name) || !nonEmpty(recipe.displayName) || typeof recipe.description !== "string") { + throw new RecipeStoreError("INVALID_RECIPE", "recipe 缺少 name、displayName 或 description。"); + } + if (!Array.isArray(recipe.useCases) || !isObject(recipe.source) || !isObject(recipe.runtime) + || !isObject(recipe.request) || !isObject(recipe.response) || !isObject(recipe.pagination) || !Array.isArray(recipe.fields)) { + throw new RecipeStoreError("INVALID_RECIPE", "recipe 缺少完整的 source/runtime/request/response/pagination/fields。"); + } + if (!nonEmpty(recipe.source.apiUrl) || !nonEmpty(recipe.source.pageUrl) || !nonEmpty(recipe.source.method)) { + throw new RecipeStoreError("INVALID_RECIPE", "recipe.source 不完整。"); + } + if (!Array.isArray(recipe.request.queryFields) || !Array.isArray(recipe.request.bodyFields) || !isObject(recipe.request.query)) { + throw new RecipeStoreError("INVALID_RECIPE", "recipe.request 不完整。"); + } + if (!nonEmpty(recipe.response.type) || typeof recipe.response.listPath !== "string" || typeof recipe.response.totalPath !== "string") { + throw new RecipeStoreError("INVALID_RECIPE", "recipe.response 不完整。"); + } +} + +function cloneRecipe(recipe: DataRecipe): DataRecipe { + return JSON.parse(JSON.stringify(recipe)) as DataRecipe; +} + +function createRecipeId(): string { + return globalThis.crypto?.randomUUID?.() ?? `recipe-${Date.now()}-${Math.random().toString(36).slice(2)}`; +} + +function isObject(value: unknown): value is Record { + return !!value && typeof value === "object" && !Array.isArray(value); +} + +function nonEmpty(value: unknown): value is string { + return typeof value === "string" && value.trim().length > 0; +} diff --git a/packages/skill-builder/src/index.ts b/packages/skill-builder/src/index.ts index 20f3c29..c401a6d 100644 --- a/packages/skill-builder/src/index.ts +++ b/packages/skill-builder/src/index.ts @@ -6,12 +6,51 @@ export interface DataSkillPackage { } export interface DataSkillPackageFile { - path: "SKILL.md" | "recipe.json" | "examples.md" | "README.md"; + path: string; content: string; } -export interface BuildDataSkillPackageInput { +export type WorkflowOperation = "list" | "filter" | "detail" | "diff"; + +export type WorkflowValueRef = + | { type: "user_input"; name: string; path?: string } + | { type: "step_output"; stepId: string; path: string } + | { type: "literal"; value: unknown }; + +export interface DataSkillWorkflowStep { + id: string; + operation: WorkflowOperation; + recipeId?: string; + optional?: boolean; + dependsOn?: string[]; + inputs: Record; + outputs: Record; +} + +export interface DataSkillWorkflow { + version: 1; + description: string; + userInputs: Array<{ + name: string; + type: "string" | "number" | "boolean" | "object"; + required: boolean; + description: string; + examples?: unknown[]; + parsing?: string; + }>; + steps: DataSkillWorkflowStep[]; + finalOutputs: Record; +} + +export interface DataSkillRecipeInput { + recipeId: string; recipe: DataRecipe; +} + +export interface BuildDataSkillPackageInput { + packageName?: string; + recipes: DataSkillRecipeInput[]; + workflow: DataSkillWorkflow; userGoal?: string; /** * SKILL.md authored by the controlling AI Agent after it has inspected the @@ -34,29 +73,36 @@ export class MockSkillMarkdownFallback implements SkillMarkdownFallback { } export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSkillPackage { - const packageName = input.recipe.name || "data-skill"; - const goal = input.userGoal?.trim() || input.recipe.description; + if (!input.recipes.length) throw new Error("At least one recipe is required."); + assertWorkflow(input.workflow, input.recipes); + const packageName = input.packageName?.trim() || input.recipes[0]?.recipe.name || "data-skill"; + const goal = input.userGoal?.trim() || input.workflow.description; if (!input.skillMarkdown.trim()) { throw new Error("skillMarkdown must be authored by the Agent before export."); } const skillMarkdown = ensureTrailingNewline(input.skillMarkdown); + const recipeFiles = input.recipes.map(({ recipeId, recipe }) => ({ + path: `recipes/${normalizeRecipeId(recipeId)}.json`, + content: `${JSON.stringify(recipe, null, 2)}\n` + })); return { packageName, files: [ { path: "SKILL.md", content: skillMarkdown }, - { path: "recipe.json", content: `${JSON.stringify(input.recipe, null, 2)}\n` }, + { path: "workflow.json", content: `${JSON.stringify(input.workflow, null, 2)}\n` }, + ...recipeFiles, { path: "examples.md", content: input.examplesMarkdown?.trim() ? ensureTrailingNewline(input.examplesMarkdown) - : buildExamplesMarkdown(input.recipe, goal) + : buildExamplesMarkdown(input.recipes[0]!.recipe, goal) }, { path: "README.md", content: input.readmeMarkdown?.trim() ? ensureTrailingNewline(input.readmeMarkdown) - : buildReadmeMarkdown(input.recipe, goal) + : buildReadmeMarkdown(input.recipes, input.workflow, goal) } ] }; @@ -66,13 +112,112 @@ export function buildDataSkillPackage(input: BuildDataSkillPackageInput): DataSk export function buildMockDataSkillPackageForDevelopment( input: Omit ): DataSkillPackage { - const goal = input.userGoal?.trim() || input.recipe.description; + const firstRecipe = input.recipes[0]?.recipe; + if (!firstRecipe) throw new Error("At least one recipe is required."); + const goal = input.userGoal?.trim() || input.workflow.description; return buildDataSkillPackage({ ...input, - skillMarkdown: new MockSkillMarkdownFallback().buildFallbackSkillMarkdown(input.recipe, goal) + skillMarkdown: new MockSkillMarkdownFallback().buildFallbackSkillMarkdown(firstRecipe, goal) }); } +function assertWorkflow(workflow: DataSkillWorkflow, recipes: DataSkillRecipeInput[]): void { + if (!isRecord(workflow) || workflow.version !== 1 || typeof workflow.description !== "string" + || !Array.isArray(workflow.userInputs) || !Array.isArray(workflow.steps) || workflow.steps.length === 0 + || !isRecord(workflow.finalOutputs)) { + throw new Error("workflow.json requires version, description, userInputs, steps, and finalOutputs."); + } + workflow.userInputs.forEach((input, index) => { + if (!isRecord(input) || typeof input.name !== "string" || !input.name + || !["string", "number", "boolean", "object"].includes(String(input.type)) + || typeof input.required !== "boolean" || typeof input.description !== "string") { + throw new Error(`Workflow user input ${index} is invalid.`); + } + }); + recipes.forEach((item, index) => { + if (!item || typeof item.recipeId !== "string" || !item.recipeId.trim() || !item.recipe) { + throw new Error(`Recipe entry ${index} is invalid.`); + } + }); + const recipeIds = new Set(recipes.map((item) => item.recipeId)); + const normalizedRecipeIds = new Set(recipes.map((item) => normalizeRecipeId(item.recipeId))); + if (recipeIds.size !== recipes.length || normalizedRecipeIds.size !== recipes.length) { + throw new Error("Recipe IDs must be unique after file-name normalization."); + } + const userInputNames = new Set(workflow.userInputs.map((input) => input.name)); + if (userInputNames.size !== workflow.userInputs.length) throw new Error("Workflow user input names must be unique."); + const stepIds = new Set(); + workflow.steps.forEach((step, index) => { + if (!isRecord(step) || typeof step.id !== "string" || !step.id + || !["list", "filter", "detail", "diff"].includes(String(step.operation)) + || !isRecord(step.inputs) || !isRecord(step.outputs) + || (step.dependsOn !== undefined && (!Array.isArray(step.dependsOn) || !step.dependsOn.every((id) => typeof id === "string")))) { + throw new Error(`Workflow step ${index} is invalid.`); + } + Object.entries(step.inputs).forEach(([name, value]) => assertWorkflowValueRef(value, `Workflow step ${step.id} input ${name}`)); + Object.entries(step.outputs).forEach(([name, value]) => { + if (!isRecord(value) || typeof value.path !== "string") throw new Error(`Workflow step ${step.id} output ${name} is invalid.`); + }); + if (stepIds.has(step.id)) throw new Error(`Workflow step IDs must be unique: ${step.id}`); + stepIds.add(step.id); + if ((step.operation === "list" || step.operation === "detail") && !step.recipeId) { + throw new Error(`Workflow step ${step.id} requires recipeId.`); + } + if (step.recipeId && !recipeIds.has(step.recipeId)) { + throw new Error(`Workflow step ${step.id} references missing recipe ${step.recipeId}.`); + } + }); + Object.entries(workflow.finalOutputs).forEach(([name, value]) => assertWorkflowValueRef(value, `Workflow final output ${name}`)); + const priorStepIds = new Set(); + workflow.steps.forEach((step) => { + step.dependsOn?.forEach((dependency) => { + if (!priorStepIds.has(dependency)) throw new Error(`Workflow step ${step.id} depends on missing or later step ${dependency}.`); + }); + Object.values(step.inputs).forEach((input) => { + if (input.type === "user_input" && !userInputNames.has(input.name)) { + throw new Error(`Workflow step ${step.id} reads missing user input ${input.name}.`); + } + if (input.type === "step_output" && !priorStepIds.has(input.stepId)) { + throw new Error(`Workflow step ${step.id} reads missing or later step ${input.stepId}.`); + } + if (input.type === "step_output" && !step.dependsOn?.includes(input.stepId)) { + throw new Error(`Workflow step ${step.id} must declare dependency ${input.stepId}.`); + } + }); + priorStepIds.add(step.id); + }); + Object.values(workflow.finalOutputs).forEach((output) => { + if (output.type === "user_input" && !userInputNames.has(output.name)) { + throw new Error(`Workflow final output reads missing user input ${output.name}.`); + } + if (output.type === "step_output" && !stepIds.has(output.stepId)) { + throw new Error(`Workflow final output reads missing step ${output.stepId}.`); + } + }); + const referenced = new Set(workflow.steps.flatMap((step) => step.recipeId ? [step.recipeId] : [])); + recipes.forEach(({ recipeId }) => { + if (!referenced.has(recipeId)) throw new Error(`Recipe ${recipeId} is not referenced by workflow.json.`); + }); +} + +function assertWorkflowValueRef(value: unknown, context: string): asserts value is WorkflowValueRef { + if (!isRecord(value) || typeof value.type !== "string") throw new Error(`${context} is invalid.`); + if (value.type === "user_input" && typeof value.name === "string" && (!value.path || typeof value.path === "string")) return; + if (value.type === "step_output" && typeof value.stepId === "string" && typeof value.path === "string") return; + if (value.type === "literal" && Object.prototype.hasOwnProperty.call(value, "value")) return; + throw new Error(`${context} is invalid.`); +} + +function isRecord(value: unknown): value is Record { + return !!value && typeof value === "object" && !Array.isArray(value); +} + +function normalizeRecipeId(value: string): string { + const normalized = value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""); + if (!normalized) throw new Error("recipeId must contain a safe file name."); + return normalized; +} + function ensureTrailingNewline(value: string): string { return value.endsWith("\n") ? value : `${value}\n`; } @@ -116,10 +261,10 @@ ${execution} - Only use this skill for data the user is authorized to access. - Do not use it to bypass login, captchas, risk controls, dynamic signatures, or anti-bot measures. -- Do not call the underlying data source URL recorded in recipe.json directly. +- Do not call the underlying data source URL recorded under recipes/ directly. - Do not ask the user for cookies, Authorization headers, or other credentials. - Dry-run the recipe through the Browser RPC Bridge first to confirm the data preview is healthy before drawing conclusions. -- ${recipe.runtime.permissionNote || "Follow the runtime configuration recorded in recipe.json."} +- ${recipe.runtime.permissionNote || "Follow the runtime configuration recorded under recipes/."} ## Examples @@ -137,7 +282,7 @@ function buildInputsMarkdown(recipe: DataRecipe): string { const queryFields = [...recipe.request.queryFields, ...recipe.request.bodyFields]; if (queryFields.length === 0) { - return "- This data source has no confirmed query conditions yet.\n- Inspect the recipe.json `request.queryFields` and `request.bodyFields` before asking the user for parameters."; + return "- This data source has no confirmed query conditions yet.\n- Inspect the selected file under `recipes/` and its `request.queryFields` / `request.bodyFields` before asking the user for parameters."; } const items = queryFields @@ -181,7 +326,7 @@ function buildExecutionMarkdown(recipe: DataRecipe): string { const parts = [ "1. Confirm the user's goal and which inputs they want to use.", - "2. Call the Browser RPC Bridge with the recipe recorded in recipe.json.", + "2. Call the Browser RPC Bridge with the selected recipe recorded under recipes/.", `3. Site scope: \`${origin}\`. 4. ${session} 5. ${confirmation}`, @@ -213,7 +358,7 @@ function buildSkillExamplesMarkdown(recipe: DataRecipe, goal: string): string { ### Expected flow -The agent first asks the Browser RPC Bridge for a dry-run preview of recipe.json, confirms the data looks healthy, then organizes and analyzes the returned fields: ${fieldList}.`; +The agent first asks the Browser RPC Bridge for a dry-run preview of the selected recipe under recipes/, confirms the data looks healthy, then organizes and analyzes the returned fields: ${fieldList}.`; } function buildRuntimeMarkdown(recipe: DataRecipe): string { @@ -246,28 +391,43 @@ function buildExamplesMarkdown(recipe: DataRecipe, goal: string): string { ## 示例输出 -系统会先通过 Browser RPC Bridge 在用户授权的浏览器会话中测试运行 recipe.json,确认能读取数据,再基于返回字段进行整理和分析。 +系统会先通过 Browser RPC Bridge 在用户授权的浏览器会话中测试运行 recipes/ 下的配方,确认能读取数据,再基于返回字段进行整理和分析。 `; } -function buildReadmeMarkdown(recipe: DataRecipe, goal: string): string { - return `# ${recipe.displayName} +function buildReadmeMarkdown( + recipes: DataSkillRecipeInput[], + workflow: DataSkillWorkflow, + goal: string +): string { + const primary = recipes[0]!.recipe; + const recipeList = recipes.map(({ recipeId }) => `- recipes/${normalizeRecipeId(recipeId)}.json`).join("\n"); + return `# ${primary.displayName} ${goal} ## 包含文件 - SKILL.md: 给 AI Agent 使用的技能说明。 -- recipe.json: 可测试运行的数据配方。 +- workflow.json: 多步骤输入输出依赖。 +- recipes/: 可测试运行的数据配方目录。 - examples.md: 示例问题和示例输出。 - README.md: 给人看的说明。 +## 数据配方 + +${recipeList} + +## 工作流 + +${workflow.steps.map((step) => `- ${step.id}: ${step.operation}${step.recipeId ? ` → ${step.recipeId}` : ""}`).join("\n")} + ## 运行方式 这个技能默认通过 Browser RPC Bridge 在用户授权的 Chrome 会话中运行,不直接暴露 Cookie 或 Authorization header。 ## 验证方式 -用 recipe.json 通过 Browser RPC Bridge 进行测试运行,并确认可以读取预期数据。 +按 workflow.json 顺序,通过 Browser RPC Bridge 运行 recipes/ 中的配方并确认输入输出依赖有效。 `; } diff --git a/packages/skill-exporter/package.json b/packages/skill-exporter/package.json index 789ae50..6b0ae4a 100644 --- a/packages/skill-exporter/package.json +++ b/packages/skill-exporter/package.json @@ -16,6 +16,7 @@ "typecheck": "tsc -b tsconfig.json" }, "dependencies": { - "@data-recipe/skill-builder": "workspace:*" + "@data-recipe/skill-builder": "workspace:*", + "fflate": "^0.8.3" } } diff --git a/packages/skill-exporter/src/index.ts b/packages/skill-exporter/src/index.ts index 0f02b00..8c872a4 100644 --- a/packages/skill-exporter/src/index.ts +++ b/packages/skill-exporter/src/index.ts @@ -1,4 +1,5 @@ -import type { DataSkillPackage } from "@data-recipe/skill-builder"; +import { strFromU8, strToU8, unzipSync, zipSync } from "fflate"; +import type { DataSkillPackage, DataSkillWorkflow } from "@data-recipe/skill-builder"; export interface DataSkillPackageValidation { ok: boolean; @@ -6,72 +7,110 @@ export interface DataSkillPackageValidation { errors: string[]; } -export interface ExportedDataSkillPackage { +export interface ExportedDataSkillPackageZip { + fileName: string; + mimeType: "application/zip"; + content: Uint8Array; +} + +export interface ExportedDataSkillPackageJson { fileName: string; mimeType: "application/json"; content: string; } -const REQUIRED_FILES = ["SKILL.md", "recipe.json", "examples.md", "README.md"] as const; +const REQUIRED_FILES = ["SKILL.md", "workflow.json", "examples.md", "README.md"] as const; export function validateDataSkillPackage(skillPackage: DataSkillPackage): DataSkillPackageValidation { const existing = new Set(skillPackage.files.map((file) => file.path)); const missingFiles = REQUIRED_FILES.filter((file) => !existing.has(file)); const errors: string[] = []; + const recipePaths = skillPackage.files.filter((file) => /^recipes\/[^/]+\.json$/.test(file.path)); - if (!skillPackage.packageName.trim()) { - errors.push("packageName is required"); - } - + if (!skillPackage.packageName.trim()) errors.push("packageName is required"); + if (recipePaths.length === 0) errors.push("at least one recipes/*.json file is required"); skillPackage.files.forEach((file) => { - if (!file.content.trim()) { - errors.push(`${file.path} is empty`); - } + if (!file.content.trim()) errors.push(`${file.path} is empty`); + if (file.path.startsWith("/") || file.path.includes("..")) errors.push(`${file.path} is not a safe relative path`); }); + const workflowFile = skillPackage.files.find((file) => file.path === "workflow.json"); + if (workflowFile) validateWorkflowReferences(workflowFile.content, recipePaths.map((file) => file.path), errors); + + return { ok: missingFiles.length === 0 && errors.length === 0, missingFiles, errors }; +} + +export function exportDataSkillPackageAsZip(skillPackage: DataSkillPackage): ExportedDataSkillPackageZip { + const validation = validateDataSkillPackage(skillPackage); + if (!validation.ok) throw new Error(`Invalid Data Skill Package: ${[...validation.missingFiles, ...validation.errors].join(", ")}`); + const entries = Object.fromEntries(skillPackage.files.map((file) => [file.path, strToU8(file.content)])); + return { + fileName: `${normalizeFileName(skillPackage.packageName || "data-skill")}.zip`, + mimeType: "application/zip", + content: zipSync(entries, { level: 6 }) + }; +} + +/** Development/import interchange only. ZIP is the production export format. */ +export function exportDataSkillPackageAsJson(skillPackage: DataSkillPackage): ExportedDataSkillPackageJson { + const safeName = normalizeFileName(skillPackage.packageName || "data-skill"); return { - ok: missingFiles.length === 0 && errors.length === 0, - missingFiles, - errors + fileName: `${safeName}.data-skill.json`, + mimeType: "application/json", + content: `${JSON.stringify(skillPackage, null, 2)}\n` }; } export function validateExportedDataSkillPackageJson(content: string): DataSkillPackageValidation { try { const parsed = JSON.parse(content) as DataSkillPackage; - if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.files)) { - return { - ok: false, - missingFiles: [...REQUIRED_FILES], - errors: ["exported package must contain a files array"] - }; + return { ok: false, missingFiles: [...REQUIRED_FILES], errors: ["exported package must contain a files array"] }; } - return validateDataSkillPackage(parsed); } catch { - return { - ok: false, - missingFiles: [...REQUIRED_FILES], - errors: ["exported package is not valid JSON"] - }; + return { ok: false, missingFiles: [...REQUIRED_FILES], errors: ["exported package is not valid JSON"] }; } } -export function exportDataSkillPackageAsJson(skillPackage: DataSkillPackage): ExportedDataSkillPackage { - const safeName = normalizeFileName(skillPackage.packageName || "data-skill"); - return { - fileName: `${safeName}.data-skill.json`, - mimeType: "application/json", - content: `${JSON.stringify(skillPackage, null, 2)}\n` - }; +export function inspectDataSkillPackageZip(content: Uint8Array): string[] { + return Object.keys(unzipSync(content)).sort(); } -function normalizeFileName(value: string): string { - const normalized = value - .toLowerCase() - .replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-") - .replace(/^-+|-+$/g, ""); +export function validateDataSkillPackageZip(content: Uint8Array): DataSkillPackageValidation { + try { + const files = Object.entries(unzipSync(content)).map(([path, bytes]) => ({ path, content: strFromU8(bytes) })); + return validateDataSkillPackage({ packageName: "imported-data-skill", files }); + } catch { + return { ok: false, missingFiles: [...REQUIRED_FILES], errors: ["exported package is not a valid ZIP"] }; + } +} +function validateWorkflowReferences(content: string, recipePaths: string[], errors: string[]): void { + try { + const workflow = JSON.parse(content) as DataSkillWorkflow; + if (workflow.version !== 1 || !Array.isArray(workflow.steps) || workflow.steps.length === 0) { + errors.push("workflow.json must contain version 1 steps"); + return; + } + const available = new Set(recipePaths.map((path) => path.slice("recipes/".length, -".json".length))); + const referenced = new Set(workflow.steps.flatMap((step) => step.recipeId ? [normalizeRecipeId(step.recipeId)] : [])); + referenced.forEach((recipeId) => { + if (!available.has(recipeId)) errors.push(`workflow.json references missing recipe ${recipeId}`); + }); + available.forEach((recipeId) => { + if (!referenced.has(recipeId)) errors.push(`recipes/${recipeId}.json is not referenced by workflow.json`); + }); + } catch { + errors.push("workflow.json is not valid JSON"); + } +} + +function normalizeRecipeId(value: string): string { + return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""); +} + +function normalizeFileName(value: string): string { + const normalized = value.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, ""); return normalized || "data-skill"; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 77c4b75..a6fcbd0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,12 @@ importers: '@data-recipe/skill-exporter': specifier: workspace:* version: link:../../packages/skill-exporter + dompurify: + specifier: ^3.4.11 + version: 3.4.11 + marked: + specifier: ^18.0.5 + version: 18.0.5 devDependencies: rimraf: specifier: ^6.0.1 @@ -94,6 +100,9 @@ importers: '@data-recipe/skill-builder': specifier: workspace:* version: link:../skill-builder + fflate: + specifier: ^0.8.3 + version: 0.8.3 packages: @@ -419,6 +428,9 @@ packages: '@types/har-format@1.2.16': resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + acorn@8.17.0: resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} @@ -469,6 +481,9 @@ packages: supports-color: optional: true + dompurify@3.4.11: + resolution: {integrity: sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==} + esbuild@0.27.7: resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} @@ -483,6 +498,9 @@ packages: picomatch: optional: true + fflate@0.8.3: + resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} + fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} @@ -517,6 +535,11 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + marked@18.0.5: + resolution: {integrity: sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==} + engines: {node: '>= 20'} + hasBin: true + minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} @@ -839,6 +862,9 @@ snapshots: '@types/har-format@1.2.16': {} + '@types/trusted-types@2.0.7': + optional: true + acorn@8.17.0: {} any-promise@1.3.0: {} @@ -870,6 +896,10 @@ snapshots: dependencies: ms: 2.1.3 + dompurify@3.4.11: + optionalDependencies: + '@types/trusted-types': 2.0.7 + esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -903,6 +933,8 @@ snapshots: optionalDependencies: picomatch: 4.0.5 + fflate@0.8.3: {} + fix-dts-default-cjs-exports@1.0.1: dependencies: magic-string: 0.30.21 @@ -932,6 +964,8 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + marked@18.0.5: {} + minimatch@10.2.5: dependencies: brace-expansion: 5.0.7 diff --git a/scripts/test-agent-runtime.mjs b/scripts/test-agent-runtime.mjs index f986716..3f9daf4 100644 --- a/scripts/test-agent-runtime.mjs +++ b/scripts/test-agent-runtime.mjs @@ -1,61 +1,434 @@ import assert from "node:assert/strict"; import { + AgentRunError, OpenAICompatibleProvider, ToolCallingAgentRuntime } from "../packages/agent-runtime/dist/index.js"; +import { RecipeStore, RecipeStoreError } from "../packages/agent-tools-core/dist/index.js"; +import { createDataRecipeDraft } from "../packages/recipe-core/dist/index.js"; +import { buildDataSkillPackage } from "../packages/skill-builder/dist/index.js"; +import { + exportDataSkillPackageAsZip, + inspectDataSkillPackageZip, + validateDataSkillPackageZip +} from "../packages/skill-exporter/dist/index.js"; +import { SidepanelAgentToolLayer } from "../apps/extension/src/agent-tools.ts"; + +const tool = { type: "function", function: { name: "echo", description: "echo", parameters: { type: "object" } } }; + +await testStreamingText(); +await testStreamingToolCalls(); +await testStreamingFallback(); +await testFailureHistoryCheckpoint(); +await testToolCallsAppearBeforeExecution(); +await testAgentRunErrorPartialHistory(); +await testMaxIterationsSummary(); +await testRepeatedFailureStops(); +await testRecipeStoreAndRecipeIdTools(); +await testWeeklyReportMultiRecipeZip(); +console.log("agent-runtime and agent-tool tests passed"); + +async function testStreamingText() { + await withFetch(async () => sseResponse([ + `data: ${JSON.stringify({ choices: [{ delta: { content: "你" }, finish_reason: null }] })}\n\n`, + `data: ${JSON.stringify({ choices: [{ delta: { content: "好" }, finish_reason: "stop" }] })}\n\n`, + "data: [DONE]\n\n" + ], [7, 13, 5]), async () => { + const deltas = []; + const provider = configuredProvider(); + const completion = await provider.complete({ messages: [{ role: "user", content: "hi" }] }, { + onTextDelta: (delta) => deltas.push(delta) + }); + assert.equal(completion.message.content, "你好"); + assert.deepEqual(deltas, ["你", "好"]); + assert.equal(completion.streamed, true); + }); +} + +async function testStreamingToolCalls() { + await withFetch(async () => sseResponse([ + `data: ${JSON.stringify({ choices: [{ delta: { tool_calls: [{ index: 0, id: "call-1", type: "function", function: { name: "build", arguments: "{\"recipe" } }] }, finish_reason: null }] })}\n\n`, + `data: ${JSON.stringify({ choices: [{ delta: { tool_calls: [{ index: 0, function: { name: "Recipe", arguments: "Id\":\"r1\"}" } }] }, finish_reason: "tool_calls" }] })}\n\n`, + "data: [DONE]\n\n" + ], [11, 3, 29]), async () => { + const completion = await configuredProvider().complete({ messages: [{ role: "user", content: "tool" }], tools: [tool] }); + assert.equal(completion.message.tool_calls?.[0]?.id, "call-1"); + assert.equal(completion.message.tool_calls?.[0]?.function.name, "buildRecipe"); + assert.equal(completion.message.tool_calls?.[0]?.function.arguments, "{\"recipeId\":\"r1\"}"); + }); +} + +async function testStreamingFallback() { + let turn = 0; + const streamFlags = []; + const statuses = []; + await withFetch(async (_url, init) => { + streamFlags.push(JSON.parse(String(init.body)).stream); + turn += 1; + if (turn === 1) { + return new Response(JSON.stringify({ error: { message: "streaming not supported" } }), { status: 400, headers: { "content-type": "application/json" } }); + } + return jsonResponse({ choices: [{ finish_reason: "stop", message: { role: "assistant", content: "fallback ok" } }] }); + }, async () => { + const completion = await configuredProvider().complete({ messages: [{ role: "user", content: "fallback" }] }, { + onStatusChange: (status) => statuses.push(status) + }); + assert.equal(completion.message.content, "fallback ok"); + assert.deepEqual(streamFlags, [true, false]); + assert.ok(statuses.includes("fallback")); + }); +} + +async function testFailureHistoryCheckpoint() { + let turn = 0; + const checkpoints = []; + const runtime = new ToolCallingAgentRuntime({ + async complete(input) { + turn += 1; + if (turn === 1) return toolCompletion("failure-1", "echo", "{\"value\":1}"); + assert.ok(input.messages.some((message) => message.role === "tool" && message.tool_call_id === "failure-1")); + return textCompletion("history preserved"); + } + }); + const result = await runtime.run({ + systemPrompt: "system", + messages: [{ role: "user", content: "run" }], + tools: [tool], + executeTool: async () => ({ ok: false, error: { code: "EXPECTED", message: "failed", retryable: true, expectedInput: {} } }), + onMessagesUpdated: (messages) => checkpoints.push(messages) + }); + assert.match(result.finalText, /^history preserved/); + assert.match(result.finalText, /1 个工具错误(EXPECTED)/); + assert.equal(result.outcome.failedToolCalls.length, 1); + assert.ok(checkpoints.some((messages) => messages.some((message) => message.role === "tool"))); +} -const originalFetch = globalThis.fetch; -let requestedUrl = ""; -let requestedBody; -globalThis.fetch = async (url, init) => { - requestedUrl = String(url); - requestedBody = JSON.parse(String(init.body)); - assert.equal(init.headers.authorization, "Bearer test-key"); - return new Response(JSON.stringify({ - choices: [{ - finish_reason: "tool_calls", - message: { - role: "assistant", - content: null, - tool_calls: [{ id: "call-1", type: "function", function: { name: "echo", arguments: "{\"value\":42}" } }] +async function testToolCallsAppearBeforeExecution() { + let turn = 0; + const timeline = []; + const runtime = new ToolCallingAgentRuntime({ + async complete() { + turn += 1; + if (turn === 1) { + return { + message: { + role: "assistant", + content: null, + tool_calls: [ + { id: "call-a", type: "function", function: { name: "echo", arguments: "{\"value\":\"a\"}" } }, + { id: "call-b", type: "function", function: { name: "echo", arguments: "{\"value\":\"b\"}" } } + ] + }, + streamed: false + }; } - }] - }), { status: 200, headers: { "content-type": "application/json" } }); -}; - -const provider = new OpenAICompatibleProvider({ baseUrl: "https://provider.example", apiKey: "test-key", model: "tool-model" }); -const completion = await provider.complete({ - messages: [{ role: "user", content: "test" }], - tools: [{ type: "function", function: { name: "echo", description: "echo", parameters: { type: "object" } } }] -}); -assert.equal(requestedUrl, "https://provider.example/v1/chat/completions"); -assert.equal(requestedBody.stream, false); -assert.equal(completion.message.tool_calls?.[0]?.function.name, "echo"); -globalThis.fetch = originalFetch; - -let providerTurn = 0; -const runtime = new ToolCallingAgentRuntime({ - async complete() { - providerTurn += 1; - if (providerTurn === 1) { - return { - message: { - role: "assistant", - content: null, - tool_calls: [{ id: "call-2", type: "function", function: { name: "echo", arguments: "{\"value\":7}" } }] - } - }; - } - return { message: { role: "assistant", content: "完成" } }; - } -}); - -const result = await runtime.run({ - systemPrompt: "system", - messages: [{ role: "user", content: "run" }], - tools: [{ type: "function", function: { name: "echo", description: "echo", parameters: { type: "object" } } }], - executeTool: async (name, input) => ({ name, input }) -}); -assert.equal(result.finalText, "完成"); -assert.equal(result.messages.find((message) => message.role === "tool")?.tool_call_id, "call-2"); -console.log("agent-runtime tests passed"); + return textCompletion("done"); + } + }); + await runtime.run({ + systemPrompt: "system", + messages: [{ role: "user", content: "two calls" }], + tools: [tool], + onToolCall: ({ toolCall }) => timeline.push(`call:${toolCall.id}`), + executeTool: async (_name, args) => { + timeline.push(`execute:${args.value}`); + return { ok: true, data: args }; + } + }); + assert.deepEqual(timeline, ["call:call-a", "call:call-b", "execute:a", "execute:b"]); +} + +async function testAgentRunErrorPartialHistory() { + let turn = 0; + const runtime = new ToolCallingAgentRuntime({ + async complete() { + turn += 1; + if (turn === 1) return toolCompletion("partial-1", "echo", "{}"); + throw new Error("provider down"); + } + }); + await assert.rejects( + runtime.run({ systemPrompt: "system", messages: [{ role: "user", content: "run" }], tools: [tool], executeTool: async () => ({ ok: true, data: {} }) }), + (error) => { + assert.ok(error instanceof AgentRunError); + assert.ok(error.partialMessages.some((message) => message.role === "tool" && message.tool_call_id === "partial-1")); + assert.equal(error.iterations, 2); + assert.equal(error.outcome.status, "failed_tool"); + assert.ok(error.outcome.completedSteps.includes("echo:partial-1")); + return true; + } + ); +} + +async function testMaxIterationsSummary() { + let sawSummaryChoice = false; + const runtime = new ToolCallingAgentRuntime({ + async complete(input) { + if (input.toolChoice === "none") { + sawSummaryChoice = true; + return textCompletion("达到上限,建议新建对话后缩小目标"); + } + return toolCompletion("loop-1", "echo", "{}"); + } + }); + const result = await runtime.run({ + systemPrompt: "system", + messages: [{ role: "user", content: "loop" }], + tools: [tool], + maxIterations: 1, + executeTool: async () => ({ ok: true, data: {} }) + }); + assert.equal(result.terminationReason, "max_iterations"); + assert.equal(result.finalText, "达到上限,建议新建对话后缩小目标"); + assert.equal(sawSummaryChoice, true); + assert.ok(result.messages.some((message) => message.role === "tool")); + assert.equal(result.outcome.status, "paused_budget"); + assert.equal(result.outcome.message, "本轮达到执行上限,进度已保存。"); + assert.deepEqual(result.outcome.pendingSteps, ["continue_agent_loop"]); +} + +async function testRepeatedFailureStops() { + let normalTurns = 0; + const runtime = new ToolCallingAgentRuntime({ + async complete(input) { + if (input.toolChoice === "none") return textCompletion("重复失败,建议修正参数"); + normalTurns += 1; + return toolCompletion(`repeat-${normalTurns}`, "echo", "{\"same\":true}"); + } + }); + const result = await runtime.run({ + systemPrompt: "system", + messages: [{ role: "user", content: "repeat" }], + tools: [tool], + executeTool: async () => ({ ok: false, error: { code: "BAD", message: "bad", retryable: true, expectedInput: {} } }) + }); + assert.equal(result.terminationReason, "repeated_failure"); + assert.equal(normalTurns, 2); + assert.equal(result.outcome.status, "failed_tool"); + assert.equal(result.outcome.failedToolCalls.length, 2); +} + +async function testRecipeStoreAndRecipeIdTools() { + const store = new RecipeStore(); + assert.throws(() => store.create({ name: "partial" }), (error) => { + assert.ok(error instanceof RecipeStoreError); + assert.doesNotMatch(error.message, /Cannot read properties/); + return true; + }); + + const capture = { + id: "capture-1", + pageUrl: "https://example.test/orders", + url: "https://example.test/api/orders?page=1", + method: "GET", + status: 200, + requestBody: null, + query: { page: "1" }, + responseBody: { total: 1, records: [{ id: 1, amount: 10 }] }, + responsePreview: "preview", + capturedAt: Date.now(), + transport: "fetch" + }; + const layer = new SidepanelAgentToolLayer({ getCaptures: () => [capture], confirmAction: async () => true, download: () => {}, recipeStore: store }); + const built = await layer.invoke("buildRecipe", { captureId: "capture-1", patch: { description: "orders" } }); + assert.equal(built.ok, true); + const recipeId = built.ok ? built.data.recipeId : ""; + const patched = await layer.invoke("buildRecipe", { recipeId, patch: { response: { listPath: "$.records" } } }); + assert.equal(patched.ok, true); + const run = await layer.invoke("runRecipe", { recipeId, dryRun: true }); + assert.equal(run.ok, true); + const oldProtocol = await layer.invoke("runRecipe", { recipe: { name: "partial" } }); + assert.equal(oldProtocol.ok, false); + assert.doesNotMatch(oldProtocol.ok ? "" : oldProtocol.error.message, /Cannot read properties/); + const invalidExport = await layer.invoke("exportSkillPackage", { + recipeIds: [recipeId], + workflow: { version: 1, description: "broken", userInputs: [], steps: [], finalOutputs: {} }, + skillMarkdown: "# Skill", + userGoal: "test" + }); + assert.equal(invalidExport.ok, false); + assert.equal(invalidExport.ok ? "" : invalidExport.error.code, "INVALID_WORKFLOW"); + assert.ok(invalidExport.ok ? false : invalidExport.error.expectedInput); +} + +async function testWeeklyReportMultiRecipeZip() { + const recipes = [ + { recipeId: "people-list", recipe: weeklyRecipe("people", "/api/people", "list", "$.records", ["name", "empCode", "uid"]) }, + { recipeId: "week-list", recipe: weeklyRecipe("weeks", "/api/weeks", "list", "$.records", ["year", "week", "weekId"]) }, + { recipeId: "week-detail", recipe: weeklyRecipe("detail", "/api/week-detail", "object", "$", ["weekId", "content", "updatedAt"]) } + ]; + const workflow = { + version: 1, + description: "根据“人员 + 周数”动态获取周报详情,并可选比较上一周。", + userInputs: [{ + name: "query", + type: "string", + required: true, + description: "自然语言人员与 ISO 周,例如 池佳 W25;未提供年份时使用当前年份。", + examples: ["池佳 W25"], + parsing: "解析 personName、year(缺省为当前年份)和 isoWeek;不得推断或硬编码人员标识。" + }], + steps: [ + { + id: "list_people", + operation: "list", + recipeId: "people-list", + inputs: { query: { type: "user_input", name: "query", path: "personName" } }, + outputs: { records: { path: "$.records" } } + }, + { + id: "match_person", + operation: "filter", + dependsOn: ["list_people"], + inputs: { + records: { type: "step_output", stepId: "list_people", path: "records" }, + personName: { type: "user_input", name: "query", path: "personName" } + }, + outputs: { empCode: { path: "$.empCode" }, uid: { path: "$.uid" } } + }, + { + id: "list_weeks", + operation: "list", + recipeId: "week-list", + dependsOn: ["match_person"], + inputs: { uid: { type: "step_output", stepId: "match_person", path: "uid" } }, + outputs: { weeks: { path: "$.records" } } + }, + { + id: "match_week", + operation: "filter", + dependsOn: ["list_weeks"], + inputs: { + weeks: { type: "step_output", stepId: "list_weeks", path: "weeks" }, + year: { type: "user_input", name: "query", path: "year" }, + isoWeek: { type: "user_input", name: "query", path: "isoWeek" } + }, + outputs: { weekId: { path: "$.weekId" } } + }, + { + id: "get_detail", + operation: "detail", + recipeId: "week-detail", + dependsOn: ["match_person", "match_week"], + inputs: { + empCode: { type: "step_output", stepId: "match_person", path: "empCode" }, + uid: { type: "step_output", stepId: "match_person", path: "uid" }, + weekId: { type: "step_output", stepId: "match_week", path: "weekId" } + }, + outputs: { report: { path: "$" } } + }, + { + id: "optional_diff", + operation: "diff", + optional: true, + dependsOn: ["get_detail"], + inputs: { current: { type: "step_output", stepId: "get_detail", path: "report" } }, + outputs: { changes: { path: "$" } } + } + ], + finalOutputs: { + report: { type: "step_output", stepId: "get_detail", path: "report" }, + diff: { type: "step_output", stepId: "optional_diff", path: "changes" } + } + }; + const skillMarkdown = `--- +name: weekly-report +description: 动态查询指定人员和 ISO 周的周报 +--- + +# 周报查询 + +接受“人员 + 周数”,例如“池佳 W25”。解析人员、当前年份与 ISO 周,依次执行 workflow.json。 + +- 从人员列表按姓名匹配,动态取得 empCode 和 uid。 +- 从周列表按 year 和 isoWeek 匹配 weekId。 +- 用动态标识读取详情,并按需执行 diff。 +- 禁止硬编码任何人员、empCode、uid 或 weekId。 +`; + const skillPackage = buildDataSkillPackage({ + packageName: "weekly-report", + recipes, + workflow, + userGoal: "池佳 W25", + skillMarkdown + }); + const exported = exportDataSkillPackageAsZip(skillPackage); + assert.equal(exported.mimeType, "application/zip"); + assert.match(exported.fileName, /\.zip$/); + assert.deepEqual(inspectDataSkillPackageZip(exported.content), [ + "README.md", + "SKILL.md", + "examples.md", + "recipes/people-list.json", + "recipes/week-detail.json", + "recipes/week-list.json", + "workflow.json" + ]); + assert.equal(validateDataSkillPackageZip(exported.content).ok, true); + assert.doesNotMatch(skillMarkdown, /E\d{3,}|U\d{3,}/); + assert.equal(workflow.steps.find((step) => step.id === "get_detail").inputs.weekId.type, "step_output"); + assert.throws(() => buildDataSkillPackage({ + packageName: "broken-weekly-report", + recipes: recipes.slice(0, 1), + workflow, + skillMarkdown + }), /missing recipe/); +} + +function weeklyRecipe(name, path, responseType, listPath, fields) { + const parameterNames = name === "people" ? ["name"] : name === "weeks" ? ["uid"] : ["empCode", "uid", "weekId"]; + return createDataRecipeDraft({ + pageUrl: "https://weekly.example.test/reports", + apiUrl: `https://weekly.example.test${path}`, + method: "GET", + query: {}, + body: {}, + queryFields: parameterNames.map((field) => ({ + name: field, + displayName: field, + path: `query.${field}`, + type: "string", + required: true + })), + responseType, + listPath, + totalPath: responseType === "list" ? "$.total" : "", + fields: fields.map((field) => ({ name: field, displayName: field, path: `$.${field}`, type: "string", description: field })) + }); +} + +function configuredProvider() { + return new OpenAICompatibleProvider({ baseUrl: "https://provider.example", apiKey: "test-key", model: "tool-model" }); +} + +function toolCompletion(id, name, args) { + return { message: { role: "assistant", content: null, tool_calls: [{ id, type: "function", function: { name, arguments: args } }] }, streamed: false }; +} + +function textCompletion(content) { + return { message: { role: "assistant", content }, streamed: false }; +} + +function jsonResponse(body) { + return new Response(JSON.stringify(body), { status: 200, headers: { "content-type": "application/json" } }); +} + +function sseResponse(frames, chunkSizes) { + const bytes = new TextEncoder().encode(frames.join("")); + let offset = 0; + let sizeIndex = 0; + return new Response(new ReadableStream({ + pull(controller) { + if (offset >= bytes.length) return controller.close(); + const size = chunkSizes[sizeIndex++ % chunkSizes.length]; + controller.enqueue(bytes.slice(offset, Math.min(bytes.length, offset + size))); + offset += size; + } + }), { status: 200, headers: { "content-type": "text/event-stream" } }); +} + +async function withFetch(replacement, run) { + const original = globalThis.fetch; + globalThis.fetch = replacement; + try { await run(); } finally { globalThis.fetch = original; } +} diff --git a/scripts/validate-data-skill-package.mjs b/scripts/validate-data-skill-package.mjs index 9b49d50..b4ce330 100644 --- a/scripts/validate-data-skill-package.mjs +++ b/scripts/validate-data-skill-package.mjs @@ -1,42 +1,32 @@ import { readFile } from "node:fs/promises"; +import { + validateDataSkillPackageZip, + validateExportedDataSkillPackageJson +} from "../packages/skill-exporter/dist/index.js"; -const requiredFiles = ["SKILL.md", "recipe.json", "examples.md", "README.md"]; const filePath = process.argv[2]; if (!filePath) { - console.error("Usage: pnpm validate:skill-package "); + console.error("Usage: pnpm validate:skill-package "); process.exit(1); } -let parsed; +let validation; try { - parsed = JSON.parse(await readFile(filePath, "utf8")); + const content = await readFile(filePath); + validation = filePath.toLowerCase().endsWith(".zip") + ? validateDataSkillPackageZip(new Uint8Array(content)) + : validateExportedDataSkillPackageJson(content.toString("utf8")); } catch (error) { - console.error(`Invalid JSON package: ${error instanceof Error ? error.message : String(error)}`); + console.error(`Unable to read package: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } -const files = Array.isArray(parsed.files) ? parsed.files : []; -const existing = new Set(files.map((file) => file?.path)); -const missing = requiredFiles.filter((file) => !existing.has(file)); -const empty = files - .filter((file) => typeof file?.content !== "string" || file.content.trim() === "") - .map((file) => file?.path ?? "(unknown)"); - -if (typeof parsed.packageName !== "string" || parsed.packageName.trim() === "") { - console.error("Invalid package: packageName is required."); - process.exit(1); -} - -if (missing.length > 0 || empty.length > 0) { - if (missing.length > 0) { - console.error(`Missing files: ${missing.join(", ")}`); - } - if (empty.length > 0) { - console.error(`Empty files: ${empty.join(", ")}`); - } +if (!validation.ok) { + if (validation.missingFiles.length) console.error(`Missing files: ${validation.missingFiles.join(", ")}`); + validation.errors.forEach((error) => console.error(error)); process.exit(1); } -console.log(`Valid Data Skill Package: ${parsed.packageName}`); -console.log(`Files: ${requiredFiles.join(", ")}`); +console.log("Valid Data Skill Package"); +console.log("Required structure: SKILL.md, workflow.json, recipes/*.json, examples.md, README.md");