shopify-accelerate-app 1.0.26 → 1.0.28

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify-accelerate-app",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Shopify App development with full Typescript Support",
5
5
  "author": "Felix Tellmann",
6
6
  "license": "MIT",
@@ -91,7 +91,8 @@
91
91
  "import/no-anonymous-default-export": 0,
92
92
  "react/no-unescaped-entities": 0,
93
93
  "react/jsx-sort-props": 0,
94
- "node/no-unpublished-require": 0
94
+ "node/no-unpublished-require": 0,
95
+ "max-len": ["error", { "code": 140 }]
95
96
  }
96
97
  },
97
98
  "prettier": {
@@ -99,7 +100,7 @@
99
100
  "arrowParens": "always",
100
101
  "singleQuote": false,
101
102
  "bracketSpacing": true,
102
- "printWidth": 100,
103
+ "printWidth": 140,
103
104
  "indentChains": true,
104
105
  "exportCurlySpacing": true,
105
106
  "importCurlySpacing": true,
@@ -18,9 +18,7 @@ const program = new Command();
18
18
 
19
19
  const dotenv = dotenvLoad(); // Dotenv instance
20
20
 
21
- export const root_dir = process.env.SHOPIFY_ACCELERATE_ROOT
22
- ? path.join(process.cwd(), process.env.SHOPIFY_ACCELERATE_ROOT)
23
- : process.cwd();
21
+ export const root_dir = process.env.SHOPIFY_ACCELERATE_ROOT ? path.join(process.cwd(), process.env.SHOPIFY_ACCELERATE_ROOT) : process.cwd();
24
22
 
25
23
  const tomlFile = fs.existsSync(path.join(process.cwd(), "shopify.theme.toml"))
26
24
  ? toml.parse(
@@ -92,18 +90,9 @@ export type GlobalsState = {
92
90
  };
93
91
 
94
92
  export const config: GlobalsState = {
95
- ignore_blocks:
96
- shopify_toml?.environments?.["development"]?.ignore_blocks
97
- ?.split(",")
98
- .map((str) => str.trim()) ?? [],
99
- ignore_snippets:
100
- shopify_toml?.environments?.["development"]?.ignore_snippets
101
- ?.split(",")
102
- .map((str) => str.trim()) ?? [],
103
- ignore_assets:
104
- shopify_toml?.environments?.["development"]?.ignore_assets
105
- ?.split(",")
106
- .map((str) => str.trim()) ?? [],
93
+ ignore_blocks: shopify_toml?.environments?.["development"]?.ignore_blocks?.split(",").map((str) => str.trim()) ?? [],
94
+ ignore_snippets: shopify_toml?.environments?.["development"]?.ignore_snippets?.split(",").map((str) => str.trim()) ?? [],
95
+ ignore_assets: shopify_toml?.environments?.["development"]?.ignore_assets?.split(",").map((str) => str.trim()) ?? [],
107
96
  delete_external_snippets: process.env.SHOPIFY_ACCELERATE_DELETE_EXTERNAL_SNIPPETS === "true",
108
97
  delete_external_blocks: process.env.SHOPIFY_ACCELERATE_DELETE_EXTERNAL_BLOCKS === "true",
109
98
  delete_external_assets: process.env.SHOPIFY_ACCELERATE_DELETE_EXTERNAL_ASSETS === "true",
@@ -149,9 +138,7 @@ export const config: GlobalsState = {
149
138
  theme_output_path: process.env.SHOPIFY_ACCELERATE_THEME_OUTPUT_PATH ?? "/themes/development",
150
139
  };
151
140
 
152
- program
153
- .name("shopify-accelerate-app")
154
- .description("CLI for Accelerated App Theme Extensions development");
141
+ program.name("shopify-accelerate-app").description("CLI for Accelerated App Theme Extensions development");
155
142
  /*.version(require(path.join("./", "package.json")).version);*/
156
143
 
157
144
  /*
@@ -185,15 +172,9 @@ program
185
172
  "-s, --store <store_id>",
186
173
  "Shopify store id. I.e `https://admin.shopify.com/store/<store_id>` or `https://<store_id>.myshopify.com`"
187
174
  )
188
- .option(
189
- "-t, --theme <theme_id>",
190
- "Shopify store id. I.e. `https://admin.shopify.com/store/<store_id>/themes/<theme_id>/editor`"
191
- )
175
+ .option("-t, --theme <theme_id>", "Shopify store id. I.e. `https://admin.shopify.com/store/<store_id>/themes/<theme_id>/editor`")
192
176
  .action(async (options) => {
193
- writeOnlyNew(
194
- path.join(process.cwd(), ".env"),
195
- readFile(path.join(config.package_templates, "/.env.template"))
196
- );
177
+ writeOnlyNew(path.join(process.cwd(), ".env"), readFile(path.join(config.package_templates, "/.env.template")));
197
178
 
198
179
  buildAppExtension();
199
180
  runEsbuild();
@@ -13,12 +13,9 @@ const { build } = require("esbuild");
13
13
  const watch = require("node-watch");
14
14
  const fs = require("fs");
15
15
 
16
- export const transformClassNameStrings = (
17
- stringContent,
18
- final = false,
19
- cssOutput = "",
20
- special = false
21
- ) => {
16
+ export const notCSSClasses = new Map<string, string>();
17
+
18
+ export const transformClassNameStrings = (stringContent, final = false, cssOutput = "", special = false) => {
22
19
  const prefix = process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX;
23
20
 
24
21
  if (special) {
@@ -29,9 +26,7 @@ export const transformClassNameStrings = (
29
26
  return stringContent;
30
27
  }
31
28
  }
32
- const classNameString = special
33
- ? stringContent.split(" ")
34
- : stringContent.replace(/\s+/gi, " ").split(" ");
29
+ const classNameString = special ? stringContent.split(" ") : stringContent.replace(/\s+/gi, " ").split(" ");
35
30
 
36
31
  const prefixedClassNames = classNameString.map((className) => {
37
32
  if (!className.trim()) return className;
@@ -50,19 +45,12 @@ export const transformClassNameStrings = (
50
45
  if (
51
46
  final &&
52
47
  (str.startsWith(`${prefix}-`) || str.startsWith(`!${prefix}-`)) &&
53
- !cssOutput?.includes(str.replace(/([/.[\]])/gi, "\\$1"))
48
+ !cssOutput?.includes(str.replace(/([@()%,/.[\]])/gi, "\\$1"))
54
49
  ) {
55
- console.log(
56
- { className: str, b: str.replace(/([/.[\]])/gi, "\\$1") },
57
- str?.includes(str.replace(/([/.[\]])/gi, "\\$1"))
58
- );
50
+ notCSSClasses.set(str, str.replace(/([@()%,/.[\]])/gi, "\\$1"));
59
51
  return str.replace(`${prefix}-`, "").replace(`!${prefix}-`, "");
60
52
  }
61
- if (
62
- index === arr.length - 1 &&
63
- !str.startsWith(`${prefix}-`) &&
64
- !str.startsWith(`!${prefix}-`)
65
- ) {
53
+ if (index === arr.length - 1 && !str.startsWith(`${prefix}-`) && !str.startsWith(`!${prefix}-`)) {
66
54
  if (/^!/gi.test(str)) {
67
55
  return `!${prefix}-${str.replace(/^!/gi, "")}`;
68
56
  }
@@ -75,15 +63,10 @@ export const transformClassNameStrings = (
75
63
  if (
76
64
  final &&
77
65
  (className.startsWith(`${prefix}-`) || className.startsWith(`!${prefix}-`)) &&
78
- !cssOutput?.includes(`${className.replace(/([/.[\]])/gi, "\\$1")} `) &&
79
- !cssOutput?.includes(`${className.replace(/([/.[\]])/gi, "\\$1")}:`)
66
+ !cssOutput?.includes(`${className.replace(/([@()%,/.[\]])/gi, "\\$1")} `) &&
67
+ !cssOutput?.includes(`${className.replace(/([@()%,/.[\]])/gi, "\\$1")}:`)
80
68
  ) {
81
- console.log(
82
- { className: className.replace(/([/.[\]])/gi, "\\$1") },
83
- cssOutput?.includes(className.replace(/([/.[\]])/gi, "\\$1")),
84
- className.replace(/([/.[\]])/gi, "\\$1")
85
- );
86
-
69
+ notCSSClasses.set(className, className.replace(/([@()%,/.[\]])/gi, "\\$1"));
87
70
  return className.replace(`${prefix}-`, "").replace(`!${prefix}-`, "");
88
71
  }
89
72
 
@@ -122,7 +105,7 @@ export const transformContent = (input, final = false, cssOutput = "") => {
122
105
  return `className${p1}${p2}${transformClassNameStrings(p3, final, cssOutput)}${p2}`;
123
106
  })
124
107
  .replace(classNameWithClsxRegex, (match, p1, p2, p3) => {
125
- return `className${p1}(${p2.replace(/(["'`])([^"'`]+)\1/g, (match, p1, p2) => {
108
+ return `className${p1}(${p2.replace(/(["'`])([^"'`]*?)\1/g, (match, p1, p2) => {
126
109
  return `${p1}${transformClassNameStrings(p2, final, cssOutput)}${p1}`;
127
110
  })})${p3}`;
128
111
  })
@@ -130,18 +113,13 @@ export const transformContent = (input, final = false, cssOutput = "") => {
130
113
  };
131
114
 
132
115
  const current = { timeout: null };
133
- const runBlockJsEsbuild = async (
134
- entryFile,
135
- block: ShopifyAppBlock & { path: string; folder: string }
136
- ) => {
116
+
117
+ const runBlockJsEsbuild = async (entryFile, block: ShopifyAppBlock & { path: string; folder: string }) => {
137
118
  const startTime = Date.now();
138
119
  const folder = block.folder;
139
120
 
140
121
  writeOnlyNew(
141
- path.join(
142
- process.cwd(),
143
- process.env.SHOPIFY_ACCELERATE_ROOT ? "tsconfig.theme-extension.json" : "tsconfig.json"
144
- ),
122
+ path.join(process.cwd(), process.env.SHOPIFY_ACCELERATE_ROOT ? "tsconfig.theme-extension.json" : "tsconfig.json"),
145
123
  fs.readFileSync(path.join(config.package_root, "tsconfig.theme-extension.json"), {
146
124
  encoding: "utf-8",
147
125
  })
@@ -174,10 +152,7 @@ const runBlockJsEsbuild = async (
174
152
  treeShaking: true,
175
153
  loader: { ".js": "jsx" },
176
154
  minify: true,
177
- tsconfig: path.join(
178
- process.cwd(),
179
- process.env.SHOPIFY_ACCELERATE_ROOT ? "tsconfig.theme-extension.json" : "tsconfig.json"
180
- ),
155
+ tsconfig: path.join(process.cwd(), process.env.SHOPIFY_ACCELERATE_ROOT ? "tsconfig.theme-extension.json" : "tsconfig.json"),
181
156
  format: "iife",
182
157
  // platform: "browser",
183
158
  legalComments: "none",
@@ -194,10 +169,7 @@ const runBlockJsEsbuild = async (
194
169
  // eslint-disable-next-line no-process-exit
195
170
  })
196
171
  .then((res) => {
197
- fs.writeFileSync(
198
- path.join(block.path.replace("schema.ts", ""), "metafile.json"),
199
- JSON.stringify(res.metafile ?? {})
200
- );
172
+ fs.writeFileSync(path.join(block.path.replace("schema.ts", ""), "metafile.json"), JSON.stringify(res.metafile ?? {}));
201
173
  });
202
174
 
203
175
  let content = fs.readFileSync(outPath, { encoding: "utf-8" });
@@ -231,13 +203,14 @@ const runBlockJsEsbuild = async (
231
203
  encoding: "utf-8",
232
204
  })
233
205
  );
206
+ console.log(Object.fromEntries(notCSSClasses.entries()));
234
207
  fs.writeFileSync(finalPath, `${finalContent}\n\n/* CSS CROSS CHECKED */`);
235
208
  if (process.env.SHOPIFY_ACCELERATE_THEME_OUTPUT_PATH) {
236
209
  fs.writeFileSync(themePath, `${finalContent}\n\n/* CSS CROSS CHECKED */`);
237
210
  }
238
211
  }
239
212
  });
240
- }, 1300);
213
+ }, 1800);
241
214
 
242
215
  try {
243
216
  // await delay(20);
@@ -247,9 +220,9 @@ const runBlockJsEsbuild = async (
247
220
  }
248
221
 
249
222
  console.log(
250
- `[${chalk.gray(new Date().toLocaleTimeString())}]: [${chalk.magentaBright(
251
- `${Date.now() - startTime}ms`
252
- )}] ${chalk.magenta(`File Bundled: ${finalPath}`)}`
223
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: [${chalk.magentaBright(`${Date.now() - startTime}ms`)}] ${chalk.magenta(
224
+ `File Bundled: ${finalPath}`
225
+ )}`
253
226
  );
254
227
  return true;
255
228
  };
@@ -260,9 +233,7 @@ const buildAllBlocks = async () => {
260
233
  if (isBlockTs(name) && name.includes("index.ts")) {
261
234
  const filename = name.split(/[\\/]/gi).at(-1);
262
235
 
263
- const block = Object.values(config.sources.blockSchemas).find((block) =>
264
- block.path.includes(name.replace(filename, ""))
265
- );
236
+ const block = Object.values(config.sources.blockSchemas).find((block) => block.path.includes(name.replace(filename, "")));
266
237
 
267
238
  if (block && !block.disabled) {
268
239
  try {
@@ -290,9 +261,7 @@ export const runEsbuild = async () => {
290
261
  if (isBlockTs(name)) {
291
262
  const filename = name.split(/[\\/]/gi).at(-1);
292
263
 
293
- const block = Object.values(config.sources.blockSchemas).find((block) =>
294
- block.path.includes(name.replace(filename, ""))
295
- );
264
+ const block = Object.values(config.sources.blockSchemas).find((block) => block.path.includes(name.replace(filename, "")));
296
265
 
297
266
  if (block && !block.disabled) {
298
267
  try {
@@ -1,21 +1,25 @@
1
1
  import chalk from "chalk";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import { notCSSClasses, transformClassNameStrings } from "../esbuild/esbuild";
4
5
  import { config, root_dir } from "../../shopify-accelerate-app";
5
- import { deleteFile, writeCompareFile, writeOnlyNew } from "../utils/fs";
6
+ import { deleteFile, readFile, writeCompareFile, writeOnlyNew } from "../utils/fs";
6
7
  import { isObject } from "../utils/is-object";
7
8
  import { toLocaleFriendlySnakeCase } from "../utils/to-snake-case";
8
9
  import { generateBlockFiles } from "./generate-block-files";
9
10
 
10
- export const generateLiquidFiles = () => {
11
- const {
12
- extension_path,
13
- folders,
14
- sources,
15
- targets,
16
- delete_external_blocks,
17
- delete_external_snippets,
18
- } = config;
11
+ const current = { timeout: null };
12
+
13
+ const transformContent = (input: string, final = false, cssOutput = "") => {
14
+ const classRegex = /class=(["'])([^"']+)\1/g;
15
+
16
+ return input.replace(classRegex, (match, p1, p2, p3) => {
17
+ return `class=${p1}${transformClassNameStrings(p2, final, cssOutput)}${p1}`;
18
+ });
19
+ };
20
+
21
+ export const generateLiquidFiles = (final?: boolean, cssOutput?: string) => {
22
+ const { extension_path, folders, sources, targets, delete_external_blocks, delete_external_snippets } = config;
19
23
 
20
24
  const translations: any = {};
21
25
  const snippets = sources.snippets;
@@ -28,9 +32,7 @@ export const generateLiquidFiles = () => {
28
32
  const blockPath = path.join(process.cwd(), extension_path, "blocks", sectionName);
29
33
 
30
34
  if (schema.disabled) {
31
- const targetFile = targets.blocks.find(
32
- (target) => target.split(/[\\/]/gi).at(-1) === sectionName
33
- );
35
+ const targetFile = targets.blocks.find((target) => target.split(/[\\/]/gi).at(-1) === sectionName);
34
36
  if (targetFile) {
35
37
  config.targets.blocks = config.targets.blocks.filter((target) => target !== targetFile);
36
38
  deleteFile(path.join(root_dir, targetFile));
@@ -64,59 +66,57 @@ export const generateLiquidFiles = () => {
64
66
  });
65
67
 
66
68
  if (rawContent) {
67
- const translatedContent = rawContent.replace(
68
- /<t(\s+[^>]*)*>((.|\r|\n)*?)<\/t>/gi,
69
- (str, group1, group2) => {
70
- const group = toLocaleFriendlySnakeCase(schema.folder);
71
- const content = toLocaleFriendlySnakeCase(
72
- group2?.split(" ")?.slice(0, 2)?.join("_") ?? ""
73
- ).trim();
74
- const backupContent = toLocaleFriendlySnakeCase(group2).trim();
75
- const id = toLocaleFriendlySnakeCase(group1?.replace(/id="(.*)"/gi, "$1") ?? "").trim();
76
-
77
- if (!(group in translations)) {
78
- translations[group] = {};
79
- }
69
+ const translatedContent = rawContent.replace(/<t(\s+[^>]*)*>((.|\r|\n)*?)<\/t>/gi, (str, group1, group2) => {
70
+ const group = toLocaleFriendlySnakeCase(schema.folder);
71
+ const content = toLocaleFriendlySnakeCase(group2?.split(" ")?.slice(0, 2)?.join("_") ?? "").trim();
72
+ const backupContent = toLocaleFriendlySnakeCase(group2).trim();
73
+ const id = toLocaleFriendlySnakeCase(group1?.replace(/id="(.*)"/gi, "$1") ?? "").trim();
74
+
75
+ if (!(group in translations)) {
76
+ translations[group] = {};
77
+ }
80
78
 
81
- if (id && !(id in translations[group])) {
82
- translations[group][id] = group2;
83
- return `{{ "${group}.${id}" | t }}`;
84
- }
79
+ if (id && !(id in translations[group])) {
80
+ translations[group][id] = group2;
81
+ return `{{ "${group}.${id}" | t }}`;
82
+ }
85
83
 
86
- if (!(content in translations[group])) {
87
- translations[group][content] = group2;
88
- return `{{ "${group}.${content}" | t }}`;
89
- }
84
+ if (!(content in translations[group])) {
85
+ translations[group][content] = group2;
86
+ return `{{ "${group}.${content}" | t }}`;
87
+ }
90
88
 
91
- if (translations[group][content] !== group2) {
92
- if (!(backupContent in translations[group])) {
93
- translations[group][backupContent] = group2;
94
- return `{{ "${group}.${backupContent}" | t }}`;
95
- }
96
- if (translations[group][backupContent] !== group2) {
97
- translations[group][`${content}_2`] = group2;
98
- return `{{ "${group}.${content}_2" | t }}`;
99
- }
89
+ if (translations[group][content] !== group2) {
90
+ if (!(backupContent in translations[group])) {
91
+ translations[group][backupContent] = group2;
92
+ return `{{ "${group}.${backupContent}" | t }}`;
100
93
  }
101
-
102
- if (translations[group][content] === group2) {
103
- return `{{ "${group}.${content}" | t }}`;
94
+ if (translations[group][backupContent] !== group2) {
95
+ translations[group][`${content}_2`] = group2;
96
+ return `{{ "${group}.${content}_2" | t }}`;
104
97
  }
98
+ }
105
99
 
106
- return group2;
100
+ if (translations[group][content] === group2) {
101
+ return `{{ "${group}.${content}" | t }}`;
107
102
  }
108
- );
109
103
 
110
- translationArray.push(translatedContent);
104
+ return group2;
105
+ });
106
+
107
+ translationArray.push(
108
+ final ? transformContent(transformContent(translatedContent), final, cssOutput) : transformContent(translatedContent)
109
+ );
110
+ if (final) {
111
+ console.log(Object.fromEntries(notCSSClasses.entries()));
112
+ }
111
113
  }
112
114
 
113
115
  translationArray.push(generateBlockFiles(schema));
114
116
 
115
117
  if (config.ignore_blocks?.includes(blockPath.split(/[/\\]/)?.at(-1))) {
116
118
  console.log(
117
- `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.greenBright(
118
- `Ignored: ${blockPath.replace(process.cwd(), "")}`
119
- )}`
119
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.greenBright(`Ignored: ${blockPath.replace(process.cwd(), "")}`)}`
120
120
  );
121
121
  writeOnlyNew(blockPath, translationArray.join("\n"));
122
122
  } else {
@@ -128,9 +128,7 @@ export const generateLiquidFiles = () => {
128
128
  const snippet = snippets[i];
129
129
  const snippetName = snippet.split(/[\\/]/gi).at(-1);
130
130
 
131
- const block = Object.values(blockSchemas).find((section) =>
132
- section.path.includes(snippet.replace(snippetName, ""))
133
- );
131
+ const block = Object.values(blockSchemas).find((section) => section.path.includes(snippet.replace(snippetName, "")));
134
132
  if (block && block.disabled) {
135
133
  continue;
136
134
  }
@@ -143,58 +141,49 @@ export const generateLiquidFiles = () => {
143
141
  });
144
142
 
145
143
  if (rawContent) {
146
- const translatedContent = rawContent.replace(
147
- /<t(\s+[^>]*)*>((.|\r|\n)*?)<\/t>/gi,
148
- (_, group1, group2) => {
149
- const group = toLocaleFriendlySnakeCase(
150
- snippet.split(/[\\/]/gi).at(-1).split(".").at(0)
151
- ).trim();
152
- const content = toLocaleFriendlySnakeCase(
153
- group2?.split(" ")?.slice(0, 2)?.join("_") ?? ""
154
- ).trim();
155
- const backupContent = toLocaleFriendlySnakeCase(group2).trim();
156
- const id = toLocaleFriendlySnakeCase(group1?.replace(/id="(.*)"/gi, "$1") ?? "").trim();
157
-
158
- if (!(group in translations)) {
159
- translations[group] = {};
160
- }
144
+ const translatedContent = rawContent.replace(/<t(\s+[^>]*)*>((.|\r|\n)*?)<\/t>/gi, (_, group1, group2) => {
145
+ const group = toLocaleFriendlySnakeCase(snippet.split(/[\\/]/gi).at(-1).split(".").at(0)).trim();
146
+ const content = toLocaleFriendlySnakeCase(group2?.split(" ")?.slice(0, 2)?.join("_") ?? "").trim();
147
+ const backupContent = toLocaleFriendlySnakeCase(group2).trim();
148
+ const id = toLocaleFriendlySnakeCase(group1?.replace(/id="(.*)"/gi, "$1") ?? "").trim();
149
+
150
+ if (!(group in translations)) {
151
+ translations[group] = {};
152
+ }
161
153
 
162
- if (id && !(id in translations[group])) {
163
- translations[group][id] = group2;
164
- return `{{ "${group}.${id}" | t }}`;
165
- }
154
+ if (id && !(id in translations[group])) {
155
+ translations[group][id] = group2;
156
+ return `{{ "${group}.${id}" | t }}`;
157
+ }
166
158
 
167
- if (!(content in translations[group])) {
168
- translations[group][content] = group2;
169
- return `{{ "${group}.${content}" | t }}`;
170
- }
159
+ if (!(content in translations[group])) {
160
+ translations[group][content] = group2;
161
+ return `{{ "${group}.${content}" | t }}`;
162
+ }
171
163
 
172
- if (translations[group][content] !== group2) {
173
- if (!(backupContent in translations[group])) {
174
- translations[group][backupContent] = group2;
175
- return `{{ "${group}.${backupContent}" | t }}`;
176
- }
177
- if (translations[group][backupContent] !== group2) {
178
- translations[group][`${content}_2`] = group2;
179
- return `{{ "${group}.${content}_2" | t }}`;
180
- }
164
+ if (translations[group][content] !== group2) {
165
+ if (!(backupContent in translations[group])) {
166
+ translations[group][backupContent] = group2;
167
+ return `{{ "${group}.${backupContent}" | t }}`;
181
168
  }
182
- if (translations[group][content] === group2) {
183
- return `{{ "${group}.${content}" | t }}`;
169
+ if (translations[group][backupContent] !== group2) {
170
+ translations[group][`${content}_2`] = group2;
171
+ return `{{ "${group}.${content}_2" | t }}`;
184
172
  }
185
-
186
- return group2;
187
173
  }
188
- );
174
+ if (translations[group][content] === group2) {
175
+ return `{{ "${group}.${content}" | t }}`;
176
+ }
177
+
178
+ return group2;
179
+ });
189
180
 
190
181
  returnArr.push(translatedContent);
191
182
  }
192
183
 
193
184
  if (config.ignore_snippets?.includes(snippetPath.split(/[/\\]/)?.at(-1))) {
194
185
  console.log(
195
- `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.greenBright(
196
- `Ignored: ${snippetPath.replace(process.cwd(), "")}`
197
- )}`
186
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.greenBright(`Ignored: ${snippetPath.replace(process.cwd(), "")}`)}`
198
187
  );
199
188
  writeOnlyNew(snippetPath, returnArr.join("\n"));
200
189
  } else {
@@ -232,10 +221,7 @@ declare global {
232
221
  }
233
222
  `;
234
223
 
235
- writeCompareFile(
236
- path.join(process.cwd(), extension_path, "locales", "en.default.json"),
237
- JSON.stringify(translations, undefined, 2)
238
- );
224
+ writeCompareFile(path.join(process.cwd(), extension_path, "locales", "en.default.json"), JSON.stringify(translations, undefined, 2));
239
225
  /*writeCompareFile(
240
226
  path.join(process.cwd(), extension_path, "snippets", "_layout.translations.liquid"),
241
227
  translationsJs
@@ -246,19 +232,13 @@ declare global {
246
232
 
247
233
  sources.blocksJs.forEach((name) => {
248
234
  const filename = name.split(/[\\/]/gi).at(-1);
249
- const block = Object.values(blockSchemas).find((section) =>
250
- section.path.includes(name.replace(filename, ""))
251
- );
235
+ const block = Object.values(blockSchemas).find((section) => section.path.includes(name.replace(filename, "")));
252
236
  const targetName = `__block--${filename.replace(/\.(ts)x?$/gi, ".js")}`;
253
237
  const targetFile = targets.dynamicJs.find((file) => file.includes(targetName));
254
238
 
255
239
  if (block && !block.disabled) {
256
- dynamicJsImports.push(
257
- `<link rel="preload" as="script" href="{{ '${targetName}' | asset_url }}">`
258
- );
259
- dynamicJsImports.push(
260
- `<script type="module" src="{{ '${targetName}' | asset_url }}" defer></script>`
261
- );
240
+ dynamicJsImports.push(`<link rel="preload" as="script" href="{{ '${targetName}' | asset_url }}">`);
241
+ dynamicJsImports.push(`<script type="module" src="{{ '${targetName}' | asset_url }}" defer></script>`);
262
242
  } else if (targetFile) {
263
243
  deleteFile(path.join(root_dir, targetFile));
264
244
  config.targets.dynamicJs = config.targets.dynamicJs.filter((target) => target !== targetFile);
@@ -268,16 +248,12 @@ declare global {
268
248
  targets.dynamicJs.forEach((name) => {
269
249
  const targetName = name.split(/[\\/]/gi).at(-1).replace(/\.js$/gi, "");
270
250
 
271
- const blockFile = sources.blocksJs.find((section) =>
272
- section.includes(targetName.replace(/__block--/gi, ""))
273
- );
251
+ const blockFile = sources.blocksJs.find((section) => section.includes(targetName.replace(/__block--/gi, "")));
274
252
 
275
253
  if (blockFile) {
276
254
  const filename = blockFile?.split(/[\\/]/gi)?.at(-1);
277
255
 
278
- const block = Object.values(blockSchemas).find((section) =>
279
- section.path.includes(blockFile.replace(filename, ""))
280
- );
256
+ const block = Object.values(blockSchemas).find((section) => section.path.includes(blockFile.replace(filename, "")));
281
257
 
282
258
  if (!block || block.disabled) {
283
259
  deleteFile(path.join(root_dir, name));
@@ -297,9 +273,7 @@ declare global {
297
273
  if (delete_external_snippets) {
298
274
  targets.snippets.forEach((file) => {
299
275
  const fileName = file.split(/[\\/]/gi).at(-1);
300
- const targetFile = snippets.find(
301
- (sourcePath) => sourcePath.split(/[\\/]/gi).at(-1) === fileName
302
- );
276
+ const targetFile = snippets.find((sourcePath) => sourcePath.split(/[\\/]/gi).at(-1) === fileName);
303
277
  if (
304
278
  fileName.includes("_layout.translations.liquid") ||
305
279
  fileName.includes("_layout.dynamic-imports.liquid") ||
@@ -319,12 +293,22 @@ declare global {
319
293
  if (delete_external_blocks) {
320
294
  targets.blocks.forEach((file) => {
321
295
  const fileName = file.split(/[\\/]/gi).at(-1);
322
- const targetFile = sources.blocksLiquid.find(
323
- (sourcePath) => sourcePath.split(/[\\/]/gi).at(-1) === fileName
324
- );
296
+ const targetFile = sources.blocksLiquid.find((sourcePath) => sourcePath.split(/[\\/]/gi).at(-1) === fileName);
325
297
  if (!targetFile) {
326
298
  deleteFile(path.join(process.cwd(), file));
327
299
  }
328
300
  });
329
301
  }
302
+
303
+ clearTimeout(current.timeout);
304
+ if (!final) {
305
+ current.timeout = setTimeout(() => {
306
+ generateLiquidFiles(
307
+ true,
308
+ fs.readFileSync(path.join(config.extension_path, `assets/tailwind.css`), {
309
+ encoding: "utf-8",
310
+ })
311
+ );
312
+ }, 1800);
313
+ }
330
314
  };
@@ -32,15 +32,9 @@ export const runTailwindCSSWatcher = () => {
32
32
  [
33
33
  "tailwindcss",
34
34
  "--config",
35
- /*hasConfig ? "tailwind.config.js" :*/ path.join(
36
- package_root,
37
- `src/tailwind/tailwind.config.js`
38
- ),
35
+ /*hasConfig ? "tailwind.config.js" :*/ path.join(package_root, `src/tailwind/tailwind.config.js`),
39
36
  "--postcss",
40
- /*hasPostCss ? "postcss.config.js" : */ path.join(
41
- package_root,
42
- `src/tailwind/postcss.config.js`
43
- ),
37
+ /*hasPostCss ? "postcss.config.js" : */ path.join(package_root, `src/tailwind/postcss.config.js`),
44
38
  "-i",
45
39
  path.join(root_dir, `assets`, `_tailwind.css`),
46
40
  "-o",
@@ -87,12 +81,7 @@ export const runTailwindCSSWatcher = () => {
87
81
  });
88
82
 
89
83
  if (writeOut) {
90
- const finalClassName = line
91
- .replace(/\./g, "")
92
- .replace(/{/g, "")
93
- .replace(/}/g, "")
94
- .replace(/\\/g, "")
95
- .trim();
84
+ const finalClassName = line.replace(/\./g, "").replace(/{/g, "").replace(/}/g, "").replace(/\\/g, "").trim();
96
85
  if (finalClassName !== "") {
97
86
  classesInOrder.push(`${finalClassName}`);
98
87
  }
@@ -111,11 +100,7 @@ export const runTailwindCSSWatcher = () => {
111
100
  .join("\n")
112
101
  .replace(
113
102
  new RegExp(
114
- `${
115
- process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX
116
- ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-`
117
- : ""
118
- }`,
103
+ `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : ""}`,
119
104
  "gi"
120
105
  ),
121
106
  ""
@@ -1,9 +1,7 @@
1
1
  /** @type {import('tailwindcss').Config} */
2
2
  // eslint-disable-next-line node/no-unpublished-require
3
3
  // import { require } from "../../require";
4
- const {
5
- defaultExtractor: createDefaultExtractor,
6
- } = require("tailwindcss/lib/lib/defaultExtractor");
4
+ const { defaultExtractor: createDefaultExtractor } = require("tailwindcss/lib/lib/defaultExtractor");
7
5
 
8
6
  const { default: resolveConfig } = require("tailwindcss/lib/util/resolveConfig");
9
7
  const plugin = require("tailwindcss/plugin");
@@ -35,22 +33,31 @@ module.exports = {
35
33
  `!${process.env.SHOPIFY_ACCELERATE_EXTENSION_PATH}/!**!/!*.css`,
36
34
  `!${process.env.SHOPIFY_ACCELERATE_EXTENSION_PATH}/!**/!*.css`,
37
35
  ],
38
- /* extract: {
39
- ts: extractor,
40
- tsx: extractor,
41
- html: extractor,
42
- liquid: extractor,
43
- js: extractor,
44
- json: extractor,
45
- },*/
36
+ extract: {
37
+ // ts: extractor,
38
+ // tsx: extractor,
39
+ // html: extractor,
40
+ // liquid: (content) => {
41
+ // console.log({ content });
42
+ // return content;
43
+ // },
44
+ // js: extractor,
45
+ // json: extractor,
46
+ },
46
47
  },
48
+ safelist: [
49
+ `!${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : ""}fixed`,
50
+ `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : ""}inset-0`,
51
+ `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : ""}pointer-events-none`,
52
+ `${
53
+ process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : ""
54
+ }[&>*]:pointer-events-auto`,
55
+ ],
47
56
  darkMode: "class", // or 'media' or 'class'
48
57
  // mode: process.env.NODE_ENV ? "jit" : undefined,
49
58
  // important: true,
50
59
  important: process.env.SHOPIFY_ACCELERATE_TAILWIND_IMPORTANT,
51
- prefix: process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX
52
- ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-`
53
- : undefined,
60
+ prefix: process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX ? `${process.env.SHOPIFY_ACCELERATE_TAILWIND_PREFIX}-` : undefined,
54
61
  corePlugins: {
55
62
  preflight: false,
56
63
  },
@@ -94,13 +101,26 @@ module.exports = {
94
101
  "5xl": "1024px",
95
102
  "6xl": "1152px",
96
103
  "7xl": "1280px",
104
+ "8xl": "1440px",
97
105
  },
98
106
  fontSize: {
107
+ 8: ["9px", "1.55"],
99
108
  9: ["9px", "1.5"],
100
109
  10: ["10px", "1.5"],
101
110
  11: ["11px", "1.5"],
102
111
  12: ["12px", "1.5"],
103
112
  13: ["13px", "1.5"],
113
+ 14: ["14px", "1.5"],
114
+ 15: ["15px", "1.5"],
115
+ 16: ["16px", "1.5"],
116
+ 17: ["17px", "1.5"],
117
+ 18: ["18px", "1.45"],
118
+ 19: ["19px", "1.45"],
119
+ 20: ["20px", "1.45"],
120
+ 21: ["21px", "1.45"],
121
+ 22: ["22px", "1.4"],
122
+ 23: ["23px", "1.4"],
123
+ 24: ["24px", "1.4"],
104
124
  xs: ["12px", { lineHeight: "16px" }],
105
125
  sm: ["14px", { lineHeight: "20px" }],
106
126
  base: ["16px", { lineHeight: "24px" }],
@@ -194,6 +214,22 @@ module.exports = {
194
214
  xxs: "373px" /* tiny phone*/,
195
215
  xs: "427px" /*smaller than iphone pro max*/,
196
216
  },
217
+ containers: {
218
+ xxs: "373px" /* tiny phone*/,
219
+ xs: "427px" /*smaller than iphone pro max*/,
220
+ sm: "640px",
221
+ md: "768px",
222
+ lg: "1024px",
223
+ xl: "1280px",
224
+ "2xl": "1536px",
225
+ "max-xxs": "-373px" /* tiny phone*/,
226
+ "max-xs": "-427px" /*smaller than iphone pro max*/,
227
+ "max-sm": "-640px",
228
+ "max-md": "-768px",
229
+ "max-lg": "-1024px",
230
+ "max-xl": "-1280px",
231
+ "max-2xl": "-1536px",
232
+ },
197
233
  fontSize: {
198
234
  8: ["9px", "1.55"],
199
235
  9: ["9px", "1.5"],
@@ -249,6 +285,9 @@ module.exports = {
249
285
  "0%, 100%": { opacity: "1" },
250
286
  "50%": { opacity: "0" },
251
287
  },
288
+ "pulse-bg": {
289
+ "50%": { "--tw-bg-opacity": "0.5" },
290
+ },
252
291
  },
253
292
  animation: {
254
293
  slide: "slide 30s linear infinite",
@@ -257,8 +296,17 @@ module.exports = {
257
296
  circle: "circle 8.1s linear",
258
297
  dot: "dot 8.1s linear",
259
298
  typewriter: "typewriter 0.5s linear infinite",
299
+ "pulse-bg": "pulse-bg 1s cubic-bezier(0.4, 0, 0.6, 1) infinite",
260
300
  },
261
301
  colors: {
302
+ theme: {
303
+ "trigger-bg": "rgb(var(--lx-color-trigger-bg) / <alpha-value>)",
304
+ "trigger-text": "rgb(var(--lx-color-trigger-text) / <alpha-value>)",
305
+ bg: "rgb(var(--lx-color-bg) / <alpha-value>)",
306
+ text: "rgb(var(--lx-color-text) / <alpha-value>)",
307
+ "button-bg": "rgb(var(--lx-color-button-bg) / <alpha-value>)",
308
+ "button-text": "rgb(var(--lx-color-button-text) / <alpha-value>)",
309
+ },
262
310
  border: "hsl(var(--border))",
263
311
  input: "hsl(var(--input))",
264
312
  ring: "hsl(var(--ring))",
@@ -321,6 +369,7 @@ module.exports = {
321
369
  addVariant("fa", ["&:focus", "&:active"]);
322
370
  addVariant("f", ["&:focus"]);
323
371
  addVariant("fw", ["&:focus-within"]);
372
+ addVariant("fv", ["&:focus-visible"]);
324
373
  addVariant("h", ["&:hover"]);
325
374
  addVariant("d", [".dark &"]);
326
375
  addVariant("ac", ["&.active"]);
@@ -334,23 +383,9 @@ module.exports = {
334
383
  addVariant("group-ac", [".group.active &"]);
335
384
 
336
385
  addVariant("group-hfva", [".group:hover &", ".group:focus-visible &", ".group:active &"]);
337
- addVariant("group-hfwa", [
338
- ".group:hover &",
339
- ".group:focus-visible &",
340
- ".group:focus-within &",
341
- ".group:active &",
342
- ]);
343
- addVariant("group-hfw", [
344
- ".group:hover &",
345
- ".group:focus-visible &",
346
- ".group:focus-within &",
347
- ]);
348
- addVariant("peer-hfwa", [
349
- ".peer:hover ~ &",
350
- ".peer:focus-visible ~ &",
351
- ".peer:focus-within ~ &",
352
- ".peer:active ~ &",
353
- ]);
386
+ addVariant("group-hfwa", [".group:hover &", ".group:focus-visible &", ".group:focus-within &", ".group:active &"]);
387
+ addVariant("group-hfw", [".group:hover &", ".group:focus-visible &", ".group:focus-within &"]);
388
+ addVariant("peer-hfwa", [".peer:hover ~ &", ".peer:focus-visible ~ &", ".peer:focus-within ~ &", ".peer:active ~ &"]);
354
389
  addVariant("peer-fw", [".peer:focus-within ~ &"]);
355
390
  matchUtilities(
356
391
  {
@@ -360,6 +395,27 @@ module.exports = {
360
395
  },
361
396
  { values: theme("spacing") }
362
397
  );
398
+ matchUtilities(
399
+ {
400
+ "auto-col-flow": (value) => {
401
+ if (value?.includes("/")) {
402
+ const [cols, gap] = value.split("/");
403
+ const calculatedGap = /^(\d|\.)*$/gi.test(gap?.trim()) ? `${+gap * 4}px` : gap;
404
+
405
+ return {
406
+ gridAutoFlow: `column`,
407
+ gridAutoColumns: ` calc((100% - (${calculatedGap} * (${cols} - 1))) / ${cols})`,
408
+ columnGap: `${calculatedGap}`,
409
+ };
410
+ }
411
+ return {
412
+ gridAutoFlow: `column`,
413
+ gridAutoColumns: `${value}`,
414
+ };
415
+ },
416
+ },
417
+ { values: theme("width") }
418
+ );
363
419
  /*matchUtilities(
364
420
  {
365
421
  "border-w": (value) => ({