appflare 0.0.26 → 0.0.27

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 (2) hide show
  1. package/cli/index.ts +48 -1
  2. package/package.json +1 -1
package/cli/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  import chokidar, { FSWatcher } from "chokidar";
4
4
  import { Command } from "commander";
5
5
  import { promises as fs } from "node:fs";
6
+ import os from "node:os";
6
7
  import path from "node:path";
7
8
  import { pathToFileURL } from "node:url";
8
9
  import {
@@ -82,13 +83,59 @@ async function main(): Promise<void> {
82
83
  await program.parseAsync(process.argv);
83
84
  }
84
85
 
86
+ /**
87
+ * Regex that matches ES import lines pulling in React Native / Expo native
88
+ * modules (e.g. `import * as SecureStore from "expo-secure-store"`).
89
+ * These cannot be transpiled by Bun and are only needed at client runtime.
90
+ */
91
+ const NATIVE_IMPORT_RE =
92
+ /^import\s+(?:(?:\*\s+as\s+(\w+))|(?:\{[^}]*\})|(?:(\w+)(?:\s*,\s*\{[^}]*\})?))?\s*from\s*["'](expo-[^"']+)["'];?\s*$/gm;
93
+
94
+ /**
95
+ * Strip native-module imports from a config source and replace them with
96
+ * harmless stub declarations so the CLI can evaluate the config object
97
+ * without triggering Bun transpilation errors on native code.
98
+ */
99
+ function sanitizeConfigSource(source: string): string {
100
+ const stubs: string[] = [];
101
+ const sanitized = source.replace(
102
+ NATIVE_IMPORT_RE,
103
+ (_match, starAs, defaultImport, _mod) => {
104
+ const name = starAs || defaultImport;
105
+ if (name) {
106
+ stubs.push(`const ${name} = {} as any;`);
107
+ }
108
+ return ""; // remove the original import line
109
+ },
110
+ );
111
+ return stubs.length > 0 ? stubs.join("\n") + "\n" + sanitized : sanitized;
112
+ }
113
+
85
114
  async function loadConfig(
86
115
  configPathAbs: string,
87
116
  ): Promise<{ config: AppflareConfig; configDirAbs: string }> {
88
117
  await assertFileExists(configPathAbs, `Config not found: ${configPathAbs}`);
89
118
  const configDirAbs = path.dirname(configPathAbs);
90
119
 
91
- const mod = await import(pathToFileURL(configPathAbs).href);
120
+ // Read the config source and strip native-module imports (e.g. expo-secure-store)
121
+ // that Bun cannot transpile. Write the sanitized source to a temp file and import that.
122
+ const raw = await fs.readFile(configPathAbs, "utf-8");
123
+ const sanitized = sanitizeConfigSource(raw);
124
+
125
+ let mod: Record<string, unknown>;
126
+ if (sanitized !== raw) {
127
+ const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "appflare-cfg-"));
128
+ const tmpFile = path.join(tmpDir, path.basename(configPathAbs));
129
+ await fs.writeFile(tmpFile, sanitized);
130
+ try {
131
+ mod = await import(pathToFileURL(tmpFile).href);
132
+ } finally {
133
+ await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {});
134
+ }
135
+ } else {
136
+ mod = await import(pathToFileURL(configPathAbs).href);
137
+ }
138
+
92
139
  const config = (mod?.default ?? mod) as Partial<AppflareConfig>;
93
140
  if (!config || typeof config !== "object") {
94
141
  throw new Error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appflare",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "bin": {
5
5
  "appflare": "./cli/index.ts"
6
6
  },