Skip to content

Commit

Permalink
fix: theme.json generator (#1240)
Browse files Browse the repository at this point in the history
  • Loading branch information
kellymears committed Mar 16, 2022
1 parent d265e44 commit 7479051
Show file tree
Hide file tree
Showing 18 changed files with 167 additions and 86 deletions.
4 changes: 2 additions & 2 deletions sources/@roots/bud-esbuild/src/features/esbuild-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export const tsFeature: Extension.Module = {
options: async ({path}) => ({
loader: 'tsx',
target: 'es2015',
tsconfigRaw: (await pathExists(path('@project', 'tsconfig.json')))
? await readJson(path('@project', 'tsconfig.json'))
tsconfigRaw: (await pathExists(path('tsconfig.json')))
? await readJson(path('tsconfig.json'))
: {
compilerOptions: {
importsNotUsedAsValues: 'remove',
Expand Down
6 changes: 3 additions & 3 deletions sources/@roots/bud-eslint/src/eslint.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export interface options {

export const options: options = ({path}) => ({
extensions: ['js', 'jsx', 'ts', 'tsx', 'vue'],
cacheLocation: path(`@storage/cache/eslint.json`),
cacheLocation: path('@storage/cache/eslint.json'),
cacheStrategy: 'content',
cwd: path('@project'),
cwd: path(),
eslintPath: require.resolve('eslint'),
resolvePluginsRelativeTo: path('@project'),
resolvePluginsRelativeTo: path(),
threads: cpus.length / 2,
})
22 changes: 12 additions & 10 deletions sources/@roots/bud-framework/src/Framework/methods/make.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,25 @@ export async function make(
name: string,
tap?: (app: Framework) => any,
): Promise<Framework> {
this as Framework
const app = this as Framework

handleChildNestingError.bind(this)()
this.logger.instance.fav(`new instance:`, name)
handleChildNestingError.bind(app)()
app.logger.instance.fav(`new instance:`, name)

const instance = new this.implementation({
childOf: this,
config: {...this.options.config, name},
context: this.context,
services: this.options.services,
const instance = new app.implementation({
name,
mode: app.mode,
childOf: app,
config: {...app.options.config, name},
context: app.context,
services: app.options.services,
})

await instance.lifecycle()

if (tap) await tap(instance)

this.children?.set(name, instance)
app.children?.set(name, instance)

return this
return app
}
66 changes: 53 additions & 13 deletions sources/@roots/bud-framework/src/Framework/methods/path.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,70 @@
import {join} from 'path'
import {join, resolve, sep as slash} from 'node:path'

import {Framework} from '../..'

export interface path {
(base?: string, ...segments: Array<string>): string
}

/**
* Transform `@alias` path
*
* @param app - Framework instance
* @param base - Path segment
* @returns string
*
* @public
*/
const transformShorthandBase = (app: Framework, base: string): string => {
const parts = base.includes('/') ? base.split('/') : [base]
parts[0] = app.hooks.filter(`location.${parts[0]}`)
return parts.join('/')
/**
* If path contains multiple segments, explode into an array
* If path contains one segment, insert it into a blank array
*/
const [ident, ...parts] = base.includes(slash)
? base.split(slash)
: [base]

!app.hooks.has(`location.${ident}`) &&
app.error(
`\`${ident}\` is not a registered path. It must be defined with bud.setPath`,
)

/**
* Replace
*/
const value = app.hooks.filter(`location.${ident}`)

return join(value, ...(parts ?? []).filter(Boolean))
}

export const path: path = function (
base?: string,
...segments: Array<string>
): string {
const ctx = this as Framework
const app = this as Framework
/**
* If no base path was provided return the project directory
*/
if (!base) return app.context.projectDir

/**
* If base path starts with `/` return the joined path and segments (if any)
*/
if (base.startsWith('/'))
return segments.length ? join(base, ...segments) : base

/**
* Replace any `@alias` aliases with their corresponding entry
*/
const normalized = base.startsWith(`@`)
? transformShorthandBase(app, base)
: base

if (!base || base.startsWith(`/`)) return ctx.context.projectDir
const absolutePath = base.startsWith(`/`)
? normalized
: resolve(app.context.projectDir, normalized)

return join(
ctx.context.projectDir,
...[
base.startsWith(`@`) ? transformShorthandBase(ctx, base) : base,
...(segments ?? []),
].filter(Boolean),
)
return segments.length
? resolve(absolutePath, ...(segments ?? []).filter(Boolean))
: absolutePath
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@ const {isString} = lodash
* @internal
*/
export interface setPath {
<
T extends `${Omit<
'@project',
`${keyof Framework.Locations & string}`
> &
string}`,
>(
<T extends `${keyof Framework.Locations & string}`>(
arg1: T | Record<T, string>,
arg2?: string,
): Framework.Framework
Expand Down
4 changes: 0 additions & 4 deletions sources/@roots/bud-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@
"@babel/plugin-syntax-jsx": "^7.16.0",
"@babel/preset-react": "^7.16.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.4",
"autobind-decorator": "2.4.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-hot-loader": "^4.13.0",
Expand Down
1 change: 0 additions & 1 deletion sources/@roots/bud/src/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ export const seed: Partial<Store.Repository> = {
[`build.parallelism`]: app => Math.max(cpus().length - 1, 1),
[`build.performance`]: app => ({hints: false}),
[`build.resolve.alias`]: app => ({
'@project': app.path(),
'@src': app.path('@src'),
'@dist': app.path('@dist'),
}),
Expand Down
3 changes: 0 additions & 3 deletions sources/@roots/sage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
".": "./lib/cjs/index.js",
"./client": "./lib/cjs/client/index.js",
"./client/dom-ready": "./lib/cjs/client/domReady.js",
"./eslint-config": "./eslint-config/index.js",
"./stylelint-config": "./stylelint-config/index.js",
"./theme/tailwind": "./lib/cjs/theme/tailwind.adapter.js",
"./tsconfig": "./tsconfig/tsconfig.json"
Expand All @@ -60,14 +59,12 @@
"@roots/bud-api": "workspace:sources/@roots/bud-api",
"@roots/bud-framework": "workspace:sources/@roots/bud-framework",
"@skypack/package-check": "0.2.2",
"@types/lodash": "4.14.179",
"@types/node": "16.11.26",
"webpack": "5.68.0"
},
"dependencies": {
"@roots/bud-preset-wordpress": "workspace:sources/@roots/bud-preset-wordpress",
"@roots/bud-support": "workspace:sources/@roots/bud-support",
"helpful-decorators": "^2.1.0",
"tslib": "^2.3.1"
}
}
27 changes: 17 additions & 10 deletions sources/@roots/sage/src/theme/api/themeJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,32 @@ export interface facade {
(input?: Mutator | WPThemeJson['settings'], raw?: boolean): Framework
}

const getContainerOptions = (app: Framework) =>
app.extensions.get('wp-theme-json').options

const getRawOptions = (app: Framework) =>
app.extensions.get('wp-theme-json').options.all()

export const method: method = async function (
input?: Mutator | WPThemeJson['settings'],
raw?: boolean,
) {
const ctx = this as Framework
const app = this as Framework

if (!app.extensions.has('wp-theme-json')) return

ctx.extensions.get('wp-theme-json').set('when', true)
app.extensions.get('wp-theme-json').set('when', true)

if (!input) return ctx
if (!input) return app

isFunction(input)
? ctx.extensions
? app.extensions
.get('wp-theme-json')
.setOptions(
raw === true
? input(ctx.extensions.get('wp-theme-json').options.all())
: input(ctx.extensions.get('wp-theme-json').options),
.setOption(
'settings',
raw === true ? getRawOptions(app) : getContainerOptions(app),
)
: ctx.extensions.get('wp-theme-json').setOptions(input)
: app.extensions.get('wp-theme-json').setOption('settings', input)

return ctx
return app
}
2 changes: 1 addition & 1 deletion sources/@roots/sage/src/theme/api/useTailwindColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const method: method = async function () {

ctx.extensions
.get('wp-theme-json')
.setOption('color.palette', transformPalette(palette))
.setOption('settings.color.palette', transformPalette(palette))

return ctx
}
12 changes: 9 additions & 3 deletions sources/@roots/sage/src/theme/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as useTailwindColors from './api/useTailwindColors'
import {Options, ThemeJsonWebpackPlugin} from './plugin'

/**
* Extension for managing WordPress `theme.json` values
* Extension for managing WordPress `theme.json`
*
* @public
*/
Expand All @@ -15,6 +15,7 @@ export interface ThemeExtension
Options
> {
name: 'wp-theme-json'
options: (app: Framework.Framework) => Options
api: {
themeJson: themeJson.method
useTailwindColors: useTailwindColors.method
Expand All @@ -35,7 +36,7 @@ export const name: ThemeExtension['name'] = 'wp-theme-json'
*/
export const options: ThemeExtension['options'] = app => ({
path: app.path('theme.json'),
json: {
settings: {
color: {
custom: false,
customGradient: false,
Expand Down Expand Up @@ -73,7 +74,12 @@ export const api: ThemeExtension['api'] = {
export const make: ThemeExtension['make'] = options =>
new ThemeJsonWebpackPlugin({
path: options.get('path'),
json: options.get('json'),
settings: options.get('settings'),
})

/**
* Extension when
*
* @public
*/
export const when: ThemeExtension['when'] = false
75 changes: 66 additions & 9 deletions sources/@roots/sage/src/theme/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ThemeJSON} from '@roots/bud-preset-wordpress'
import {fs} from '@roots/bud-support'
import {bind, fs} from '@roots/bud-support'
import {Compiler, WebpackPluginInstance} from 'webpack'

/**
Expand All @@ -11,7 +11,7 @@ export interface Options {
/**
* JSON contents
*/
json: ThemeJSON.JSONSchemaForWordPressBlockThemeGlobalSettingsAndStyles['settings']
settings: ThemeJSON.JSONSchemaForWordPressBlockThemeGlobalSettingsAndStyles['settings']

/**
* Emit path
Expand All @@ -21,17 +21,74 @@ export interface Options {

/**
* ThemeJSONWebpackPlugin
*
* @public
*/
export class ThemeJsonWebpackPlugin implements WebpackPluginInstance {
/**
* theme.json path
*
* @public
*/
public get path(): string {
return this.options.path
}

/**
* theme.json settings
*
* @public
*/
public get settings(): string {
return JSON.stringify(
{
__generated__: '⚠️ This file is generated. Do not edit.',
$schema: 'https://schemas.wp.org/trunk/theme.json',
version: 2,
settings: this.options.settings,
},
null,
2,
)
}

/**
* Class constructor
*
* @param options - Plugin options
*
* @public
*/
public constructor(public options: Options) {}

/**
* Apply plugin
*
* @param compiler - Webpack compiler
* @returns void
*
* @public
* @decorator `@bind`
*/
@bind
public apply(compiler: Compiler) {
compiler.hooks.done.tapPromise(this.constructor.name, async () => {
try {
await fs.writeFile(this.options.path, this.options.json, 'utf8')
} catch (err) {
throw new Error(err)
}
})
compiler.hooks.done.tapPromise(this.constructor.name, this.done)
}

/**
* Compiler done
*
* @returns Promise
*
* @public
* @decorator `@bind`
*/
@bind
public async done() {
try {
await fs.writeFile(this.path, this.settings, 'utf8')
} catch (err) {
throw new Error(err)
}
}
}
1 change: 0 additions & 1 deletion tests/unit/bud-api/repository/alias.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ describe('bud.alias', function () {
expect(alias).toEqual({
'@dist': bud.path('@dist'),
'@src': bud.path('@src'),
'@project': bud.path(),
'@foo': bud.path('bar'),
})
})
Expand Down
Loading

0 comments on commit 7479051

Please sign in to comment.