expo-desktop 1.0.0-beta.0 → 1.0.0-beta.2

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.
@@ -27,6 +27,7 @@ const require = createRequire(import.meta.url);
27
27
  const JsonFile = require("@expo/json-file").default;
28
28
  const debug = Debug("expo-desktop:create-app:template");
29
29
  const isMacOS = process.platform === "darwin";
30
+ const isWindows = process.platform === "win32";
30
31
  // keep this list in sync with the validation helper in WWW: src/utils/experienceParser.ts
31
32
  const FORBIDDEN_NAMES = [
32
33
  "react-native",
@@ -435,7 +436,6 @@ export async function sanitizeTemplateAsync({ displayName: displayNameArg, rdns:
435
436
  android: {
436
437
  package: androidPackage,
437
438
  },
438
- // @ts-expect-error macos and windows missing from types
439
439
  windows: {
440
440
  displayName,
441
441
  namespace: windowsNamespace,
@@ -448,6 +448,10 @@ export async function sanitizeTemplateAsync({ displayName: displayNameArg, rdns:
448
448
  CFBundleName: displayName,
449
449
  },
450
450
  },
451
+ experiments: {
452
+ // @ts-expect-error Earlier Expo SDKs don't provide typings for this.
453
+ outOfTreePlatforms: true,
454
+ },
451
455
  };
452
456
  const appFile = new JsonFile(path.join(projectRoot, "app.json"), { default: {} });
453
457
  const appContent = (await appFile.readAsync());
@@ -613,13 +617,13 @@ export function logProjectReady({ cdPath, packageManager, }) {
613
617
  console.log();
614
618
  }
615
619
  console.log(`- ${chalk.bold(formatRunCommand(packageManager, "android"))}`);
616
- let macOSComment = "";
617
- if (!isMacOS) {
618
- macOSComment =
619
- " # you need to use macOS to build the iOS or macOS projects - use the Expo app if you need to do Apple development without a Mac";
620
- }
620
+ const macOSComment = isMacOS
621
+ ? ""
622
+ : " # you need to use macOS to build the iOS or macOS projects - use the Expo app if you need to do Apple development without a Mac";
621
623
  console.log(`- ${chalk.bold(formatRunCommand(packageManager, "ios"))}${macOSComment}`);
622
624
  console.log(`- ${chalk.bold(formatRunCommand(packageManager, "macos"))}${macOSComment}`);
625
+ const windowsComment = isWindows ? "" : " # you need to use Windows to build the Windows project";
626
+ console.log(`- ${chalk.bold(formatRunCommand(packageManager, "windows"))}${windowsComment}`);
623
627
  console.log(`- ${chalk.bold(formatRunCommand(packageManager, "web"))}`);
624
628
  }
625
629
  export async function installPodsAsync(projectRoot, platform) {
@@ -132,6 +132,16 @@ export function updatePkgScripts({ pkg }) {
132
132
  pkg.scripts.ios = "expo run:ios";
133
133
  hasChanged = true;
134
134
  }
135
+ if (pkg.scripts.macos ===
136
+ "node -e \"console.log('Please run \\`npx expo-desktop prebuild\\` to set up the React Native macOS project.'); process.exit(1);\"") {
137
+ pkg.scripts.macos = "rnc-cli run-macos";
138
+ hasChanged = true;
139
+ }
140
+ if (pkg.scripts.windows ===
141
+ "node -e \"console.log('Please run \\`npx expo-desktop prebuild\\` to set up the React Native Windows project.'); process.exit(1);\"") {
142
+ pkg.scripts.windows = "rnc-cli run-windows";
143
+ hasChanged = true;
144
+ }
135
145
  return hasChanged;
136
146
  }
137
147
  function normalizeDependencyMap(deps) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-desktop",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.2",
4
4
  "description": "Best-effort desktop support for Expo",
5
5
  "keywords": [
6
6
  "android",
@@ -45,7 +45,7 @@
45
45
  "citty": "^0.2.2",
46
46
  "debug": "^4.4.3",
47
47
  "expo-desktop-config-plugins": "^1.2.0-beta.0",
48
- "expo-desktop-prebuild-config": "^1.1.0-beta.0",
48
+ "expo-desktop-prebuild-config": "^1.1.0-beta.1",
49
49
  "getenv": "^2.0.0",
50
50
  "glob": "^10.5.0",
51
51
  "kleur": "^4.1.5",
@@ -1,166 +0,0 @@
1
- import { tasks } from "@clack/prompts";
2
- import { getPackageJson } from "@expo/config";
3
- import crypto from "crypto";
4
- import fs from "fs";
5
- import path from "path";
6
- /** Modifies the `package.json` with `modifyPackageJson` and format/displays the results. */
7
- export async function updatePackageJSONAsync(projectRoot, { templateDirectory, templatePkg = getPackageJson(templateDirectory), pkg, skipDependencyUpdate, }) {
8
- let hasChanges;
9
- let results;
10
- await tasks([
11
- {
12
- title: "Updating package.json",
13
- task: async (_message) => {
14
- results = modifyPackageJson(projectRoot, {
15
- templatePkg,
16
- pkg,
17
- skipDependencyUpdate,
18
- });
19
- hasChanges = !!results.changedDependencies.length || results.scriptsChanged;
20
- // NOTE: This is effectively bundler caching and subject to breakage if the inputs don't match the mutations.
21
- if (hasChanges) {
22
- await fs.promises.writeFile(path.resolve(projectRoot, "package.json"),
23
- // Add new line to match the format of running yarn.
24
- // This prevents the `package.json` from changing when running `prebuild --no-install` multiple times.
25
- JSON.stringify(pkg, null, 2) + "\n");
26
- }
27
- },
28
- },
29
- ]);
30
- return results;
31
- }
32
- /**
33
- * Make required modifications to the `package.json` file as a JSON object.
34
- *
35
- * 1. Update `package.json` `scripts`.
36
- * 2. Update `package.json` `dependencies` (not `devDependencies`).
37
- * 3. Update `package.json` `main`.
38
- *
39
- * @param projectRoot The root directory of the project.
40
- * @param templatePkg Template project package.json as JSON.
41
- * @param pkg Current package.json as JSON.
42
- * @param skipDependencyUpdate Array of dependencies to skip updating.
43
- * @returns
44
- */
45
- function modifyPackageJson(projectRoot, { templatePkg, pkg, skipDependencyUpdate, }) {
46
- const scriptsChanged = updatePkgScripts({ pkg });
47
- // TODO: Move to `npx expo-doctor`
48
- return {
49
- scriptsChanged,
50
- ...updatePkgDependencies(projectRoot, {
51
- pkg,
52
- templatePkg,
53
- skipDependencyUpdate,
54
- }),
55
- };
56
- }
57
- /**
58
- * Update `package.json` dependencies by combining the `dependencies` in the
59
- * project we are creating with the dependencies in the template project.
60
- *
61
- * > Exposed for testing.
62
- */
63
- export function updatePkgDependencies(projectRoot, { pkg, templatePkg, skipDependencyUpdate = [], }) {
64
- const { dependencies } = templatePkg;
65
- // The default values come from the bare-minimum template's package.json.
66
- // Users can change this by using different templates with the `--template` flag.
67
- // The main reason for allowing the changing of dependencies would be to include
68
- // dependencies that are required for the native project to build. For example,
69
- // it does not need to include dependencies that are used in the JS-code only.
70
- const defaultDependencies = createDependenciesMap(dependencies);
71
- // NOTE: This is a hack to ensure this doesn't trigger an extraneous change in the `package.json`
72
- // it isn't required for anything in the `ios` and `android` folders.
73
- delete defaultDependencies["expo-status-bar"];
74
- // NOTE: Expo splash screen is installed by default in the template but the config plugin also lives in prebuild-config
75
- // so we can delete it to prevent an extraneous change in the `package.json`.
76
- delete defaultDependencies["expo-splash-screen"];
77
- const combinedDependencies = createDependenciesMap({
78
- ...defaultDependencies,
79
- ...pkg.dependencies,
80
- });
81
- // Only change the dependencies if the normalized hash changes, this helps to
82
- // reduce meaningless changes.
83
- const hasNewDependencies = hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);
84
- // Save the dependencies
85
- let changedDependencies = [];
86
- if (hasNewDependencies) {
87
- changedDependencies = diffKeys(combinedDependencies, pkg.dependencies ?? {}).sort();
88
- // Use Object.assign to preserve the original order of dependencies, this
89
- // makes it easier to see what changed in the git diff.
90
- pkg.dependencies = Object.assign(pkg.dependencies ?? {}, combinedDependencies);
91
- }
92
- return {
93
- changedDependencies,
94
- };
95
- }
96
- function diffKeys(a, b) {
97
- return Object.keys(a).filter((key) => a[key] !== b[key]);
98
- }
99
- /**
100
- * Create an object of type DependenciesMap a dependencies object or throw if not valid.
101
- *
102
- * @param dependencies - ideally an object of type {[key]: string} - if not then this will error.
103
- */
104
- export function createDependenciesMap(dependencies) {
105
- if (typeof dependencies !== "object") {
106
- throw new Error(`Dependency map is invalid, expected object but got ${typeof dependencies}`);
107
- }
108
- else if (!dependencies) {
109
- return {};
110
- }
111
- const outputMap = {};
112
- for (const key of Object.keys(dependencies)) {
113
- const value = dependencies[key];
114
- if (typeof value === "string") {
115
- outputMap[key] = value;
116
- }
117
- else {
118
- throw new Error(`Dependency for key \`${key}\` should be a \`string\`, instead got: \`{ ${key}: ${JSON.stringify(value)} }\``);
119
- }
120
- }
121
- return outputMap;
122
- }
123
- /**
124
- * Updates the package.json scripts for prebuild if the scripts match
125
- * the default values used in project templates.
126
- */
127
- export function updatePkgScripts({ pkg }) {
128
- let hasChanged = false;
129
- if (!pkg.scripts) {
130
- pkg.scripts = {};
131
- }
132
- if (pkg.scripts.android === "expo start --android" ||
133
- pkg.scripts.android === "react-native run-android") {
134
- pkg.scripts.android = "expo run:android";
135
- hasChanged = true;
136
- }
137
- if (pkg.scripts.ios === "expo start --ios" || pkg.scripts.ios === "react-native run-ios") {
138
- pkg.scripts.ios = "expo run:ios";
139
- hasChanged = true;
140
- }
141
- if (pkg.scripts.macos ===
142
- "node -e \"console.log('Please run \\`npx expo-desktop prebuild\\` to set up the React Native macOS project.'); process.exit(1);\"") {
143
- pkg.scripts.macos = "rnc-cli run-macos";
144
- hasChanged = true;
145
- }
146
- if (pkg.scripts.windows ===
147
- "node -e \"console.log('Please run \\`npx expo-desktop prebuild\\` to set up the React Native Windows project.'); process.exit(1);\"") {
148
- pkg.scripts.windows = "rnc-cli run-windows";
149
- hasChanged = true;
150
- }
151
- return hasChanged;
152
- }
153
- function normalizeDependencyMap(deps) {
154
- return Object.keys(deps)
155
- .map((dependency) => `${dependency}@${deps[dependency]}`)
156
- .sort();
157
- }
158
- export function hashForDependencyMap(deps = {}) {
159
- const depsList = normalizeDependencyMap(deps);
160
- const depsString = depsList.join("\n");
161
- return createFileHash(depsString);
162
- }
163
- export function createFileHash(contents) {
164
- // this doesn't need to be secure, the shorter the better.
165
- return crypto.createHash("sha1").update(contents).digest("hex");
166
- }