Skip to content

Commit 2004bed

Browse files
authored
fix: handling deploy cli argument in build action adapter handler (#105)
Fixes handling the `deploy` CLI argument in the build action adapter handler addressing #101. Adds handling `deploy` property of an adapter implementation when the value of `deploy` is a function. See more in the docs at https://react-server.dev/deploy/api#define-the-adapter-handler. Implements feature request at #48 (comment)
1 parent 138ef89 commit 2004bed

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

docs/src/pages/en/(pages)/deploy/api.mdx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,26 @@ You need to pass adapter properties to the `createAdapter` function to configure
5555

5656
`handler`: The adapter handler function.
5757

58-
`deploy`: The deployment command and arguments. This is optional. When provided, the adapter will show what command the developer needs to run to deploy the application after it has been built. If the `--deploy` flag is provided during the build, the adapter will run this command.
58+
`deploy`: The deployment command and arguments. This is optional. When provided, the adapter will show what command the developer needs to run to deploy the application after it has been built. If the `--deploy` flag is provided during the build, the adapter will run this command. The `deploy` property can also be a function that will be called with the adapter options, CLI options and the handler result. This is useful if you need to customize the deployment command based on the adapter options or the handler result. If you don't provide a result with `command` and `args`, the default deployment handling spawning the command will be skipped. This is useful if you want to implement a custom deployment workflow in the adapter.
59+
60+
```js
61+
export const adapter = createAdapter({
62+
// ...
63+
handler: async ({ adapterOptions, files, copy, config, reactServerDir, reactServerOutDir, root, options }) => {
64+
// Your adapter handler implementation
65+
return {
66+
// Your handler result, this will be passed to the deploy function
67+
};
68+
},
69+
async deploy({ adapterOptions, options, handlerResult }) {
70+
// customize the deployment command based on the adapter options, CLI options or handler result
71+
return {
72+
command: "vercel",
73+
args: ["deploy", "--prebuilt"],
74+
};
75+
},
76+
});
77+
```
5978

6079
<Link name="adapter-handler">
6180
## Adapter handler

packages/react-server-adapter-core/index.d.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ declare module "@lazarv/react-server-adapter-core" {
33
(adapterOptions: T, root: string, options: any): Promise<void>;
44
}
55

6-
export function createAdapter<T = any>(options: {
6+
export type DeployCommandDescriptor = {
7+
command: string;
8+
args: string[];
9+
message?: string;
10+
};
11+
12+
export function createAdapter<T = any, R = void>(options: {
713
name: string;
814
outDir: string;
915
outStaticDir?: string;
@@ -32,8 +38,19 @@ declare module "@lazarv/react-server-adapter-core" {
3238
reactServerDir: string;
3339
reactServerOutDir: string;
3440
root: string;
35-
options: any;
36-
}) => Promise<void>;
41+
options: Record<string, any>;
42+
}) => Promise<R>;
43+
deploy:
44+
| DeployCommandDescriptor
45+
| ((context: {
46+
adapterOptions: T;
47+
options: Record<string, any>;
48+
handlerResult: R;
49+
}) =>
50+
| DeployCommandDescriptor
51+
| Promise<DeployCommandDescriptor>
52+
| void
53+
| Promise<void>);
3754
}): Adapter<T>;
3855

3956
export function banner(message: string): void;

packages/react-server-adapter-core/index.mjs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ export function createAdapter({
446446
await copy.server();
447447
}
448448

449-
await handler({
449+
const handlerResult = await handler({
450450
files,
451451
copy,
452452
config,
@@ -458,17 +458,23 @@ export function createAdapter({
458458
});
459459

460460
success(`${name} deployment successfully created.`);
461-
if (deploy && deploy.command && deploy.args) {
462-
if (options.deploy) {
463-
banner(`deploying to ${name}`);
464-
clearProgress();
465-
await spawnCommand(deploy.command, deploy.args);
466-
} else {
467-
console.log(
468-
`${colors.gray(`Deploy to ${name} using:`)} ${deploy.command} ${deploy.args.join(" ")}`
469-
);
470-
if (deploy.message) {
471-
console.log(deploy.message);
461+
if (deploy) {
462+
const { command, args, message } =
463+
typeof deploy === "function"
464+
? await deploy({ adapterOptions, options, handlerResult })
465+
: deploy;
466+
if (command && args) {
467+
if (options.deploy) {
468+
banner(`deploying to ${name}`);
469+
clearProgress();
470+
await spawnCommand(command, args);
471+
} else {
472+
console.log(
473+
`${colors.gray(`Deploy to ${name} using:`)} ${command} ${args.join(" ")}`
474+
);
475+
if (message) {
476+
console.log(message);
477+
}
472478
}
473479
}
474480
}

packages/react-server/lib/build/adapter.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export default async function adapter(root, options) {
1515
const adapter =
1616
options?.adapter?.[0] === "false"
1717
? null
18-
: options.adapter || config.adapter;
18+
: typeof options.adapter?.[0] === "string" && options.adapter?.[0]
19+
? options.adapter?.[0]
20+
: config.adapter;
1921
if (adapter) {
2022
if (typeof adapter === "function") {
2123
return await adapter({}, root, options);

0 commit comments

Comments
 (0)