diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index eeece84..2aab3ad 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -24,6 +24,7 @@ jobs: - name: Run tests with coverage run: yarn vitest run --coverage + # - name: Upload coverage to Codecov # uses: codecov/codecov-action@v5 diff --git a/.github/workflows/todo.yml b/.github/workflows/todo.yml index 3061d3d..a05c181 100644 --- a/.github/workflows/todo.yml +++ b/.github/workflows/todo.yml @@ -12,10 +12,10 @@ jobs: issues: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 @@ -36,10 +36,15 @@ jobs: name: todo-report path: TODO_REPORT.md - - name: Commit TODO report + - name: Generate Changelog from TODOs + run: yarn changelog + + - name: Commit TODO report and CHANGELOG run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - git add TODO_REPORT.md - git commit -m "chore(report): update TODO report" || echo "No changes" + git add TODO_REPORT.md CHANGELOG.md + git diff --cached --quiet && echo "No changes to commit." || git commit -m "chore(report): update TODO report and changelog [skip ci]" git push + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3db9676 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# 📝 Changelog (from TODOs) + +## TODO +- .ts (`src/testTodo.ts:1`) + +## TODO · refactor +- Refactor this logic to improve performance (`src/testTodo.ts:2`) + +## TODO · performance +- Refactor this logic to improve performance (`src/testTodo.ts:2`) diff --git a/package.json b/package.json index b5071b0..437cd7c 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "scripts": { "build": "tsc", "test": "vitest run", - "prepare": "yarn ncc build src/ActionMain.ts -o dist" + "prepare": "yarn ncc build src/ActionMain.ts -o dist", + "changelog": "ts-node scripts/generateChangelog.ts", + "build:dist": "ncc build src/ActionMain.ts -o dist" }, "keywords": [ "github-action", @@ -27,6 +29,7 @@ "@types/node": "^20.11.17", "@vercel/ncc": "^0.38.3", "@vitest/coverage-v8": "^3.1.1", + "ts-node": "^10.9.2", "typescript": "^5.3.3", "vitest": "^3.1.1" } diff --git a/scripts/generateChangelog.ts b/scripts/generateChangelog.ts new file mode 100644 index 0000000..c87f17e --- /dev/null +++ b/scripts/generateChangelog.ts @@ -0,0 +1,55 @@ +import fs from 'fs'; +import path from 'path'; +import { extractTodosFromDir } from '../src/parser/extractTodosFromDir'; +import { classifyTodoText } from '../src/core/classifier'; +import { TodoItem } from '../src/parser/types'; + +function formatGroupHeader(tag: string, semantic: string, metadataKey?: string, metadataValue?: string): string { + const parts = [tag]; + if (semantic) parts.push(semantic); + if (metadataKey && metadataValue) parts.push(`${metadataKey}:${metadataValue}`); + return `## ${parts.join(' · ')}`; +} + +function generateChangelogContent(todos: TodoItem[]): string { + type GroupKey = string; + const groups: Record = {}; + + for (const todo of todos) { + const semantics = classifyTodoText(todo.text); + const metadataEntries = Object.entries(todo.metadata || {}) || [['', '']]; + const tag = todo.tag.toUpperCase(); + + for (const semantic of semantics.length ? semantics : ['']) { + for (const [metaKey, metaValue] of metadataEntries.length ? metadataEntries : [['', '']]) { + const key = JSON.stringify({ tag, semantic, metaKey, metaValue }); + if (!groups[key]) groups[key] = []; + groups[key].push(todo); + } + } + } + + const output: string[] = ['# 📝 Changelog (from TODOs)', '']; + + for (const key of Object.keys(groups)) { + const { tag, semantic, metaKey, metaValue } = JSON.parse(key); + output.push(formatGroupHeader(tag, semantic, metaKey, metaValue)); + + for (const todo of groups[key]) { + output.push(`- ${todo.text} (\`${todo.file}:${todo.line}\`)`); + } + + output.push(''); + } + + return output.join('\n'); +} + +async function main() { + const todos = await extractTodosFromDir('src'); + const changelog = generateChangelogContent(todos); + fs.writeFileSync('CHANGELOG.md', changelog, 'utf8'); + console.log('✅ Changelog saved to CHANGELOG.md'); +} + +main(); diff --git a/src/ActionMain.ts b/src/ActionMain.ts index f0b0648..3e16293 100644 --- a/src/ActionMain.ts +++ b/src/ActionMain.ts @@ -1,11 +1,14 @@ +// src/ActionMain.ts import * as core from '@actions/core'; import * as github from '@actions/github'; import path from 'path'; +import fs from 'fs'; import { extractTodosFromDir } from './parser/extractTodosFromDir'; import { TodoItem } from './parser/types'; import { getExistingIssueTitles, createIssueIfNeeded } from './core/issueManager'; import { generateMarkdownReport } from './core/report'; import { limitTodos, todoKey } from './core/todoUtils'; +import { generateChangelogFromTodos } from './core/changelog'; async function run(): Promise { try { @@ -48,6 +51,10 @@ async function run(): Promise { if (generateReport) { generateMarkdownReport(todos); core.info('📝 Generated TODO_REPORT.md'); + + const changelog = generateChangelogFromTodos(todos); + fs.writeFileSync('CHANGELOG.md', changelog, 'utf8'); + core.info('📦 Generated CHANGELOG.md'); } } catch (error: any) { @@ -56,3 +63,4 @@ async function run(): Promise { } run(); + diff --git a/src/core/changelog.ts b/src/core/changelog.ts new file mode 100644 index 0000000..65c11e6 --- /dev/null +++ b/src/core/changelog.ts @@ -0,0 +1,44 @@ +// src/core/changelog.ts +import { TodoItem } from '../parser/types'; +import { classifyTodoText } from './classifier'; + +function formatGroupHeader(tag: string, semantic: string, metadataKey?: string, metadataValue?: string): string { + const parts = [tag]; + if (semantic) parts.push(semantic); + if (metadataKey && metadataValue) parts.push(`${metadataKey}:${metadataValue}`); + return `## ${parts.join(' · ')}`; +} + +export function generateChangelogFromTodos(todos: TodoItem[]): string { + type GroupKey = string; + const groups: Record = {}; + + for (const todo of todos) { + const semantics = classifyTodoText(todo.text); + const metadataEntries = Object.entries(todo.metadata || {}) || [['', '']]; + const tag = todo.tag.toUpperCase(); + + for (const semantic of semantics.length ? semantics : ['']) { + for (const [metaKey, metaValue] of metadataEntries.length ? metadataEntries : [['', '']]) { + const key = JSON.stringify({ tag, semantic, metaKey, metaValue }); + if (!groups[key]) groups[key] = []; + groups[key].push(todo); + } + } + } + + const output: string[] = ['# 📝 Changelog (from TODOs)', '']; + + for (const key of Object.keys(groups)) { + const { tag, semantic, metaKey, metaValue } = JSON.parse(key); + output.push(formatGroupHeader(tag, semantic, metaKey, metaValue)); + + for (const todo of groups[key]) { + output.push(`- ${todo.text} (\`${todo.file}:${todo.line}\`)`); + } + + output.push(''); + } + + return output.join('\n'); +} diff --git a/src/core/classifier.ts b/src/core/classifier.ts new file mode 100644 index 0000000..49f6bc2 --- /dev/null +++ b/src/core/classifier.ts @@ -0,0 +1,64 @@ +/** + * Classifies a given TODO text into one or more predefined categories based on its content. + * + * @param text - The TODO text to classify. + * @returns An array of strings representing the labels that match the content of the text. + * + * The function identifies the following categories: + * - `refactor`: Matches keywords related to code refactoring, simplification, or optimization. + * - `test`: Matches keywords related to testing, such as adding tests or verifying functionality. + * - `doc`: Matches keywords related to documentation, comments, or explaining code. + * - `performance`: Matches keywords related to performance improvements or latency issues. + * - `security`: Matches keywords related to security concerns, vulnerabilities, or sanitization. + * - `maintenance`: Matches keywords related to deprecation, migration, upgrades, or legacy code removal. + */ +export function classifyTodoText(text: string): string[] { + const lower = text.toLowerCase(); + const labels = new Set(); + + // Refactor / cleanup + if ( + /\b(refactor|simplify|clean[\s\-]?up|restructure|optimi[sz]e|rework|rewrite)\b/.test(lower) + ) { + labels.add('refactor'); + } + + // Testing + if ( + /\b(tests?|add(ed)? tests?|unit tests?|test\s+coverage|verify|assert)\b/.test(lower) + ) { + labels.add('test'); + } + + // Documentation + if ( + /\b(docs?|documentation|comment[s]?|explain|document(ed|ing)?)\b/.test(lower) + ) { + labels.add('doc'); + } + + // Performance + if ( + /\b(performance|perf|slow|latency|optimi[sz]e)\b/.test(lower) + ) { + labels.add('performance'); + } + + // Security + if ( + /\b(security|vuln(?:erability)?|injection|auth|encrypt|sanitize)\b/.test(lower) + ) { + labels.add('security'); + } + + // Deprecation / migration / upgrade + if ( + /\b(deprecat(e|ed|ing)?|migrat(e|ed|ing)?|upgrade[d]?|legacy|remove[d]?)\b/.test(lower) + ) { + labels.add('maintenance'); + } + + return Array.from(labels); +} + + \ No newline at end of file diff --git a/src/core/issueManager.ts b/src/core/issueManager.ts index f44c5de..ab886a4 100644 --- a/src/core/issueManager.ts +++ b/src/core/issueManager.ts @@ -1,7 +1,12 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; import { TodoItem } from '../parser/types'; -import { LABELS_BY_TAG, labelsFromMetadata, ensureLabelExists } from './labelManager'; +import { + LABELS_BY_TAG, + labelsFromMetadata, + ensureLabelExists, + labelsFromTodo // ⬅️ novo +} from './labelManager'; import { loadTemplate, applyTemplate } from '../templates/utils'; export async function getExistingIssueTitles( @@ -65,10 +70,8 @@ export async function createIssueIfNeeded( return; } - const tag = todo.tag.toUpperCase(); - const baseLabels = LABELS_BY_TAG[tag] || ['todo']; - const metaLabels = labelsFromMetadata(todo.metadata); - const labels = [...baseLabels, ...metaLabels]; + const labels = labelsFromTodo(todo); + for (const label of labels) { await ensureLabelExists(octokit, owner, repo, label); diff --git a/src/core/labelManager.ts b/src/core/labelManager.ts index be73ed5..ac10b68 100644 --- a/src/core/labelManager.ts +++ b/src/core/labelManager.ts @@ -1,5 +1,7 @@ import * as github from '@actions/github'; import * as core from '@actions/core'; +import { TodoItem } from '../parser/types'; +import { classifyTodoText } from './classifier'; // Novo: classificador heurístico ou LLM // Labels atribuídas por tipo de comentário export const LABELS_BY_TAG: Record = { @@ -14,7 +16,10 @@ export const LABEL_COLORS: Record = { bug: 'd73a4a', enhancement: 'a2eeef', todo: 'cfd3d7', - 'technical-debt': 'e99695' + 'technical-debt': 'e99695', + refactor: 'f9d0c4', + test: 'fef2c0', + doc: '0075ca' }; // Fallback para labels metadata:priority, due, etc. @@ -23,6 +28,16 @@ export function labelsFromMetadata(metadata?: Record): string[] return Object.entries(metadata).map(([key, value]) => `${key}:${value}`); } +// Novo: combina tag, metadata e classificação semântica +export function labelsFromTodo(todo: TodoItem): string[] { + const tag = todo.tag.toUpperCase(); + const tagLabels = LABELS_BY_TAG[tag] || ['todo']; + const metaLabels = labelsFromMetadata(todo.metadata); + const semanticLabels = classifyTodoText(todo.text); // ← vem de `classifier.ts` + + return Array.from(new Set([...tagLabels, ...metaLabels, ...semanticLabels])); +} + // Garante que uma label existe no repositório export async function ensureLabelExists( octokit: ReturnType, @@ -49,3 +64,4 @@ export async function ensureLabelExists( } } } + diff --git a/src/core/__tests__/applyTemplate.test.ts b/tests/applyTemplate.test.ts similarity index 93% rename from src/core/__tests__/applyTemplate.test.ts rename to tests/applyTemplate.test.ts index dea01fa..55b4019 100644 --- a/src/core/__tests__/applyTemplate.test.ts +++ b/tests/applyTemplate.test.ts @@ -1,4 +1,4 @@ -import { applyTemplate } from '../../templates/utils'; +import { applyTemplate } from '../src/templates/utils'; import { describe, it, expect } from 'vitest' describe('applyTemplate', () => { diff --git a/tests/classifier.test.ts b/tests/classifier.test.ts new file mode 100644 index 0000000..fd02ab7 --- /dev/null +++ b/tests/classifier.test.ts @@ -0,0 +1,46 @@ +import { describe, it, expect } from 'vitest'; +import { classifyTodoText } from '../src/core/classifier'; + +describe('classifyTodoText', () => { + it('classifies refactor-related TODOs', () => { + const text = 'Refactor this function to improve readability'; + expect(classifyTodoText(text)).toContain('refactor'); + }); + + it('classifies test-related TODOs', () => { + const text = 'Add unit tests for edge cases'; + expect(classifyTodoText(text)).toContain('test'); + }); + + it('classifies doc-related TODOs', () => { + const text = 'Document this method and its arguments'; + expect(classifyTodoText(text)).toContain('doc'); + }); + + it('classifies performance-related TODOs', () => { + const text = 'Optimize this query to reduce latency'; + expect(classifyTodoText(text)).toContain('performance'); + }); + + it('classifies security-related TODOs', () => { + const text = 'Check for injection vulnerabilities'; + expect(classifyTodoText(text)).toContain('security'); + }); + + it('classifies maintenance-related TODOs', () => { + const text = 'Deprecate old API and migrate to v2'; + expect(classifyTodoText(text)).toContain('maintenance'); + }); + + it('returns empty array for unrelated TODOs', () => { + const text = 'Ask John about next steps'; + expect(classifyTodoText(text)).toEqual([]); + }); + + it('handles mixed case and accents', () => { + const text = 'Rewrite legacy logic and add docs'; + const labels = classifyTodoText(text); + expect(labels).toContain('refactor'); + expect(labels).toContain('doc'); + }); +}); diff --git a/src/core/__tests__/commentPatterns.test.ts b/tests/commentPatterns.test.ts similarity index 94% rename from src/core/__tests__/commentPatterns.test.ts rename to tests/commentPatterns.test.ts index 90d7d21..408f1f3 100644 --- a/src/core/__tests__/commentPatterns.test.ts +++ b/tests/commentPatterns.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { extractTodosFromString } from '../../parser/extractTodosFromContent'; +import { extractTodosFromString } from '../src/parser/extractTodosFromContent'; describe('extractTodosFromString - comment support by extension', () => { it('extracts from JS-style (//) for .js/.ts/.go/.java', () => { diff --git a/src/core/__tests__/extractTodos.test.ts b/tests/extractTodos.test.ts similarity index 91% rename from src/core/__tests__/extractTodos.test.ts rename to tests/extractTodos.test.ts index 00f6e61..a2d2daf 100644 --- a/src/core/__tests__/extractTodos.test.ts +++ b/tests/extractTodos.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -import { extractTodosFromString } from '../../parser/extractTodosFromContent'; -import { TodoItem } from '../../parser/types'; +import { extractTodosFromString } from '../src/parser/extractTodosFromContent'; +import { TodoItem } from '../src/parser/types'; diff --git a/src/core/__tests__/extractTodosFromContent.test.ts b/tests/extractTodosFromContent.test.ts similarity index 92% rename from src/core/__tests__/extractTodosFromContent.test.ts rename to tests/extractTodosFromContent.test.ts index 7e6844e..8a802be 100644 --- a/src/core/__tests__/extractTodosFromContent.test.ts +++ b/tests/extractTodosFromContent.test.ts @@ -1,4 +1,4 @@ -import { extractTodosFromString } from '../../parser/extractTodosFromContent'; +import { extractTodosFromString } from '../src/parser/extractTodosFromContent'; import { describe, it, expect } from 'vitest' describe('extractTodosFromString', () => { diff --git a/src/core/__tests__/extractTodosFromDir.test.ts b/tests/extractTodosFromDir.test.ts similarity index 92% rename from src/core/__tests__/extractTodosFromDir.test.ts rename to tests/extractTodosFromDir.test.ts index 485c9a9..5b6812f 100644 --- a/src/core/__tests__/extractTodosFromDir.test.ts +++ b/tests/extractTodosFromDir.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import path from 'path'; -import { extractTodosFromDir } from '../../parser/extractTodosFromDir'; +import { extractTodosFromDir } from '../src/parser/extractTodosFromDir'; describe('extractTodosFromDir', () => { const base = path.join(__dirname, 'fixtures'); diff --git a/src/core/__tests__/fixtures/nested/inner.py b/tests/fixtures/nested/inner.py similarity index 100% rename from src/core/__tests__/fixtures/nested/inner.py rename to tests/fixtures/nested/inner.py diff --git a/src/core/__tests__/fixtures/one-file.ts b/tests/fixtures/one-file.ts similarity index 100% rename from src/core/__tests__/fixtures/one-file.ts rename to tests/fixtures/one-file.ts diff --git a/src/core/__tests__/issueManager.test.ts b/tests/issueManager.test.ts similarity index 72% rename from src/core/__tests__/issueManager.test.ts rename to tests/issueManager.test.ts index 719a000..81325a4 100644 --- a/src/core/__tests__/issueManager.test.ts +++ b/tests/issueManager.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import * as core from '@actions/core'; -import { getExistingIssueTitles, createIssueIfNeeded } from '../issueManager'; -import { TodoItem } from '../../parser/types'; +import { getExistingIssueTitles, createIssueIfNeeded } from '../src/core/issueManager'; +import { TodoItem } from '../src/parser/types'; // Mocks const mockOctokit = { @@ -15,10 +15,11 @@ const mockOctokit = { } }; -vi.mock('../labelManager', () => ({ +vi.mock('../src/core/labelManager', () => ({ ensureLabelExists: vi.fn(), LABELS_BY_TAG: { TODO: ['enhancement'] }, - labelsFromMetadata: () => ['priority:high'] + labelsFromMetadata: () => ['priority:high'], + labelsFromTodo: (todo: TodoItem) => ['enhancement', 'priority:high', 'refactor'] // 🆕 mock do novo método })); describe('getExistingIssueTitles', () => { @@ -56,15 +57,15 @@ describe('createIssueIfNeeded', () => { }); it('should skip duplicate issues', async () => { - const existingTitles: Set = new Set(['[TODO] Refactor component']); + const existingTitles: Set = new Set(['[TODO] Refactor component']); await createIssueIfNeeded(octokit, owner, repo, todo, existingTitles); - expect(octokit.rest.issues.create).not.toHaveBeenCalled(); + expect(octokit.rest.issues.create).not.toHaveBeenCalled(); // ✅ espera não ser chamado }); it('should create a new issue if not duplicated', async () => { - const existingTitles: Set = new Set(); + const existingTitles: Set = new Set(); await createIssueIfNeeded(octokit, owner, repo, todo, existingTitles); @@ -72,8 +73,8 @@ describe('createIssueIfNeeded', () => { owner, repo, title: '[TODO] Refactor component', - body: expect.stringContaining('src/file.ts'), - labels: ['enhancement', 'priority:high'] + body: expect.stringContaining('Refactor component'), + labels: ['enhancement', 'priority:high', 'refactor'] // ✅ agora incluindo semantic label }); }); }); diff --git a/src/core/__tests__/labelManager.test.ts b/tests/labelManager.test.ts similarity index 91% rename from src/core/__tests__/labelManager.test.ts rename to tests/labelManager.test.ts index 75ee22b..10ec123 100644 --- a/src/core/__tests__/labelManager.test.ts +++ b/tests/labelManager.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi } from 'vitest'; import * as core from '@actions/core'; -import { labelsFromMetadata, ensureLabelExists } from '../labelManager'; +import { labelsFromMetadata, ensureLabelExists } from '../src/core/labelManager'; const mockOctokit = { rest: { @@ -55,3 +55,6 @@ describe('ensureLabelExists', () => { }); }); }); +function beforeEach(setupFunction: () => void): void { + setupFunction(); +} diff --git a/tsconfig.json b/tsconfig.json index e2efd40..175a3c7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,6 @@ ], "exclude": [ "node_modules", - "dist" + "dist", ] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e0c1a5c..4215abd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,6 +78,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz#bbe12dca5b4ef983a0d0af4b07b9bc90ea0ababa" integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@esbuild/aix-ppc64@0.25.2": version "0.25.2" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz#b87036f644f572efb2b3c75746c97d1d2d87ace8" @@ -234,7 +241,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/resolve-uri@^3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== @@ -249,6 +256,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -554,6 +569,26 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz#fd92d31a2931483c25677b9c6698106490cbbc76" integrity sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ== +"@tsconfig/node10@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/estree@1.0.7", "@types/estree@^1.0.0": version "1.0.7" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" @@ -648,6 +683,18 @@ loupe "^3.1.3" tinyrainbow "^2.0.0" +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.11.0, acorn@^8.4.1: + version "8.14.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" + integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -670,6 +717,11 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + assertion-error@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" @@ -730,6 +782,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" @@ -756,6 +813,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -952,6 +1014,11 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + minimatch@^9.0.4: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" @@ -1208,6 +1275,25 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" @@ -1240,6 +1326,11 @@ universal-user-agent@^7.0.0, universal-user-agent@^7.0.2: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.2.tgz#52e7d0e9b3dc4df06cc33cb2b9fd79041a54827e" integrity sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + vite-node@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-3.1.1.tgz#ad186c07859a6e5fca7c7f563e55fb11b16557bc" @@ -1341,3 +1432,8 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==