Skip to content

Commit

Permalink
feat: also rewrite custom preview and live host links (#367)
Browse files Browse the repository at this point in the history
fixes #359
  • Loading branch information
tripodsan authored Jul 25, 2023
1 parent 711b572 commit 136376c
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 10 deletions.
22 changes: 14 additions & 8 deletions src/PipelineState.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import {PathInfo, S3Loader, FormsMessageDispatcher, PipelineTimer, AuthEnvLoader } from "./index";
import {PipelineContent} from "./PipelineContent";
import {Modifiers} from './utils/modifiers';
import {ProjectConfig} from "./project-config";

declare enum PipelineType {
html = 'html',
Expand All @@ -31,13 +32,6 @@ declare interface AccessConfig {
};
}

declare interface HelixConfigAll {
host:string;
routes:RegExp[];
access?:AccessConfig;
[string]:any;
}

declare interface PipelineOptions {
log: Console;
s3Loader: S3Loader;
Expand Down Expand Up @@ -101,7 +95,7 @@ declare class PipelineState {
/**
* the /.helix/config.json in object form
*/
config?: HelixConfigAll;
config?: ProjectConfig;

/**
* the metadata.json in modifier form.
Expand All @@ -127,5 +121,17 @@ declare class PipelineState {
* Authentication information
*/
authInfo?: AuthInfo;

/**
* the custom preview host if configured via config.cdn.preview.host
* this is initialized after the config is loaded.
*/
previewHost?: string;

/**
* the custom live host if configured via config.cdn.live.host
* this is initialized after the config is loaded.
*/
liveHost?: string;
}

157 changes: 157 additions & 0 deletions src/project-config.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright 2023 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

// NOTE: this file is autogenerated via 'npm run docs:types' in helix-admin-support

export interface ProjectConfig {
/**
* Name of the project used by the slack bot when reporting.
*/
name?: string;
/**
* Name of the project used by the sidekick.
*/
project?: string;
/**
* Timezone to be used by the slack bot when reporting times.
*/
timezone?: string;
/**
* Production host use by the slack bot to display project information.
*/
host?: string;
/**
* configuration blueprint repository in the owner/repo format.
*/
blueprint?: string;
/**
* the slack teamId/channelID(s) where the slack bot is used.
*/
slack?: string | string[];
cdn?: ProjectCDNConfig;
access?: SiteAccessConfig;
admin?: AdminConfig;
}
/**
* The CDN config
*/
export interface ProjectCDNConfig {
prod: FastlyConfig | AkamaiConfig | CloudflareConfig | ManagedConfig;
live?: {
/**
* Sidekick config to override the default preview host. it supports parameters $owner and $repo
*/
host: string;
};
preview?: {
/**
* Sidekick config to override the default live host. it supports parameters $owner and $repo
*/
host: string;
};
}
/**
* Production CDN configuration for Fastly
*/
export interface FastlyConfig {
type: 'fastly';
/**
* production host
*/
host: string;
/**
* Route or routes on the CDN that are rendered with Franklin
*/
route: string | string[];
/**
* The Fastly Service ID
*/
serviceId: string;
/**
* A Fastly token for purging
*/
authToken: string;
}
export interface AkamaiConfig {
type: 'akamai';
/**
* production host
*/
host: string;
/**
* Route or routes on the CDN that are rendered with Franklin
*/
route: string | string[];
endpoint: string;
clientSecret: string;
clientToken: string;
accessToken: string;
}
export interface CloudflareConfig {
type: 'cloudflare';
/**
* production host
*/
host: string;
/**
* Route or routes on the CDN that are rendered with Franklin
*/
route: string | string[];
origin: string;
plan: string;
zoneId: string;
apiToken: string;
}
export interface ManagedConfig {
type: 'managed';
/**
* production host
*/
host: string;
/**
* Route or routes on the CDN that are rendered with Franklin
*/
route: string | string[];
}
export interface SiteAccessConfig {
/**
* The email glob of the users that are allowed.
*/
allow: string | string[];
/**
* the id of the API key(s). this is used to validate the API KEYS and allows to invalidate them.
*/
apiKeyId?: string | string[];
require?: {
/**
* The list of owner/repo pointers to projects that are allowed to use this content.
*/
repository: string | string[];
};
}
export interface AdminConfig {
role?: Role;
/**
* the id of the API key(s). this is used to validate the API KEYS and allows to invalidate them.
*/
apiKeyId?: string | string[];
}
export interface Role {
/**
* The email glob of the users with author role.
*/
author?: string | string[];
/**
* The email glob of the users with publish role.
*/
publish?: string | string[];
}
12 changes: 12 additions & 0 deletions src/steps/fetch-config-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ export function computeRoutes(value) {
});
}

