@everystack/cli 0.2.14 → 0.2.17
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/package.json +1 -1
- package/src/cli/commands/update.ts +32 -50
- package/src/cli/utils/export.ts +1 -1
package/package.json
CHANGED
|
@@ -9,8 +9,8 @@ import { resolveConfig, type CliConfig } from '../config.js';
|
|
|
9
9
|
import { uploadToS3, invokeAction } from '../aws.js';
|
|
10
10
|
import { step, success, warn, fail, info } from '../output.js';
|
|
11
11
|
import { exportApp } from '../utils/export.js';
|
|
12
|
-
import { loadSstSecrets } from '../utils/secrets.js';
|
|
13
12
|
import { walkDirectory } from '../utils/walk.js';
|
|
13
|
+
import { loadSstSecrets } from '../utils/secrets.js';
|
|
14
14
|
|
|
15
15
|
export interface UpdateFlags {
|
|
16
16
|
channel?: string;
|
|
@@ -60,47 +60,27 @@ export async function updateCommand(flags: UpdateFlags & Record<string, string>)
|
|
|
60
60
|
// Stage may not be deployed yet — HOST_URL falls back to loadSstOutputs
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
63
|
+
// Inject SST secrets into process.env so app.config.js / Metro can read them.
|
|
64
|
+
// The CLI injects ALL secrets — the app's deny-by-default filter (e.g.
|
|
65
|
+
// expo-secrets.config.js) is the security boundary that gates what reaches
|
|
66
|
+
// the bundle. This avoids requiring `sst shell` in deploy scripts.
|
|
67
67
|
try {
|
|
68
|
-
step('Loading SST secrets...');
|
|
69
68
|
const { parseAppName } = await import('../discover.js');
|
|
70
69
|
const appName = await parseAppName();
|
|
71
|
-
const region = resolvedConfig?.region
|
|
72
|
-
|
|
70
|
+
const region = resolvedConfig?.region || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
|
|
71
|
+
step('Loading SST secrets...');
|
|
73
72
|
const secrets = await loadSstSecrets({ appName, stage: flags.stage, region });
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
process.env[key] ||= value;
|
|
73
|
+
let injected = 0;
|
|
74
|
+
for (const [k, v] of Object.entries(secrets)) {
|
|
75
|
+
if (!process.env[k]) {
|
|
76
|
+
process.env[k] = v;
|
|
77
|
+
injected++;
|
|
80
78
|
}
|
|
81
|
-
success(`Injected ${publicSecrets.length} EXPO_PUBLIC_* secrets: ${publicSecrets.map(([k]) => k).join(', ')}`);
|
|
82
|
-
} else if (allNames.length > 0) {
|
|
83
|
-
info('No EXPO_PUBLIC_* secrets found (server secrets are provided by SST at runtime)');
|
|
84
|
-
} else {
|
|
85
|
-
info('No SST secrets found for this stage');
|
|
86
|
-
}
|
|
87
|
-
if (skipped > 0) {
|
|
88
|
-
info(`Skipped ${skipped} server secret(s) — provided by SST Resource linking at Lambda runtime`);
|
|
89
79
|
}
|
|
80
|
+
success(`${injected} secret(s) injected into env (${Object.keys(secrets).length} total)`);
|
|
90
81
|
} catch (err: any) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const msg = err.message || String(err);
|
|
94
|
-
if (msg.includes("Cannot find package '@aws-sdk/client-ssm'")) {
|
|
95
|
-
warn('Secrets skipped: @aws-sdk/client-ssm not installed');
|
|
96
|
-
info('Install with: pnpm add -D @aws-sdk/client-ssm');
|
|
97
|
-
} else if (msg.includes("Cannot find package '@aws-sdk/client-s3'")) {
|
|
98
|
-
warn('Secrets skipped: @aws-sdk/client-s3 not installed');
|
|
99
|
-
info('Install with: pnpm add -D @aws-sdk/client-s3');
|
|
100
|
-
} else {
|
|
101
|
-
warn(`Could not load SST secrets: ${msg}`);
|
|
102
|
-
}
|
|
103
|
-
info('Set secrets with: everystack secrets set KEY "value" --stage ' + flags.stage);
|
|
82
|
+
warn(`Could not load SST secrets: ${err.message}`);
|
|
83
|
+
info('Secrets may be unavailable during export. Provide env vars from the caller if needed.');
|
|
104
84
|
}
|
|
105
85
|
}
|
|
106
86
|
|
|
@@ -114,21 +94,6 @@ export async function updateCommand(flags: UpdateFlags & Record<string, string>)
|
|
|
114
94
|
const appConfig = await loadAppConfig();
|
|
115
95
|
const runtimeVersion = appConfig.runtimeVersion;
|
|
116
96
|
|
|
117
|
-
// Validate: SSR flags in the expo-router plugin config will crash native devices.
|
|
118
|
-
// The bundle is compiled with server rendering code paths that have no server at runtime.
|
|
119
|
-
const ssrFlags = getExpoRouterSsrFlags(appConfig);
|
|
120
|
-
if (ssrFlags.useServerRendering || ssrFlags.useServerDataLoaders) {
|
|
121
|
-
fail('Export contains server rendering flags that will crash native devices.');
|
|
122
|
-
info('expo-router plugin has unstable_useServerRendering or unstable_useServerDataLoaders enabled.');
|
|
123
|
-
info('Use SSR_ENABLED to opt in only for web server exports:');
|
|
124
|
-
info('');
|
|
125
|
-
info(" ['expo-router', {");
|
|
126
|
-
info(' unstable_useServerRendering: !!process.env.SSR_ENABLED,');
|
|
127
|
-
info(' unstable_useServerDataLoaders: !!process.env.SSR_ENABLED,');
|
|
128
|
-
info(' }]');
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
97
|
if (!runtimeVersion) {
|
|
133
98
|
fail('No runtimeVersion found in app.json/app.config.js');
|
|
134
99
|
info('Add "runtimeVersion" to your app.json, e.g.:');
|
|
@@ -141,6 +106,23 @@ export async function updateCommand(flags: UpdateFlags & Record<string, string>)
|
|
|
141
106
|
const distDir = path.resolve('dist');
|
|
142
107
|
const needsMobile = platformFilter !== 'web';
|
|
143
108
|
|
|
109
|
+
// Validate: SSR flags in the expo-router plugin config will crash native devices.
|
|
110
|
+
// Only check when mobile platforms are involved — web-only updates want SSR enabled.
|
|
111
|
+
if (needsMobile) {
|
|
112
|
+
const ssrFlags = getExpoRouterSsrFlags(appConfig);
|
|
113
|
+
if (ssrFlags.useServerRendering || ssrFlags.useServerDataLoaders) {
|
|
114
|
+
fail('Export contains server rendering flags that will crash native devices.');
|
|
115
|
+
info('expo-router plugin has unstable_useServerRendering or unstable_useServerDataLoaders enabled.');
|
|
116
|
+
info('Use SSR_ENABLED to opt in only for web server exports:');
|
|
117
|
+
info('');
|
|
118
|
+
info(" ['expo-router', {");
|
|
119
|
+
info(' unstable_useServerRendering: !!process.env.SSR_ENABLED,');
|
|
120
|
+
info(' unstable_useServerDataLoaders: !!process.env.SSR_ENABLED,');
|
|
121
|
+
info(' }]');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
144
126
|
// First export: mobile-safe bundles (no SSR_ENABLED).
|
|
145
127
|
// Always re-export — stale dist/ is the #1 cause of broken OTA pushes.
|
|
146
128
|
if (needsMobile) {
|
package/src/cli/utils/export.ts
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'fs/promises';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
5
5
|
export function exportApp(platform?: string): Promise<void> {
|
|
6
|
-
const args = ['expo', 'export', '--output-dir', 'dist'];
|
|
6
|
+
const args = ['expo', 'export', '--output-dir', 'dist', '--clear'];
|
|
7
7
|
if (platform) args.push('--platform', platform);
|
|
8
8
|
|
|
9
9
|
return new Promise((resolve, reject) => {
|