@tamagui/cli 2.0.0-rc.8 → 2.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.
package/dist/add.cjs CHANGED
@@ -2,92 +2,117 @@ var __create = Object.create;
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf,
6
- __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
7
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: !0
11
- });
12
- },
13
- __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
16
  get: () => from[key],
16
17
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
18
  });
18
- return to;
19
- };
19
+ }
20
+ return to;
21
+ };
20
22
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
- value: mod,
27
- enumerable: !0
28
- }) : target, mod)),
29
- __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
30
- value: !0
31
- }), mod);
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
+ value: mod,
29
+ enumerable: true
30
+ }) : target, mod));
31
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
+ value: true
33
+ }), mod);
32
34
  var add_exports = {};
33
35
  __export(add_exports, {
34
36
  generatedPackageTypes: () => generatedPackageTypes,
35
37
  installGeneratedPackage: () => installGeneratedPackage
36
38
  });
37
39
  module.exports = __toCommonJS(add_exports);
38
- var import_node_child_process = require("node:child_process"),
39
- import_node_fs = require("node:fs"),
40
- import_promises = require("node:fs/promises"),
41
- import_node_os = require("node:os"),
42
- import_node_path = __toESM(require("node:path")),
43
- import_chalk = __toESM(require("chalk")),
44
- import_change_case = require("change-case"),
45
- import_fs_extra = require("fs-extra"),
46
- import_marked = require("marked"),
47
- import_marked_terminal = __toESM(require("marked-terminal")),
48
- import_opener = __toESM(require("opener")),
49
- import_prompts = __toESM(require("prompts"));
40
+ var import_node_child_process = require("node:child_process");
41
+ var import_node_fs = require("node:fs");
42
+ var import_promises = require("node:fs/promises");
43
+ var import_node_os = require("node:os");
44
+ var import_node_path = __toESM(require("node:path"));
45
+ var import_chalk = __toESM(require("chalk"));
46
+ var import_change_case = require("change-case");
47
+ var import_fs_extra = require("fs-extra");
48
+ var import_marked = require("marked");
49
+ var import_marked_terminal = __toESM(require("marked-terminal"));
50
+ var import_opener = __toESM(require("opener"));
51
+ var import_prompts = __toESM(require("prompts"));
50
52
  import_marked.marked.setOptions({
51
53
  renderer: new import_marked_terminal.default()
52
54
  });
