Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PFX-553] - startServer action, nextjs plugin files, comment out plugin start, createLogger action, update tests #725

Merged
merged 31 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
634d1a6
feat: initial makeGasket with actions
agerard-godaddy Apr 3, 2024
35c44de
docs: cleanup copy/pasta
agerard-godaddy Apr 3, 2024
73f2f10
feat: more work on makeGasket with actions
agerard-godaddy Apr 5, 2024
1fba634
feat: adjust plugin action types
agerard-godaddy Apr 5, 2024
24b164e
test: changes to engine plugins config
agerard-godaddy Apr 5, 2024
7fa0d32
test: changes to engine plugins config
agerard-godaddy Apr 5, 2024
7125e16
test: changes to next config handling
agerard-godaddy Apr 5, 2024
53339c6
test: changes to engine plugins config
agerard-godaddy Apr 5, 2024
6e14aa4
test: changes to engine plugins config
agerard-godaddy Apr 5, 2024
eb1a729
feat: adjust engine args again
agerard-godaddy Apr 5, 2024
3c1c7b7
test: adjust engine args
agerard-godaddy Apr 5, 2024
01046b5
merge: v7
agerard-godaddy Apr 6, 2024
ee4d60d
test: adjusting types
agerard-godaddy Apr 6, 2024
884036f
fix: force tsc check
agerard-godaddy Apr 6, 2024
53f295d
fix: lockfile
agerard-godaddy Apr 6, 2024
c674b0a
startServer action, nextjs plugin files, comment out plugin start, cr…
mmason2-godaddy Apr 9, 2024
ffd528a
Merge branch 'v7' of https://github.com/godaddy/gasket into PFX-553
mmason2-godaddy Apr 9, 2024
b6cd849
tune ts types
mmason2-godaddy Apr 9, 2024
85a41ff
merge
mmason2-godaddy Apr 9, 2024
6438288
regen lockfile
mmason2-godaddy Apr 9, 2024
5b11323
merge
mmason2-godaddy Apr 11, 2024
79fac91
lockfile
mmason2-godaddy Apr 11, 2024
b9a9aa2
Update packages/gasket-plugin-https/README.md
mmason2-godaddy Apr 11, 2024
7282b9f
remove resolve function use, testPlugin to generatorDir more generic:
mmason2-godaddy Apr 11, 2024
95773b8
revert createLogger to init hook, add getLogger action
mmason2-godaddy Apr 11, 2024
e65fe89
adjust createLogger hook to execSync, make init handler sync
mmason2-godaddy Apr 11, 2024
c17a14c
fix tests
mmason2-godaddy Apr 11, 2024
d50e51e
merge
mmason2-godaddy Apr 11, 2024
18be7f6
merge
mmason2-godaddy Apr 11, 2024
31a9552
adjust server file, change extensions to js
mmason2-godaddy Apr 12, 2024
9045e55
fix typo
mmason2-godaddy Apr 12, 2024
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
718 changes: 679 additions & 39 deletions package-lock.json

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions packages/gasket-plugin-https/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,75 @@ module.exports = {
};
```

### Local Proxy Server

Create a proxy server for local development. See full `http-proxy` options [here](https://www.npmjs.com/package/http-proxy#options).

```diff
// gasket.config.js
module.exports = {
http: 80,
+ devProxy: {
+ hostname: 'my-host.com',
+ port: 443,
+ protocol: 'https',
+ xfwd: true,
+ ws: true,
+ target: {
+ host: 'localhost',
+ port: 80
+ }
+ }
}
```

## Lifecycles

### devProxy

Adjust and configure `devProxy` options for a proxy server during local development. This is useful if `https` is needed in local development. The options for `http-proxy` can be found [here](https://www.npmjs.com/package/http-proxy#options). The `devProxy` configuration must be defined in some capacity on the gasket config for this lifecycle to execute.

```js
/**
* Adding options to `devProxy` that are not defined in the gasket config
*
* @param {Gasket} gasket Gasket API.
* @param {Object} devProxyConfig The original config if defined in the gasket config
* @return {Object} devProxy config
*/
devProxy: async function devProxy(gasket, devProxyConfig) {
return {
...devProxyConfig,
hostname: 'local.example.com',
port: 8443
}
}

