Skip to content

Commit

Permalink
Merge pull request #335 from adobe/issue-333
Browse files Browse the repository at this point in the history
feat: load sidekick from admin API
  • Loading branch information
rofe committed May 2, 2023
2 parents 9ca4cb0 + 367a089 commit aa66df5
Show file tree
Hide file tree
Showing 26 changed files with 548 additions and 422 deletions.
29 changes: 3 additions & 26 deletions src/bookmarklet/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,34 +114,11 @@
initSidekickCompatMode();
} else {
// extract and validate base config
const {
owner, repo, ref = 'main', devMode,
} = baseConfig;
const { owner, repo } = baseConfig;
baseConfig.scriptUrl = appScript.getAttribute('src');
if (owner && repo) {
// init sidekick config
window.hlx.sidekickConfig = {};
// look for custom config in project
let configOrigin = '';
if (devMode) {
configOrigin = 'http://localhost:3000';
} else if (!new RegExp(`${repo}\\-\\-${owner}\\.hlx(\\-\\d|3)?\\.page$`)
.test(window.location.hostname)) {
// load config from inner CDN
configOrigin = `https://${ref}--${repo}--${owner}.hlx.live`;
}
try {
const res = await fetch(`${configOrigin}/tools/sidekick/config.json`);
if (res.ok) {
console.log(`custom sidekick config loaded from ${configOrigin}/tools/sidekick/config.json`);
// apply custom config
Object.assign(window.hlx.sidekickConfig, await res.json());
}
} catch (e) {
console.log('error retrieving custom sidekick config', e);
}
// apply base config
Object.assign(window.hlx.sidekickConfig, baseConfig);
// load sidekick
window.hlx.sidekickConfig = baseConfig;
window.hlx.initSidekick();

showExtensionHint({
Expand Down
142 changes: 88 additions & 54 deletions src/extension/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,19 +404,88 @@
return new RegExp(`^${reString}$`);
}

/**
* Creates an Admin URL for an API and path.
* @private
* @param {Object} config The sidekick configuration
* @param {string} api The API endpoint to call
* @param {string} path The current path
* @returns {URL} The admin URL
*/
function getAdminUrl({
owner, repo, ref, adminVersion,
}, api, path = '') {
const adminUrl = new URL([
'https://admin.hlx.page/',
api,
`/${owner}`,
`/${repo}`,
`/${ref}`,
path,
].join(''));
if (adminVersion) {
adminUrl.searchParams.append('hlx-admin-version', adminVersion);
}
return adminUrl;
}

/**
* Returns the fetch options for admin requests
* @returns {object}
*/
function getAdminFetchOptions() {
const opts = {
cache: 'no-store',
credentials: 'include',
headers: {},
};
return opts;
}

/**
* Returns the sidekick configuration.
* @private
* @param {SidekickConfig} cfg The sidekick config (defaults to {@link window.hlx.sidekickConfig})
* @param {Location} location The current location
* @returns {Object} The sidekick configuration
*/
function initConfig(cfg, location) {
const config = cfg || (window.hlx && window.hlx.sidekickConfig) || {};
async function initConfig(cfg, location) {
let config = cfg || (window.hlx && window.hlx.sidekickConfig) || {};
const {
owner,
repo,
ref = 'main',
devMode,
adminVersion,
_extended,
} = config;
if (owner && repo && !_extended) {
// look for custom config in project
const configUrl = devMode
? `${DEV_URL.origin}/tools/sidekick/config.json`
: getAdminUrl(config, 'sidekick', '/config.json');
try {
const res = await fetch(configUrl, getAdminFetchOptions());
if (res.status === 200) {
config = {
...config,
...(await res.json()),
// no overriding below
owner,
repo,
ref,
devMode,
adminVersion,
_extended: Date.now(),
};
console.log('extended config found');
}
} catch (e) {
console.log('error retrieving custom sidekick config', e);
}
}

const {
outerHost,
host,
project,
Expand Down Expand Up @@ -479,7 +548,6 @@
scriptRoot,
host: publicHost,
project: project || '',
pushDown,
pushDownElements,
specialView,
};
Expand Down Expand Up @@ -858,45 +926,6 @@
return evt.metaKey || evt.shiftKey || evt.which === 2;
}

/**
* Creates an Admin URL for an API and path.
* @private
* @param {Object} config The sidekick configuration
* @param {string} api The API endpoint to call
* @param {string} path The current path
* @returns {URL} The admin URL
*/
function getAdminUrl({
owner, repo, ref, adminVersion,
}, api, path = '') {
const adminUrl = new URL([
'https://admin.hlx.page/',
api,
`/${owner}`,
`/${repo}`,
`/${ref}`,
path,
].join(''));
if (adminVersion) {
adminUrl.searchParams.append('hlx-admin-version', adminVersion);
}
return adminUrl;
}

/**
* Returns the fetch options for admin requests
* @param {object} config
* @returns {object}
*/
function getAdminFetchOptions() {
const opts = {
cache: 'no-store',
credentials: 'include',
headers: {},
};
return opts;
}

/**
* Adds the edit plugin to the sidekick.
* @private
Expand Down Expand Up @@ -1381,9 +1410,11 @@
// update copy url button texts based on selection size
['', 'preview', 'live', 'prod'].forEach((env) => {
const text = i18n(sk, `copy_${env}${env ? '_' : ''}url${sel.length === 1 ? '' : 's'}`);
const button = sk.get(`bulk-copy-${env}${env ? '-' : ''}urls`).querySelector('button');
button.textContent = text;
button.title = text;
const button = sk.get(`bulk-copy-${env}${env ? '-' : ''}urls`)?.querySelector('button');
if (button) {
button.textContent = text;
button.title = text;
}
});
};

Expand Down Expand Up @@ -1421,7 +1452,6 @@
}, concurrency);
const lines = [];
const ok = results.filter((res) => res.ok);
console.log(ok);
if (ok.length > 0) {
lines.push(getBulkText([ok.length], 'result', operation, 'success'));
lines.push(createTag({
Expand Down Expand Up @@ -1793,10 +1823,7 @@
const opts = getAdminFetchOptions(sk.config);
return fetch(url, opts)
.then((res) => res.json())
.then((json) => {
console.log(json);
return json.status === status;
})
.then((json) => (json.status === status))
.catch(() => false);
}

Expand Down Expand Up @@ -1828,12 +1855,15 @@

async function checkLoggedIn() {
if (loginWindow.closed) {
const { config, status, location } = sk;
attempts += 1;
// try 5 times after login window has been closed
if (await checkProfileStatus(sk, 200)) {
// logged in, stop checking
delete sk.status.status;
delete status.status;
sk.addEventListener('statusfetched', () => sk.hideModal(), { once: true });
sk.config = await initConfig(config, location);
sk.config.authToken = window.hlx.sidekickConfig.authToken;
sk.fetchStatus();
fireEvent(sk, 'loggedin');
return;
Expand Down Expand Up @@ -2467,6 +2497,7 @@
},
});
this.addEventListener('contextloaded', () => {
this.loadCSS();
// containers
this.pluginContainer = appendTag(this.root, {
tag: 'div',
Expand Down Expand Up @@ -2566,6 +2597,10 @@
addBulkPlugins(this);
// fetch status
this.fetchStatus();
// push down content
pushDownContent(this);
// show special view
showSpecialView(this);
}, { once: true });
this.addEventListener('statusfetched', () => {
checkUserState(this);
Expand All @@ -2574,7 +2609,6 @@
enableInfoBtn(this);
});
this.addEventListener('shown', async () => {
await showSpecialView(this);
pushDownContent(this);
});
this.addEventListener('hidden', () => {
Expand All @@ -2583,9 +2617,9 @@
});
this.status = {};
this.plugins = [];
this.config = {};

this.loadContext(cfg);
this.loadCSS();
checkForIssues(this);

// collapse dropdowns when document is clicked
Expand Down Expand Up @@ -2684,7 +2718,7 @@
*/
async loadContext(cfg) {
this.location = getLocation();
this.config = initConfig(cfg, this.location);
this.config = await initConfig(cfg, this.location);

// load dictionary based on user language
const lang = this.config.lang || navigator.language.split('-')[0];
Expand Down
36 changes: 5 additions & 31 deletions src/extension/sidekick.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import {} from './lib/polyfills.min.js';

import {
DEV_URL,
log,
url,
getConfig,
Expand All @@ -35,7 +34,7 @@ export default async function injectSidekick(config, display) {
// create sidekick
log.debug('sidekick.js: no sidekick yet, create it');
// reduce config to only include properties relevant for sidekick
let curatedConfig = Object.fromEntries(Object.entries(config)
const curatedConfig = Object.fromEntries(Object.entries(config)
.filter(([k]) => [
'owner',
'repo',
Expand All @@ -53,44 +52,19 @@ export default async function injectSidekick(config, display) {
// inject sidekick
await import(curatedConfig.scriptUrl);

// look for custom config in project
const {
owner, repo, ref, devMode, adminVersion,
} = config;
const configOrigin = devMode
? DEV_URL
: `https://${ref}--${repo}--${owner}.hlx.live`;
try {
const res = await fetch(`${configOrigin}/tools/sidekick/config.json`);
if (res.ok) {
log.info('custom sidekick config found');
curatedConfig = {
...curatedConfig,
...(await res.json()),
// no overriding below
owner,
repo,
ref,
devMode,
adminVersion,
};
}
log.debug('sidekick.js: extended config', curatedConfig);
} catch (e) {
// init sidekick without extended config
log.info('error retrieving custom sidekick config', e);
}

// init sidekick
window.hlx.initSidekick(curatedConfig);

const {
owner, repo,
} = curatedConfig;

// todo: improve config change handling. currently we only update the authToken
chrome.storage.sync.onChanged.addListener((changes) => {
const newAuthToken = changes[`${owner}/${repo}`]?.newValue?.authToken;
if (newAuthToken) {
log.debug(`adding authToken to config ${owner}/${repo} and refreshig sidekick`);
window.hlx.sidekickConfig.authToken = newAuthToken;
window.hlx.sidekick.loadContext(window.hlx.sidekickConfig);
}
});

Expand Down
Loading

0 comments on commit aa66df5

Please sign in to comment.