shopify-accelerate-app 1.0.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.
Files changed (47) hide show
  1. package/@types/metafields.ts +9 -0
  2. package/@types/sections.ts +1769 -0
  3. package/@types/settings.ts +3 -0
  4. package/@types/shopify.ts +1871 -0
  5. package/@types/types.d.ts +17 -0
  6. package/README.md +2 -0
  7. package/package.json +111 -0
  8. package/shopify-accelerate-app.ts +394 -0
  9. package/shopify.graphql +48866 -0
  10. package/src/esbuild/esbuild.ts +246 -0
  11. package/src/scaffold-theme/build-theme.ts +24 -0
  12. package/src/scaffold-theme/generate-asset-files.ts +48 -0
  13. package/src/scaffold-theme/generate-base-types.ts +23 -0
  14. package/src/scaffold-theme/generate-block-files.ts +194 -0
  15. package/src/scaffold-theme/generate-blocks-types.ts +242 -0
  16. package/src/scaffold-theme/generate-config-files.ts +34 -0
  17. package/src/scaffold-theme/generate-liquid-files.ts +995 -0
  18. package/src/scaffold-theme/generate-schema-locales.ts +195 -0
  19. package/src/scaffold-theme/generate-schema-variables.ts +380 -0
  20. package/src/scaffold-theme/generate-section-files.ts +303 -0
  21. package/src/scaffold-theme/generate-section-preset-files.ts +296 -0
  22. package/src/scaffold-theme/generate-section-types.ts +339 -0
  23. package/src/scaffold-theme/generate-setting-types.ts +123 -0
  24. package/src/scaffold-theme/generate-settings-file.ts +103 -0
  25. package/src/scaffold-theme/parse-files.ts +466 -0
  26. package/src/scaffold-theme/parse-locales.ts +98 -0
  27. package/src/shopify-cli/pull.ts +103 -0
  28. package/src/tailwind/postcss.config.js +8 -0
  29. package/src/tailwind/tailwind-watch.ts +133 -0
  30. package/src/tailwind/tailwind.config.js +261 -0
  31. package/src/telemetry/telemetry.ts +84 -0
  32. package/src/templates/.env.template +12 -0
  33. package/src/templates/shopify.theme.toml +9 -0
  34. package/src/utils/capitalize.ts +3 -0
  35. package/src/utils/delay.ts +3 -0
  36. package/src/utils/fs.ts +87 -0
  37. package/src/utils/is-object.ts +3 -0
  38. package/src/utils/json.ts +8 -0
  39. package/src/utils/to-camel-case.ts +6 -0
  40. package/src/utils/to-kebab-case.ts +6 -0
  41. package/src/utils/to-pascal-case.ts +12 -0
  42. package/src/utils/to-snake-case.ts +45 -0
  43. package/src/validate-cli-options.ts +281 -0
  44. package/src/watch-headless/watch-headless.ts +81 -0
  45. package/src/watch-theme/watch-theme.ts +84 -0
  46. package/tsconfig.json +82 -0
  47. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,133 @@