```

### serverConfig

Allows for server options to be added before `createServers` is called. Example use-case would be adding `sni` configurations when using `https` for local development.

```js
/**
* Adding sni certs to https
*
* @param {Gasket} gasket Gasket API.
* @param {Object} rawConfig raw server config
* @returns {Object} rawConfig
*/
serverConfig: async function serverConfig(gasket, rawConfig) {
rawConfig.https.sni = {
'*.my-domain.com': '/path/to/cert',
'*.my-other-domain.com': '/path/to/cert'
};

return rawConfig;
}

```

### createServers

Executed in order to retrieve the server options and the handler. Prefer to configure HTTP and port information in the `gasket.config.js` or
Expand Down
58 changes: 53 additions & 5 deletions packages/gasket-plugin-https/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import type { MaybeMultiple, MaybeAsync } from '@gasket/engine';
import type { SecureContextOptions } from 'tls';
import type { Server as HttpServer } from 'http';
import type { Server as HttpsServer } from 'https';
import type { Agent as HttpAgent, Server as HttpServer } from 'http';
import type { Agent as HttpsAgent, Server as HttpsServer } from 'https';
import type { SecureServerOptions, Http2Server } from 'http2';
import type { TerminusOptions, HealthCheckError } from '@godaddy/terminus';

type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =
Pick<T, Exclude<keyof T, Keys>>
& {
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>
}[Keys];

declare module '@gasket/engine' {
type BaseListenerConfig = {
port?: number,
Expand All @@ -23,19 +29,59 @@ declare module '@gasket/engine' {
honorCipherOrder?: boolean
};

type HttpsSettings =
type HttpsSettings =
& CustomHttpsSettings
& Omit<
SecureContextOptions,
keyof CustomHttpsSettings | 'secureProtocol' | 'secureOptions'
>;

type Http2Settings =
type Http2Settings =
& CustomHttpsSettings
& Omit<
SecureServerOptions,
keyof CustomHttpsSettings | 'secureProtocol' | 'secureOptions'
>;
>;

interface BaseDevProxyConfig {
target?: {
host: string;
port: number;
};
forward?: {
host: string;
port: number;
};
agent?: HttpAgent | HttpsAgent;
ssl?: {
key: CertInput;
cert: CertInput;
SNICallback: (hostname: string, cb: (err: Error | null, ctx: SecureContextOptions) => void) => void;
};
ws?: boolean;
xfwd?: boolean;
secure?: boolean;
toProxy?: boolean;
prependPath?: boolean;
ignorePath?: boolean;
localAddress?: string;
changeOrigin?: boolean;
preserveHeaderKeyCase?: boolean;
auth?: string;
hostRewrite?: string;
autoRewrite?: boolean;
protocolRewrite?: string;
cookieDomainRewrite?: false | string | { [key: string]: string };
cookiePathRewrite?: false | string | { [key: string]: string };
headers?: Record<string, string>;
proxyTimeout?: number;
timeout?: number;
followRedirects?: boolean;
selfHandleResponse?: boolean;
buffer?: Buffer;
}

type DevProxyConfig = RequireAtLeastOne<BaseDevProxyConfig, 'target' | 'forward'>;

interface ServerOptions {
hostname?: string,
Expand All @@ -50,6 +96,7 @@ declare module '@gasket/engine' {

export interface GasketConfig extends ServerOptions {
terminus?: TerminusOptions
devProxy?: DevProxyConfig
}

type CreatedServers = {
Expand All @@ -59,6 +106,7 @@ declare module '@gasket/engine' {
}

export interface HookExecTypes {
devProxy(proxyConfig: DevProxyConfig): MaybeAsync<DevProxyConfig>,
createServers(serveropts: ServerOptions): MaybeAsync<ServerOptions>,
servers(servers: CreatedServers): MaybeAsync<void>,
terminus(opts: TerminusOptions): MaybeAsync<TerminusOptions>,
Expand Down
75 changes: 64 additions & 11 deletions packages/gasket-plugin-https/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const debug = require('diagnostics')('gasket:https');
const create = require('create-servers');
const one = require('one-time/async');
const errs = require('errs');
const proxy = require('http-proxy');

/**
* Provide port defaults
Expand Down Expand Up @@ -31,23 +32,58 @@ function portInUseError(errors) {
}

/**
* Start lifecycle of a gasket application
* Create a https proxy server for local development
* @param {Object} opts devProxy configuration
* @param {Object} logger Gasket logger
*/
function startProxy(opts, logger) {
const { protocol = 'http', hostname = 'localhost', port = 8080 } = opts;
proxy.createServer({
protocol,
hostname,
port,
...opts
}).on('error', (e) => {
logger.error('Request failed to proxy:', e);
}).listen(
port,
() => logger.info(`Proxy server started: ${protocol}://${hostname}:${port}`)
);
}

