-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(task:http-headers): add support for other providers (Vercel, Fir…
…ebase)
- Loading branch information
Showing
7 changed files
with
343 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { SUPPORTS } from './index' | ||
import type { PathPlaceholder } from '../builder' | ||
import type { IPathHeadersMap, IOptions } from '../../options' | ||
import { Filesystem } from '@postbuild/filesystem' | ||
|
||
export type IPathPlaceholders = { | ||
[p in Exclude<PathPlaceholder, PathPlaceholder.Pages | PathPlaceholder.Assets>]: string | ||
} | ||
|
||
export interface IProviderArtifact { | ||
filename: string | ||
data: string | ||
} | ||
|
||
export abstract class Provider { | ||
protected abstract filename: string | ||
protected abstract placeholders: IPathPlaceholders | ||
protected readonly options: IOptions | ||
protected readonly fs: Filesystem | ||
constructor (options: IOptions, fs: Filesystem) { | ||
this.options = options | ||
this.fs = fs | ||
} | ||
|
||
static factory = (options: IOptions, fs: Filesystem): Provider => { | ||
if (!(options.provider in SUPPORTS)) { | ||
throw new TypeError(`Invalid headers file provider "${options.provider}"`) | ||
} | ||
|
||
// @ts-expect-error | ||
return new SUPPORTS[options.provider](options, fs) | ||
} | ||
|
||
public getFilename (): string { | ||
return this.filename | ||
} | ||
|
||
public processPath (path: string): string { | ||
return path in this.placeholders | ||
? this.placeholders[path as keyof IPathPlaceholders] | ||
: path | ||
} | ||
|
||
public abstract build (headers: IPathHeadersMap): Promise<string> | ||
} | ||
|
||
export default Provider |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import Provider from './base' | ||
import { PathPlaceholder } from '../builder' | ||
import type { IPathHeadersMap } from '../../options' | ||
|
||
export default class FirebaseProvider extends Provider { | ||
filename = 'firebase.json' | ||
placeholders = { | ||
[PathPlaceholder.All]: '**/*', | ||
[PathPlaceholder.PageData]: 'page-data/**', | ||
[PathPlaceholder.Static]: 'static/**' | ||
} | ||
|
||
processPath (path: string): string { | ||
path = super.processPath(path) | ||
if (path.startsWith('/')) { | ||
path = path.replace('/', '') | ||
} | ||
return path | ||
} | ||
|
||
async build (headers: IPathHeadersMap): Promise<string> { | ||
let config: any = { | ||
hosting: { | ||
public: 'public', | ||
ignore: [ | ||
'firebase.json', | ||
'**/.*', | ||
'**/node_modules/**' | ||
] | ||
} | ||
} | ||
try { | ||
config = JSON.parse(await this.fs.read('../firebase.json')) | ||
} catch (e) {} | ||
|
||
config.hosting.headers = [] | ||
for (const path in headers) { | ||
const pathHeaders = [] | ||
for (const header in headers[path]) { | ||
const value = headers[path][header] | ||
pathHeaders.push({ | ||
key: header, | ||
value: Array.isArray(value) | ||
? value.join(', ') | ||
: value | ||
}) | ||
} | ||
config.hosting.headers.push({ | ||
source: path, | ||
headers: pathHeaders | ||
}) | ||
} | ||
|
||
return JSON.stringify(config, null, 2) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import Provider from './base' | ||
import FirebaseProvider from './firebase' | ||
import NetlifyProvider from './netlify' | ||
import VercelProvider from './vercel' | ||
|
||
export enum ProviderSymbol { | ||
Netlify = 'netlify', | ||
Vercel = 'vercel', | ||
Firebase = 'firebase' | ||
} | ||
|
||
export const SUPPORTS: { [ext: string]: typeof Provider } = { | ||
[ProviderSymbol.Netlify]: NetlifyProvider, | ||
[ProviderSymbol.Vercel]: VercelProvider, | ||
[ProviderSymbol.Firebase]: FirebaseProvider | ||
} | ||
|
||
export { Provider } | ||
export type { IProviderArtifact } from './base' | ||
export default Provider |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Provider from './base' | ||
import { PathPlaceholder } from '../builder' | ||
import type { IPathHeadersMap } from '../../options' | ||
|
||
export default class NetlifyProvider extends Provider { | ||
filename = '_headers' | ||
placeholders = { | ||
[PathPlaceholder.All]: '/*', | ||
[PathPlaceholder.PageData]: '/page-data/*', | ||
[PathPlaceholder.Static]: '/static/*' | ||
} | ||
|
||
async build (headers: IPathHeadersMap): Promise<string> { | ||
const lines = [] | ||
for (const path in headers) { | ||
lines.push(path) | ||
for (const header in headers[path]) { | ||
const value = headers[path][header] | ||
if (Array.isArray(value)) { | ||
value.forEach(v => lines.push(` ${header}: ${v}`)) | ||
continue | ||
} | ||
lines.push(` ${header}: ${value}`) | ||
} | ||
} | ||
return lines.join('\n') | ||
} | ||
} |
Oops, something went wrong.