diff --git a/package.json b/package.json index 27e1ab8cd..cc8aa1171 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "metadata-batch-cli": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-batch-cli.ts", "metadata-batch-cli:dry": "pnpm metadata-batch-cli --dry-run", "metadata-batch-cli:verbose": "pnpm metadata-batch-cli --verbose", - "validate-metadata": "CHANGED_FILES=$(git diff --name-only HEAD) NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-manager.ts", + "validate-metadata": "CHANGED_FILES=$(git diff --name-only HEAD) pnpm metadata-batch-cli:dry", "validate-pr-metadata": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-manager.ts --pr", "dev": "next dev", "build": "next build", @@ -34,6 +34,7 @@ "clsx": "^2.1.1", "dotenv": "^16.4.7", "escape-string-regexp": "^5.0.0", + "glob": "^11.0.1", "js-yaml": "^4.1.0", "next": "14.2.21", "next-sitemap": "^4.2.3", @@ -50,6 +51,7 @@ "@eth-optimism/core-utils": "^0.13.1", "@eth-optimism/sdk": "^3.1.6", "@types/dotenv": "^8.2.3", + "@types/glob": "^8.1.0", "@types/js-yaml": "^4.0.9", "@types/node": "18.11.10", "cspell": "^8.1.3", diff --git a/pages/app-developers/interop.mdx b/pages/app-developers/interop.mdx index 67dbf45bb..8f49c1b23 100644 --- a/pages/app-developers/interop.mdx +++ b/pages/app-developers/interop.mdx @@ -9,7 +9,6 @@ personas: - protocol-developer categories: - protocol - - architecture - mainnet is_imported_content: 'true' --- diff --git a/pages/app-developers/tools/build/account-abstraction.mdx b/pages/app-developers/tools/build/account-abstraction.mdx index e49d97727..db70f9fe3 100644 --- a/pages/app-developers/tools/build/account-abstraction.mdx +++ b/pages/app-developers/tools/build/account-abstraction.mdx @@ -11,7 +11,7 @@ personas: categories: - account-abstraction - paymasters - - Transactions + - transactions is_imported_content: 'false' --- diff --git a/pages/app-developers/tutorials.mdx b/pages/app-developers/tutorials.mdx index 9ce83a312..c1132b076 100644 --- a/pages/app-developers/tutorials.mdx +++ b/pages/app-developers/tutorials.mdx @@ -5,14 +5,13 @@ description: >- topics such as bridging tokens, deploying contracts, and estimating transaction costs. lang: en-US -content_type: guide +content_type: landing-page topic: app-dev-tutorials personas: - app-developer categories: - mainnet - testnet - - reference is_imported_content: 'false' --- diff --git a/pages/app-developers/tutorials/supersim.mdx b/pages/app-developers/tutorials/supersim.mdx index 2ae58b8fe..d48fa17b4 100644 --- a/pages/app-developers/tutorials/supersim.mdx +++ b/pages/app-developers/tutorials/supersim.mdx @@ -1,18 +1,11 @@ --- title: Supersim guides and tutorials -description: >- - A collection of guides and tutorials to understanding and working with - Supersim, including getting started, CLI reference, and chain environment. +description: A collection of guides and tutorials to understanding and working with Supersim. lang: en-US content_type: tutorial topic: supersim-guides-and-tutorials -personas: - - app-developer -categories: - - supersim - - devnets - - testing - - protocol +personas: app-developer +categories: ['supersim', 'devnets', 'cli'] is_imported_content: 'false' --- diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c598a364..e1f7616b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,6 +49,9 @@ importers: escape-string-regexp: specifier: ^5.0.0 version: 5.0.0 + glob: + specifier: ^11.0.1 + version: 11.0.1 js-yaml: specifier: ^4.1.0 version: 4.1.0 @@ -92,6 +95,9 @@ importers: '@types/dotenv': specifier: ^8.2.3 version: 8.2.3 + '@types/glob': + specifier: ^8.1.0 + version: 8.1.0 '@types/js-yaml': specifier: ^4.0.9 version: 4.0.9 @@ -1010,6 +1016,9 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/glob@8.1.0': + resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + '@types/hast@2.3.7': resolution: {integrity: sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw==} @@ -1043,6 +1052,9 @@ packages: '@types/mdx@2.0.9': resolution: {integrity: sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg==} + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + '@types/ms@0.7.33': resolution: {integrity: sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==} @@ -1992,6 +2004,11 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + glob@11.0.1: + resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -2372,6 +2389,10 @@ packages: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} + jackspeak@4.1.0: + resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} + engines: {node: 20 || >=22} + js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} @@ -2484,6 +2505,10 @@ packages: resolution: {integrity: sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==} engines: {node: 14 || >=16.14} + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -2808,6 +2833,10 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2826,6 +2855,10 @@ packages: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -3001,6 +3034,9 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -3068,6 +3104,10 @@ packages: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -5043,6 +5083,11 @@ snapshots: '@types/estree@1.0.5': {} + '@types/glob@8.1.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 18.11.10 + '@types/hast@2.3.7': dependencies: '@types/unist': 2.0.9 @@ -5075,6 +5120,8 @@ snapshots: '@types/mdx@2.0.9': {} + '@types/minimatch@5.1.2': {} + '@types/ms@0.7.33': {} '@types/node@18.11.10': {} @@ -6222,6 +6269,15 @@ snapshots: minipass: 7.0.4 path-scurry: 1.10.1 + glob@11.0.1: + dependencies: + foreground-child: 3.1.1 + jackspeak: 4.1.0 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -6631,6 +6687,10 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.0: + dependencies: + '@isaacs/cliui': 8.0.2 + js-sha3@0.8.0: {} js-tokens@4.0.0: {} @@ -6722,6 +6782,8 @@ snapshots: lru-cache@10.0.3: {} + lru-cache@11.0.2: {} + lru-cache@4.1.5: dependencies: pseudomap: 1.0.2 @@ -7459,6 +7521,10 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -7475,6 +7541,8 @@ snapshots: minipass@7.0.4: {} + minipass@7.1.2: {} + mri@1.2.0: {} ms@2.1.2: {} @@ -7691,6 +7759,8 @@ snapshots: dependencies: p-limit: 4.0.0 + package-json-from-dist@1.0.1: {} + param-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -7772,6 +7842,11 @@ snapshots: lru-cache: 10.0.3 minipass: 7.0.4 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + path-type@4.0.0: {} pathval@1.1.1: {} diff --git a/utils/metadata-batch-cli.ts b/utils/metadata-batch-cli.ts index 81c31a452..51b033c66 100644 --- a/utils/metadata-batch-cli.ts +++ b/utils/metadata-batch-cli.ts @@ -7,6 +7,8 @@ import { updateMetadata as updateMetadataFile } from './metadata-manager' import matter from 'gray-matter' import { analyzeContent } from './metadata-analyzer' import { MetadataResult } from './types/metadata-types' +import { generateMetadata } from './metadata-manager' +import globby from 'globby' // @ts-ignore const globModule = await import('glob') @@ -174,12 +176,12 @@ async function processFiles(files: string[], options: CliOptions): Promise<{ const content = await fs.readFile(file, 'utf8') const { data: frontmatter } = matter(content) const analysis = analyzeContent(content, file, options.verbose) - const result = await updateMetadataFile(file, { - dryRun: true, - verbose: false, + const result = await updateMetadataFile(file, { + dryRun: options.dryRun, + verbose: options.verbose, analysis, - validateOnly: true, - prMode: true + validateOnly: false, + prMode: false }) console.log(`\n${colors.blue}📄 ${file}${colors.reset}`) @@ -199,7 +201,7 @@ async function processFiles(files: string[], options: CliOptions): Promise<{ stats.needsReview++ } else { if (!options.dryRun) { - await updateMetadataFile(file, { + await updateMetadataFile(file, { dryRun: false, verbose: options.verbose || false, analysis, @@ -231,50 +233,70 @@ async function processFiles(files: string[], options: CliOptions): Promise<{ async function main() { try { - console.log('Checking metadata...') + const isDryRun = process.argv.includes('--dry-run') + const isVerbose = process.argv.includes('--verbose') - let modifiedFiles: string[] = [] - - // Check if we have a direct glob pattern argument - const globPattern = process.argv.find(arg => arg.includes('*.mdx')) - if (globPattern) { - modifiedFiles = await globModule.glob(globPattern) + // Get files from either CHANGED_FILES or command line glob patterns + let mdxFiles = [] + if (process.env.CHANGED_FILES) { + mdxFiles = process.env.CHANGED_FILES.split('\n').filter(Boolean) } else { - // Fall back to CHANGED_FILES if no glob pattern - const gitOutput = process.env.CHANGED_FILES || '' - modifiedFiles = gitOutput - .split('\n') - .filter(file => file.trim()) - .filter(file => file.endsWith('.mdx')) - .map(file => path.resolve(process.cwd(), file)) - } - - if (modifiedFiles.length === 0) { - console.log(`${colors.green}✓ No MDX files to check${colors.reset}`) - process.exit(0) + // Get glob patterns from command line args (skip the first two args) + const patterns = process.argv.slice(2).filter(arg => !arg.startsWith('--')) + if (patterns.length > 0) { + mdxFiles = await globby(patterns) + } } - - // Validate file paths - const validFiles = await validateFilePaths(modifiedFiles) - if (validFiles.length === 0) { - console.log(`${colors.yellow}⚠️ No valid files to check${colors.reset}`) + mdxFiles = mdxFiles.filter(file => file.endsWith('.mdx')) + + if (mdxFiles.length === 0) { + console.log('✓ No MDX files to check') process.exit(0) } - console.log(`Found ${validFiles.length} valid files to check`) + console.log(`Found ${mdxFiles.length} valid files to check\n`) - const options: CliOptions = { - dryRun: process.argv.includes('--dry-run'), - verbose: process.argv.includes('--verbose') + let processedCount = 0 + let needsReviewCount = 0 + + for (const file of mdxFiles) { + try { + const metadata = await generateMetadata(file) + const result = await updateMetadataFile(file, { + dryRun: isDryRun, + verbose: isVerbose, + validateOnly: false, + prMode: false, + analysis: metadata + }) + + processedCount++ + + // Show metadata for each file + console.log(`\nFile: ${file}`) + console.log('Categories:', metadata.categories?.join(', ') || 'none') + + if (!result.isValid) { + needsReviewCount++ + console.log('\x1b[33m⚠️ Review needed:\x1b[0m') + result.errors.forEach(error => console.log(` → ${error}`)) + } + } catch (error) { + console.error(`Error processing ${file}:`, error) + } } - const { hasErrors, stats } = await processFiles(validFiles, options) - // Don't exit with error code - we want this to be non-blocking - process.exit(0) + // Summary with colors + console.log(`\n${processedCount} files processed`) + if (needsReviewCount === 0) { + console.log('\x1b[32m✓ All files have valid metadata\x1b[0m') + } else { + console.log(`\x1b[33m⚠️ ${needsReviewCount} files need review\x1b[0m`) + } } catch (error) { - console.error(`${colors.yellow}⚠️ Error: ${error}${colors.reset}`) - process.exit(0) + console.error('\x1b[31mError:\x1b[0m', error) + process.exit(1) } } diff --git a/utils/metadata-manager.ts b/utils/metadata-manager.ts index 07e2f7c39..9e4fda3fd 100644 --- a/utils/metadata-manager.ts +++ b/utils/metadata-manager.ts @@ -106,6 +106,11 @@ export async function generateMetadata(filePath: string): Promise c.trim()) } + let personas = existingMetadata.personas || [] + if (typeof personas === 'string') { + personas = [personas] + } + const metadata: MetadataResult = { ...existingMetadata, ...analysis, @@ -113,7 +118,7 @@ export async function generateMetadata(filePath: string): Promise