Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions apps/test-suite/tests/FileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1539,13 +1539,14 @@ export async function test({ describe, expect, it, ...t }) {
});

it('can cancel a download with AbortSignal', async () => {
// Use a large file to ensure we have time to cancel
const url = 'https://httpbingo.org/bytes/5242880';
// Use a slow-streaming endpoint to ensure the download is still in-flight when we cancel.
// Note: httpbingo.org/bytes has a 524288 byte limit and returns 400 for larger values.
const url = 'https://httpbingo.org/drip?numbytes=51200&duration=5&delay=0';
const file = new File(testDirectory, 'cancel_test.bin');
const controller = new AbortController();

// Cancel after a short delay
setTimeout(() => controller.abort(), 50);
// Cancel after a short delay — the /drip endpoint streams over 5s so this is safe.
setTimeout(() => controller.abort(), 100);

let error: any;
try {
Expand Down Expand Up @@ -1582,7 +1583,8 @@ export async function test({ describe, expect, it, ...t }) {
});

it('can use onProgress and signal together', async () => {
const url = 'https://httpbingo.org/bytes/524288';
// /drip streams data over 5s, so progress events fire before the download completes.
const url = 'https://httpbingo.org/drip?numbytes=51200&duration=5&delay=0';
const file = new File(testDirectory, 'progress_and_cancel.bin');
const controller = new AbortController();
const progressUpdates: { bytesWritten: number; totalBytes: number }[] = [];
Expand Down
14 changes: 7 additions & 7 deletions packages/@expo/cli/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ installEventLogger();

// Check Node.js version and issue a loud warning if it's too outdated
// This is sent to stderr (console.error) so it doesn't interfere with programmatic commands
const NODE_MIN = [20, 19, 4];
const NODE_MIN = [20, 19, 4] as const;
const nodeVersion = process.version?.slice(1).split('.', 3).map(Number);
if (nodeVersion[0] < NODE_MIN[0] || (nodeVersion[0] === NODE_MIN[0] && nodeVersion[1] < NODE_MIN[1])) {
if (nodeVersion[0]! < NODE_MIN[0] || (nodeVersion[0] === NODE_MIN[0] && nodeVersion[1]! < NODE_MIN[1])) {
console.error(
chalk.red`{bold Node.js (${process.version}) is outdated and unsupported.}`
+ chalk.red` Please update to a newer Node.js LTS version (required: >=${NODE_MIN.join('.')})\n`
Expand Down Expand Up @@ -90,7 +90,7 @@ if (args['--non-interactive']) {
}

// Check if we are running `npx expo <subcommand>` or `npx expo`
const isSubcommand = Boolean(commands[args._[0]]);
const isSubcommand = !!(args._[0] && commands[args._[0]]);

// Handle `--help` flag
if (!isSubcommand && args['--help']) {
Expand Down Expand Up @@ -191,7 +191,7 @@ if (!isSubcommand) {

// TODO: Log telemetry about invalid command used.
const subcommand = args._[0];
if (subcommand in migrationMap) {
if (subcommand && subcommand in migrationMap) {
const replacement = migrationMap[subcommand];
console.log();
const instruction = subcommand === 'upgrade' ? 'follow this guide' : 'use';
Expand All @@ -202,15 +202,15 @@ if (!isSubcommand) {
process.exit(1);
}
const deprecated = ['send', 'client:ios'];
if (deprecated.includes(subcommand)) {
if (subcommand && deprecated.includes(subcommand)) {
console.log();
console.log(chalk.yellow` {gray $} {bold expo ${subcommand}} is deprecated`);
console.log();
process.exit(1);
}
}

const command = isSubcommand ? args._[0] : defaultCmd;
const command = isSubcommand ? args._[0]! : defaultCmd;
const commandArgs = isSubcommand ? args._.slice(1) : args._;

// Push the help flag to the subcommand args.
Expand All @@ -222,7 +222,7 @@ if (args['--help']) {
process.on('SIGINT', () => process.exit(0));
process.on('SIGTERM', () => process.exit(0));

commands[command]().then((exec) => {
commands[command]!().then((exec) => {
exec(commandArgs);

// NOTE(EvanBacon): Track some basic telemetry events indicating the command
Expand Down
6 changes: 3 additions & 3 deletions packages/@expo/cli/e2e/__tests__/export-dom-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ describe('Export DOM Components', () => {
const nativeBundlePath = globSync('**/*.{hbc,js}', {
cwd: path.join(outputDir, '_expo/static/js/ios'),
absolute: true,
})[0];
})[0]!;
const domEntry = await fs.readFile(
globSync('www.bundle/**/*.html', {
cwd: outputDir,
absolute: true,
})[0],
})[0]!,
'utf8'
);
const md5HtmlBundle = crypto.createHash('md5').update(domEntry).digest('hex');
Expand All @@ -79,7 +79,7 @@ describe('Export DOM Components', () => {
globSync('www.bundle/**/*.js', {
cwd: outputDir,
absolute: true,
})[0],
})[0]!,
'utf8'
);
const md5DomJsBundle = crypto.createHash('md5').update(domJsBundleContent).digest('hex');
Expand Down
2 changes: 1 addition & 1 deletion packages/@expo/cli/e2e/__tests__/export.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe('server', () => {
const bundlePath = globSync('**/*.js', {
cwd: path.join(outputDir, '_expo'),
absolute: true,
})[0];
})[0]!;

const bundle = await fs.readFile(bundlePath, 'utf8');

Expand Down
8 changes: 5 additions & 3 deletions packages/@expo/cli/e2e/__tests__/export/base-path.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ describe('static-rendering with a custom base path', () => {

const jsFiles = indexHtml
.querySelectorAll('script')
.filter((script) => !!script.attributes.src)
.map((script) => script.attributes.src);
.map((script) => script.attributes.src)
.filter((src): src is string => !!src);
expect(jsFiles).toEqual([
expect.stringMatching(/\/one\/two\/_expo\/static\/js\/web\/entry-.*\.js/),
]);
Expand All @@ -68,7 +68,9 @@ describe('static-rendering with a custom base path', () => {
return link.attributes.as !== 'font';
});

const cssFiles = links.map((link) => link.attributes.href);
const cssFiles = links
.map((link) => link.attributes.href)
.filter((link): link is string => !!link);

cssFiles.forEach((src) => {
// Linked to the expected static location
Expand Down
4 changes: 2 additions & 2 deletions packages/@expo/cli/e2e/__tests__/export/no-bytecode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('exports for hermes with no bytecode', () => {
const bundlePath = globSync('**/*.js', {
cwd: path.join(outputDir, '_expo'),
absolute: true,
})[0];
})[0]!;

const bundle = await fs.promises.readFile(bundlePath, 'utf8');
// Minified mark
Expand Down Expand Up @@ -116,7 +116,7 @@ describe('exports for hermes with no bytecode and no minification', () => {
const bundlePath = globSync('**/*.js', {
cwd: path.join(outputDir, '_expo'),
absolute: true,
})[0];
})[0]!;

const bundle = await fs.promises.readFile(bundlePath, 'utf8');
// Unminified mark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('exports with serializer plugins', () => {
expect(files).not.toEqual([]);

// Load the sourcemap and parse it as JSON
const rawmap = await JsonFile.readAsync(path.resolve(outputDir, files[0]));
const rawmap = await JsonFile.readAsync(path.resolve(outputDir, files[0] ?? ''));
const sourcemap = rawmap as unknown as BasicSourceMap;

// Ensure the sourcemap does not contain absolute paths to the project directory
Expand Down
12 changes: 6 additions & 6 deletions packages/@expo/cli/e2e/__tests__/export/server-rendering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ describe('exports server', () => {
.filter((script) => !!script.attributes.src)
.forEach((script) => {
const jsBundle = fs.readFileSync(
path.join(server.outputDir, 'client', script.attributes.src),
path.join(server.outputDir, 'client', script.attributes.src ?? ''),
'utf8'
);

Expand Down Expand Up @@ -276,15 +276,15 @@ describe('exports server', () => {
if (globalPreload) {
expect(
fs.readFileSync(
path.join(server.outputDir, 'client', globalPreload.attributes.href),
path.join(server.outputDir, 'client', globalPreload.attributes.href ?? ''),
'utf-8'
)
).toMatchInlineSnapshot(`"div{background:#0ff}"`);
}

// CSS Module
expect(
fs.readFileSync(path.join(server.outputDir, 'client', links[2].attributes.href), 'utf-8')
fs.readFileSync(path.join(server.outputDir, 'client', links[2]?.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`".HPV33q_text{color:#1e90ff}"`);

const styledHtml = getHtml(await server.fetchAsync('/styled').then((res) => res.text()));
Expand All @@ -300,17 +300,17 @@ describe('exports server', () => {

const links = indexHtml.querySelectorAll('html > head > link[as="font"]');
expect(links.length).toBe(1);
expect(links[0].attributes.href).toBe(
expect(links[0]?.attributes.href).toBe(
'/assets/__e2e__/static-rendering/sweet.7c9263d3cffcda46ff7a4d9c00472c07.ttf'
);

expect(links[0].toString()).toMatch(
expect(links[0]?.toString()).toMatch(
/<link rel="preload" href="\/assets\/__e2e__\/static-rendering\/sweet\.[a-zA-Z0-9]{32}\.ttf" as="font" crossorigin="" >/
);

expect(
fs.readFileSync(
path.join(server.outputDir, 'client', links[0].attributes.href.replace(/\?.*$/, '')),
path.join(server.outputDir, 'client', links[0]?.attributes.href?.replace(/\?.*$/, '') ?? ''),
'utf-8'
)
).toBeDefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('exports with single-page', () => {
.querySelectorAll('script')
.filter((script) => script.attributes.src)
.forEach((script) => {
const jsBundle = fs.readFileSync(path.join(outputDir, script.attributes.src), 'utf8');
const jsBundle = fs.readFileSync(path.join(outputDir, script.attributes.src ?? ''), 'utf8');

// Ensure the bundle is valid
expect(jsBundle).toMatch('__BUNDLE_START_TIME__');
Expand Down Expand Up @@ -136,15 +136,15 @@ describe('exports with single-page', () => {
expect(globalPreload).toBeDefined();
if (globalPreload) {
expect(
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`"div{background:#0ff}"`);
}

const testPreload = links.find((l) => /test\.module-.*\.css/.test(l.attributes.href!));
expect(testPreload).toBeDefined();
if (testPreload) {
expect(
fs.readFileSync(path.join(outputDir, testPreload.attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, testPreload.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`".HPV33q_text{color:#1e90ff}"`);
}
});
Expand Down
12 changes: 6 additions & 6 deletions packages/@expo/cli/e2e/__tests__/export/static-rendering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ describe('exports static', () => {
.querySelectorAll('script')
.filter((script) => !!script.attributes.src)
.forEach((script) => {
const jsBundle = fs.readFileSync(path.join(outputDir, script.attributes.src), 'utf8');
const jsBundle = fs.readFileSync(path.join(outputDir, script.attributes.src ?? ''), 'utf8');

// Ensure the bundle is valid
expect(jsBundle).toMatch('__BUNDLE_START_TIME__');
Expand Down Expand Up @@ -227,13 +227,13 @@ describe('exports static', () => {
expect(globalPreload).toBeDefined();
if (globalPreload) {
expect(
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`"div{background:#0ff}"`);
}

// CSS Module
expect(
fs.readFileSync(path.join(outputDir, links[2].attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, links[2]?.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`".HPV33q_text{color:#1e90ff}"`);

const styledHtml = await getPageHtml(outputDir, 'styled.html');
Expand All @@ -251,16 +251,16 @@ describe('exports static', () => {

const links = indexHtml.querySelectorAll('html > head > link[as="font"]');
expect(links.length).toBe(1);
expect(links[0].attributes.href).toBe(
expect(links[0]?.attributes.href).toBe(
'/assets/__e2e__/static-rendering/sweet.7c9263d3cffcda46ff7a4d9c00472c07.ttf'
);

expect(links[0].toString()).toMatch(
expect(links[0]?.toString()).toMatch(
/<link rel="preload" href="\/assets\/__e2e__\/static-rendering\/sweet\.[a-zA-Z0-9]{32}\.ttf" as="font" crossorigin="" >/
);

expect(
fs.readFileSync(path.join(outputDir, links[0].attributes.href.replace(/\?.*$/, '')), 'utf-8')
fs.readFileSync(path.join(outputDir, links[0]?.attributes.href?.replace(/\?.*$/, '') ?? ''), 'utf-8')
).toBeDefined();

// Ensure the font is used
Expand Down
14 changes: 7 additions & 7 deletions packages/@expo/cli/e2e/__tests__/export/static-splitting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ describe('exports static with bundle splitting', () => {

const script = indexHtml
.querySelectorAll('script')
.filter((script) => !!script.attributes.src)[0];
const jsBundle = fs.readFileSync(path.join(outputDir, script.attributes.src), 'utf8');
.find((script) => !!script.attributes.src);
const jsBundle = fs.readFileSync(path.join(outputDir, script?.attributes.src ?? ''), 'utf8');

// Ensure the bundle is valid
expect(jsBundle).toMatch('__BUNDLE_START_TIME__');
Expand Down Expand Up @@ -222,13 +222,13 @@ describe('exports static with bundle splitting', () => {
expect(globalPreload).toBeDefined();
if (globalPreload) {
expect(
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, globalPreload.attributes.href!), 'utf-8')
).toMatchInlineSnapshot(`"div{background:#0ff}"`);
}

// CSS Module
expect(
fs.readFileSync(path.join(outputDir, links[2].attributes.href), 'utf-8')
fs.readFileSync(path.join(outputDir, links[2]?.attributes.href ?? ''), 'utf-8')
).toMatchInlineSnapshot(`".HPV33q_text{color:#1e90ff}"`);

const styledHtml = await getPageHtml(outputDir, 'styled.html');
Expand All @@ -246,16 +246,16 @@ describe('exports static with bundle splitting', () => {

const links = indexHtml.querySelectorAll('html > head > link[as="font"]');
expect(links.length).toBe(1);
expect(links[0].attributes.href).toBe(
expect(links[0]?.attributes.href).toBe(
'/assets/__e2e__/static-rendering/sweet.7c9263d3cffcda46ff7a4d9c00472c07.ttf'
);

expect(links[0].toString()).toMatch(
expect(links[0]?.toString()).toMatch(
/<link rel="preload" href="\/assets\/__e2e__\/static-rendering\/sweet\.[a-zA-Z0-9]{32}\.ttf" as="font" crossorigin="" >/
);

expect(
fs.readFileSync(path.join(outputDir, links[0].attributes.href.replace(/\?.*$/, '')), 'utf-8')
fs.readFileSync(path.join(outputDir, links[0]?.attributes.href?.replace(/\?.*$/, '') ?? ''), 'utf-8')
).toBeDefined();

// Ensure the font is used
Expand Down
1 change: 0 additions & 1 deletion packages/@expo/cli/e2e/__tests__/install-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
getLoadedModulesAsync,
setupTestProjectWithOptionsAsync,
findProjectFiles,
stripWhitespace,
} from './utils';
import { executePnpmAsync, executeExpoAsync } from '../utils/expo';

Expand Down
6 changes: 3 additions & 3 deletions packages/@expo/cli/e2e/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export function getHtmlHelpers(outputDir: string) {
// Remove scripts without a src attribute
.filter((script) => !!script.attributes.src)
.map((script) => {
expect(fs.existsSync(path.join(outputDir, script.attributes.src))).toBe(true);
expect(fs.existsSync(path.join(outputDir, script.attributes.src ?? ''))).toBe(true);

return script.attributes.src;
});
Expand All @@ -248,8 +248,8 @@ export function getHtmlHelpers(outputDir: string) {
return tags;
}

function ensureEntryChunk(relativePath: string) {
expect(fs.readFileSync(path.join(outputDir, relativePath), 'utf8')).toMatch(
function ensureEntryChunk(relativePath: string | undefined) {
expect(fs.readFileSync(path.join(outputDir, relativePath ?? ''), 'utf8')).toMatch(
/__BUNDLE_START_TIME__/
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@expo/cli/e2e/utils/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function executeAsync(
const { npm_config_minimum_release_age, ...processEnv } = process.env;
const [bin, ...flags] = command ? command.concat(commandOrFlags) : commandOrFlags;

const child = execa(bin, flags, {
const child = execa(bin!, flags, {
...spawnOptions,
cwd,
env: { ...processEnv, ...env },
Expand Down
2 changes: 1 addition & 1 deletion packages/@expo/cli/e2e/utils/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function createBackgroundServer({
spawnOptions.env ??= {};
spawnOptions.env.PORT = String(port);

child = spawn(bin, commandOrFlags, {
child = spawn(bin!, commandOrFlags, {
shell: false,
stdio: ['ignore', 'pipe', 'pipe'],
...spawnOptions,
Expand Down
2 changes: 1 addition & 1 deletion packages/@expo/cli/src/api/user/otp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ async function promptForBackupOTPAsync(
body: JSON.stringify({
username,
password,
secondFactorDeviceID: device.id,
secondFactorDeviceID: device?.id,
}),
});

Expand Down
Loading
Loading