53
- const home = (0, import_node_os.homedir)(),
54
- tamaguiDir = import_node_path.default.join(home, ".tamagui"),
55
- generatedPackageTypes = ["font", "icon"],
56
- installGeneratedPackage = async (type, packagesPath) => {
57
- if (packagesPath = packagesPath || import_node_path.default.join(process.cwd(), "packages"), !generatedPackageTypes.includes(type)) throw new Error(`${type ? `Type "${type}" is Not supported.` : "No type provided."} Supported types: ${generatedPackageTypes.join(", ")}`);
58
- const repoName = type === "font" ? "tamagui-google-fonts" : "tamagui-iconify";
59
- console.info(`Setting up ${import_chalk.default.blueBright(tamaguiDir)}...`), await (0, import_fs_extra.ensureDir)(tamaguiDir);
60
- const tempDir = import_node_path.default.join(tamaguiDir, repoName);
61
- (0, import_node_fs.existsSync)(tempDir) && (0, import_node_fs.rmSync)(tempDir, {
62
- recursive: !0
55
+ const home = (0, import_node_os.homedir)();
56
+ const tamaguiDir = import_node_path.default.join(home, ".tamagui");
57
+ const generatedPackageTypes = ["font", "icon"];
58
+ const installGeneratedPackage = async (type, packagesPath) => {
59
+ packagesPath = packagesPath || import_node_path.default.join(process.cwd(), "packages");
60
+ if (!generatedPackageTypes.includes(type)) {
61
+ throw new Error(`${type ? `Type "${type}" is Not supported.` : `No type provided.`} Supported types: ${generatedPackageTypes.join(", ")}`);
62
+ }
63
+ const repoName = type === "font" ? "tamagui-google-fonts" : "tamagui-iconify";
64
+ console.info(`Setting up ${import_chalk.default.blueBright(tamaguiDir)}...`);
65
+ await (0, import_fs_extra.ensureDir)(tamaguiDir);
66
+ const tempDir = import_node_path.default.join(tamaguiDir, repoName);
67
+ if ((0, import_node_fs.existsSync)(tempDir)) {
68
+ (0, import_node_fs.rmSync)(tempDir, {
69
+ recursive: true
63
70
  });
71
+ }
72
+ try {
73
+ process.chdir(tamaguiDir);
64
74
  try {
65
- process.chdir(tamaguiDir);
66
- try {
67
- console.info("Attempting to clone with SSH"), (0, import_node_child_process.execSync)(`git clone -n --depth=1 --branch generated --filter=tree:0 git@github.com:tamagui/${repoName}.git`);
68
- } catch {
69
- console.info("SSH failed - Attempting to c lone with HTTPS"), (0, import_node_child_process.execSync)(`git clone -n --depth=1 --branch generated --filter=tree:0 https://github.com/tamagui/${repoName}`);
70
- }
71
- process.chdir(tempDir), (0, import_node_child_process.execSync)(["git sparse-checkout set --no-cone meta", "git checkout"].join(" && "));
75
+ console.info("Attempting to clone with SSH");
76
+ (0, import_node_child_process.execSync)(`git clone -n --depth=1 --branch generated --filter=tree:0 git@github.com:tamagui/${repoName}.git`);
72
77
  } catch (error) {
73
- if (error instanceof Error) throw error?.stderr.includes("Repository not found") && (console.info(import_chalk.default.yellow(`You don't have access to Tamagui ${type === "font" ? "fonts" : "icons"}. Check \u{1F961} Tamagui Takeout (https://tamagui.dev/takeout) for more info.`)), (0, import_opener.default)("https://tamagui.dev/takeout"), process.exit(0)), error;
78
+ console.info("SSH failed - Attempting to c lone with HTTPS");
79
+ (0, import_node_child_process.execSync)(`git clone -n --depth=1 --branch generated --filter=tree:0 https://github.com/tamagui/${repoName}`);
80
+ }
81
+ process.chdir(tempDir);
82
+ (0, import_node_child_process.execSync)([`git sparse-checkout set --no-cone meta`, `git checkout`].join(" && "));
83
+ } catch (error) {
84
+ if (error instanceof Error) {
85
+ if (error?.stderr.includes("Repository not found")) {
86
+ console.info(import_chalk.default.yellow(`You don't have access to Tamagui ${type === "font" ? "fonts" : "icons"}. Check \u{1F961} Tamagui Takeout (https://tamagui.dev/takeout) for more info.`));
87
+ (0, import_opener.default)("https://tamagui.dev/takeout");
88
+ process.exit(0);
89
+ }
90
+ throw error;
74
91
  }
75
- const meta = JSON.parse(await (0, import_promises.readFile)(import_node_path.default.join(tamaguiDir, repoName, "meta", "data.json")).then(r => r.toString()));
76
- console.info(import_chalk.default.gray("Use \u21E7/\u21E9 to navigate. Use tab to cycle the result. Use Page Up/Page Down (on Mac: fn + \u21E7 / \u21E9) to change page. Hit enter to select the highlighted item below the prompt."));
77
- const result = await (0, import_prompts.default)({
78
- name: "packageName",
79
- type: "autocomplete",
80
- message: type === "icon" ? "Pick an icon pack:" : type === "font" ? "Pick a font:" : "Pick one:",
81
- choices: Object.entries(meta).map(([slug, data]) => ({
82
- title: type === "font" ? `${slug}: ${data.weights.length} weights, ${data.styles.length} styles, ${data.subsets.length} subsets (https://fonts.google.com/specimen/${(0, import_change_case.pascalCase)(slug)})` : `${data.name}: ${data.total} icons, ${data.license.title} license (${data.author.url})`,
83
- value: slug
84
- }))
85
- }),
86
- packageName = `${type}-${result.packageName}`,
87
- packageDir = import_node_path.default.join(tempDir, "packages", packageName);
88
- process.chdir(tempDir), (0, import_node_child_process.execSync)([`git sparse-checkout set --no-cone packages/${packageName}`, "git checkout"].join(" && "));
89
- const finalDir = import_node_path.default.join(packagesPath, packageName);
90
- await (0, import_fs_extra.ensureDir)(packagesPath), await (0, import_fs_extra.copy)(packageDir, finalDir), console.info(), console.info(import_chalk.default.green(`Created the package under ${finalDir}`)), console.info();
91
- const readmePath = import_node_path.default.join(finalDir, "README.md");
92
- (0, import_node_fs.existsSync)(readmePath) && console.info(import_marked.marked.parse((0, import_fs_extra.readFileSync)(readmePath).toString()));
93
- };
92
+ }
93
+ const meta = JSON.parse(await (0, import_promises.readFile)(import_node_path.default.join(tamaguiDir, repoName, `meta`, `data.json`)).then(r => r.toString()));
94
+ console.info(import_chalk.default.gray(`Use \u21E7/\u21E9 to navigate. Use tab to cycle the result. Use Page Up/Page Down (on Mac: fn + \u21E7 / \u21E9) to change page. Hit enter to select the highlighted item below the prompt.`));
95
+ const result = await (0, import_prompts.default)({
96
+ name: "packageName",
97
+ type: "autocomplete",
98
+ message: type === "icon" ? `Pick an icon pack:` : type === "font" ? `Pick a font:` : `Pick one:`,
99
+ choices: Object.entries(meta).map(([slug, data]) => ({
100
+ title: type === "font" ? `${slug}: ${data.weights.length} weights, ${data.styles.length} styles, ${data.subsets.length} subsets (https://fonts.google.com/specimen/${(0, import_change_case.pascalCase)(slug)})` : `${data.name}: ${data.total} icons, ${data.license.title} license (${data.author.url})`,
101
+ value: slug
102
+ }))
103
+ });
104
+ const packageName = `${type}-${result.packageName}`;
105
+ const packageDir = import_node_path.default.join(tempDir, "packages", packageName);
106
+ process.chdir(tempDir);
107
+ (0, import_node_child_process.execSync)([`git sparse-checkout set --no-cone packages/${packageName}`, `git checkout`].join(" && "));
108
+ const finalDir = import_node_path.default.join(packagesPath, packageName);
109
+ await (0, import_fs_extra.ensureDir)(packagesPath);
110
+ await (0, import_fs_extra.copy)(packageDir, finalDir);
111
+ console.info();
112
+ console.info(import_chalk.default.green(`Created the package under ${finalDir}`));
113
+ console.info();
114
+ const readmePath = import_node_path.default.join(finalDir, "README.md");
115
+ if ((0, import_node_fs.existsSync)(readmePath)) {
116
+ console.info(import_marked.marked.parse((0, import_fs_extra.readFileSync)(readmePath).toString()));
117
+ }
118
+ };
package/dist/build.cjs CHANGED
@@ -2,80 +2,96 @@ var __create = Object.create;
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf,
6
- __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
7
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: !0
11
- });
12
- },
13
- __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
16
  get: () => from[key],
