Skip to content

Commit

Permalink
Merge pull request #24 from bericp1/chore/rename-now-to-vercel
Browse files Browse the repository at this point in the history
[Chore] Rename now to vercel
  • Loading branch information
bericp1 authored Mar 13, 2021
2 parents 0f04c39 + b767bc3 commit 39ac9b0
Show file tree
Hide file tree
Showing 23 changed files with 151 additions and 82 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ for `netlify-cms`.

This package exposes an API that makes it easy to use in a traditional long-running Node server (i.e. using `express`)
or in stateless serverless functions (i.e.
[Zeit Now Serverless Functions](https://zeit.co/docs/v2/serverless-functions/introduction)).
[Vercel Serverless Functions](https://vercel.com/docs/serverless-functions/introduction)).

## Usage

**Note:** More detailed documentation and inline code samples are in the works. For now it's best to check out the
**Note:** More detailed documentation and inline code samples are in the works. For now, it's best to check out the
examples:

- [Generic Node HTTP server](./examples/generic)
- [Zeit Now functions](./examples/now)
- [Vercel functions](./examples/vercel)

### Overview

Expand All @@ -22,9 +22,9 @@ This library exports handler-creating functions:
- `createBeginHandler(config: object, options: CreateConfigOptions): function(state: string=): Promise<string>`
- `createCompleteHandler(config: object, options: CreateConfigOptions): function(code: string=, params: object=): Promise<string>`
- `createHandlers(config: object, options: CreateConfigOptions): ({ begin: (function(state: string=): Promise<string>), complete: (function(code: string=, params: object=): Promise<string>) })`
- `createNowBeginHandler(config: object, options: CreateConfigOptions): AsyncNowServerlessFunction`
- `createNowCompleteHandler(config: object, options: CreateConfigOptions): AsyncNowServerlessFunction`
- `createNowHandlers(config: object, options: CreateConfigOptions): ({ begin: AsyncNowServerlessFunction, complete: AsyncNowServerlessFunction })`
- `createVercelBeginHandler(config: object, options: CreateConfigOptions): AsyncVercelServerlessFunction`
- `createVercelCompleteHandler(config: object, options: CreateConfigOptions): AsyncVercelServerlessFunction`
- `createVercelHandlers(config: object, options: CreateConfigOptions): ({ begin: AsyncVercelServerlessFunction, complete: AsyncVercelServerlessFunction })`

They do the following:

Expand All @@ -38,12 +38,12 @@ They do the following:
the authorization code with the provider to netlify-cms.
- `createHandlers`: Creates both of the above handlers and returns an object containing them on the `begin` and
`complete` keys.
- Zeit Now Handlers
- `createNowBeginHandler`: Creates an async Zeit Now serverless function that handles everything for you and
- Vercel Handlers
- `createVercelBeginHandler`: Creates an async Vercel serverless function that handles everything for you and
delegates to the generic begin handler described above.
- `createCompleteHandler`: Creates an async Zeit Now serverless function that handles everything for you and
- `createVercelCompleteHandler`: Creates an async Vercel serverless function that handles everything for you and
delegates to the generic complete handler described above.
- `createNowHandlers`: Creates both of the above async Zeit Now serverless functions and returns an object containing
- `createVercelHandlers`: Creates both of the above async Vercel serverless functions and returns an object containing
them on the `begin` and `complete` keys.

That's a lot to digest but essentially:
Expand Down
53 changes: 53 additions & 0 deletions examples/common/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const fs = require('fs');
const path = require('path');
const frontmatter = require('front-matter');
const marked = require('marked');

async function render(name) {
// Resolve the path to the possible markdown file
const fullPathToPossibleMarkdownFile = path.resolve(
__dirname,
`./pages/${name}${name.endsWith('.md') ? '' : '.md'}`,
);
// Attempt to read the file, returning false ("no I did not handle this request") if any error occurs reading the file.
let markdownFileContents = null;
try {
markdownFileContents = await fs.promises.readFile(fullPathToPossibleMarkdownFile, { encoding: 'utf8' });
} catch (ignored) {
return false;
}
// Parse the file first using `front-matter` and `marked`
const fileFrontmatter = frontmatter(markdownFileContents);
const htmlFileContents = marked(fileFrontmatter.body);
// Generate the HTML, using the frontmatter to generate the title.
return `<html lang="en"><head><title>${fileFrontmatter.attributes.title || ''}</title>`
+ `</head><body>\n${htmlFileContents}</body></html>`;
}

/**
* @returns {Promise<[string, string][]>}
*/
async function renderAllPages() {
const fullPathToPages = path.resolve(
__dirname,
`./pages`,
);
const filesInPagesDir = await fs.promises.readdir(fullPathToPages, { encoding: 'utf8', withFileTypes: true });
return Promise.all(
filesInPagesDir
.reduce((entries, dirEnt) => {
if (dirEnt.isFile() && dirEnt.name.endsWith('.md')) {
entries.push(
render(dirEnt.name)
.then((html) => [
dirEnt.name.replace(/\.md$/i, '.html'),
html,
])
);
}
return entries;
}, []),
);
}

module.exports = { render, renderAllPages };
3 changes: 2 additions & 1 deletion examples/generic/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public/
# Note that we want this example to always use the latest version of the main package so we don't lock
yarn.lock

.now
.now
.vercel
2 changes: 1 addition & 1 deletion examples/generic/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Netlify CMS + netlify-cms-oauth-provider-node Now Test</title>
<title>Netlify CMS + netlify-cms-oauth-provider-node Test</title>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
Expand Down
24 changes: 3 additions & 21 deletions examples/generic/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const http = require('http');
const fs = require('fs');
const path = require('path');
const frontmatter = require('front-matter');
const marked = require('marked');
const { render } = require('../common/render'); // eslint-disable-line node/no-unpublished-require
const netlifyCmsOAuth = require('netlify-cms-oauth-provider-node');

const port = process.env.PORT || 3000;
Expand Down Expand Up @@ -134,25 +133,8 @@ const handleAdmin = createStaticFileHandler('admin.html', 'text/html; charset=ut
* otherwise.
*/
async function handlePage(req, res, { route }) {
// Resolve the path to the possible markdown file
const fullPathToPossibleMarkdownFile = path.resolve(
__dirname,
'../common/pages',
`${route.replace(/^\//, '')}.md`,
);
// Attempt to read the file, returning false ("no I did not handle this request") if any error occurs reading the file.
let markdownFileContents = null;
try {
markdownFileContents = await fs.promises.readFile(fullPathToPossibleMarkdownFile, { encoding: 'utf8' });
} catch (ignored) {
return false;
}
// Parse the file first using `front-matter` and `marked`
const fileFrontmatter = frontmatter(markdownFileContents);
const htmlFileContents = marked(fileFrontmatter.body);
// Generate the HTML, using the frontmatter to generate the title.
const finalHtml = `<html lang="en"><head><title>${fileFrontmatter.attributes.title || ''}</title>`
+ `</head><body>\n${htmlFileContents}</body></html>`;
const pageName = route.replace(/^\//, '');
const finalHtml = await render(pageName);
// Serve the HTML to the user.
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(finalHtml);
Expand Down
2 changes: 1 addition & 1 deletion examples/generic/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "netlify-cms-oauth-provider-node-now-example",
"name": "netlify-cms-oauth-provider-node-generic-example",
"private": true,
"main": "index.js",
"scripts": {
Expand Down
3 changes: 0 additions & 3 deletions examples/now/api/begin.js

This file was deleted.

3 changes: 0 additions & 3 deletions examples/now/api/complete.js

This file was deleted.

15 changes: 0 additions & 15 deletions examples/now/package.json

This file was deleted.

3 changes: 2 additions & 1 deletion examples/now/.gitignore → examples/vercel/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public/
# Note that we want this example to always use the latest version of the main package so we don't lock
yarn.lock

.now
.now
.vercel
7 changes: 4 additions & 3 deletions examples/now/README.md → examples/vercel/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Zeit Now Serverless Functions Examples
# Zeit Vercel Serverless Functions Examples

## Prerequisites

- [The `now` CLI](https://zeit.co/download): `npm i -g now@latest`
- [The `vercel` CLI](https://zeit.co/download): `npm i -g vercel@latest`

## Instructions

**Note:** Right now this example _does not_ use the local source files in the serverless functions inside
[`api/`](./api) since, at the time of this writing, `now dev` does not support symlinked packages or local dependencies.
[`api/`](./api) since, at the time of this writing, `vercel dev` does not support symlinked packages or
local dependencies.

1. Install the latest version of the main package as a dep to this example:
```shell script
Expand Down
2 changes: 1 addition & 1 deletion examples/now/index.html → examples/vercel/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Netlify CMS + netlify-cms-oauth-provider-node Now Test</title>
<title>Netlify CMS + netlify-cms-oauth-provider-node Vercel Test</title>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
Expand Down
3 changes: 3 additions & 0 deletions examples/vercel/api/begin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { createVercelBeginHandler } = require('netlify-cms-oauth-provider-node');

module.exports = createVercelBeginHandler({}, { useEnv: true });
3 changes: 3 additions & 0 deletions examples/vercel/api/complete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { createVercelCompleteHandler } = require('netlify-cms-oauth-provider-node');

module.exports = createVercelCompleteHandler({}, { useEnv: true });
11 changes: 11 additions & 0 deletions examples/vercel/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const fs = require('fs');
const path = require('path');
const { renderAllPages } = require('../common/render'); // eslint-disable-line node/no-unpublished-require

renderAllPages()
.then((pages) => Promise.all(pages.map(async ([fileName, html]) => {
const finalFileName = fileName === 'home.html' ? 'index.html' : fileName;
const publicPathForFile = path.resolve(__dirname, './public', finalFileName);
console.log(`Writing ${finalFileName} to ${publicPathForFile}`);
await fs.promises.writeFile(publicPathForFile, html);
})));
File renamed without changes.
17 changes: 17 additions & 0 deletions examples/vercel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "netlify-cms-oauth-provider-node-vercel-example",
"private": true,
"scripts": {
"start": "vercel dev",
"clean": "rm -rf public/",
"build": "yarn run clean && mkdir public && cp admin.html config.yml public/ && node ./build.js"
},
"engines": {
"node": "14.x"
},
"dependencies": {
"front-matter": "^4.0.2",
"marked": "^2.0.1",
"netlify-cms-oauth-provider-node": "latest"
}
}
3 changes: 3 additions & 0 deletions examples/vercel/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"cleanUrls": true
}
4 changes: 2 additions & 2 deletions lib/handlers/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const generic = require('./generic');
const now = require('./now');
const vercel = require('./vercel');

module.exports = {
generic,
now,
vercel,
};
22 changes: 11 additions & 11 deletions lib/handlers/now.js → lib/handlers/vercel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ const {
createCompleteHandler: createGenericCompleteHandler,
} = require('./generic');

const DEBUG_KEY = 'handlers:now';
const DEBUG_KEY = 'handlers:vercel';

/**
* @typedef {function(Request, Response): *} NowServerlessFunction
* @typedef {function(Request, Response): *} VercelServerlessFunction
*/

/**
* @typedef {function(Request, Response): Promise<*>} AsyncNowServerlessFunction
* @typedef {function(Request, Response): Promise<*>} AsyncVercelServerlessFunction
*/

/**
* A decorator function intended to wrap a Zeit Now Serverless Function to properly respond in error scenarios. Unless it is truly
* A decorator function intended to wrap a Vercel Serverless Function to properly respond in error scenarios. Unless it is truly
* impossible to send an error response (i.e. bug in error coercion logic OR response stream has already ended) than this will properly
* respond (with HTML) with the error (detailed info in dev mode).
*
* @param {AsyncNowServerlessFunction} handler
* @param {AsyncVercelServerlessFunction} handler
* @param {object=} extraCoerceErrorToMessageOptions
* @return {AsyncNowServerlessFunction}
* @return {AsyncVercelServerlessFunction}
*/
function handlesErrors(handler, extraCoerceErrorToMessageOptions = {}) {
const debug = createDebug(DEBUG_KEY, 'handlesErrors');
Expand Down Expand Up @@ -74,9 +74,9 @@ function handlesErrors(handler, extraCoerceErrorToMessageOptions = {}) {
}

/**
* Given config, create an async Now Serverless Function that redirects to an OAuth authorization URI to begin the provider OAuth flow.
* Given config, create an async Vercel Serverless Function that redirects to an OAuth authorization URI to begin the provider OAuth flow.
*
* @type {function(object=, CreateConfigOptions): AsyncNowServerlessFunction}
* @type {function(object=, CreateConfigOptions): AsyncVercelServerlessFunction}
*/
const createBeginHandler = receivesUserConfig((config) => {
return handlesErrors(
Expand All @@ -101,12 +101,12 @@ const createBeginHandler = receivesUserConfig((config) => {
});

/**
* Given config, create an async Now Serverless Function that attempts to extract an OAuth authorization code from the query string
* Given config, create an async Vercel Serverless Function that attempts to extract an OAuth authorization code from the query string
* under the `code` param, and runs that through the provider to exchange it for an access token. It will respond with HTML that
* is then rendered in the user's browser to communicate with the netlify-cms instance that opened the window in order to send it the
* access token we received from the provider (or the error if it occurred).
*
* @type {function(object=, CreateConfigOptions): AsyncNowServerlessFunction}
* @type {function(object=, CreateConfigOptions): AsyncVercelServerlessFunction}
*/
const createCompleteHandler = receivesUserConfig((config) => {
return handlesErrors(
Expand Down Expand Up @@ -138,7 +138,7 @@ const createCompleteHandler = receivesUserConfig((config) => {
* @see createBeginHandler
* @see createCompleteHandler
*
* @type {function(object=, CreateConfigOptions): { begin: AsyncNowServerlessFunction, complete: AsyncNowServerlessFunction }}
* @type {function(object=, CreateConfigOptions): { begin: AsyncVercelServerlessFunction, complete: AsyncVercelServerlessFunction }}
*/
const createHandlers = receivesUserConfig((config) => {
return {
Expand Down
20 changes: 13 additions & 7 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ const handlers = require('./handlers');

const {
generic: { createBeginHandler, createCompleteHandler, createHandlers },
now: {
createBeginHandler: createNowBeginHandler,
createCompleteHandler: createNowCompleteHandler,
createHandlers: createNowHandlers,

vercel: {
createBeginHandler: createVercelBeginHandler,
createCompleteHandler: createVercelCompleteHandler,
createHandlers: createVercelHandlers,
},
} = handlers;

Expand All @@ -16,7 +17,12 @@ module.exports = {
createCompleteHandler,
createHandlers,

createNowBeginHandler,
createNowCompleteHandler,
createNowHandlers,
createVercelBeginHandler,
createVercelCompleteHandler,
createVercelHandlers,

// Deprecated, kept for backwards compatibility
createNowBeginHandler: createVercelBeginHandler,
createNowCompleteHandler: createVercelCompleteHandler,
createNowHandlers: createVercelHandlers,
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^5.0.0",
"front-matter": "^4.0.2",
"husky": "^5.1.3",
"jest": "^26.6.3",
"lint-staged": "^10.5.4",
"marked": "^2.0.1",
"prettier": "^2.2.1",
"semantic-release": "^17.4.2"
},
"engines": {
"node": ">=10.0.0"
"node": ">=11.15.0"
},
"lint-staged": {
"{*,{lib,docs}/**/*,__{tests,mocks}__/**/*}.js": [
Expand Down
Loading

0 comments on commit 39ac9b0

Please sign in to comment.