@todesktop/cli 1.15.1 → 1.17.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/cli.js CHANGED
@@ -192,12 +192,14 @@ var firebaseApp = (0, import_app.initializeApp)({
192
192
  });
193
193
  var auth = (0, import_auth.getAuth)(firebaseApp);
194
194
  var db = (0, import_firestore.getFirestore)(firebaseApp);
195
- var currentUser = () => auth.currentUser;
195
+ var currentUser = () => {
196
+ return auth.currentUser;
197
+ };
196
198
  var signInWithCustomToken = async (token) => {
197
199
  return (0, import_auth.signInWithCustomToken)(auth, token);
198
200
  };
199
201
  var onUserAuth = (handler) => (0, import_auth.onAuthStateChanged)(auth, (user) => {
200
- handler(user || {});
202
+ handler(user != null ? user : {});
201
203
  });
202
204
  var firestore_default = db;
203
205
 
@@ -322,7 +324,7 @@ var track = (event, properties = {}, callback = () => {
322
324
  analytics.track(
323
325
  {
324
326
  event,
325
- userId: user ? user.uid : void 0,
327
+ userId: user == null ? void 0 : user.uid,
326
328
  anonymousId,
327
329
  properties: {
328
330
  ...properties,
@@ -1062,8 +1064,8 @@ function loadTypeScriptConfig(configPath) {
1062
1064
  );
1063
1065
  }
1064
1066
  }
1065
- const fs6 = require("fs");
1066
- const sourceCode = fs6.readFileSync(configPath, "utf8");
1067
+ const fs7 = require("fs");
1068
+ const sourceCode = fs7.readFileSync(configPath, "utf8");
1067
1069
  const result = typescript.transpile(sourceCode, {
1068
1070
  target: typescript.ScriptTarget.ES2018,
1069
1071
  module: typescript.ModuleKind.CommonJS,
@@ -1643,6 +1645,20 @@ var schema_default = {
1643
1645
  appFiles: { $ref: "#/definitions/appFilesProperty" },
1644
1646
  appProtocolScheme: { $ref: "#/definitions/appProtocolSchemeProperty" },
1645
1647
  appPath: { $ref: "#/definitions/appPathProperty" },
1648
+ bundleWorkspacePackages: {
1649
+ type: "object",
1650
+ additionalProperties: false,
1651
+ description: "Useful when your application is a monorepo (e.g. pnpm workspaces). You can configure whether the CLI bundles workspace packages alongside the app upload. When enabled, workspace dependencies referenced via `workspace:` or local `file:` specifiers are bundled with your application upload and dependency ranges are rewritten to `file:` paths so they install deterministically on the build servers.",
1652
+ examples: ['{"enabled":true}'],
1653
+ default: { enabled: false },
1654
+ properties: {
1655
+ enabled: {
1656
+ type: "boolean",
1657
+ default: false,
1658
+ description: "Enable automatic bundling of workspace packages for this project."
1659
+ }
1660
+ }
1661
+ },
1646
1662
  asar: { $ref: "#/definitions/asarProperty" },
1647
1663
  asarUnpack: { $ref: "#/definitions/asarUnpackProperty" },
1648
1664
  buildVersion: { $ref: "#/definitions/buildVersionProperty" },
@@ -2705,6 +2721,19 @@ var getVersionControlInfo_default = async (directory) => {
2705
2721
  // src/commands/build/utilities/spyBuild.ts
2706
2722
  var import_events = __toESM(require("events"));
2707
2723
  var import_firestore3 = require("firebase/firestore");
2724
+
2725
+ // src/utilities/firestoreData.ts
2726
+ var readQueryDocument = (doc9) => {
2727
+ return doc9.data();
2728
+ };
2729
+ var readDocumentSnapshot = (snapshot) => {
2730
+ return snapshot.exists() ? snapshot.data() : void 0;
2731
+ };
2732
+ var readQuerySnapshot = (snapshot) => {
2733
+ return snapshot.docs.map((doc9) => readQueryDocument(doc9));
2734
+ };
2735
+
2736
+ // src/commands/build/utilities/spyBuild.ts
2708
2737
  function spyBuild() {
2709
2738
  const emitter = new import_events.default();
2710
2739
  let unsubscribeSnapshot;
@@ -2734,7 +2763,7 @@ function spyBuild() {
2734
2763
  unsubscribeSnapshot = (0, import_firestore3.onSnapshot)(
2735
2764
  (0, import_firestore3.doc)(firestore_default, buildPath),
2736
2765
  (snapshot) => {
2737
- latestBuildDoc = snapshot.exists() ? snapshot.data() : void 0;
2766
+ latestBuildDoc = readDocumentSnapshot(snapshot);
2738
2767
  emitter.emit("update", {
2739
2768
  build: latestBuildDoc,
2740
2769
  snapshot
@@ -2771,9 +2800,9 @@ function buildHasSettled(build) {
2771
2800
  }
2772
2801
 
2773
2802
  // src/commands/build/utilities/uploadApplicationSource.ts
2774
- var import_fast_glob = __toESM(require("fast-glob"));
2775
- var fs5 = __toESM(require("fs"));
2776
- var path7 = __toESM(require("path"));
2803
+ var import_fast_glob2 = __toESM(require("fast-glob"));
2804
+ var fs6 = __toESM(require("fs"));
2805
+ var path8 = __toESM(require("path"));
2777
2806
 
2778
2807
  // src/commands/build/utilities/generateS3Key.ts
2779
2808
  var generateS3Key_default = ({ appId, buildId, filenameSuffix }) => `${appId}/sourceArchives/${buildId}--${filenameSuffix}`;
@@ -2859,13 +2888,29 @@ async function zip_default({
2859
2888
  });
2860
2889
  const processedFiles = await Promise.all(
2861
2890
  files.map(async (file) => {
2891
+ if (file.content !== void 0 && file.content !== null) {
2892
+ const buffer = Buffer.isBuffer(file.content) ? file.content : Buffer.from(file.content);
2893
+ return {
2894
+ ...file,
2895
+ contentBuffer: buffer,
2896
+ isDirectory: false,
2897
+ size: buffer.length,
2898
+ virtual: true
2899
+ };
2900
+ }
2901
+ if (!file.from) {
2902
+ throw new Error(
2903
+ `Zip entry for ${file.to} must provide either a source path or in-memory content.`
2904
+ );
2905
+ }
2862
2906
  const stats = import_fs2.default.lstatSync(file.from);
2863
2907
  const isDirectory = stats.isDirectory();
2864
2908
  return {
2865
2909
  ...file,
2866
2910
  isDirectory,
2867
2911
  stats,
2868
- size: isDirectory ? await (0, import_du.default)(file.from) : stats.size
2912
+ size: isDirectory ? await (0, import_du.default)(file.from) : stats.size,
2913
+ virtual: false
2869
2914
  };
2870
2915
  })
2871
2916
  );
@@ -2888,15 +2933,21 @@ Your app is larger than ${fileSizeLimit}MB. Your app is ${import_chalk.default.b
2888
2933
  );
2889
2934
  return stream;
2890
2935
  }
2891
- processedFiles.forEach(({ from, isDirectory, stats, to }) => {
2892
- if (isDirectory) {
2936
+ processedFiles.forEach((entry) => {
2937
+ const { from, isDirectory, stats, to, virtual, contentBuffer, mode } = entry;
2938
+ if (virtual) {
2939
+ stream.append(contentBuffer, {
2940
+ name: to,
2941
+ mode: mode != null ? mode : 420
2942
+ });
2943
+ } else if (isDirectory) {
2893
2944
  stream.directory(from, to);
2894
2945
  } else if (appPkgJson && to === import_path7.default.join("app", "package.json")) {
2895
2946
  stream.append(JSON.stringify(appPkgJson), {
2896
2947
  name: to
2897
2948
  });
2898
2949
  } else {
2899
- stream.file(from, { name: to, mode: stats.mode });
2950
+ stream.file(from, { name: to, mode: mode != null ? mode : stats.mode });
2900
2951
  }
2901
2952
  });
2902
2953
  stream.finalize();
@@ -2910,6 +2961,533 @@ Your app is larger than ${fileSizeLimit}MB. Your app is ${import_chalk.default.b
2910
2961
  return stream;
2911
2962
  }
2912
2963
 
2964
+ // src/commands/build/utilities/workspace/index.ts
2965
+ var import_fast_glob = __toESM(require("fast-glob"));
2966
+ var import_fs3 = __toESM(require("fs"));
2967
+ var import_path8 = __toESM(require("path"));
2968
+ var import_js_yaml = __toESM(require("js-yaml"));
2969
+ var BUNDLED_ROOT = "bundledPackages";
2970
+ var DEFAULT_IGNORE_GLOBS = [
2971
+ "**/node_modules/**",
2972
+ "**/.git/**",
2973
+ "**/.hg/**",
2974
+ "**/.svn/**",
2975
+ "**/.DS_Store",
2976
+ "**/npm-debug.log",
2977
+ "**/yarn-error.log"
2978
+ ];
2979
+ async function prepareWorkspaceBundle(input) {
2980
+ var _a;
2981
+ const { config: config2, appPkgJson, appPath } = input;
2982
+ if (!((_a = config2.bundleWorkspacePackages) == null ? void 0 : _a.enabled)) {
2983
+ return {
2984
+ appPackageJson: appPkgJson,
2985
+ entries: [],
2986
+ shouldBundle: false
2987
+ };
2988
+ }
2989
+ const workspace = findWorkspaceDefinition(appPath, appPkgJson);
2990
+ if (!workspace) {
2991
+ throw new Error(
2992
+ "Bundle workspace packages is enabled but no workspace root could be found."
2993
+ );
2994
+ }
2995
+ if (workspace.warning) {
2996
+ logger_default.warn(workspace.warning);
2997
+ }
2998
+ const workspacePackages = collectWorkspacePackages(workspace);
2999
+ const bundledPackageNames = determineBundleClosure({
3000
+ appPath,
3001
+ appPkgJson,
3002
+ workspace,
3003
+ workspacePackages
3004
+ });
3005
+ if (!bundledPackageNames.size) {
3006
+ logger_default.info("No workspace packages matched bundle criteria.");
3007
+ return {
3008
+ appPackageJson: appPkgJson,
3009
+ entries: [],
3010
+ shouldBundle: false
3011
+ };
3012
+ }
3013
+ const bundleEntries = [];
3014
+ const appRewriteMap = {};
3015
+ const bundledPackageContexts = /* @__PURE__ */ new Map();
3016
+ const sortedPackageNames = Array.from(bundledPackageNames).sort();
3017
+ for (const packageName of sortedPackageNames) {
3018
+ const pkg = workspacePackages.get(packageName);
3019
+ if (!pkg) {
3020
+ throw new Error(
3021
+ `Workspace package "${packageName}" referenced for bundling but not found in workspace map.`
3022
+ );
3023
+ }
3024
+ const bundlePath = getBundlePath(packageName);
3025
+ bundledPackageContexts.set(packageName, { bundlePath, packageName });
3026
+ appRewriteMap[packageName] = `file:../${import_path8.default.posix.join(
3027
+ BUNDLED_ROOT,
3028
+ bundlePath
3029
+ )}`;
3030
+ const packageEntries = await buildPackageEntries({
3031
+ bundlePath,
3032
+ workspacePackage: pkg,
3033
+ bundledNames: bundledPackageNames,
3034
+ contexts: bundledPackageContexts
3035
+ });
3036
+ bundleEntries.push(...packageEntries.files);
3037
+ bundleEntries.push(packageEntries.packageJsonEntry);
3038
+ }
3039
+ const rewrittenAppPkgJson = applyRewriteMap(appPkgJson, appRewriteMap);
3040
+ logger_default.info(
3041
+ `Bundling ${sortedPackageNames.length} workspace package(s) from ${workspace.type} workspace at ${workspace.rootDir}`
3042
+ );
3043
+ logger_default.info(`Bundled packages: ${sortedPackageNames.join(", ")}`);
3044
+ return {
3045
+ appPackageJson: rewrittenAppPkgJson,
3046
+ entries: bundleEntries,
3047
+ shouldBundle: true
3048
+ };
3049
+ }
3050
+ function findWorkspaceDefinition(appPath, appPkgJson) {
3051
+ const appDir = import_path8.default.resolve(appPath);
3052
+ let currentDir = appDir;
3053
+ let previousDir = "";
3054
+ const pnpmPreference = detectPnpmPreference(appPkgJson);
3055
+ while (currentDir !== previousDir) {
3056
+ const pnpmFile = import_path8.default.join(currentDir, "pnpm-workspace.yaml");
3057
+ const packageJsonPath = import_path8.default.join(currentDir, "package.json");
3058
+ const hasPnpm = import_fs3.default.existsSync(pnpmFile);
3059
+ const packageJson2 = readPackageJsonIfExists(packageJsonPath);
3060
+ const npmWorkspaces = getNpmWorkspaces(packageJson2);
3061
+ if (hasPnpm || npmWorkspaces.length) {
3062
+ const pnpmDefinition = hasPnpm ? createPnpmDefinition({ pnpmFile, rootDir: currentDir }) : void 0;
3063
+ const npmDefinition = npmWorkspaces.length ? createNpmDefinition({ globs: npmWorkspaces, rootDir: currentDir }) : void 0;
3064
+ const chosen = chooseWorkspaceDefinition({
3065
+ pnpmPreference,
3066
+ pnpmDefinition,
3067
+ npmDefinition
3068
+ });
3069
+ if (chosen) {
3070
+ const includesApp = workspaceIncludesPath({
3071
+ appDir,
3072
+ globs: chosen.globs,
3073
+ rootDir: chosen.rootDir
3074
+ });
3075
+ if (includesApp) {
3076
+ return chosen;
3077
+ }
3078
+ }
3079
+ }
3080
+ previousDir = currentDir;
3081
+ currentDir = import_path8.default.dirname(currentDir);
3082
+ }
3083
+ return void 0;
3084
+ }
3085
+ function detectPnpmPreference(appPkgJson) {
3086
+ const pkgManager = appPkgJson.packageManager;
3087
+ if (typeof pkgManager !== "string") {
3088
+ return false;
3089
+ }
3090
+ return pkgManager.startsWith("pnpm@");
3091
+ }
3092
+ function readPackageJsonIfExists(filePath) {
3093
+ if (!import_fs3.default.existsSync(filePath)) {
3094
+ return void 0;
3095
+ }
3096
+ try {
3097
+ return JSON.parse(import_fs3.default.readFileSync(filePath, "utf8"));
3098
+ } catch (error) {
3099
+ throw new Error(`Unable to parse package.json at ${filePath}: ${error}`);
3100
+ }
3101
+ }
3102
+ function getNpmWorkspaces(packageJson2) {
3103
+ if (!packageJson2) {
3104
+ return [];
3105
+ }
3106
+ const { workspaces } = packageJson2;
3107
+ if (!workspaces) {
3108
+ return [];
3109
+ }
3110
+ if (Array.isArray(workspaces)) {
3111
+ return workspaces.filter(
3112
+ (value) => typeof value === "string"
3113
+ );
3114
+ }
3115
+ if (typeof workspaces === "object" && Array.isArray(workspaces.packages)) {
3116
+ return workspaces.packages.filter(
3117
+ (value) => typeof value === "string"
3118
+ );
3119
+ }
3120
+ return [];
3121
+ }
3122
+ function createPnpmDefinition({
3123
+ pnpmFile,
3124
+ rootDir
3125
+ }) {
3126
+ const packages = parsePnpmWorkspaceFile(pnpmFile);
3127
+ if (!packages.length) {
3128
+ throw new Error(
3129
+ `pnpm workspace file at ${pnpmFile} does not define any packages.`
3130
+ );
3131
+ }
3132
+ return {
3133
+ globs: packages,
3134
+ rootDir,
3135
+ realRootDir: import_fs3.default.realpathSync(rootDir),
3136
+ type: "pnpm"
3137
+ };
3138
+ }
3139
+ function createNpmDefinition({
3140
+ globs,
3141
+ rootDir
3142
+ }) {
3143
+ return {
3144
+ globs,
3145
+ rootDir,
3146
+ realRootDir: import_fs3.default.realpathSync(rootDir),
3147
+ type: "npm"
3148
+ };
3149
+ }
3150
+ function chooseWorkspaceDefinition({
3151
+ pnpmPreference,
3152
+ pnpmDefinition,
3153
+ npmDefinition
3154
+ }) {
3155
+ if (pnpmDefinition && npmDefinition) {
3156
+ const warning = "Both pnpm-workspace.yaml and package.json workspaces detected; defaulting to pnpm.";
3157
+ if (pnpmPreference) {
3158
+ return pnpmDefinition;
3159
+ }
3160
+ return { ...pnpmDefinition, warning };
3161
+ }
3162
+ return pnpmDefinition || npmDefinition;
3163
+ }
3164
+ function parsePnpmWorkspaceFile(filePath) {
3165
+ const content = import_fs3.default.readFileSync(filePath, "utf8");
3166
+ const parsed = import_js_yaml.default.load(content);
3167
+ let packagesField;
3168
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
3169
+ packagesField = parsed.packages;
3170
+ } else {
3171
+ packagesField = parsed;
3172
+ }
3173
+ if (!Array.isArray(packagesField)) {
3174
+ throw new Error(
3175
+ `pnpm workspace file at ${filePath} does not define any packages.`
3176
+ );
3177
+ }
3178
+ const packages = packagesField.map((value) => typeof value === "string" ? value.trim() : "").filter((value) => Boolean(value));
3179
+ if (!packages.length) {
3180
+ throw new Error(
3181
+ `pnpm workspace file at ${filePath} does not define any packages.`
3182
+ );
3183
+ }
3184
+ return packages;
3185
+ }
3186
+ function workspaceIncludesPath({
3187
+ appDir,
3188
+ globs,
3189
+ rootDir
3190
+ }) {
3191
+ const target = import_path8.default.resolve(appDir);
3192
+ const matches = import_fast_glob.default.sync(globs, {
3193
+ absolute: true,
3194
+ cwd: rootDir,
3195
+ onlyDirectories: true,
3196
+ followSymbolicLinks: false,
3197
+ ignore: ["**/node_modules/**"]
3198
+ });
3199
+ return matches.some((dir) => import_path8.default.resolve(dir) === target);
3200
+ }
3201
+ function collectWorkspacePackages(definition) {
3202
+ const { globs, rootDir } = definition;
3203
+ const directories = import_fast_glob.default.sync(globs, {
3204
+ absolute: true,
3205
+ cwd: rootDir,
3206
+ onlyDirectories: true,
3207
+ followSymbolicLinks: false,
3208
+ ignore: ["**/node_modules/**"]
3209
+ });
3210
+ const packages = /* @__PURE__ */ new Map();
3211
+ for (const dir of directories) {
3212
+ const packageJsonPath = import_path8.default.join(dir, "package.json");
3213
+ if (!import_fs3.default.existsSync(packageJsonPath)) {
3214
+ continue;
3215
+ }
3216
+ const manifest = readPackageJsonIfExists(packageJsonPath);
3217
+ if (!manifest || !manifest.name) {
3218
+ continue;
3219
+ }
3220
+ const name = manifest.name;
3221
+ if (packages.has(name)) {
3222
+ const existing = packages.get(name);
3223
+ throw new Error(
3224
+ `Duplicate workspace package name "${name}" found at ${existing == null ? void 0 : existing.dir} and ${dir}`
3225
+ );
3226
+ }
3227
+ const absoluteDir = import_path8.default.resolve(dir);
3228
+ const pkg = {
3229
+ dir: absoluteDir,
3230
+ manifest,
3231
+ name,
3232
+ realDir: import_fs3.default.realpathSync(absoluteDir)
3233
+ };
3234
+ packages.set(name, pkg);
3235
+ }
3236
+ return packages;
3237
+ }
3238
+ function determineBundleClosure({
3239
+ appPath,
3240
+ appPkgJson,
3241
+ workspace,
3242
+ workspacePackages
3243
+ }) {
3244
+ const bundled = /* @__PURE__ */ new Set();
3245
+ const queue = [];
3246
+ collectDependencyReferences({
3247
+ manifest: appPkgJson,
3248
+ packageDir: appPath,
3249
+ queue,
3250
+ workspace,
3251
+ workspacePackages,
3252
+ sourceName: "app"
3253
+ });
3254
+ while (queue.length) {
3255
+ const ref = queue.shift();
3256
+ if (!ref) {
3257
+ continue;
3258
+ }
3259
+ const targetPackage = workspacePackages.get(ref.name);
3260
+ if (!targetPackage) {
3261
+ throw new Error(
3262
+ `Dependency "${ref.name}" referenced via ${ref.section} is not part of the workspace.`
3263
+ );
3264
+ }
3265
+ if (bundled.has(targetPackage.name)) {
3266
+ continue;
3267
+ }
3268
+ bundled.add(targetPackage.name);
3269
+ collectDependencyReferences({
3270
+ manifest: targetPackage.manifest,
3271
+ packageDir: targetPackage.dir,
3272
+ queue,
3273
+ workspace,
3274
+ workspacePackages,
3275
+ sourceName: targetPackage.name
3276
+ });
3277
+ }
3278
+ return bundled;
3279
+ }
3280
+ function collectDependencyReferences({
3281
+ manifest,
3282
+ packageDir,
3283
+ queue,
3284
+ workspace,
3285
+ workspacePackages,
3286
+ sourceName
3287
+ }) {
3288
+ const sections = [
3289
+ "dependencies",
3290
+ "optionalDependencies",
3291
+ "devDependencies"
3292
+ ];
3293
+ for (const section of sections) {
3294
+ const deps = manifest[section];
3295
+ if (!deps)
3296
+ continue;
3297
+ for (const [depName, spec] of Object.entries(deps)) {
3298
+ if (typeof spec !== "string")
3299
+ continue;
3300
+ const target = resolveWorkspaceTarget({
3301
+ depName,
3302
+ packageDir,
3303
+ spec,
3304
+ workspace,
3305
+ workspacePackages,
3306
+ sourceName
3307
+ });
3308
+ if (target) {
3309
+ queue.push({ name: target, spec, section });
3310
+ }
3311
+ }
3312
+ }
3313
+ }
3314
+ function resolveWorkspaceTarget({
3315
+ depName,
3316
+ packageDir,
3317
+ spec,
3318
+ workspace,
3319
+ workspacePackages,
3320
+ sourceName
3321
+ }) {
3322
+ if (spec.startsWith("workspace:")) {
3323
+ if (!workspacePackages.has(depName)) {
3324
+ throw new Error(
3325
+ `Workspace dependency "${depName}" referenced by ${sourceName} is not declared in workspace globs.`
3326
+ );
3327
+ }
3328
+ return depName;
3329
+ }
3330
+ if (spec.startsWith("file:")) {
3331
+ const targetPath = spec.slice("file:".length);
3332
+ const resolved = import_path8.default.resolve(packageDir, targetPath);
3333
+ const targetRealPath = import_fs3.default.realpathSync(resolved);
3334
+ const relativeToRoot = import_path8.default.relative(workspace.realRootDir, targetRealPath);
3335
+ if (relativeToRoot.startsWith("..") || import_path8.default.isAbsolute(relativeToRoot)) {
3336
+ throw new Error(
3337
+ `Dependency "${depName}" from ${sourceName} resolves outside of workspace root via spec ${spec}.`
3338
+ );
3339
+ }
3340
+ for (const pkg of workspacePackages.values()) {
3341
+ if (pkg.realDir === targetRealPath) {
3342
+ return pkg.name;
3343
+ }
3344
+ }
3345
+ throw new Error(
3346
+ `Dependency "${depName}" from ${sourceName} points to ${resolved}, which is not a known workspace package.`
3347
+ );
3348
+ }
3349
+ return void 0;
3350
+ }
3351
+ function getBundlePath(packageName) {
3352
+ if (packageName.startsWith("@")) {
3353
+ const [scope, ...rest] = packageName.split("/");
3354
+ return [scope, rest.join("/")].filter(Boolean).join("/");
3355
+ }
3356
+ return packageName;
3357
+ }
3358
+ function applyRewriteMap(manifest, rewriteMap) {
3359
+ const clone = JSON.parse(JSON.stringify(manifest));
3360
+ const sections = [
3361
+ "dependencies",
3362
+ "optionalDependencies",
3363
+ "devDependencies"
3364
+ ];
3365
+ for (const section of sections) {
3366
+ const sectionDeps = clone[section];
3367
+ if (!sectionDeps)
3368
+ continue;
3369
+ for (const [depName, rewrite] of Object.entries(rewriteMap)) {
3370
+ if (sectionDeps[depName]) {
3371
+ sectionDeps[depName] = rewrite;
3372
+ }
3373
+ }
3374
+ }
3375
+ return clone;
3376
+ }
3377
+ async function buildPackageEntries({
3378
+ bundlePath,
3379
+ workspacePackage,
3380
+ bundledNames,
3381
+ contexts
3382
+ }) {
3383
+ const packageDir = workspacePackage.dir;
3384
+ const manifest = workspacePackage.manifest;
3385
+ const filesToInclude = await gatherPackageFiles({ packageDir, manifest });
3386
+ const files = filesToInclude.map((absolutePath) => {
3387
+ const relative3 = import_path8.default.relative(packageDir, absolutePath);
3388
+ const posixRelative = toPosix(import_path8.default.join(bundlePath, relative3));
3389
+ return {
3390
+ from: absolutePath,
3391
+ to: import_path8.default.posix.join(BUNDLED_ROOT, posixRelative)
3392
+ };
3393
+ });
3394
+ const rewrites = buildRewriteMapForPackage({
3395
+ bundlePath,
3396
+ manifest,
3397
+ bundledNames,
3398
+ contexts
3399
+ });
3400
+ const packageJsonEntry = {
3401
+ content: Buffer.from(
3402
+ `${JSON.stringify(applyRewriteMap(manifest, rewrites), null, 2)}
3403
+ `
3404
+ ),
3405
+ to: import_path8.default.posix.join(BUNDLED_ROOT, bundlePath, "package.json")
3406
+ };
3407
+ return { files, packageJsonEntry };
3408
+ }
3409
+ async function gatherPackageFiles({
3410
+ packageDir,
3411
+ manifest
3412
+ }) {
3413
+ const declaredPatterns = Array.isArray(manifest.files) ? manifest.files : ["**/*"];
3414
+ const normalizedPatterns = declaredPatterns.flatMap((pattern) => {
3415
+ if (pattern.includes("*")) {
3416
+ return [pattern];
3417
+ }
3418
+ const absoluteCandidate = import_path8.default.join(packageDir, pattern);
3419
+ try {
3420
+ const stats = import_fs3.default.statSync(absoluteCandidate);
3421
+ if (stats.isDirectory()) {
3422
+ const posixPattern = pattern.replace(/\\/g, "/");
3423
+ return [pattern, `${posixPattern}/**/*`];
3424
+ }
3425
+ } catch (error) {
3426
+ }
3427
+ return [pattern];
3428
+ });
3429
+ const matchedFiles = await (0, import_fast_glob.default)(normalizedPatterns, {
3430
+ absolute: true,
3431
+ cwd: packageDir,
3432
+ dot: true,
3433
+ onlyFiles: true,
3434
+ followSymbolicLinks: false,
3435
+ ignore: DEFAULT_IGNORE_GLOBS
3436
+ });
3437
+ const extras = [
3438
+ "README",
3439
+ "README.md",
3440
+ "README.txt",
3441
+ "LICENSE",
3442
+ "LICENCE",
3443
+ "NOTICE",
3444
+ "CHANGELOG",
3445
+ "CHANGELOG.md"
3446
+ ];
3447
+ for (const extra of extras) {
3448
+ const extraPath = import_path8.default.join(packageDir, extra);
3449
+ if (import_fs3.default.existsSync(extraPath) && import_fs3.default.statSync(extraPath).isFile()) {
3450
+ matchedFiles.push(extraPath);
3451
+ }
3452
+ }
3453
+ const uniqueFiles = Array.from(new Set(matchedFiles));
3454
+ return uniqueFiles.filter((filePath) => !filePath.endsWith("package.json"));
3455
+ }
3456
+ function buildRewriteMapForPackage({
3457
+ bundlePath,
3458
+ manifest,
3459
+ bundledNames,
3460
+ contexts
3461
+ }) {
3462
+ var _a, _b;
3463
+ const rewriteMap = {};
3464
+ const sections = [
3465
+ "dependencies",
3466
+ "optionalDependencies",
3467
+ "devDependencies"
3468
+ ];
3469
+ for (const section of sections) {
3470
+ const deps = manifest[section];
3471
+ if (!deps)
3472
+ continue;
3473
+ for (const [depName, spec] of Object.entries(deps)) {
3474
+ if (typeof spec !== "string")
3475
+ continue;
3476
+ if (bundledNames.has(depName)) {
3477
+ const targetBundlePath = (_b = (_a = contexts.get(depName)) == null ? void 0 : _a.bundlePath) != null ? _b : getBundlePath(depName);
3478
+ const fromPath = import_path8.default.posix.join(BUNDLED_ROOT, bundlePath);
3479
+ const toPath = import_path8.default.posix.join(BUNDLED_ROOT, targetBundlePath);
3480
+ const relative3 = import_path8.default.posix.relative(fromPath, toPath) || ".";
3481
+ rewriteMap[depName] = `file:${relative3}`;
3482
+ }
3483
+ }
3484
+ }
3485
+ return rewriteMap;
3486
+ }
3487
+ function toPosix(targetPath) {
3488
+ return targetPath.split(import_path8.default.sep).join(import_path8.default.posix.sep);
3489
+ }
3490
+
2913
3491
  // src/commands/build/utilities/uploadApplicationSource.ts
2914
3492
  var getAppFiles = async (globsInput, appPath, appPkgJson) => {
2915
3493
  const globs = [
@@ -2923,11 +3501,11 @@ var getAppFiles = async (globsInput, appPath, appPkgJson) => {
2923
3501
  if (globsInput && globsInput.length) {
2924
3502
  globs.push(
2925
3503
  ...globsInput,
2926
- path7.join(appPath, "package.json"),
2927
- path7.join(appPath, "package-lock.json"),
2928
- path7.join(appPath, "yarn.lock"),
2929
- path7.join(appPath, "pnpm-lock.yaml"),
2930
- path7.join(appPath, "shrinkwrap.yaml")
3504
+ path8.join(appPath, "package.json"),
3505
+ path8.join(appPath, "package-lock.json"),
3506
+ path8.join(appPath, "yarn.lock"),
3507
+ path8.join(appPath, "pnpm-lock.yaml"),
3508
+ path8.join(appPath, "shrinkwrap.yaml")
2931
3509
  );
2932
3510
  } else {
2933
3511
  globs.push("**");
@@ -2938,14 +3516,14 @@ var getAppFiles = async (globsInput, appPath, appPkgJson) => {
2938
3516
  "todesktop:afterPack"
2939
3517
  ]) {
2940
3518
  if (appPkgJson.scripts && appPkgJson.scripts[hookName]) {
2941
- globs.push(path7.join(appPath, appPkgJson.scripts[hookName]));
3519
+ globs.push(path8.join(appPath, appPkgJson.scripts[hookName]));
2942
3520
  }
2943
3521
  }
2944
3522
  const normalizedGlobs = globs.map((glob) => {
2945
- const globToUse = path7.isAbsolute(glob) ? path7.relative(appPath, glob) : glob;
3523
+ const globToUse = path8.isAbsolute(glob) ? path8.relative(appPath, glob) : glob;
2946
3524
  return globToUse.replace(/\\/g, "/").replace(/\/+$/, "");
2947
3525
  }).filter((glob) => !glob.startsWith("..") && !glob.startsWith("!.."));
2948
- let absolutePaths = await (0, import_fast_glob.default)(normalizedGlobs, {
3526
+ let absolutePaths = await (0, import_fast_glob2.default)(normalizedGlobs, {
2949
3527
  absolute: true,
2950
3528
  cwd: appPath,
2951
3529
  dot: true,
@@ -2957,7 +3535,7 @@ var getAppFiles = async (globsInput, appPath, appPkgJson) => {
2957
3535
  });
2958
3536
  if (process.platform === "win32") {
2959
3537
  absolutePaths = absolutePaths.map(
2960
- (absolutePath) => absolutePath.replace(/\//g, path7.sep)
3538
+ (absolutePath) => absolutePath.replace(/\//g, path8.sep)
2961
3539
  );
2962
3540
  }
2963
3541
  if (!absolutePaths || !absolutePaths.length) {
@@ -2971,21 +3549,21 @@ var getAppFiles = async (globsInput, appPath, appPkgJson) => {
2971
3549
  } else {
2972
3550
  let mainFilePath = appPath;
2973
3551
  if (appPkgJson.main) {
2974
- mainFilePath = path7.join(mainFilePath, appPkgJson.main);
3552
+ mainFilePath = path8.join(mainFilePath, appPkgJson.main);
2975
3553
  }
2976
- if (fs5.statSync(mainFilePath).isDirectory()) {
2977
- mainFilePath = path7.join(mainFilePath, "index.js");
3554
+ if (fs6.statSync(mainFilePath).isDirectory()) {
3555
+ mainFilePath = path8.join(mainFilePath, "index.js");
2978
3556
  }
2979
3557
  if (!absolutePaths.includes(mainFilePath)) {
2980
3558
  throw new Error(
2981
- `The "main" file specified in your package.json (${appPkgJson.main ? path7.relative(appPath, mainFilePath) : "defaults to index.js"}) is not set to be uploaded to our servers. This is likely due to how you have configured the \`appFiles\` option. Learn more at https://www.npmjs.com/package/@todesktop/cli#appfiles----optional-array-of-glob-patterns. If this is not the case, please contact us.`
3559
+ `The "main" file specified in your package.json (${appPkgJson.main ? path8.relative(appPath, mainFilePath) : "defaults to index.js"}) is not set to be uploaded to our servers. This is likely due to how you have configured the \`appFiles\` option. Learn more at https://www.npmjs.com/package/@todesktop/cli#appfiles----optional-array-of-glob-patterns. If this is not the case, please contact us.`
2982
3560
  );
2983
3561
  }
2984
3562
  }
2985
3563
  return absolutePaths.map((absolutePath) => {
2986
3564
  return {
2987
3565
  from: absolutePath,
2988
- to: path7.join("app", path7.relative(appPath, absolutePath))
3566
+ to: path8.join("app", path8.relative(appPath, absolutePath))
2989
3567
  };
2990
3568
  });
2991
3569
  };
@@ -3010,11 +3588,29 @@ async function uploadApplicationSource({
3010
3588
  "uploadApplicationSource"
3011
3589
  );
3012
3590
  let totalBytes = 0;
3591
+ let effectiveAppPkgJson = appPkgJson;
3592
+ let workspaceEntries = [];
3593
+ try {
3594
+ const workspaceBundle = await prepareWorkspaceBundle({
3595
+ appPath: config2.appPath,
3596
+ appPkgJson,
3597
+ config: config2
3598
+ });
3599
+ effectiveAppPkgJson = workspaceBundle.appPackageJson;
3600
+ workspaceEntries = workspaceBundle.entries;
3601
+ } catch (error) {
3602
+ logger_default.error({ err: error }, "Failed to prepare workspace bundle");
3603
+ throw error;
3604
+ }
3013
3605
  const files = [
3014
3606
  /*
3015
3607
  App files (stored in app/ in the ZIP)
3016
3608
  */
3017
- ...await getAppFiles(config2.appFiles, config2.appPath, appPkgJson),
3609
+ ...await getAppFiles(
3610
+ config2.appFiles,
3611
+ config2.appPath,
3612
+ effectiveAppPkgJson
3613
+ ),
3018
3614
  /*
3019
3615
  Optional extra content files (stored in extraContentFiles/ in the ZIP). Their
3020
3616
  paths within is the their relative path from the project root so
@@ -3025,7 +3621,7 @@ async function uploadApplicationSource({
3025
3621
  ...(config2.extraContentFiles || []).map(({ from, to = "." }) => {
3026
3622
  return {
3027
3623
  from,
3028
- to: path7.join("extraContentFiles", to, path7.basename(from))
3624
+ to: path8.join("extraContentFiles", to, path8.basename(from))
3029
3625
  };
3030
3626
  }),
3031
3627
  /*
@@ -3035,7 +3631,7 @@ async function uploadApplicationSource({
3035
3631
  ...(config2.extraResources || []).map(({ from, to = "." }) => {
3036
3632
  return {
3037
3633
  from,
3038
- to: path7.join("extraResources", to, path7.basename(from))
3634
+ to: path8.join("extraResources", to, path8.basename(from))
3039
3635
  };
3040
3636
  }),
3041
3637
  /*
@@ -3043,16 +3639,16 @@ async function uploadApplicationSource({
3043
3639
  */
3044
3640
  {
3045
3641
  from: config2.icon,
3046
- to: path7.join("icons", "appIcon" + path7.extname(config2.icon))
3642
+ to: path8.join("icons", "appIcon" + path8.extname(config2.icon))
3047
3643
  }
3048
3644
  ];
3049
3645
  if (config2.linux) {
3050
3646
  if (config2.linux.icon) {
3051
3647
  files.push({
3052
3648
  from: config2.linux.icon,
3053
- to: path7.join(
3649
+ to: path8.join(
3054
3650
  "icons",
3055
- "appIcon-linux" + path7.extname(config2.linux.icon)
3651
+ "appIcon-linux" + path8.extname(config2.linux.icon)
3056
3652
  )
3057
3653
  });
3058
3654
  }
@@ -3061,10 +3657,10 @@ async function uploadApplicationSource({
3061
3657
  const possibleIcons = [];
3062
3658
  for (const fa of config2.fileAssociations) {
3063
3659
  if (fa.icon) {
3064
- const icon = path7.parse(fa.icon);
3660
+ const icon = path8.parse(fa.icon);
3065
3661
  possibleIcons.push(
3066
- { ext: fa.ext, icon: path7.join(icon.dir, icon.name) + ".ico" },
3067
- { ext: fa.ext, icon: path7.join(icon.dir, icon.name) + ".icns" }
3662
+ { ext: fa.ext, icon: path8.join(icon.dir, icon.name) + ".ico" },
3663
+ { ext: fa.ext, icon: path8.join(icon.dir, icon.name) + ".icns" }
3068
3664
  );
3069
3665
  }
3070
3666
  }
@@ -3073,7 +3669,7 @@ async function uploadApplicationSource({
3073
3669
  if (await exists(icon)) {
3074
3670
  files.push({
3075
3671
  from: icon,
3076
- to: path7.join("icons", "association-" + ext + path7.extname(icon))
3672
+ to: path8.join("icons", "association-" + ext + path8.extname(icon))
3077
3673
  });
3078
3674
  }
3079
3675
  })
@@ -3083,25 +3679,25 @@ async function uploadApplicationSource({
3083
3679
  if (config2.mac.entitlements) {
3084
3680
  files.push({
3085
3681
  from: config2.mac.entitlements,
3086
- to: path7.join("other", "mac", "entitlements.mac.plist")
3682
+ to: path8.join("other", "mac", "entitlements.mac.plist")
3087
3683
  });
3088
3684
  }
3089
3685
  if (config2.mac.entitlementsInherit) {
3090
3686
  files.push({
3091
3687
  from: config2.mac.entitlementsInherit,
3092
- to: path7.join("other", "mac", "entitlementsInherit.mac.plist")
3688
+ to: path8.join("other", "mac", "entitlementsInherit.mac.plist")
3093
3689
  });
3094
3690
  }
3095
3691
  if (config2.mac.icon) {
3096
3692
  files.push({
3097
3693
  from: config2.mac.icon,
3098
- to: path7.join("icons", "appIcon-mac" + path7.extname(config2.mac.icon))
3694
+ to: path8.join("icons", "appIcon-mac" + path8.extname(config2.mac.icon))
3099
3695
  });
3100
3696
  }
3101
3697
  if (config2.mac.requirements) {
3102
3698
  files.push({
3103
3699
  from: config2.mac.requirements,
3104
- to: path7.join("other", "mac", "requirements.txt")
3700
+ to: path8.join("other", "mac", "requirements.txt")
3105
3701
  });
3106
3702
  }
3107
3703
  }
@@ -3109,19 +3705,19 @@ async function uploadApplicationSource({
3109
3705
  if (config2.mas.entitlements) {
3110
3706
  files.push({
3111
3707
  from: config2.mas.entitlements,
3112
- to: path7.join("other", "mac", "entitlements.mas.plist")
3708
+ to: path8.join("other", "mac", "entitlements.mas.plist")
3113
3709
  });
3114
3710
  }
3115
3711
  if (config2.mas.entitlementsInherit) {
3116
3712
  files.push({
3117
3713
  from: config2.mas.entitlementsInherit,
3118
- to: path7.join("other", "mac", "entitlementsInherit.mas.plist")
3714
+ to: path8.join("other", "mac", "entitlementsInherit.mas.plist")
3119
3715
  });
3120
3716
  }
3121
3717
  if (config2.mas.provisioningProfile) {
3122
3718
  files.push({
3123
3719
  from: config2.mas.provisioningProfile,
3124
- to: path7.join("other", "mac", "mas.provisionprofile")
3720
+ to: path8.join("other", "mac", "mas.provisionprofile")
3125
3721
  });
3126
3722
  }
3127
3723
  }
@@ -3129,7 +3725,7 @@ async function uploadApplicationSource({
3129
3725
  if (config2.dmg.background) {
3130
3726
  files.push({
3131
3727
  from: config2.dmg.background,
3132
- to: path7.join("other", "mac", "dmg-background.tiff")
3728
+ to: path8.join("other", "mac", "dmg-background.tiff")
3133
3729
  });
3134
3730
  }
3135
3731
  }
@@ -3137,19 +3733,22 @@ async function uploadApplicationSource({
3137
3733
  if (config2.windows.icon) {
3138
3734
  files.push({
3139
3735
  from: config2.windows.icon,
3140
- to: path7.join(
3736
+ to: path8.join(
3141
3737
  "icons",
3142
- "appIcon-windows" + path7.extname(config2.windows.icon)
3738
+ "appIcon-windows" + path8.extname(config2.windows.icon)
3143
3739
  )
3144
3740
  });
3145
3741
  }
3146
3742
  if (config2.windows.nsisInclude) {
3147
3743
  files.push({
3148
3744
  from: config2.windows.nsisInclude,
3149
- to: path7.join("other", "installer.nsh")
3745
+ to: path8.join("other", "installer.nsh")
3150
3746
  });
3151
3747
  }
3152
3748
  }
3749
+ if (workspaceEntries.length) {
3750
+ files.push(...workspaceEntries);
3751
+ }
3153
3752
  return uploadToS3_default({
3154
3753
  bucket: config2.bucket || void 0,
3155
3754
  inputStream: await zip_default({
@@ -3158,15 +3757,15 @@ async function uploadApplicationSource({
3158
3757
  onError: (e) => {
3159
3758
  throw e;
3160
3759
  },
3161
- onProgress({ fs: fs6 }) {
3162
- totalBytes = fs6.totalBytes;
3760
+ onProgress({ fs: fs7 }) {
3761
+ totalBytes = fs7.totalBytes;
3163
3762
  },
3164
- appPkgJson
3763
+ appPkgJson: effectiveAppPkgJson
3165
3764
  }),
3166
3765
  key: generateS3Key_default({
3167
3766
  appId,
3168
3767
  buildId,
3169
- filenameSuffix: `${(_a = appPkgJson.name) == null ? void 0 : _a.replaceAll("/", "")}.zip`
3768
+ filenameSuffix: `${(_a = effectiveAppPkgJson.name) == null ? void 0 : _a.replaceAll("/", "")}.zip`
3170
3769
  }),
3171
3770
  onProgress({ loaded, total }) {
3172
3771
  onProgress(loaded / total * 100, loaded);
@@ -3175,7 +3774,7 @@ async function uploadApplicationSource({
3175
3774
  }
3176
3775
  async function exists(filePath) {
3177
3776
  try {
3178
- await fs5.promises.access(filePath);
3777
+ await fs6.promises.access(filePath);
3179
3778
  return true;
3180
3779
  } catch (e) {
3181
3780
  return false;
@@ -3714,7 +4313,7 @@ async function subscribeToFirebaseDoc(key, receiver) {
3714
4313
  (snapshot) => {
3715
4314
  receiver({
3716
4315
  snapshot,
3717
- data: snapshot.exists() ? snapshot.data() : void 0
4316
+ data: readDocumentSnapshot(snapshot)
3718
4317
  });
3719
4318
  resolve5(unsubscribe);
3720
4319
  },
@@ -3744,15 +4343,22 @@ var subscribeToBuild_default = async ({ appId, buildId, onDataReceived, userId }
3744
4343
  var import_firestore12 = require("firebase/firestore");
3745
4344
  var getCollection = async (collectionRef) => {
3746
4345
  const resp = await (0, import_firestore12.getDocs)(collectionRef);
3747
- const result = [];
3748
- resp.forEach((doc9) => result.push(doc9.data()));
3749
- return result;
4346
+ return readQuerySnapshot(resp);
3750
4347
  };
3751
4348
  var acceptedUsersCollection = (id) => (0, import_firestore12.collection)(firestore_default, `users/${id}/acceptedUsers`);
3752
4349
  var findAppUserId = async (appId) => {
3753
- const { uid, email } = currentUser();
3754
- const acceptedUsers = await getCollection(acceptedUsersCollection(uid));
3755
- const primaryUser = { id: uid, label: email };
4350
+ var _a;
4351
+ const authUser = currentUser();
4352
+ if (!(authUser == null ? void 0 : authUser.uid)) {
4353
+ throw new Error("A signed-in Firebase user is required");
4354
+ }
4355
+ const acceptedUsers = await getCollection(
4356
+ acceptedUsersCollection(authUser.uid)
4357
+ );
4358
+ const primaryUser = {
4359
+ id: authUser.uid,
4360
+ label: (_a = authUser.email) != null ? _a : authUser.uid
4361
+ };
3756
4362
  const users = [
3757
4363
  primaryUser,
3758
4364
  ...acceptedUsers.map((user) => ({ id: user.id, label: user.email }))
@@ -3978,13 +4584,13 @@ var OngoingBuildGuard = ({
3978
4584
  builds: []
3979
4585
  };
3980
4586
  if (!buildsResult.empty) {
3981
- const latestBuild = buildsResult.docs[0].data();
4587
+ const latestBuild = readQueryDocument(buildsResult.docs[0]);
3982
4588
  const isRunning = isBuildRunning(latestBuild) && latestBuild.status !== "preparation";
3983
4589
  logger_default.debug(
3984
4590
  { isRunning },
3985
4591
  "OngoingBuildGuard component: got latest build"
3986
4592
  );
3987
- stateUpdates.builds = buildsResult.docs.map((doc9) => doc9.data()).filter((build) => {
4593
+ stateUpdates.builds = buildsResult.docs.map((doc9) => readQueryDocument(doc9)).filter((build) => {
3988
4594
  if (isBuildRunning(build) && build.status !== "preparation") {
3989
4595
  return true;
3990
4596
  }
@@ -4372,7 +4978,7 @@ async function getBuilds({
4372
4978
  if (buildsResult.empty) {
4373
4979
  return [];
4374
4980
  }
4375
- return buildsResult.docs.map((doc9) => doc9.data());
4981
+ return readQuerySnapshot(buildsResult);
4376
4982
  }
4377
4983
 
4378
4984
  // src/utilities/getRelativeDateFromDateString.ts
@@ -4752,6 +5358,7 @@ async function getBuildById({
4752
5358
  buildId,
4753
5359
  userId
4754
5360
  }) {
5361
+ var _a;
4755
5362
  logger_default.debug({ appId, buildId }, "getBuildById");
4756
5363
  const snapshot = await (0, import_firestore19.getDoc)(
4757
5364
  (0, import_firestore19.doc)(firestore_default, `users/${userId}/applications/${appId}/builds/${buildId}`)
@@ -4759,7 +5366,7 @@ async function getBuildById({
4759
5366
  if (!snapshot.exists()) {
4760
5367
  return null;
4761
5368
  }
4762
- return snapshot.data();
5369
+ return (_a = readDocumentSnapshot(snapshot)) != null ? _a : null;
4763
5370
  }
4764
5371
 
4765
5372
  // src/utilities/getLatestReleasedBuild.ts
@@ -4770,7 +5377,7 @@ async function getLatestReleasedBuild({
4770
5377
  var _a, _b;
4771
5378
  const appRef = (0, import_firestore21.doc)(firestore_default, `users/${userId}/applications/${appId}`);
4772
5379
  const appSnapshot = await (0, import_firestore21.getDoc)(appRef);
4773
- const app2 = appSnapshot.exists() ? appSnapshot.data() : void 0;
5380
+ const app2 = readDocumentSnapshot(appSnapshot);
4774
5381
  if (!app2) {
4775
5382
  throw new Error(`Application with ID of ${appId} doesn't exist.`);
4776
5383
  }
@@ -4787,7 +5394,7 @@ async function getLatestReleasedBuild({
4787
5394
  (0, import_firestore21.limit)(1)
4788
5395
  );
4789
5396
  const buildsResult = await (0, import_firestore21.getDocs)(buildsQuery);
4790
- return buildsResult.empty ? void 0 : buildsResult.docs[0].data();
5397
+ return buildsResult.empty ? void 0 : readQueryDocument(buildsResult.docs[0]);
4791
5398
  }
4792
5399
 
4793
5400
  // src/components/BuildPicker.tsx
@@ -4931,6 +5538,7 @@ async function getBuildAttributes({
4931
5538
  buildId,
4932
5539
  configPath
4933
5540
  }) {
5541
+ var _a;
4934
5542
  const {
4935
5543
  id: appId,
4936
5544
  nodeVersion,
@@ -4938,7 +5546,7 @@ async function getBuildAttributes({
4938
5546
  pnpmVersion
4939
5547
  } = getProjectConfig(configPath).config;
4940
5548
  const { id: userId } = await findAppUserId_default(appId);
4941
- const { uid: contextUserId } = currentUser();
5549
+ const contextUserId = (_a = currentUser()) == null ? void 0 : _a.uid;
4942
5550
  const build = await fetchBuild({ appId, buildId, userId });
4943
5551
  return {
4944
5552
  appId,
@@ -4971,8 +5579,9 @@ async function releaseBuild({
4971
5579
  try {
4972
5580
  await getCallableFirebaseFunction_default("releaseBuild")({ appId, buildId });
4973
5581
  } catch (e) {
4974
- if (isFirebaseFunctionError(e) && (e.code === "failed-precondition" || e.code === "not-found")) {
4975
- throw CliError.from(e, "build-error");
5582
+ if (isFirebaseFunctionError(e)) {
5583
+ const errorType = e.code === "failed-precondition" || e.code === "not-found" ? "build-error" : "error";
5584
+ throw CliError.from(e, errorType);
4976
5585
  } else {
4977
5586
  throw new CliError("Unexpected internal error while releasing build");
4978
5587
  }
@@ -5820,7 +6429,10 @@ async function waitUntilFinished({
5820
6429
  const unsubscribe = (0, import_firestore27.onSnapshot)(
5821
6430
  (0, import_firestore27.doc)(firestore_default, docPath),
5822
6431
  (snapshot) => {
5823
- const data = snapshot.exists() ? snapshot.data() : void 0;
6432
+ const data = readDocumentSnapshot(snapshot);
6433
+ if (!data) {
6434
+ return;
6435
+ }
5824
6436
  const progress = makeProgress(data);
5825
6437
  onProgress(progress);
5826
6438
  if (progress.isFinished) {
@@ -6000,7 +6612,7 @@ var exitIfCLIOutOfDate_default = () => {
6000
6612
  (0, import_latest_version.default)(pkg.name).then((latest) => {
6001
6613
  if (import_semver3.default.gt(latest, pkg.version)) {
6002
6614
  const commandToUpdate = import_chalk3.default.greenBright(
6003
- `npm install ${import_is_installed_globally.default ? "--location=global" : "--save-dev"} @todesktop/cli`
6615
+ `npm install ${import_is_installed_globally.default ? "-g" : "--save-dev"} @todesktop/cli`
6004
6616
  );
6005
6617
  console.log(
6006
6618
  `Your version of @todesktop/cli is out of date.
@@ -6025,7 +6637,7 @@ var package_default = {
6025
6637
  access: "public"
6026
6638
  },
6027
6639
  name: "@todesktop/cli",
6028
- version: "1.15.0",
6640
+ version: "1.15.2",
6029
6641
  license: "MIT",
6030
6642
  author: "Dave Jeffery <dave@todesktop.com> (http://www.todesktop.com/)",
6031
6643
  homepage: "https://todesktop.com/cli",
@@ -6093,6 +6705,7 @@ var package_default = {
6093
6705
  "ink-text-input": "^4.0.1",
6094
6706
  "is-ci": "^3.0.1",
6095
6707
  "is-installed-globally": "^0.3.2",
6708
+ "js-yaml": "^4.1.0",
6096
6709
  "latest-version": "^5.1.0",
6097
6710
  "lodash.merge": "^4.6.2",
6098
6711
  "lodash.throttle": "^4.1.1",
@@ -6155,7 +6768,8 @@ var package_default = {
6155
6768
  "**/*.test.tsx",
6156
6769
  "!build/**/*",
6157
6770
  "!test/fixtures/**/*",
6158
- "!test/utilities/**/*"
6771
+ "!test/utilities/**/*",
6772
+ "!worktrees/**/*"
6159
6773
  ],
6160
6774
  require: [
6161
6775
  "esbuild-register",