1
+ import child_process from "child_process";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { config, root_dir } from "../../shopify-accelerate-app";
5
+ import { deleteFile } from "../utils/fs";
6
+ const watch = require("node-watch");
7
+
8
+ export const runTailwindCSSWatcher = () => {
9
+ const { package_root } = config;
10
+ const hasConfig = fs.existsSync(path.join(root_dir, "tailwind.config.js"));
11
+ const hasPostCss = fs.existsSync(path.join(root_dir, "postcss.config.js"));
12
+ const inputFile = fs.existsSync(path.join(root_dir, `assets`, `_tailwind.css`));
13
+ const resetInputFile = fs.existsSync(path.join(root_dir, `assets`, `_reset.css`));
14
+
15
+ if (!inputFile) {
16
+ console.log("Tailwind Input file not found");
17
+ return;
18
+ }
19
+
20
+ const filePath = path.join(root_dir, `assets`, `tailwind_pre_sort.css.liquid`);
21
+ deleteFile(filePath);
22
+ /*= =============== Tailwind Watcher ================ */
23
+ child_process.spawn(
24
+ "npx",
25
+ [
26
+ "tailwindcss",
27
+ "--config",
28
+ /*hasConfig ? "tailwind.config.js" :*/ path.join(
29
+ package_root,
30
+ `src/tailwind/tailwind.config.js`
31
+ ),
32
+ "--postcss",
33
+ /*hasPostCss ? "postcss.config.js" : */ path.join(
34
+ package_root,
35
+ `src/tailwind/postcss.config.js`
36
+ ),
37
+ "-i",
38
+ path.join(root_dir, `assets`, `_tailwind.css`),
39
+ "-o",
40
+ filePath,
41
+ "--watch",
42
+ ],
43
+ {
44
+ shell: true,
45
+ stdio: "inherit",
46
+ }
47
+ );
48
+
49
+ if (!resetInputFile) {
50
+ console.log("Tailwind Reset Input file not found");
51
+ return;
52
+ }
53
+ /*= =============== Tailwind Reset ================ */
54
+ child_process.spawn(
55
+ "npx",
56
+ [
57
+ "tailwindcss",
58
+ "--config",
59
+ /*hasConfig ? "tailwind.config.js" :*/ path.join(
60
+ package_root,
61
+ `src/tailwind/tailwind.config.js`
62
+ ),
63
+ "--postcss",
64
+ /*hasPostCss ? "postcss.config.js" :*/ path.join(
65
+ package_root,
66
+ `src/tailwind/postcss.config.js`
67
+ ),
68
+ "-i",
69
+ path.join(root_dir, `assets`, `_reset.css`),
70
+ "-o",
71
+ path.join(root_dir, `assets`, `reset.css.liquid`),
72
+ ],
73
+ {
74
+ shell: true,
75
+ stdio: "inherit",
76
+ }
77
+ );
78
+
79
+ /*= =============== Tailwind Plugin Order ================ */
80
+ watch(path.join(root_dir, "assets"), { recursive: false }, async (evt, name) => {
81
+ if (
82
+ !name.match(/tailwind_pre_sort.css.liquid$/) ||
83
+ !fs.existsSync(path.join(root_dir, "./assets/tailwind_pre_sort.css.liquid"))
84
+ )
85
+ return;
86
+ const file = fs.readFileSync(path.join(root_dir, "./assets/tailwind_pre_sort.css.liquid"), {
87
+ encoding: "utf-8",
88
+ });
89
+
90
+ const top = file
91
+ .split(/\n}/gi)
92
+ .filter((str) => !/\n@container \(/gi.test(str))
93
+ .join("\n}");
94
+ const bottom = `${file
95
+ .split(/\n}/gi)
96
+ .filter((str) => /\n@container \(/gi.test(str))
97
+ .join("\n}")}\n}`;
98
+ const content = top + bottom;
99
+
100
+ const classesInOrder = [];
101
+ const omitCompoundClasses = [":not", ":where", ">", "*", ","];
102
+
103
+ content.split("\n").forEach((line) => {
104
+ if (!line.startsWith(".")) {
105
+ return;
106
+ }
107
+
108
+ let writeOut = true;
109
+
110
+ omitCompoundClasses.forEach((classToOmit) => {
111
+ if (line.includes(classToOmit)) {
112
+ writeOut = false;
113
+ return;
114
+ }
115
+ });
116
+
117
+ if (writeOut) {
118
+ const finalClassName = line
119
+ .replace(/\./g, "")
120
+ .replace(/{/g, "")
121
+ .replace(/}/g, "")
122
+ .replace(/\\/g, "")
123
+ .trim();
124
+ if (finalClassName !== "") {
125
+ classesInOrder.push(`${finalClassName}`);
126
+ }
127
+ }
128
+ });
129
+
130
+ fs.writeFileSync(path.join(root_dir, `assets/tailwind.css.liquid`), content);
131
+ fs.writeFileSync(path.join(process.cwd(), ".tailwindorder"), classesInOrder.join("\n"));
132
+ });
133
+ };
@@ -0,0 +1,261 @@
1
+ // eslint-disable-next-line node/no-unpublished-require
2
+ const plugin = require("tailwindcss/plugin");
3
+ require("dotenv").config();
4
+
5
+ module.exports = {
6
+ content: [
7
+ `${process.env.THEME_PATH}/**/*{html,liquid,js,json}`,
8
+ `!${process.env.THEME_PATH}/**/*.css.liquid`,
9
+ `!${process.env.THEME_PATH}/**/*.css`,
10
+ ],
11
+ darkMode: "class", // or 'media' or 'class'
12
+ // mode: process.env.NODE_ENV ? "jit" : undefined,
13
+ // important: true,
14
+ mode: "jit",
15
+ theme: {
16
+ extend: {
17
+ screens: {
18
+ xxs: "373px" /* tiny phone*/,
19
+ xs: "427px" /*smaller than iphone pro max*/,
20
+ },
21
+ fontSize: {
22
+ 9: ["9px", "1.5"],
23
+ 10: ["10px", "1.5"],
24
+ 11: ["11px", "1.5"],
25
+ 12: ["12px", "1.5"],
26
+ 13: ["13px", "1.5"],
27
+ },
28
+ padding: {
29
+ gutter: "var(--layout-container-gutter)",
30
+ },
31
+ maxWidth: {
32
+ container: {
33
+ xs: `var(--layout-page-width-xs)`,
34
+ sm: `var(--layout-page-width-sm)`,
35
+ md: `var(--layout-page-width-md)`,
36
+ lg: `var(--layout-page-width-lg)`,
37
+ },
38
+ "8xl": "90rem",
39
+ },
40
+ borderRadius: {
41
+ "theme-sm": `var(--rounded-theme-sm)`,
42
+ theme: `var(--rounded-theme)`,
43
+ "theme-md": `var(--rounded-theme-md)`,
44
+ "theme-lg": `var(--rounded-theme-lg)`,
45
+ "theme-xl": `var(--rounded-theme-xl)`,
46
+ "theme-2xl": `var(--rounded-theme-2xl)`,
47
+ "theme-3xl": `var(--rounded-theme-3xl)`,
48
+ },
49
+ colors: {
50
+ theme: {
51
+ bg: "rgb(var(--color-bg) / <alpha-value>)",
52
+ "bg-hex": "var(--color-bg-hex)",
53
+ text: "rgb(var(--color-text) / <alpha-value>)",
54
+ "text-hex": "var(--color-text-hex)",
55
+ "overlay-text": "rgb(var(--color-overlay-text) / <alpha-value>)",
56
+ "overlay-text-hex": "var(--color-overlay-text-hex)",
57
+ accent: "rgb(var(--color-accent) / <alpha-value>)",
58
+ border: "rgb(var(--color-border) / <alpha-value>)",
59
+ },
60
+ error: "rgb(var(--color-error) / <alpha-value>)",
61
+ warning: "rgb(var(--color-warning) / <alpha-value>)",
62
+ success: "rgb(var(--color-success) / <alpha-value>)",
63
+ info: "rgb(var(--color-info) / <alpha-value>)",
64
+ gray: {
65
+ 50: "rgb(var(--color-gray-50) / <alpha-value>)",
66
+ 100: "rgb(var(--color-gray-100) / <alpha-value>)",
67
+ 200: "rgb(var(--color-gray-200) / <alpha-value>)",
68
+ 300: "rgb(var(--color-gray-300) / <alpha-value>)",
69
+ 400: "rgb(var(--color-gray-400) / <alpha-value>)",
70
+ 500: "rgb(var(--color-gray-500) / <alpha-value>)",
71
+ 600: "rgb(var(--color-gray-600) / <alpha-value>)",
72
+ 700: "rgb(var(--color-gray-700) / <alpha-value>)",
73
+ 800: "rgb(var(--color-gray-800) / <alpha-value>)",
74
+ 900: "rgb(var(--color-gray-900) / <alpha-value>)",
75
+ },
76
+ },
77
+ ringColor: {
78
+ DEFAULT: `rgb(var(--color-accent))`,
79
+ },
80
+ boxShadow: {
81
+ "invert-sm": "0 -1px 2px 0 rgb(0 0 0 / 0.05)",
82
+ invert: "0 -3px 5px 1px rgb(0 0 0 / 0.03), 0 -2px 4px 2px rgb(0 0 0 / 0.03)",
83
+ "invert-md": "0 -4px 6px 1px rgb(0 0 0 / 0.07), 0 -2px 4px 2px rgb(0 0 0 / 0.07)",
84
+ "invert-lg": "0 -10px 15px 3px rgb(0 0 0 / 0.1), 0 -4px 6px 4px rgb(0 0 0 / 0.1)",
85
+ "invert-xl": "0 -20px 25px 5px rgb(0 0 0 / 0.1), 0 -8px 10px 6px rgb(0 0 0 / 0.1)",
86
+ "invert-2xl": "0 -25px 50px 12px rgb(0 0 0 / 0.25)",
87
+ },
88
+ keyframes: {
89
+ slide: {
90
+ "0%, 100%": { transform: "translate3d(0,0,0)" },
91
+ "100%": { transform: "translate3d(-50%,0,0)" },
92
+ },
93
+ marquee1: {
94
+ "0%, 100%": { transform: "translate3d(0,0,0)" },
95
+ "100%": { transform: "translate3d(-100%,0,0)" },
96
+ },
97
+ marquee2: {
98
+ "0%, 100%": { transform: "translate3d(100%,0,0)" },
99
+ "100%": { transform: "translate3d(0,0,0)" },
100
+ },
101
+ circle: {
102
+ "0%": { strokeDashoffset: "90" },
103
+ "100%": { strokeDashoffset: "0" },
104
+ },
105
+ dot: {
106
+ "0%,95%": { fill: "transparent", stroke: "currentColor", strokeOpacity: "0.1" },
107
+ "100%": { fill: "currentColor", stroke: "transparent", strokeOpacity: "0" },
108
+ },
109
+ typewriter: {
110
+ "0%, 100%": { opacity: "1" },
111
+ "50%": { opacity: "0" },
112
+ },
113
+ },
114
+ animation: {
115
+ slide: "slide 30s linear infinite",
116
+ marquee1: "marquee1 30s linear infinite",
117
+ marquee2: "marquee2 30s linear infinite",
118
+ circle: "circle 8.1s linear",
119
+ dot: "dot 8.1s linear",
120
+ typewriter: "typewriter 0.5s linear infinite",
121
+ },
122
+ },
123
+ variants: {
124
+ extend: {},
125
+ },
126
+ },
127
+ plugins: [
128
+ require("@tailwindcss/aspect-ratio"),
129
+ require("tailwindcss-container-queries-with-max-width"),
130
+ // require("@tailwindcss/forms"),
131
+ plugin(({ addVariant, addUtilities, matchUtilities, theme }) => {
132
+ addVariant("svg", ["& svg"]);
133
+ addVariant("hfa", ["&:hover", "&:focus", "&:active"]);
134
+ addVariant("hfw", ["&:hover", "&:focus-visible", "&:focus-within"]);
135
+ addVariant("hfwa", ["&:hover", "&:focus-visible", "&:focus-within", "&:active"]);
136
+ addVariant("hfwaa", ["&:hover", "&:focus-visible", "&:focus-within", "&:active", "&.active"]);
137
+ addVariant("hfva", ["&:hover", "&:focus", "&:focus-visible", "&:active"]);
138
+ addVariant("ha", ["&:hover", "&:active"]);
139
+ addVariant("hf", ["&:hover", "&:focus-visible"]);
140
+ addVariant("fa", ["&:focus", "&:active"]);
141
+ addVariant("f", ["&:focus"]);
142
+ addVariant("fw", ["&:focus-within"]);
143
+ addVariant("h", ["&:hover"]);
144
+ addVariant("d", [".dark &"]);
145
+ addVariant("ac", ["&.active"]);
146
+ addVariant("b", ["&::before"]);
147
+ addVariant("a", ["&::after"]);
148
+ addVariant("not-prose", [":not(.prose &)&"]);
149
+ addVariant("hfaa", ["&:hover", "&:focus", "&:active", "&.active"]);
150
+ addVariant("hfvaa", ["&:hover", "&:focus", "&:focus-visible", "&:active", "&.active"]);
151
+ addVariant("group-hfa", [".group:hover &", ".group:focus &", ".group:active &"]);
152
+ addVariant("group-hf", [".group:hover &", ".group:focus &"]);
153
+ addVariant("group-ac", [".group.active &"]);
154
+
155
+ addVariant("group-hfva", [".group:hover &", ".group:focus-visible &", ".group:active &"]);
156
+ addVariant("group-hfwa", [
157
+ ".group:hover &",
158
+ ".group:focus-visible &",
159
+ ".group:focus-within &",
160
+ ".group:active &",
161
+ ]);
162
+ addVariant("group-hfw", [
163
+ ".group:hover &",
164
+ ".group:focus-visible &",
165
+ ".group:focus-within &",
166
+ ]);
167
+ addVariant("peer-hfwa", [
168
+ ".peer:hover ~ &",
169
+ ".peer:focus-visible ~ &",
170
+ ".peer:focus-within ~ &",
171
+ ".peer:active ~ &",
172
+ ]);
173
+ matchUtilities(
174
+ {
175
+ "top-spacing": (value) => ({
176
+ top: `calc(${theme("spacing.top-bar-spacing")} + ${value})`,
177
+ }),
178
+ },
179
+ { values: theme("spacing") }
180
+ );
181
+ matchUtilities(
182
+ {
183
+ "border-w": (value) => ({
184
+ borderWidth: `${value}`,
185
+ }),
186
+ },
187
+ { values: theme("spacing") }
188
+ );
189
+ matchUtilities(
190
+ {
191
+ "border-x-w": (value) => ({
192
+ borderLeftWidth: `${value}`,
193
+ borderRightWidth: `${value}`,
194
+ }),
195
+ },
196
+ { values: theme("spacing") }
197
+ );
198
+ matchUtilities(
199
+ {
200
+ "border-l-w": (value) => ({
201
+ borderLeftWidth: `${value}`,
202
+ }),
203
+ },
204
+ { values: theme("spacing") }
205
+ );
206
+ matchUtilities(
207
+ {
208
+ "border-r-w": (value) => ({
209
+ borderRightWidth: `${value}`,
210
+ }),
211
+ },
212
+ { values: theme("spacing") }
213
+ );
214
+ matchUtilities(
215
+ {
216
+ "border-y-w": (value) => ({
217
+ borderTopWidth: `${value}`,
218
+ borderBottomWidth: `${value}`,
219
+ }),
220
+ },
221
+ { values: theme("spacing") }
222
+ );
223
+ matchUtilities(
224
+ {
225
+ "border-t-w": (value) => ({
226
+ borderTopWidth: `${value}`,
227
+ }),
228
+ },
229
+ { values: theme("spacing") }
230
+ );
231
+ matchUtilities(
232
+ {
233
+ "border-b-w": (value) => ({
234
+ borderBottomWidth: `${value}`,
235
+ }),
236
+ },
237
+ { values: theme("spacing") }
238
+ );
239
+ addUtilities({
240
+ ".shape-geometric-precision": {
241
+ "shape-rendering": "geometricPrecision",
242
+ },
243
+ ".open-quote": {
244
+ content: "open-quote",
245
+ },
246
+ ".close-quote": {
247
+ content: "close-quote",
248
+ },
249
+ ".leading-0": {
250
+ "line-height": "0",
251
+ },
252
+ ".animation-pause": {
253
+ "animation-play-state": "paused",
254
+ },
255
+ ".animation-play": {
256
+ "animation-play-state": "running",
257
+ },
258
+ });
259
+ }),
260
+ ],
261
+ };
@@ -0,0 +1,84 @@
1
+ import chalk from "chalk";
2
+ import fs from "fs";
3
+ import os from "os";
4
+ import path from "path";
5
+ import toml from "toml";
6
+
7
+ export const telemetry = () => {
8
+ const root = process.cwd();
9
+ try {
10
+ let shop_url = "";
11
+ let theme_id = "";
12
+ let shop_url_prod = "";
13
+ let theme_id_prod = "";
14
+
15
+ try {
16
+ const shopifySettings = fs.readFileSync(path.join(root, "shopify.theme.toml"), {
17
+ encoding: "utf-8",
18
+ });
19
+ const userSettings = JSON.parse(JSON.stringify(toml.parse(shopifySettings)));
20
+ if (
21
+ typeof userSettings === "object" &&
22
+ "environments" in userSettings &&
23
+ "development" in userSettings.environments
24
+ ) {
25
+ theme_id = userSettings.environments.development.theme;
26
+ shop_url = userSettings.environments.development.store;
27
+ theme_id_prod = userSettings.environments.production.theme;
28
+ shop_url_prod = userSettings.environments.production.store;
29
+ }
30
+ console.log(
31
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.yellowBright(
32
+ `Dev Environment: Theme: ${theme_id} - Shop: ${shop_url}`
33
+ )}`
34
+ );
35
+ console.log(
36
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.yellowBright(
37
+ `Prod Environment: Theme: ${theme_id_prod} - Shop: ${shop_url_prod}`
38
+ )}`
39
+ );
40
+ } catch (err) {
41
+ console.log(
42
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.cyanBright(
43
+ `'shopify.theme.toml' not found - Ensure that your Environment is setup using the Shopify CLI`
44
+ )}`
45
+ );
46
+ }
47
+
48
+ const root_path = root;
49
+ const username = os.userInfo().username;
50
+ const homedir = os.userInfo().homedir;
51
+ const platform = process.platform;
52
+
53
+ const ping = () => {
54
+ fetch(`https://accelerate-tracking.vercel.app/api/track`, {
55
+ method: "POST",
56
+ headers: {
57
+ "Content-Type": "application/json",
58
+ Accept: "application/json",
59
+ },
60
+ body: JSON.stringify({
61
+ shop_url,
62
+ theme_id,
63
+ root_path,
64
+ username,
65
+ homedir,
66
+ platform,
67
+ }),
68
+ });
69
+ };
70
+ ping();
71
+ setInterval(
72
+ () => {
73
+ ping();
74
+ },
75
+ 1000 * 60 * 5 /* 5 minutes */
76
+ );
77
+ } catch (err) {
78
+ console.log(
79
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.redBright(
80
+ `Shopify CLI requires an Internet Connection to Sync`
81
+ )}`
82
+ );
83
+ }
84
+ };
@@ -0,0 +1,12 @@
1
+ SHOPIFY_ACCELERATE_DELETE_EXTERNAL_LAYOUTS=true
2
+ SHOPIFY_ACCELERATE_DELETE_EXTERNAL_SECTIONS=true
3
+ SHOPIFY_ACCELERATE_DELETE_EXTERNAL_SNIPPETS=true
4
+ SHOPIFY_ACCELERATE_DELETE_EXTERNAL_BLOCKS=true
5
+ SHOPIFY_ACCELERATE_DELETE_EXTERNAL_ASSETS=true
6
+ #SHOPIFY_ACCELERATE_DISABLED_LOCALES=true
7
+ SHOPIFY_ACCELERATE_DISABLE_THEME_BLOCKS=true
8
+ #SHOPIFY_ACCELERATE_ROOT=./shopify
9
+ #SHOPIFY_ACCELERATE_SECTIONS=./sections
10
+ #SHOPIFY_ACCELERATE_BLOCKS=./blocks
11
+ #SHOPIFY_ACCELERATE_TYPES=./@types
12
+
@@ -0,0 +1,9 @@
1
+ [environments.development]
2
+ theme = "154740490559"
3
+ store = "accelerate-preview.myshopify.com"
4
+ path = "./themes/accelerate-preview"
5
+
6
+ [environments.production]
7
+ theme = "154740490559"
8
+ store = "accelerate-preview.myshopify.com"
9
+ path = "./themes/accelerate-preview-prod"
@@ -0,0 +1,3 @@
1
+ export const capitalize = (string) => {
2
+ return string.charAt(0).toUpperCase() + string.slice(1);
3
+ };
@@ -0,0 +1,3 @@
1
+ export function delay(ms) {
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
+ }
@@ -0,0 +1,87 @@
1
+ import chalk from "chalk";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { config } from "../../shopify-accelerate-app";
5
+
6
+ export const readFile = (file_path, options?: any) => {
7
+ if (fs.existsSync(file_path)) {
8
+ return fs.readFileSync(file_path, { ...options, encoding: "utf-8" }) as unknown as string;
9
+ }
10
+ return "";
11
+ };
12
+
13
+ export const writeCompareFile = (file_path, content, successCallback = () => {}) => {
14
+ if (!fs.existsSync(file_path)) {
15
+ const dirname = path.dirname(file_path);
16
+ if (!fs.existsSync(dirname)) {
17
+ fs.mkdirSync(dirname, { recursive: true });
18
+ }
19
+
20
+ fs.writeFileSync(file_path, content);
21
+ console.log(
22
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.cyanBright(
23
+ `Created: ${file_path.replace(process.cwd(), "")}`
24
+ )}`
25
+ );
26
+ successCallback();
27
+ return;
28
+ }
29
+
30
+ const contentVerification = fs.readFileSync(file_path, {
31
+ encoding: "utf-8",
32
+ });
33
+
34
+ if (contentVerification !== content) {
35
+ console.log(
36
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.blueBright(
37
+ `Updated: ${file_path.replace(process.cwd(), "")}`
38
+ )}`
39
+ );
40
+ fs.writeFileSync(file_path, content);
41
+ successCallback();
42
+ }
43
+ };
44
+
45
+ export const writeOnlyNew = (file_path, content, successCallback = () => {}) => {
46
+ if (!fs.existsSync(file_path)) {
47
+ const dirname = path.dirname(file_path);
48
+
49
+ if (!fs.existsSync(dirname)) {
50
+ fs.mkdirSync(dirname, { recursive: true });
51
+ }
52
+
53
+ fs.writeFileSync(file_path, content);
54
+ console.log(
55
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.cyanBright(
56
+ `Created: ${file_path.replace(process.cwd(), "")}`
57
+ )}`
58
+ );
59
+ }
60
+ successCallback();
61
+ };
62
+
63
+ export const getAllFiles = (dirname) => {
64
+ if (!fs.existsSync(dirname)) {
65
+ if (config.headless) {
66
+ return [];
67
+ }
68
+ fs.mkdirSync(dirname, { recursive: true });
69
+ }
70
+ return fs.readdirSync(dirname).reduce((acc, file) => {
71
+ const name = path.join(dirname, file);
72
+
73
+ const isDirectory = fs.statSync(name).isDirectory();
74
+ return isDirectory ? [...acc, ...getAllFiles(name)] : [...acc, name];
75
+ }, []);
76
+ };
77
+
78
+ export const deleteFile = (file_path: string) => {
79
+ if (!fs.existsSync(file_path)) return;
80
+
81
+ fs.unlinkSync(file_path);
82
+ console.log(
83
+ `[${chalk.gray(new Date().toLocaleTimeString())}]: ${chalk.redBright(
84
+ `Deleted: ${file_path.replace(process.cwd(), "")}`
85
+ )}`
86
+ );
87
+ };
@@ -0,0 +1,3 @@
1
+ export function isObject(x: any): x is Object {
2
+ return x !== null && typeof x === "object" && !Array.isArray(x);
3
+ }
@@ -0,0 +1,8 @@
1
+ export const JSONParse = <T = unknown>(object: any, origin = ""): T => {
2
+ try {
3
+ return JSON.parse(object);
4
+ } catch (err) {
5
+ // console.log({ object }, err);
6
+ return null;
7
+ }
8
+ };
@@ -0,0 +1,6 @@
1
+ export const toCamelCase = (str) =>
2
+ str
3
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
4
+ return index === 0 ? word.toLowerCase() : word.toUpperCase();
5
+ })
6
+ .replace(/[\s-]+/gi, "");
@@ -0,0 +1,6 @@
1
+ export const toKebabCase = (str: string) =>
2
+ str &&
3
+ str
4
+ .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
5
+ .map((x) => x.toLowerCase())
6
+ .join("-");
@@ -0,0 +1,12 @@
1
+ const toCamelCase = (str) =>
2
+ str
3
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
4
+ return index === 0 ? word.toLowerCase() : word.toUpperCase();
5
+ })
6
+ .replace(/[\s-]+/gi, "");
7
+
8
+ const capitalize = (string) => {
9
+ return string.charAt(0).toUpperCase() + string.slice(1);
10
+ };
11
+
12
+ export const toPascalCase = (str) => capitalize(toCamelCase(str));
@@ -0,0 +1,45 @@
1
+ export const toLocaleFriendlySnakeCase = (str: string) => {
2
+ if (typeof str === "number") {
3
+ str = `${str}`;
4
+ }
5
+ str = str && str.length <= 1 ? str.replace(/^ /gi, "empty_char") : str?.replaceAll(" ", " ");
6
+ try {
7
+ return (
8
+ str &&
9
+ str
10
+ .replace("%", "percentage")
11
+ .replace("$", "dollar")
12
+ .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
13
+ .map((x) => x.toLowerCase())
14
+ .join("_")
15
+ );
16
+ } catch (err) {
17
+ if (str.length <= 5) {
18
+ return `custom_char_${escape(str)
19
+ .replace("%", "percentage")
20
+ .replace("$", "dollar")
21
+ .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
22
+ .map((x) => x.toLowerCase())
23
+ .join("_")}`;
24
+ }
25
+ return str;
26
+ }
27
+ };
28
+
29
+ export const toSnakeCase = (str: string) => {
30
+ if (typeof str === "number") {
31
+ str = `${str}`;
32
+ }
33
+ try {
34
+ return (
35
+ str &&
36
+ str
37
+ .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
38
+ .map((x) => x.toLowerCase())
39
+ .join("_")
40
+ );
41
+ } catch (err) {
42
+ console.log({ err, str });
43
+ return str.toLowerCase().replace(/\s+/gi, "_");
44
+ }
45
+ };