16
17
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
18
  });
18
- return to;
19
- };
19
+ }
20
+ return to;
21
+ };
20
22
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
- value: mod,
27
- enumerable: !0
28
- }) : target, mod)),
29
- __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
30
- value: !0
31
- }), mod);
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
+ value: mod,
29
+ enumerable: true
30
+ }) : target, mod));
31
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
+ value: true
33
+ }), mod);
32
34
  var build_exports = {};
33
35
  __export(build_exports, {
34
36
  build: () => build,
35
37
  insertCssImport: () => insertCssImport
36
38
  });
37
39
  module.exports = __toCommonJS(build_exports);
38
- var import_static = require("@tamagui/static"),
39
- import_chokidar = __toESM(require("chokidar")),
40
- import_fs_extra = require("fs-extra"),
41
- import_micromatch = __toESM(require("micromatch")),
42
- import_node_path = require("node:path"),
43
- import_node_os = require("node:os"),
44
- import_node_child_process = require("node:child_process"),
45
- import_node_crypto = require("node:crypto");
40
+ var import_static = require("@tamagui/static");
41
+ var import_chokidar = __toESM(require("chokidar"));
42
+ var import_fs_extra = require("fs-extra");
43
+ var import_micromatch = __toESM(require("micromatch"));
44
+ var import_node_path = require("node:path");
45
+ var import_node_os = require("node:os");
46
+ var import_node_child_process = require("node:child_process");
47
+ var import_node_crypto = require("node:crypto");
46
48
  function insertCssImport(jsContent, cssImport) {
47
49
  const directiveMatch = jsContent.match(/^(['"])use (client|server)\1;?\n?/);
48
50
  if (directiveMatch) {
49
- const directive = directiveMatch[0],
50
- rest = jsContent.slice(directive.length);
51
+ const directive = directiveMatch[0];
51
52
  return `${directive}${cssImport}
52
- ${rest}`;
53
+ ${jsContent.slice(directive.length)}`;
53
54
  }
54
55
  return `${cssImport}
55
56
  ${jsContent}`;
56
57
  }
57
58
  const build = async options => {
58
- const sourceDir = options.dir ?? ".",
59
- promises = [],
60
- isDryRun = options.dryRun || !1;
61
- isDryRun && console.info(`[dry-run] no files will be written
62
- `);
63
- const buildOptions = (0, import_static.loadTamaguiBuildConfigSync)(options.tamaguiOptions),
64
- targets = options.target === "both" || !options.target ? ["web", "native"] : [options.target],
65
- webTamaguiOptions = {
66
- ...buildOptions,
67
- platform: "web"
68
- };
59
+ const sourceDir = options.dir ?? ".";
60
+ const outputDir = options.output;
61
+ const outputAround = options.outputAround || false;
62
+ const promises = [];
63
+ const isDryRun = options.dryRun || false;
64
+ if (isDryRun) console.info("[dry-run] no files will be written\n");
65
+ if (outputDir) await (0, import_fs_extra.mkdir)(outputDir, {
66
+ recursive: true
67
+ });
68
+ const loadedOptions = (0, import_static.loadTamaguiBuildConfigSync)(options.tamaguiOptions);
69
+ if (loadedOptions.disable) console.warn(`[tamagui] Note: "disable" option in tamagui.build.ts is being ignored for CLI build command`);
70
+ const buildOptions = {
71
+ ...loadedOptions,
72
+ disable: false,
73
+ disableExtraction: false
74
+ };
75
+ const targets = options.target === "both" || !options.target ? ["web", "native"] : [options.target];
76
+ const webTamaguiOptions = {
77
+ ...buildOptions,
78
+ platform: "web"
79
+ };
69
80
  await (0, import_static.loadTamagui)(webTamaguiOptions);
70
- const allFiles = [],
71
- watchPattern = sourceDir.match(/\.(tsx|jsx)$/) ? sourceDir : `${sourceDir}/**/*.{tsx,jsx}`;
81
+ const allFiles = [];
82
+ const watchPattern = sourceDir.match(/\.(tsx|jsx)$/) ? sourceDir : `${sourceDir}/**/*.{tsx,jsx}`;
72
83
  await new Promise(res => {
73
- import_chokidar.default.watch(watchPattern, {
74
- ignoreInitial: !1
75
- }).on("add", relativePath => {
84
+ const watcher = import_chokidar.default.watch(watchPattern, {
85
+ ignoreInitial: false
86
+ });
87
+ watcher.on("add", relativePath => {
76
88
  const sourcePath = (0, import_node_path.resolve)(process.cwd(), relativePath);
77
- options.exclude && import_micromatch.default.contains(relativePath, options.exclude) || options.include && !import_micromatch.default.contains(relativePath, options.include) || allFiles.push(sourcePath);
78
- }).on("ready", () => res());
89
+ if (options.exclude && import_micromatch.default.contains(relativePath, options.exclude)) return;
90
+ if (options.include && !import_micromatch.default.contains(relativePath, options.include)) return;
91
+ allFiles.push(sourcePath);
92
+ }).on("ready", () => {
93
+ watcher.close().then(() => res());
94
+ });
79
95
  });
80
96
  const fileToTargets = /* @__PURE__ */new Map();
81
97
  for (const sourcePath of allFiles) {
@@ -83,113 +99,162 @@ const build = async options => {
83
99
  let filePlatforms = [];
84
100
  if (platformMatch) {
85
101
  const platform = platformMatch[1];
86
- platform === "web" ? filePlatforms = ["web"] : (platform === "native" || platform === "ios" || platform === "android") && (filePlatforms = ["native"]);
102
+ if (platform === "web") filePlatforms = ["web"];else if (platform === "native" || platform === "ios" || platform === "android") filePlatforms = ["native"];
87
103
  } else {
88
- const basePath = sourcePath.replace(/\.(tsx|jsx)$/, ""),
89
- hasNative = allFiles.some(f => f === `${basePath}.native.tsx` || f === `${basePath}.native.jsx` || f === `${basePath}.ios.tsx` || f === `${basePath}.ios.jsx` || f === `${basePath}.android.tsx` || f === `${basePath}.android.jsx`),
90
- hasWeb = allFiles.some(f => f === `${basePath}.web.tsx` || f === `${basePath}.web.jsx`);
91
- filePlatforms = targets.filter(target => !(target === "native" && hasNative || target === "web" && hasWeb)), hasWeb && hasNative && (filePlatforms = []);
104
+ const basePath = sourcePath.replace(/\.(tsx|jsx)$/, "");
105
+ const hasNative = allFiles.some(f => f === `${basePath}.native.tsx` || f === `${basePath}.native.jsx` || f === `${basePath}.ios.tsx` || f === `${basePath}.ios.jsx` || f === `${basePath}.android.tsx` || f === `${basePath}.android.jsx`);
106
+ const hasWeb = allFiles.some(f => f === `${basePath}.web.tsx` || f === `${basePath}.web.jsx`);
107
+ filePlatforms = targets.filter(target => {
108
+ if (target === "native" && hasNative) return false;
109
+ if (target === "web" && hasWeb) return false;
110
+ return true;
111
+ });
112
+ if (hasWeb && hasNative) filePlatforms = [];
92
113
  }
93
- filePlatforms.length > 0 && fileToTargets.set(sourcePath, filePlatforms);
114
+ if (filePlatforms.length > 0) fileToTargets.set(sourcePath, filePlatforms);
94
115
  }
95
116
  const stats = {
96
- filesProcessed: 0,
97
- optimized: 0,
98
- flattened: 0,
99
- styled: 0,
100
- found: 0
101
- },
102
- trackedFiles = [],
103
- restoreDir = options.runCommand ? (0, import_node_path.join)((0, import_node_os.tmpdir)(), `tamagui-restore-${process.pid}`) : null;
104
- restoreDir && (await (0, import_fs_extra.mkdir)(restoreDir, {
105
- recursive: !0
106
- }));
117
+ filesProcessed: 0,
118
+ optimized: 0,
119
+ flattened: 0,
120
+ styled: 0,
121
+ found: 0
122
+ };
123
+ const trackedFiles = [];
124
+ const restoreDir = options.runCommand ? (0, import_node_path.join)((0, import_node_os.tmpdir)(), `tamagui-restore-${process.pid}`) : null;
125
+ if (restoreDir) await (0, import_fs_extra.mkdir)(restoreDir, {
126
+ recursive: true
127
+ });
107
128
  const trackFile = async filePath => {
108
- if (!restoreDir) return;
109
- const hash = (0, import_node_crypto.createHash)("md5").update(filePath).digest("hex"),
110
- backupPath = (0, import_node_path.join)(restoreDir, hash);
111
- await (0, import_fs_extra.copyFile)(filePath, backupPath), trackedFiles.push({
112
- path: filePath,
113
- hardlinkPath: backupPath,
114
- mtimeAfterWrite: 0
115
- });
116
- },
117
- recordMtime = async filePath => {
118
- if (!restoreDir) return;
119
- const tracked = trackedFiles.find(t => t.path === filePath);
120
- if (tracked) {
121
- const fileStat = await (0, import_fs_extra.stat)(filePath);
122
- tracked.mtimeAfterWrite = fileStat.mtimeMs;
123
- }
124
- };
129
+ if (!restoreDir) return;
130
+ const hash = (0, import_node_crypto.createHash)("md5").update(filePath).digest("hex");
131
+ const backupPath = (0, import_node_path.join)(restoreDir, hash);
132
+ await (0, import_fs_extra.copyFile)(filePath, backupPath);
133
+ trackedFiles.push({
134
+ path: filePath,
135
+ hardlinkPath: backupPath,
136
+ mtimeAfterWrite: 0
137
+ });
138
+ };
139
+ const recordMtime = async filePath => {
140
+ if (!restoreDir) return;
141
+ const tracked = trackedFiles.find(t => t.path === filePath);
142
+ if (tracked) tracked.mtimeAfterWrite = (await (0, import_fs_extra.stat)(filePath)).mtimeMs;
143
+ };
125
144
  for (const [sourcePath, filePlatforms] of fileToTargets) promises.push((async () => {
126
- options.debug && (process.env.NODE_ENV ||= "development");
145
+ if (options.debug) process.env.NODE_ENV ||= "development";
127
146
  const originalSource = await (0, import_fs_extra.readFile)(sourcePath, "utf-8");
128
- if (isDryRun && console.info(`
129
- ${sourcePath} [${filePlatforms.join(", ")}]`), filePlatforms.includes("web")) {
147
+ if (isDryRun) console.info(`
148
+ ${sourcePath} [${filePlatforms.join(", ")}]`);
149
+ if (filePlatforms.includes("web")) {
130
150
  process.env.TAMAGUI_TARGET = "web";
131
151
  const extractor = (0, import_static.createExtractor)({
152
+ platform: "web"
153
+ });
154
+ const out = await (0, import_static.extractToClassNames)({
155
+ extractor,
156
+ source: originalSource,
157
+ sourcePath,
158
+ options: {
159
+ ...buildOptions,
132
160
  platform: "web"
133
- }),
134
- out = await (0, import_static.extractToClassNames)({
135
- extractor,
136
- source: originalSource,
137
- sourcePath,
138
- options: {
139
- ...buildOptions,
140
- platform: "web"
141
- },
142
- shouldPrintDebug: options.debug || !1
143
- });
161
+ },
162
+ shouldPrintDebug: options.debug || false
163
+ });
144
164
  if (out) {
145
- if (stats.filesProcessed++, stats.optimized += out.stats.optimized, stats.flattened += out.stats.flattened, stats.styled += out.stats.styled, stats.found += out.stats.found, isDryRun) {
146
- const jsContent = typeof out.js == "string" ? out.js : out.js.toString("utf-8");
147
- out.styles && console.info(`
165
+ stats.filesProcessed++;
166
+ stats.optimized += out.stats.optimized;
167
+ stats.flattened += out.stats.flattened;
168
+ stats.styled += out.stats.styled;
169
+ stats.found += out.stats.found;
170
+ if (isDryRun) {
171
+ const jsContent = typeof out.js === "string" ? out.js : out.js.toString("utf-8");
172
+ if (out.styles) console.info(`
148
173
  css:
149
- ${out.styles}`), console.info(`
174
+ ${out.styles}`);
175
+ console.info(`
150
176
  js:
151
177
  ${jsContent}`);
152
178
  } else {
153
- const cssName = "_" + (0, import_node_path.basename)(sourcePath, (0, import_node_path.extname)(sourcePath)),
154
- stylePath = (0, import_node_path.join)((0, import_node_path.dirname)(sourcePath), cssName + ".css"),
155
- cssImport = `import "./${cssName}.css"`,
156
- jsContent = typeof out.js == "string" ? out.js : out.js.toString("utf-8"),
157
- code = insertCssImport(jsContent, cssImport);
158
- await trackFile(sourcePath), await (0, import_fs_extra.writeFile)(sourcePath, code, "utf-8"), await recordMtime(sourcePath), await (0, import_fs_extra.writeFile)(stylePath, out.styles, "utf-8"), trackedFiles.push({
179
+ const relPath = outputDir ? (0, import_node_path.relative)((0, import_node_path.resolve)(sourceDir), sourcePath) : (0, import_node_path.basename)(sourcePath);
180
+ const cssName = "_" + (0, import_node_path.basename)(sourcePath, (0, import_node_path.extname)(sourcePath));
181
+ const outputBase = outputDir ? (0, import_node_path.join)(outputDir, (0, import_node_path.dirname)(relPath)) : (0, import_node_path.dirname)(sourcePath);
182
+ if (outputDir) await (0, import_fs_extra.mkdir)(outputBase, {
183
+ recursive: true
184
+ });
185
+ const stylePath = (0, import_node_path.join)(outputBase, cssName + ".css");
186
+ const cssImport = `import "./${cssName}.css"`;
187
+ const code = insertCssImport(typeof out.js === "string" ? out.js : out.js.toString("utf-8"), cssImport);
188
+ const webOutputPath = outputDir ? (0, import_node_path.join)(outputDir, relPath) : sourcePath;
189
+ if (!outputDir) await trackFile(sourcePath);
190
+ await (0, import_fs_extra.writeFile)(webOutputPath, code, "utf-8");
191
+ if (!outputDir) await recordMtime(sourcePath);
192
+ await (0, import_fs_extra.writeFile)(stylePath, out.styles, "utf-8");
193
+ if (!outputDir) trackedFiles.push({
159
194
  path: stylePath,
160
195
  hardlinkPath: "",
161
- // Empty means delete on restore
162
196
  mtimeAfterWrite: (await (0, import_fs_extra.stat)(stylePath)).mtimeMs
163
197
  });
164
198
  }
165
- } else isDryRun && console.info(" web: no output");
199
+ } else if (isDryRun) console.info(` web: no output`);
166
200
  }
167
201
  if (filePlatforms.includes("native")) {
168
202
  process.env.TAMAGUI_TARGET = "native";
169
203
  const nativeTamaguiOptions = {
170
- ...buildOptions,
171
- platform: "native"
172
- },
173
- nativeOut = (0, import_static.extractToNative)(sourcePath, originalSource, nativeTamaguiOptions);
174
- if (isDryRun) nativeOut.code ? console.info(`
204
+ ...buildOptions,
205
+ platform: "native"
206
+ };
207
+ const nativeOut = (0, import_static.extractToNative)(sourcePath, originalSource, nativeTamaguiOptions);
208
+ if (isDryRun) {
209
+ if (nativeOut.code) console.info(`
175
210
  native:
176
- ${nativeOut.code}`) : console.info(" native: no output");else {
211
+ ${nativeOut.code}`);else console.info(` native: no output`);
212
+ } else {
177
213
  let nativeOutputPath = sourcePath;
178
- !/\.(web|native|ios|android)\.(tsx|jsx)$/.test(sourcePath) && filePlatforms.length > 1 && (nativeOutputPath = sourcePath.replace(/\.(tsx|jsx)$/, ".native.$1")), nativeOut.code && ((nativeOutputPath === sourcePath || filePlatforms.length === 1) && (await trackFile(nativeOutputPath)), await (0, import_fs_extra.writeFile)(nativeOutputPath, nativeOut.code, "utf-8"), await recordMtime(nativeOutputPath), nativeOutputPath !== sourcePath && filePlatforms.length > 1 && trackedFiles.push({
179
- path: nativeOutputPath,
180
- hardlinkPath: "",
181
- // Empty = delete on restore
182
- mtimeAfterWrite: (await (0, import_fs_extra.stat)(nativeOutputPath)).mtimeMs
183
- }));
214
+ const needsNativeSuffix = !/\.(web|native|ios|android)\.(tsx|jsx)$/.test(sourcePath) && (filePlatforms.length > 1 || outputAround);
215
+ if (outputAround) {
216
+ nativeOutputPath = sourcePath.replace(/\.(tsx|jsx)$/, ".native.$1");
217
+ if (await (0, import_fs_extra.stat)(nativeOutputPath).catch(() => null)) throw new Error(`--output-around: ${nativeOutputPath} already exists. Remove it first or use --output instead.`);
218
+ } else if (outputDir) {
219
+ const relPath = (0, import_node_path.relative)((0, import_node_path.resolve)(sourceDir), sourcePath);
220
+ const outputRelPath = needsNativeSuffix ? relPath.replace(/\.(tsx|jsx)$/, ".native.$1") : relPath;
221
+ nativeOutputPath = (0, import_node_path.join)(outputDir, outputRelPath);
222
+ await (0, import_fs_extra.mkdir)((0, import_node_path.dirname)(nativeOutputPath), {
223
+ recursive: true
224
+ });
225
+ } else if (needsNativeSuffix) nativeOutputPath = sourcePath.replace(/\.(tsx|jsx)$/, ".native.$1");
226
+ if (nativeOut.code) {
227
+ if (nativeOut.code.includes("__ReactNativeStyleSheet") || nativeOut.code.includes("_withStableStyle")) {
228
+ stats.filesProcessed++;
229
+ const wrapperMatches = nativeOut.code.match(/_withStableStyle/g);
230
+ if (wrapperMatches) stats.flattened += wrapperMatches.length;
231
+ }
232
+ if (!outputDir && !outputAround && (nativeOutputPath === sourcePath || filePlatforms.length === 1)) await trackFile(nativeOutputPath);
233
+ await (0, import_fs_extra.writeFile)(nativeOutputPath, nativeOut.code, "utf-8");
234
+ if (!outputDir && !outputAround) await recordMtime(nativeOutputPath);
235
+ if (!outputDir && !outputAround && nativeOutputPath !== sourcePath && filePlatforms.length > 1) trackedFiles.push({
236
+ path: nativeOutputPath,
237
+ hardlinkPath: "",
238
+ mtimeAfterWrite: (await (0, import_fs_extra.stat)(nativeOutputPath)).mtimeMs
239
+ });
240
+ if (outputAround) console.info(` \u2192 ${nativeOutputPath}`);
241
+ }
184
242
  }
185
243
  }
186
244
  })());
