/
githubmirror
/
gutenberg
Обзор
Документация
Войти
/
githubmirror
/
gutenberg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
packages/create-block/lib/templates.js
345 строк
8 KB
Marco Ciampini
ESLint: Replace strict config with bulk suppressions (#81248)
07 авг 2026, 14:34
Не верифицирован
07 авг 2026, 14:34
7f43eaf
Код
Авторство
О чём код?
const { existsSync } = require( 'fs' ); const { mkdtemp, readFile } = require( 'fs' ).promises; const { tmpdir } = require( 'os' ); const { join, resolve } = require( 'path' ); const inquirer = require( '@inquirer/prompts' ); const { command } = require( 'execa' ); const glob = require( 'fast-glob' ); const npmPackageArg = require( 'npm-package-arg' ); const rimraf = require( 'rimraf' ).sync; const CLIError = require( './cli-error' ); const { info } = require( './log' ); const prompts = require( './prompts' ); const predefinedPluginTemplates = { es5: { defaultValues: { slug: 'example-static-es5', title: 'Example Static (ES5)', description: 'Example block scaffolded with Create Block tool – no build step required.', dashicon: 'smiley', supports: { html: false, }, wpScripts: false, editorScript: null, editorStyle: null, style: null, viewStyle: null, viewScript: 'file:./view.js', example: {}, }, templatesPath: join( __dirname, 'templates', 'es5' ), variants: { static: {}, dynamic: { slug: 'example-dynamic-es5', title: 'Example Dynamic (ES5)', render: 'file:./render.php', }, }, }, standard: { defaultValues: { slug: 'example-static', title: 'Example Static', description: 'Example block scaffolded with Create Block tool.', dashicon: 'smiley', supports: { html: false, }, viewScript: 'file:./view.js', example: {}, folderName: './src/$slug', npmDependencies: [ '@wordpress/block-editor', '@wordpress/blocks', '@wordpress/i18n', ], }, variants: { static: {}, dynamic: { slug: 'example-dynamic', title: 'Example Dynamic', render: 'file:./render.php', }, }, }, }; const getOutputTemplates = async ( outputTemplatesPath ) => { const outputTemplatesFiles = await glob( '**/*.mustache', { cwd: outputTemplatesPath, dot: true, } ); return Object.fromEntries( await Promise.all( outputTemplatesFiles.map( async ( outputTemplateFile ) => { const outputFile = outputTemplateFile.replace( /\.mustache$/, '' ); const outputTemplate = await readFile( join( outputTemplatesPath, outputTemplateFile ), 'utf8' ); return [ outputFile, outputTemplate ]; } ) ) ); }; const getOutputAssets = async ( outputAssetsPath ) => { const outputAssetFiles = await glob( '**/*', { cwd: outputAssetsPath, dot: true, } ); return Object.fromEntries( await Promise.all( outputAssetFiles.map( async ( outputAssetFile ) => { const outputAsset = await readFile( join( outputAssetsPath, outputAssetFile ) ); return [ outputAssetFile, outputAsset ]; } ) ) ); }; const externalTemplateExists = async ( templateName ) => { try { await command( `npm view ${ templateName }` ); } catch { return false; } return true; }; const configToTemplate = async ( { pluginTemplatesPath, blockTemplatesPath, assetsPath, defaultValues = {}, variants = {}, ...deprecated } ) => { if ( defaultValues === null || typeof defaultValues !== 'object' ) { throw new CLIError( 'Template found but invalid definition provided.' ); } if ( deprecated.templatesPath ) { pluginTemplatesPath = deprecated.templatesPath; defaultValues = { folderName: '.', editorScript: 'file:./build/index.js', editorStyle: 'file:./build/index.css', style: 'file:./build/style-index.css', ...defaultValues, }; } else { pluginTemplatesPath = pluginTemplatesPath || join( __dirname, 'templates', 'plugin' ); blockTemplatesPath = blockTemplatesPath || join( __dirname, 'templates', 'block' ); } // Process variant-specific template paths const variantTemplates = {}; for ( const [ variantName, variantConfig ] of Object.entries( variants ) ) { if ( ! variantConfig ) { continue; } const variantPluginTemplatesPath = variantConfig.pluginTemplatesPath; const variantBlockTemplatesPath = variantConfig.blockTemplatesPath; const variantAssetsPath = variantConfig.assetsPath; let pluginOutputTemplates = null; if ( variantPluginTemplatesPath === null ) { pluginOutputTemplates = {}; } else if ( variantPluginTemplatesPath ) { pluginOutputTemplates = await getOutputTemplates( variantPluginTemplatesPath ); } let blockOutputTemplates = null; if ( variantBlockTemplatesPath === null ) { blockOutputTemplates = {}; } else if ( variantBlockTemplatesPath ) { blockOutputTemplates = await getOutputTemplates( variantBlockTemplatesPath ); } let outputAssets = null; if ( variantAssetsPath === null ) { outputAssets = {}; } else if ( variantAssetsPath ) { outputAssets = await getOutputAssets( variantAssetsPath ); } variantTemplates[ variantName ] = { pluginOutputTemplates, blockOutputTemplates, outputAssets, }; } return { blockOutputTemplates: blockTemplatesPath ? await getOutputTemplates( blockTemplatesPath ) : {}, pluginOutputTemplates: await getOutputTemplates( pluginTemplatesPath ), outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {}, defaultValues, variants, variantTemplates, }; }; const getProjectTemplate = async ( templateName ) => { if ( predefinedPluginTemplates[ templateName ] ) { return await configToTemplate( predefinedPluginTemplates[ templateName ] ); } try { if ( existsSync( resolve( templateName ) ) ) { return await configToTemplate( require( resolve( templateName ) ) ); } return await configToTemplate( require( templateName ) ); } catch ( error ) { if ( error instanceof CLIError ) { throw error; } else if ( error.code !== 'MODULE_NOT_FOUND' ) { throw new CLIError( `Invalid block template loaded. Error: ${ error.message }` ); } } if ( ! ( await externalTemplateExists( templateName ) ) ) { throw new CLIError( `Invalid plugin template type name: "${ templateName }". Allowed values: ` + Object.keys( predefinedPluginTemplates ) .map( ( name ) => `"${ name }"` ) .join( ', ' ) + ', or an existing npm package name.' ); } let tempCwd; try { info( '' ); info( 'Downloading template files. It might take some time...' ); tempCwd = await mkdtemp( join( tmpdir(), 'wp-create-block-' ) ); await command( `npm install ${ templateName } --no-save`, { cwd: tempCwd, } ); const { name } = npmPackageArg( templateName ); return await configToTemplate( require( require.resolve( name, { paths: [ tempCwd ], } ) ) ); } catch ( error ) { if ( error instanceof CLIError ) { throw error; } else { throw new CLIError( `Invalid plugin template downloaded. Error: ${ error.message }` ); } } finally { if ( tempCwd ) { rimraf( tempCwd ); } } }; const getDefaultValues = ( projectTemplate, variant ) => { return { $schema: 'https://schemas.wp.org/trunk/block.json', apiVersion: 3, namespace: 'create-block', category: 'widgets', textdomain: '', author: 'The WordPress Contributors', license: 'GPL-2.0-or-later', licenseURI: 'https://www.gnu.org/licenses/gpl-2.0.html', version: '0.1.0', requiresAtLeast: '6.8', requiresPHP: '7.4', testedUpTo: '6.8', wpScripts: true, customScripts: {}, wpEnv: false, npmDependencies: [], folderName: './src', editorScript: 'file:./index.js', editorStyle: 'file:./index.css', style: 'file:./style-index.css', transformer: ( view ) => view, ...projectTemplate.defaultValues, ...projectTemplate.variants?.[ variant ], variantVars: getVariantVars( projectTemplate.variants, variant ), }; }; const runPrompts = async ( projectTemplate, promptNames, variant, optionsValues ) => { const defaultValues = getDefaultValues( projectTemplate, variant ); const result = {}; for ( const promptName of promptNames ) { if ( Object.keys( optionsValues ).includes( promptName ) ) { continue; } const { type, ...config } = prompts[ promptName ]; result[ promptName ] = await inquirer[ type ]( { ...config, default: defaultValues[ promptName ], } ); } return result; }; const getVariantVars = ( variants, variant ) => { const variantVars = {}; const variantNames = Object.keys( variants ); if ( variantNames.length === 0 ) { return variantVars; } const currentVariant = variant ?? variantNames[ 0 ]; for ( const variantName of variantNames ) { const key = variantName.charAt( 0 ).toUpperCase() + variantName.slice( 1 ); variantVars[ `is${ key }Variant` ] = currentVariant === variantName; } return variantVars; }; module.exports = { getDefaultValues, getProjectTemplate, runPrompts, getOutputTemplates, getOutputAssets, };