Skip to content

Commit

Permalink
Fix deploys to vercel
Browse files Browse the repository at this point in the history
Deploys to vercel were broken because it was not loading the appropriate
global variables

To fix this we created an adapter that explicitly loads them.
Developers looking to deploy to vercel should use that adapter in place
of node.
  • Loading branch information
lizkenyon committed Feb 16, 2024
1 parent 6df84d2 commit f1f80a6
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 16 deletions.
35 changes: 33 additions & 2 deletions loom.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,40 @@ function forkRemixProject(projects: Config.InitialProjectOptions[]) {
[
{
...project,
displayName: 'shopify-app-remix-server',
setupFilesAfterEnv: [
...(project.setupFilesAfterEnv ?? []),
'../../packages/shopify-app-remix/src/server/adapters/node/__tests__/setup-jest.ts',
],
displayName: 'shopify-app-remix-server-node',
testEnvironment: 'node',
testPathIgnorePatterns: [
'src/react',
'src/server/adapters/__tests__',
],
},
],
[
{
...project,
setupFilesAfterEnv: [
...(project.setupFilesAfterEnv ?? []),
'../../packages/shopify-app-remix/src/server/adapters/vercel/__tests__/setup-jest.ts',
],
displayName: 'shopify-app-remix-server-vercel',
testEnvironment: 'node',
testPathIgnorePatterns: [
'src/react',
'src/server/adapters/__tests__',
],
},
],
[
{
...project,
testRegex: undefined,
displayName: 'shopify-app-remix-server-adapters',
testMatch: ['<rootDir>/src/server/adapters/__tests__/**/*'],
testEnvironment: 'node',
testPathIgnorePatterns: ['src/react'],
},
],
);
Expand Down
2 changes: 1 addition & 1 deletion packages/shopify-app-remix/loom.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default createPackage((pkg) => {

const basePath = `${__dirname}/src/server/adapters`;
fs.readdirSync(basePath, {withFileTypes: true})
.filter((dirent) => dirent.isDirectory())
.filter((dirent) => dirent.isDirectory() && dirent.name !== '__tests__')
.forEach((dirent) => {
pkg.entry({root: `./src/server/adapters/${dirent.name}/index.ts`});
});
Expand Down
1 change: 1 addition & 0 deletions packages/shopify-app-remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"react-dom": "^18.2.0"
},
"dependencies": {
"@remix-run/node": "^2.6.0",
"@remix-run/server-runtime": "^2.5.1",
"@shopify/admin-api-client": "^0.2.3",
"@shopify/shopify-api": "^9.3.1",
Expand Down
3 changes: 0 additions & 3 deletions packages/shopify-app-remix/src/server/__test-helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import '@shopify/shopify-api/adapters/web-api';
import '../adapters/node';

export * from './const';
export * from './expect-admin-api-client';
export * from './expect-begin-auth-redirect';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ export async function validateMocks() {
}

if (request?.body) {
const bodyString = new TextDecoder('utf-8').decode(
request.body as any as Buffer,
);
const bodyBuffer = await stream2buffer(request.body);
const bodyString = new TextDecoder('utf-8').decode(bodyBuffer);

expected.body = expect.stringContaining(bodyString);
actual.body = init?.body?.toString();
Expand Down Expand Up @@ -137,6 +136,22 @@ export async function validateMocks() {
}
}

async function stream2buffer(
stream: ReadableStream<Uint8Array>,
): Promise<Buffer> {
const buffers = [];

for await (const data of stream as any) {
if (typeof data === 'number') {
buffers.push(Uint8Array.from([data]));
} else {
buffers.push(data);
}
}

return Buffer.concat(buffers);
}

export function skipMockChecks(value: boolean) {
skipMockChecksFlag = value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {APP_BRIDGE_URL} from '../../../authenticate/const';
import {appBridgeUrl} from '../../../authenticate/helpers';
import {APP_BRIDGE_URL} from '../../authenticate/const';
import {appBridgeUrl} from '../../authenticate/helpers';

describe('node setup import', () => {
/* eslint-disable no-process-env */
Expand All @@ -9,7 +9,7 @@ describe('node setup import', () => {
process.env.APP_BRIDGE_URL = 'http://localhost:9876/app-bridge.js';

// WHEN
await require('../index');
await require('../node/index');

// THEN
expect(appBridgeUrl()).toEqual(process.env.APP_BRIDGE_URL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('node setup import', () => {
expect(cryptoBefore).toBeUndefined();

// WHEN
await require('../index');
await require('../node');

// THEN
const cryptoAfter = (await require('@shopify/shopify-api/runtime')).crypto;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import fetchMock from 'jest-fetch-mock';
import '@shopify/shopify-api/adapters/web-api';
import '..';

// Globally disable fetch requests so we don't risk making real ones
fetchMock.enableMocks();

beforeEach(() => {
fetchMock.mockReset();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import fetchMock from 'jest-fetch-mock';
import '@shopify/shopify-api/adapters/web-api';
import '..';
import {setAbstractFetchFunc} from '@shopify/shopify-api/runtime';

// Globally disable fetch requests so we don't risk making real ones
fetchMock.enableMocks();

beforeEach(() => {
fetchMock.mockReset();
});
setAbstractFetchFunc(fetch);
13 changes: 13 additions & 0 deletions packages/shopify-app-remix/src/server/adapters/vercel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {setAbstractFetchFunc} from '@shopify/shopify-api/runtime';
import {installGlobals} from '@remix-run/node';

import '../node';

installGlobals();

const fetchFunc = fetch;
setAbstractFetchFunc(async (...args) => {
const response = await fetchFunc.apply(this, args);

return response;
});
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ describe('Headers boundary', () => {
const result = boundary.headers(headers as any);

// THEN
expect(result).toEqual(new Headers());
expect(result.entries()).toEqual(new Headers().entries());
});
});
Loading

0 comments on commit f1f80a6

Please sign in to comment.