187
- if (await Promise.all(promises), isDryRun && console.info(`
245
+ await Promise.all(promises);
246
+ if (isDryRun) console.info(`
188
247
  ${stats.filesProcessed} files | ${stats.found} found | ${stats.optimized} optimized | ${stats.flattened} flattened | ${stats.styled} styled
189
- `), options.expectOptimizations !== void 0) {
248
+ `);
249
+ if (options.expectOptimizations !== void 0) {
190
250
  const totalOptimizations = stats.optimized + stats.flattened;
191
- totalOptimizations < options.expectOptimizations && (console.error(`
192
- Expected at least ${options.expectOptimizations} optimizations but only got ${totalOptimizations}`), console.error(`Stats: ${JSON.stringify(stats, null, 2)}`), process.exit(1)), console.info(`
251
+ if (totalOptimizations < options.expectOptimizations) {
252
+ console.error(`
253
+ Expected at least ${options.expectOptimizations} optimizations but only got ${totalOptimizations}`);
254
+ console.error(`Stats: ${JSON.stringify(stats, null, 2)}`);
255
+ process.exit(1);
256
+ }
257
+ console.info(`
193
258
  \u2713 Met optimization target: ${totalOptimizations} >= ${options.expectOptimizations}`);
194
259
  }
195
260
  if (options.runCommand && options.runCommand.length > 0) {
@@ -203,7 +268,8 @@ Running: ${command}
203
268
  });
204
269
  } catch (err) {
205
270
  console.error(`
206
- Command failed with exit code ${err.status || 1}`), process.exitCode = err.status || 1;
271
+ Command failed with exit code ${err.status || 1}`);
272
+ process.exitCode = err.status || 1;
207
273
  } finally {
208
274
  await restoreFiles(trackedFiles, restoreDir);
209
275
  }
@@ -217,23 +283,32 @@ async function restoreFiles(trackedFiles, restoreDir) {
217
283
  if (!restoreDir || trackedFiles.length === 0) return;
218
284
  console.info(`
219
285
  Restoring ${trackedFiles.length} files...`);
220
- let restored = 0,
221
- skipped = 0,
222
- deleted = 0;
286
+ let restored = 0;
287
+ let skipped = 0;
288
+ let deleted = 0;
223
289
  for (const tracked of trackedFiles) try {
224
290
  const currentStat = await (0, import_fs_extra.stat)(tracked.path).catch(() => null);
225
291
  if (currentStat && currentStat.mtimeMs !== tracked.mtimeAfterWrite) {
226
- console.warn(` Skipping ${tracked.path} - modified during build`), skipped++;
292
+ console.warn(` Skipping ${tracked.path} - modified during build`);
293
+ skipped++;
227
294
  continue;
228
295
  }
229
- tracked.hardlinkPath === "" ? (await (0, import_fs_extra.rm)(tracked.path, {
230
- force: !0
231
- }), deleted++) : (await (0, import_fs_extra.copyFile)(tracked.hardlinkPath, tracked.path), restored++);
296
+ if (tracked.hardlinkPath === "") {
297
+ await (0, import_fs_extra.rm)(tracked.path, {
298
+ force: true
299
+ });
300
+ deleted++;
301
+ } else {
302
+ await (0, import_fs_extra.copyFile)(tracked.hardlinkPath, tracked.path);
303
+ restored++;
304
+ }
232
305
  } catch (err) {
233
- console.warn(` Failed to restore ${tracked.path}: ${err.message}`), skipped++;
306
+ console.warn(` Failed to restore ${tracked.path}: ${err.message}`);
307
+ skipped++;
234
308
  }
235
309
  await (0, import_fs_extra.rm)(restoreDir, {
236
- recursive: !0,
237
- force: !0
238
- }), console.info(` Restored: ${restored}, Deleted: ${deleted}, Skipped: ${skipped}`);
310
+ recursive: true,
311
+ force: true
312
+ });
313
+ console.info(` Restored: ${restored}, Deleted: ${deleted}, Skipped: ${skipped}`);
239
314
  }