@wix/origami-transforms 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,6 +3,22 @@ export function createTransformPipeline({ layout, jsxPlugins, cssPlugins }: {
|
|
|
3
3
|
jsxPlugins?: readonly import("./types.js").JsxTransformPlugin[];
|
|
4
4
|
cssPlugins?: readonly import("./types.js").CssTransformPlugin[];
|
|
5
5
|
}): {
|
|
6
|
+
/** Whether any JSX transform selects this module (structure.jsx/.tsx by default).
|
|
7
|
+
* @param {string} id
|
|
8
|
+
* @param {{ ssr?: boolean | undefined }} [contextOptions] */
|
|
9
|
+
appliesTo: (id: string, { ssr }?: {
|
|
10
|
+
ssr?: boolean | undefined;
|
|
11
|
+
}) => boolean;
|
|
12
|
+
/** Run the shared checks with JSX and TypeScript preserved for the adapter's compiler.
|
|
13
|
+
* @param {string} code
|
|
14
|
+
* @param {string} id
|
|
15
|
+
* @param {{ ssr?: boolean | undefined }} [contextOptions] */
|
|
16
|
+
transformJsx: (code: string, id: string, { ssr }?: {
|
|
17
|
+
ssr?: boolean | undefined;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
code: any;
|
|
20
|
+
map: any;
|
|
21
|
+
}>;
|
|
6
22
|
postcssPlugin: {
|
|
7
23
|
postcssPlugin: string;
|
|
8
24
|
Once(root: any, { result }: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/origami-transforms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Babel and PostCSS checks and transforms for Wix origami page files.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@babel/core": "^7.26.0",
|
|
18
|
-
"@wix/origami-fonts": "1.0.
|
|
18
|
+
"@wix/origami-fonts": "1.0.1",
|
|
19
19
|
"@wix/origami-system-components": "1.7.0",
|
|
20
20
|
"postcss": "^8.5.3",
|
|
21
21
|
"postcss-custom-media": "^12.0.1"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
},
|
|
55
55
|
"type": "module",
|
|
56
56
|
"types": "./dist/index.d.ts",
|
|
57
|
-
"falconPackageHash": "
|
|
57
|
+
"falconPackageHash": "373242c70dd5b71460d9daba8068a88149f756889c2c74db1709e9b1"
|
|
58
58
|
}
|
package/src/cssPlugins/fonts.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
// Checks the theme's font tokens (`--wst-heading-1-font: normal normal 700 --spx(88)/1em benzin`)
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Checks the theme's font tokens (`--wst-heading-1-font: normal normal 700 --spx(88)/1em benzin`), then loads the
|
|
2
|
+
// fonts the stylesheet names.
|
|
3
|
+
//
|
|
4
|
+
// The check: the editor reads the family at the end of each token as one Wix font id and fails the import otherwise,
|
|
5
|
+
// so the build fails, with every such token listed, unless the family is exactly the id of a font in the Wix font
|
|
4
6
|
// catalog bundled in @wix/origami-fonts: no quotes, commas or fallbacks, the same case. A legacy font, which the
|
|
5
7
|
// editor no longer offers, counts as not in the catalog. `origami search-font` finds the right id.
|
|
8
|
+
//
|
|
9
|
+
// The loading: a family is only a name until a `@font-face` rule says where its files are. For every Wix font a
|
|
10
|
+
// font token, `font` or `font-family` declaration names, the `@font-face` rules a live Wix site writes for it are
|
|
11
|
+
// appended to the stylesheet. They point at Wix's CDN, so no font file is downloaded into the site or its build;
|
|
12
|
+
// the browser fetches only the files of the fonts, weights and scripts a page uses. A family with no font faces,
|
|
13
|
+
// like a system font, adds nothing. The rules exist only in the served CSS, never in the site's own files.
|
|
6
14
|
|
|
7
15
|
import { basename } from 'node:path'
|
|
8
|
-
import { fonts } from '@wix/origami-fonts'
|
|
16
|
+
import { fontFaceCss, fontFaces, fonts } from '@wix/origami-fonts'
|
|
17
|
+
import postcss from 'postcss'
|
|
9
18
|
import { LayoutError } from '../transform/layoutError.js'
|
|
10
19
|
|
|
11
20
|
const FONT_TOKEN = /^--wst-[\w-]+-font$/
|
|
21
|
+
const FONT_DECLARATION = /^(?:--wst-[\w-]+-font|font|font-family)$/
|
|
12
22
|
// The size in a `font` shorthand, with its optional line height: the family follows it. The number's quantifiers
|
|
13
23
|
// never overlap, so a long run of digits that is not a size fails in linear time.
|
|
14
24
|
const SIZE = /^(?:--spx\(.*\)|calc\(.*\)|(?:\d+(?:\.\d*)?|\.\d+)(?:px|em|rem|%|vw|vh|pt)?)(?:\/\S+)?$/i
|
|
@@ -42,6 +52,13 @@ const familyOf = value => {
|
|
|
42
52
|
return parts.slice(size + 1).join(' ')
|
|
43
53
|
}
|
|
44
54
|
|
|
55
|
+
/** The Wix font ids a declaration names, as the font faces key them: each name of its family list, lowercase. */
|
|
56
|
+
const fontIdsOf = declaration => {
|
|
57
|
+
const family = declaration.prop === 'font-family' ? declaration.value : familyOf(declaration.value)
|
|
58
|
+
if (family === undefined || /var\(/.test(family)) return []
|
|
59
|
+
return family.split(',').map(name => name.trim().replace(/^(['"])(.*)\1$/, '$2').toLowerCase())
|
|
60
|
+
}
|
|
61
|
+
|
|
45
62
|
/** ` (theme.css:12)`: the carrier the declaration was written in, which the bundler doesn't name. */
|
|
46
63
|
const where = declaration => {
|
|
47
64
|
const file = declaration.source?.input.file
|
|
@@ -67,9 +84,9 @@ const locationOf = source => {
|
|
|
67
84
|
/** @type {import('../transform/types.js').CssTransformPlugin} */
|
|
68
85
|
export const fontsPlugin = {
|
|
69
86
|
name: 'fonts',
|
|
70
|
-
//
|
|
87
|
+
// Reads the declarations as authored, before spx rewrites the sizes the family follows.
|
|
71
88
|
order: 5,
|
|
72
|
-
|
|
89
|
+
validate(root) {
|
|
73
90
|
/** @type {import('postcss').Declaration[]} */
|
|
74
91
|
const declarations = []
|
|
75
92
|
root.walkDecls(FONT_TOKEN, declaration => {
|
|
@@ -90,4 +107,12 @@ export const fontsPlugin = {
|
|
|
90
107
|
throw new LayoutError(violations, locationOf(first))
|
|
91
108
|
}
|
|
92
109
|
},
|
|
110
|
+
transform(root) {
|
|
111
|
+
const ids = new Set()
|
|
112
|
+
root.walkDecls(FONT_DECLARATION, declaration => {
|
|
113
|
+
for (const id of fontIdsOf(declaration)) ids.add(id)
|
|
114
|
+
})
|
|
115
|
+
const css = fontFaceCss(fontFaces, ids)
|
|
116
|
+
if (css) root.append(postcss.parse(css).nodes)
|
|
117
|
+
},
|
|
93
118
|
}
|
package/src/cssPlugins/index.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
// layout routes declarations to wrappers and SPX converts calls using the browser's active settings. stack-children
|
|
9
9
|
// only checks, and runs between mixins and layout: it needs the mixins' declarations and the stack rules as authored,
|
|
10
10
|
// before layout compiles them away. presets runs after mixins too, so a `--preset` a mixin body carries is moved
|
|
11
|
-
// like an authored one. fonts
|
|
11
|
+
// like an authored one. fonts checks the theme's font tokens, as authored, and appends the `@font-face` rules that
|
|
12
|
+
// load the Wix fonts the stylesheet names from Wix's CDN.
|
|
12
13
|
//
|
|
13
14
|
// `@layer` needs no plugin: cascade layers have been in every browser since March 2022.
|
|
14
15
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Select and cache transform plugins by stage, file, and SSR context.
|
|
2
|
+
import { transformAsync } from '@babel/core'
|
|
2
3
|
import { cssPlugins as defaultCssPlugins } from '../cssPlugins/index.js'
|
|
3
4
|
import { jsxPlugins as defaultJsxPlugins } from '../jsxPlugins/index.js'
|
|
4
5
|
import { createContextFactory } from './context.js'
|
|
@@ -45,9 +46,41 @@ export const createTransformPipeline = ({ layout, jsxPlugins = defaultJsxPlugins
|
|
|
45
46
|
/** @type {Map<string, Set<string>>} stylesheet whose last CSS run failed -> the files it declared */
|
|
46
47
|
const cssFailures = new Map()
|
|
47
48
|
|
|
49
|
+
const babelOptionsFor = createBabelOptionsSelector({ contextFor, selectPlugins: selectFor('jsx') })
|
|
50
|
+
|
|
48
51
|
return {
|
|
52
|
+
/** Whether any JSX transform selects this module (structure.jsx/.tsx by default).
|
|
53
|
+
* @param {string} id
|
|
54
|
+
* @param {{ ssr?: boolean | undefined }} [contextOptions] */
|
|
55
|
+
appliesTo: (id, { ssr = false } = {}) => selectFor('jsx')(contextFor(id, { ssr })).length > 0,
|
|
56
|
+
|
|
57
|
+
/** Run the shared checks with JSX and TypeScript preserved for the adapter's compiler.
|
|
58
|
+
* @param {string} code
|
|
59
|
+
* @param {string} id
|
|
60
|
+
* @param {{ ssr?: boolean | undefined }} [contextOptions] */
|
|
61
|
+
transformJsx: async (code, id, { ssr = false } = {}) => {
|
|
62
|
+
const filename = id.split('?', 1)[0]
|
|
63
|
+
const options = babelOptionsFor(id, { ssr })
|
|
64
|
+
const result = await transformAsync(code, {
|
|
65
|
+
...options,
|
|
66
|
+
filename,
|
|
67
|
+
babelrc: false,
|
|
68
|
+
configFile: false,
|
|
69
|
+
sourceMaps: true,
|
|
70
|
+
parserOpts: {
|
|
71
|
+
...options.parserOpts,
|
|
72
|
+
plugins: [...new Set([
|
|
73
|
+
'jsx',
|
|
74
|
+
...(filename.endsWith('.tsx') ? ['typescript'] : []),
|
|
75
|
+
...(options.parserOpts?.plugins ?? []),
|
|
76
|
+
])],
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
return { code: result.code, map: result.map }
|
|
80
|
+
},
|
|
81
|
+
|
|
49
82
|
postcssPlugin: createCssPostcssPlugin({ contextFor, selectPlugins: selectFor('css'), failures: cssFailures }),
|
|
50
|
-
babelOptionsFor
|
|
83
|
+
babelOptionsFor,
|
|
51
84
|
|
|
52
85
|
/** Whether a stylesheet whose last CSS run failed declared `file`, so an edit to it may fix the stylesheet. */
|
|
53
86
|
failedStylesheetDependsOn: file => [...cssFailures.values()].some(files => files.has(file)),
|