@atomicsmash/compiler 0.5.0 → 0.6.0

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.
@@ -0,0 +1,4 @@
1
+ import type { LoaderContext } from "webpack";
2
+ export declare function loader(this: LoaderContext<Record<string, never>>): Promise<void>;
3
+ export default loader;
4
+ //# sourceMappingURL=BlocksLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlocksLoader.d.ts","sourceRoot":"","sources":["../src/BlocksLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,wBAAsB,MAAM,CAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,iBAc1C;AAED,eAAe,MAAM,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { tsImport } from "tsx/esm/api";
2
+ export async function loader(
3
+ // inputSourceMap?: Record<string, unknown>,
4
+ ) {
5
+ const callback = this.async();
6
+ const blockJson = await tsImport(this.resourcePath, {
7
+ parentURL: import.meta.url,
8
+ onImport: (file) => {
9
+ this.addDependency(file.slice(7));
10
+ },
11
+ }).then((module) => module.blockJson);
12
+ callback(null, JSON.stringify(blockJson));
13
+ }
14
+ export default loader;
@@ -0,0 +1,8 @@
1
+ import type { Compiler, WebpackPluginInstance } from "webpack";
2
+ export declare class BlocksPlugin implements WebpackPluginInstance {
3
+ pluginName: string;
4
+ srcFolder: string;
5
+ constructor(srcFolder: string);
6
+ apply(compiler: Compiler): void;
7
+ }
8
+ //# sourceMappingURL=BlocksPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlocksPlugin.d.ts","sourceRoot":"","sources":["../src/BlocksPlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAS/D,qBAAa,YAAa,YAAW,qBAAqB;IACzD,UAAU,SAAkB;IAC5B,SAAS,EAAE,MAAM,CAAC;gBAEN,SAAS,EAAE,MAAM;IAI7B,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA4JxB"}
@@ -0,0 +1,102 @@
1
+ import { readFile, writeFile, unlink as deleteFile } from "node:fs/promises";
2
+ import { extname, resolve, relative, sep as pathSeparator } from "node:path";
3
+ import glob from "fast-glob";
4
+ import json2php from "json2php";
5
+ import { getBlockJsonScriptFields, getBlockJsonStyleFields } from "./utils.js";
6
+ const printer = json2php.make({ linebreak: "\n", indent: "\t" });
7
+ export class BlocksPlugin {
8
+ pluginName = "BlocksPlugin";
9
+ srcFolder;
10
+ constructor(srcFolder) {
11
+ this.srcFolder = srcFolder;
12
+ }
13
+ apply(compiler) {
14
+ const { webpack: { Compilation, sources }, } = compiler;
15
+ compiler.hooks.thisCompilation.tap(this.pluginName, (compilation) => {
16
+ compilation.hooks.processAssets.tapPromise({
17
+ name: "CustomBlocksCSSHandler",
18
+ stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
19
+ }, async (assets) => {
20
+ const blockJsonFiles = Object.keys(assets).filter((asset) => asset.endsWith("block.json"));
21
+ const PHPFiles = await glob([
22
+ ...blockJsonFiles.map((blockJsonPath) => {
23
+ return `${resolve(`${this.srcFolder}${pathSeparator}${blockJsonPath}`, "..", `**${pathSeparator}*.php`)}`;
24
+ }),
25
+ ]);
26
+ await Promise.all(PHPFiles.map(async (file) => {
27
+ return readFile(file, "utf-8").then((data) => {
28
+ compilation.emitAsset(relative(this.srcFolder, file), new sources.RawSource(data), {
29
+ sourceFilename: file,
30
+ });
31
+ });
32
+ }));
33
+ });
34
+ });
35
+ compiler.hooks.afterEmit.tapPromise(this.pluginName, async (compilation) => {
36
+ const blockJsonFiles = Object.keys(compilation.assets).filter((asset) => asset.endsWith("block.json"));
37
+ const blocksManifest = {};
38
+ const wordpressAssetsFilePath = `${compilation.outputOptions.path}${pathSeparator}wordpress-assets-info.json`;
39
+ const wordpressAssets = await readFile(wordpressAssetsFilePath, "utf-8").then((data) => {
40
+ return JSON.parse(data);
41
+ });
42
+ for (const blockJsonFile of blockJsonFiles) {
43
+ await readFile(`${compilation.outputOptions.path}${pathSeparator}${blockJsonFile}`, "utf-8")
44
+ .then((data) => {
45
+ return JSON.parse(data);
46
+ })
47
+ .then(async (json) => {
48
+ const blockName = blockJsonFile.replace(`${pathSeparator}block.json`, "");
49
+ for (const fields of [
50
+ getBlockJsonScriptFields(json),
51
+ getBlockJsonStyleFields(json),
52
+ ]) {
53
+ if (fields === null) {
54
+ continue;
55
+ }
56
+ for (const [fieldName, value] of Object.entries(fields)) {
57
+ const values = [value].flat(1);
58
+ const newValues = [];
59
+ for (const srcFilePath of values) {
60
+ if (!srcFilePath.startsWith("file:")) {
61
+ newValues.push(srcFilePath);
62
+ continue;
63
+ }
64
+ const fileName = srcFilePath
65
+ .replace("file:./", "")
66
+ .replace(extname(srcFilePath), "");
67
+ const hashedAsset = Object.keys(compilation.assets).find((asset) => {
68
+ return (asset.startsWith(`${blockName}${pathSeparator}${fileName}`) && !asset.endsWith(".php"));
69
+ });
70
+ if (hashedAsset) {
71
+ if (hashedAsset in wordpressAssets) {
72
+ await writeFile(`${compilation.outputOptions.path}${pathSeparator}${hashedAsset.replace(extname(hashedAsset), ".asset.php")}`, `<?php return ${printer(wordpressAssets[hashedAsset])};\n`, "utf-8");
73
+ }
74
+ newValues.push(`file:./${hashedAsset.replace(`${blockName}${pathSeparator}`, "")}`);
75
+ }
76
+ else {
77
+ newValues.push(srcFilePath);
78
+ }
79
+ }
80
+ json[fieldName] = newValues;
81
+ }
82
+ }
83
+ return {
84
+ blockName,
85
+ newBlockJson: json,
86
+ };
87
+ })
88
+ .then(async ({ blockName, newBlockJson }) => {
89
+ await writeFile(`${compilation.outputOptions.path}${pathSeparator}${blockJsonFile}`, JSON.stringify(newBlockJson, undefined, 2), "utf-8");
90
+ blocksManifest[blockName] = newBlockJson;
91
+ });
92
+ }
93
+ const phpContent = `<?php
94
+ // This file is generated. Do not modify it manually.
95
+ return ${printer(blocksManifest)};
96
+ `;
97
+ await writeFile(`${compilation.outputOptions.path}${pathSeparator}blocks${pathSeparator}blocks-manifest.php`, phpContent);
98
+ await writeFile(`${compilation.outputOptions.path}${pathSeparator}wordpress-assets-info.php`, `<?php return ${json2php(wordpressAssets)};\n`);
99
+ await deleteFile(wordpressAssetsFilePath);
100
+ });
101
+ }
102
+ }
@@ -0,0 +1,6 @@
1
+ import type { EntryObject } from "webpack";
2
+ export declare function getBlocksAssetsEntryPoints(paths: string[], entryPoints: EntryObject, srcFolder: string): Promise<{
3
+ restOfPaths: string[];
4
+ entryPoints: EntryObject;
5
+ }>;
6
+ //# sourceMappingURL=getBlocksAssetsEntryPoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBlocksAssetsEntryPoints.d.ts","sourceRoot":"","sources":["../src/getBlocksAssetsEntryPoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAK3C,wBAAsB,0BAA0B,CAC/C,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM;;;GAkDjB"}
@@ -0,0 +1,50 @@
1
+ import { relative, resolve, extname } from "node:path";
2
+ import { tsImport } from "tsx/esm/api";
3
+ import { getBlockJsonStyleFields, getBlockJsonScriptFields } from "./utils.js";
4
+ export async function getBlocksAssetsEntryPoints(paths, entryPoints, srcFolder) {
5
+ const restOfPaths = [];
6
+ for (const path of paths) {
7
+ if (!path.endsWith("block.json.ts")) {
8
+ restOfPaths.push(path);
9
+ continue;
10
+ }
11
+ const blockJson = await tsImport(path, import.meta.url).then((module) => module.blockJson);
12
+ const fields = {
13
+ ...getBlockJsonScriptFields(blockJson),
14
+ ...getBlockJsonStyleFields(blockJson),
15
+ };
16
+ if (fields) {
17
+ for (const value of Object.values(fields).flat()) {
18
+ if (!value.startsWith("file:")) {
19
+ continue;
20
+ }
21
+ const fileLocation = resolve(path, "../", value.slice(5));
22
+ const entryName = relative(srcFolder, fileLocation);
23
+ const type = extname(fileLocation);
24
+ let fileName = entryName;
25
+ switch (type) {
26
+ case ".ts":
27
+ fileName = fileName.replace(".ts", ".[contenthash].js");
28
+ break;
29
+ case ".tsx":
30
+ fileName = fileName.replace(".tsx", ".[contenthash].js");
31
+ break;
32
+ case ".js":
33
+ fileName = fileName.replace(".js", ".[contenthash].js");
34
+ break;
35
+ case ".css":
36
+ fileName = fileName.replace(".css", ".[contenthash].css");
37
+ break;
38
+ case ".scss":
39
+ fileName = fileName.replace(".scss", ".[contenthash].css");
40
+ break;
41
+ }
42
+ entryPoints[entryName] = {
43
+ import: resolve(path, "../", value.slice(5)),
44
+ filename: fileName,
45
+ };
46
+ }
47
+ }
48
+ }
49
+ return { restOfPaths, entryPoints };
50
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsBA,OAAO,CAAC,MAAM,CAAC;IAEd,UAAU,MAAM,CAAC;QAEhB,UAAU,UAAU;YACnB,QAAQ,EAAE,YAAY,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;SAC5D;KACD;CACD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAyBA,OAAO,CAAC,MAAM,CAAC;IAEd,UAAU,MAAM,CAAC;QAEhB,UAAU,UAAU;YACnB,QAAQ,EAAE,YAAY,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;SAC5D;KACD;CACD"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { sep as pathSeparator, extname, resolve as resolvePath, } from "node:path";
2
+ import { sep as pathSeparator, extname, resolve as resolvePath, relative, } from "node:path";
3
3
  import DependencyExtractionWebpackPlugin from "@wordpress/dependency-extraction-webpack-plugin";
4
4
  import browserslistToEsbuild from "browserslist-to-esbuild";
5
5
  import CopyPlugin from "copy-webpack-plugin";
@@ -14,6 +14,8 @@ import WebpackAssetsManifest from "webpack-assets-manifest";
14
14
  import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
15
15
  import yargs from "yargs";
16
16
  import { hideBin } from "yargs/helpers";
17
+ import { BlocksPlugin } from "./BlocksPlugin.js";
18
+ import { getBlocksAssetsEntryPoints } from "./getBlocksAssetsEntryPoints.js";
17
19
  const argv = await yargs(hideBin(process.argv))
18
20
  .options({
19
21
  in: {
@@ -36,6 +38,16 @@ const argv = await yargs(hideBin(process.argv))
36
38
  default: false,
37
39
  describe: "See a report of the generated bundle once built.",
38
40
  },
41
+ experimentalBlocksSupport: {
42
+ boolean: true,
43
+ default: false,
44
+ describe: "Enable experimental support for WordPress blocks compilation.",
45
+ },
46
+ excludeBlocks: {
47
+ array: true,
48
+ default: ["__TEMPLATE__"],
49
+ describe: "A comma separated list of the folder names of blocks to exclude from compilation. Requires experimental blocks support.",
50
+ },
39
51
  })
40
52
  .showHelpOnFail(false, "Specify --help for available options")
41
53
  .parse();
@@ -64,10 +76,13 @@ const vueConfig = await import("vue-loader")
64
76
  .catch(() => ({ loader: [], plugin: [] }));
65
77
  const postCSSConfig = [
66
78
  [
79
+ // Support tailwind if package is found
67
80
  ...tailwindPostCSSPlugin,
68
81
  postCSSPresetEnv({
82
+ // Support all CSS that is considered stable.
69
83
  stage: 2,
70
84
  features: {
85
+ // Polyfill support for custom media queries
71
86
  "custom-media-queries": true,
72
87
  },
73
88
  }),
@@ -77,64 +92,115 @@ const postCSSConfig = [
77
92
  const compiler = webpack({
78
93
  resolveLoader: {
79
94
  modules: [
95
+ // Get modules from project node_modules folder
80
96
  "node_modules",
97
+ // Get modules from this package's internal node modules folder once installed
81
98
  resolvePath(import.meta.dirname, "../", "node_modules"),
82
99
  ],
83
100
  },
101
+ // Add sourcemaps in dev mode
84
102
  devtool: MODE === "development" ? "source-map" : false,
103
+ // Set the environment mode from NODE_ENV.
85
104
  mode: MODE,
86
105
  entry: await glob([
106
+ ...(argv.experimentalBlocksSupport
107
+ ? [`${srcFolder}/blocks/**/block.json.ts`]
108
+ : []),
109
+ // Parse all direct children of the JS folder, as long as they are JS & TS files
87
110
  `${srcFolder}/js/*.{js,ts,jsx,tsx}`,
111
+ // Parse all direct children of the CSS folder, as long as they are CSS files
88
112
  `${srcFolder}/css/*.css`,
113
+ // Parse all nested children of the CSS folder, as long as they are non-partial SCSS files
89
114
  `${srcFolder}/css/**/[^_]*.s[ac]ss`,
90
- ]).then((paths) => {
91
- const entryPoints = {};
92
- paths.forEach((path) => {
93
- const entryName = path.replace(srcFolder, "").replace(extname(path), "");
115
+ ], {
116
+ ignore: argv.experimentalBlocksSupport
117
+ ? argv.excludeBlocks.map((blockName) => `${srcFolder}/blocks/**/${blockName}/block.json.ts`)
118
+ : [],
119
+ }).then(async (paths) => {
120
+ const { restOfPaths, entryPoints } = argv.experimentalBlocksSupport
121
+ ? await getBlocksAssetsEntryPoints(paths, {}, srcFolder)
122
+ : { restOfPaths: paths, entryPoints: {} };
123
+ restOfPaths.forEach((path) => {
124
+ const entryName = path.replace(srcFolder, "");
94
125
  entryPoints[entryName] = {
95
126
  import: path,
127
+ // Output filenames with content hash for fingerprinting
96
128
  filename: `${path.replace(`${srcFolder}${pathSeparator}`, "").replace(extname(path), "")}${MODE === "production" ? `.[contenthash]` : ""}.js`,
97
129
  };
98
130
  });
99
131
  return entryPoints;
100
132
  }),
101
133
  output: {
134
+ // Output filenames with content hash for fingerprinting
102
135
  filename: "js/[name].[contenthash].js",
136
+ // Clear files between runs
103
137
  clean: true,
104
138
  library: {
139
+ // Output JS files with Universal Module Definition
105
140
  type: "umd",
106
141
  },
142
+ // Set the output folder
107
143
  path: distFolder,
108
144
  },
109
145
  resolve: {
110
- plugins: [new TsconfigPathsPlugin()],
146
+ // support TSConfig paths as aliases
147
+ plugins: [
148
+ new TsconfigPathsPlugin({
149
+ configFile: process.cwd() + "/tsconfig.json",
150
+ }),
151
+ ],
152
+ // resolve TS extensions
111
153
  extensions: [".tsx", ".ts", ".js", ".jsx"],
112
154
  },
113
155
  module: {
114
156
  rules: [
157
+ // Support Vue files if vue-loader is present
115
158
  ...vueConfig.loader,
159
+ // Use ESBuild loader to transpile JS & TS files
116
160
  {
117
161
  test: /\.[jt]sx?$/,
118
162
  use: {
119
163
  loader: "esbuild-loader",
120
164
  options: {
165
+ // Set target to match the browserslist config
121
166
  target: browserslistToEsbuild(),
167
+ tsconfig: process.cwd() + "/tsconfig.json",
122
168
  },
123
169
  },
124
170
  exclude: (file) => {
171
+ // Exclude all block.json.ts files (handled by a separate loader).
172
+ if (argv.experimentalBlocksSupport && file.includes("block.json")) {
173
+ return true;
174
+ }
175
+ // Exclude node_modules files from transpilation unless they are vue files and the vue-loader is present
125
176
  if (vueConfig.loader.length > 0) {
126
177
  return file.includes("node_modules") && !file.includes(".vue.js");
127
178
  }
128
179
  return file.includes("node_modules");
129
180
  },
130
181
  },
182
+ ...(argv.experimentalBlocksSupport
183
+ ? [
184
+ {
185
+ test: /block\.json\.ts$/,
186
+ type: "asset/resource",
187
+ generator: {
188
+ filename: (pathData) => relative(srcFolder, pathData.filename ?? "").slice(0, -3),
189
+ },
190
+ use: {
191
+ loader: resolvePath(import.meta.dirname, "./BlocksLoader.js"),
192
+ },
193
+ },
194
+ ]
195
+ : []),
196
+ // Transpile SCSS files and run the result through postcss
131
197
  {
132
198
  test: /\.s[ac]ss$/i,
133
199
  exclude: /node_modules/,
134
200
  type: "asset/resource",
135
201
  generator: {
136
202
  binary: false,
137
- filename: "css/[name].[contenthash].css",
203
+ filename: (pathData) => relative(srcFolder, pathData.filename ?? "").replace(".scss", ".[contenthash].css"),
138
204
  },
139
205
  use: [
140
206
  {
@@ -154,13 +220,14 @@ const compiler = webpack({
154
220
  },
155
221
  ],
156
222
  },
223
+ // Run the css files through postcss
157
224
  {
158
225
  test: /\.css$/i,
159
226
  exclude: /node_modules/,
160
227
  type: "asset/resource",
161
228
  generator: {
162
229
  binary: false,
163
- filename: "css/[name].[contenthash].css",
230
+ filename: (pathData) => relative(srcFolder, pathData.filename ?? "").replace(".css", ".[contenthash].css"),
164
231
  },
165
232
  use: [
166
233
  {
@@ -177,25 +244,32 @@ const compiler = webpack({
177
244
  ],
178
245
  },
179
246
  plugins: [
247
+ // Output progress information when compiling
180
248
  new webpack.ProgressPlugin(),
249
+ // Generate a manifest file of assets to make it possible to target fingerprinted files
181
250
  new WebpackAssetsManifest({
182
251
  writeToDisk: true,
183
252
  output: `${distFolder}/assets-manifest.json`,
184
253
  customize(entry) {
254
+ if (entry.key === "assets.php" ||
255
+ entry.key === "wordpress-assets-info.php" ||
256
+ entry.key.startsWith("fonts") ||
257
+ entry.key.startsWith("images")) {
258
+ return false;
259
+ }
185
260
  if (entry.key === "spritemap.svg") {
186
261
  return { key: "icons/sprite.svg", value: entry.value };
187
262
  }
188
263
  if (entry.key.startsWith("/")) {
189
- return { key: entry.key.slice(1), value: entry.value };
264
+ entry.key = entry.key.slice(1);
190
265
  }
191
- if (entry.key === "assets.php" ||
192
- entry.key.startsWith("fonts") ||
193
- entry.key.startsWith("images")) {
194
- return false;
266
+ if (entry.key.endsWith(".js.js")) {
267
+ entry.key = entry.key.slice(0, -3);
195
268
  }
196
269
  return entry;
197
270
  },
198
271
  }),
272
+ // Create an SVG sprite from a folder of provided icons
199
273
  new SVGSpritemapPlugin(`${srcFolder}/icons/*.svg`, {
200
274
  output: {
201
275
  filename: "icons/sprite.[contenthash].svg",
@@ -207,28 +281,50 @@ const compiler = webpack({
207
281
  },
208
282
  },
209
283
  }),
284
+ // Copy fonts and images from the src folder to assets (available for backwards compatibility, not recommended)
210
285
  new CopyPlugin({
211
286
  patterns: [
212
287
  {
213
- from: `${srcFolder}/fonts`,
214
- to: "[path]fonts/[name][ext]",
288
+ from: "**/*",
289
+ context: resolvePath(srcFolder, "fonts"),
290
+ to({ context, absoluteFilename }) {
291
+ return `fonts/${relative(context, absoluteFilename ?? "")}`;
292
+ },
215
293
  noErrorOnMissing: true,
216
294
  },
217
295
  {
218
- from: `${srcFolder}/images`,
219
- to: "[path]images/[name][ext]",
296
+ from: "**/*",
297
+ context: resolvePath(srcFolder, "images"),
298
+ to({ context, absoluteFilename }) {
299
+ return `images/${relative(context, absoluteFilename ?? "")}`;
300
+ },
220
301
  noErrorOnMissing: true,
221
302
  },
222
303
  ],
223
304
  }),
305
+ // Output a bundle analysis if flag was provided
224
306
  ...(argv.analyse ? [new BundleAnalyzerPlugin({})] : []),
307
+ // Extract wordpress dependencies from js files and output a wordpress assets file for enqueues
225
308
  new DependencyExtractionWebpackPlugin({
226
309
  combineAssets: true,
310
+ // Blocks plugin converts this to php, but it must be output as json here.
311
+ ...(argv.experimentalBlocksSupport
312
+ ? {
313
+ outputFormat: "json",
314
+ combinedOutputFile: "wordpress-assets-info.json",
315
+ }
316
+ : {
317
+ outputFormat: "php",
318
+ combinedOutputFile: "wordpress-assets-info.php",
319
+ }),
227
320
  }),
321
+ // Support Vue files if vue-loader is present
228
322
  ...vueConfig.plugin,
323
+ ...(argv.experimentalBlocksSupport ? [new BlocksPlugin(srcFolder)] : []),
229
324
  ],
230
325
  optimization: {
231
326
  minimizer: [
327
+ // Minify JS files
232
328
  new EsbuildPlugin({
233
329
  target: browserslistToEsbuild(),
234
330
  }),
@@ -0,0 +1,5 @@
1
+ import type { BlockMetaData } from "@atomicsmash/blocks-helpers";
2
+ export type BlockJson = BlockMetaData<never, never>;
3
+ export declare function getBlockJsonScriptFields(blockJson: BlockJson): Partial<Pick<BlockJson, "viewScript" | "script" | "editorScript">> | null;
4
+ export declare function getBlockJsonStyleFields(blockJson: BlockJson): Partial<Pick<BlockJson, "editorStyle" | "style" | "viewStyle">> | null;
5
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEpD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,6EAW5D;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,0EAW3D"}
package/dist/utils.js ADDED
@@ -0,0 +1,22 @@
1
+ export function getBlockJsonScriptFields(blockJson) {
2
+ const scriptFields = ["viewScript", "script", "editorScript"];
3
+ let result = null;
4
+ for (const field of scriptFields) {
5
+ if (Object.hasOwn(blockJson, field)) {
6
+ result ??= {};
7
+ result[field] = blockJson[field];
8
+ }
9
+ }
10
+ return result;
11
+ }
12
+ export function getBlockJsonStyleFields(blockJson) {
13
+ const styleFields = ["viewStyle", "style", "editorStyle"];
14
+ let result = null;
15
+ for (const field of styleFields) {
16
+ if (Object.hasOwn(blockJson, field)) {
17
+ result ??= {};
18
+ result[field] = blockJson[field];
19
+ }
20
+ }
21
+ return result;
22
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atomicsmash/compiler",
3
3
  "type": "module",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "description": "A universal compiler for all Atomic Smash projects.",
6
6
  "keywords": [
7
7
  "cli",
@@ -51,14 +51,16 @@
51
51
  "cssnano": "^7.0.6",
52
52
  "esbuild-loader": "^4.3.0",
53
53
  "fast-glob": "^3.3.2",
54
+ "json2php": "^0.0.12",
54
55
  "postcss": "^8.4.49",
55
56
  "postcss-loader": "^8.1.1",
56
- "postcss-preset-env": "^10.1.3",
57
+ "postcss-preset-env": "^10.1.5",
57
58
  "sass": "^1.83.1",
58
59
  "sass-loader": "^16.0.4",
59
60
  "style-loader": "^4.0.0",
60
61
  "svg-spritemap-webpack-plugin": "^4.7.0",
61
62
  "tsconfig-paths-webpack-plugin": "^4.2.0",
63
+ "tsx": "^4.19.3",
62
64
  "webpack": "^5.97.1",
63
65
  "webpack-assets-manifest": "^5.2.1",
64
66
  "webpack-bundle-analyzer": "^4.10.2",