function replaceParams(str, info) {
if (!str) {
return '';
}
return str
.replaceAll('$owner', info.owner)
.replaceAll('$repo', info.repo);
}

/**
* Loads the /.helix/config-all.json from the content-bus and stores it in the state. if no
* such config exists, it will load the metadata.json as fallback and separate out the
Expand Down Expand Up @@ -117,6 +126,9 @@ export default async function fetchConfigAll(state, req, res) {
// also update last-modified (only for extensionless html pipeline)
updateLastModified(state, res, extractLastModified(ret.headers));
}
// set custom preview and live hosts
state.previewHost = replaceParams(state.config.cdn?.preview?.host, state);
state.liveHost = replaceParams(state.config.cdn?.live?.host, state);
} else if (ret.status !== 404) {
throw new PipelineStatusError(502, `failed to load /.helix/config-all.json: ${ret.status}`);
} else {
Expand Down
8 changes: 6 additions & 2 deletions src/steps/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ export function rewriteUrl(state, url) {
return url;
}
try {
const { pathname, search, hash } = new URL(url);
const {
host, pathname, search, hash,
} = new URL(url);

if (AZURE_BLOB_REGEXP.test(url)) {
const filename = pathname.split('/').pop();
Expand All @@ -200,7 +202,9 @@ export function rewriteUrl(state, url) {
return `.${pathname}${hash}`;
}

if (HELIX_URL_REGEXP.test(url)) {
if (HELIX_URL_REGEXP.test(url)
|| host === state.previewHost
|| host === state.liveHost) {
if (hash && pathname === state.info?.path) {
return hash;
}
Expand Down
16 changes: 16 additions & 0 deletions test/steps/fetch-config-all.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ describe('Fetch Config-All', () => {

it('computes host and routes correctly', async () => {
const state = {
owner: 'test-owner',
repo: 'test-repo',
log: console,
contentBusId: 'foo-id',
partition: 'live',
Expand All @@ -101,6 +103,12 @@ describe('Fetch Config-All', () => {
'**/express/**',
],
},
preview: {
host: 'main--$repo--$owner.my.page',
},
live: {
host: 'main--$repo--$owner.my.live',
},
},
},
},
Expand All @@ -125,8 +133,16 @@ describe('Fetch Config-All', () => {
'**/express/**',
],
},
preview: {
host: 'main--$repo--$owner.my.page',
},
live: {
host: 'main--$repo--$owner.my.live',
},
},
});
assert.strictEqual(state.previewHost, 'main--test-repo--test-owner.my.page');
assert.strictEqual(state.liveHost, 'main--test-repo--test-owner.my.live');
});

it('throws error on invalid json', async () => {
Expand Down
9 changes: 9 additions & 0 deletions test/steps/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ describe('Rewrite URLs test', () => {
assert.strictEqual(rewriteUrl({}, 'https://main--pages--adobe.hlx.page'), '/');
});

it('replaces an custom preview or live host url', () => {
const state = {
previewHost: 'main--repo--owner.page.custom',
liveHost: 'main--repo--owner.live.custom',
};
assert.strictEqual(rewriteUrl(state, 'https://main--repo--owner.page.custom/blog/article'), '/blog/article');
assert.strictEqual(rewriteUrl(state, 'https://main--repo--owner.live.custom/blog/article'), '/blog/article');
});

it('replaces an helix url with fragments', () => {
assert.strictEqual(rewriteUrl({}, 'https://main--pages--adobe.hlx.page/blog/article#heading'), '/blog/article#heading');
assert.strictEqual(rewriteUrl({}, 'https://main--pages--adobe.hlx.live/blog/article#heading'), '/blog/article#heading');
Expand Down

0 comments on commit 136376c

Please sign in to comment.