/**
* Get server options from the gasket config
* @param {Gasket} gasket Gasket instance
* @returns {RawServerConfig} rawConfig
*/
function getRawServerConfig(gasket) {
const { hostname, http2, https, http, root } = gasket.config;
const rawConfig = {};
rawConfig.hostname = hostname;
rawConfig.root = root;
if (http) rawConfig.http = http;
if (https) rawConfig.https = https;
if (http2) rawConfig.http2 = http2;
return rawConfig;
}

/**
* Gasket action: startServer
*
* @param {Gasket} gasket Gasket instance
* @public
*/
async function start(gasket) {
const { hostname, http2, https, http, terminus, env } = gasket.config;
async function startServer(gasket) {
const { terminus, env, devProxy } = gasket.config;
const { logger } = gasket;

// Retrieving server opts
const configOpts = { hostname };

if (http) configOpts.http = http;
if (https) configOpts.https = https;
if (http2) configOpts.http2 = http2;
if (devProxy) {
const opts = await gasket.execWaterfall('devProxy', devProxy);
return startProxy(Object.assign(devProxy, opts), logger);
}

const serverOpts = await gasket.execWaterfall('createServers', configOpts);
const serverConfig = await gasket.execWaterfall('serverConfig', getRawServerConfig(gasket));
const serverOpts = await gasket.execWaterfall('createServers', serverConfig);
const { healthcheck, ...terminusDefaults } = await gasket.execWaterfall('terminus', {
healthcheck: ['/healthcheck', '/healthcheck.html'],
signals: ['SIGTERM'],
Expand Down Expand Up @@ -143,11 +179,28 @@ async function start(gasket) {
module.exports = {
name: require('../package').name,
hooks: {
start,
actions(gasket) {
return {
startServer: async () => await startServer(gasket)
};
},
metadata(gasket, meta) {
return {
...meta,
lifecycles: [{
name: 'devProxy',
method: 'execWaterfall',
description: 'Setup the devProxy options',
link: 'README.md#devProxy',
parent: 'start'
}, {
name: 'serverConfig',
method: 'execWaterfall',
description: 'Setup the server configuration',
link: 'README.md#serverConfig',
parent: 'start'
},
{
name: 'createServers',
method: 'execWaterfall',
description: 'Setup the `create-servers` options',
Expand Down
1 change: 1 addition & 0 deletions packages/gasket-plugin-https/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-unicorn": "^44.0.0",
"http-proxy": "^1.18.1",
"jest": "^29.7.0"
},
"eslintConfig": {
Expand Down
Loading
Loading