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

Add preview command support #21

Open
wants to merge 70 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
fe44395
Add preview command support
jsines Jul 26, 2023
de74c6a
Saving work
jsines Sep 25, 2023
d7136a4
Move work in from cloudlfare worker, start implementation of proxy, f…
jsines Oct 2, 2023
f3fb919
Proxying works mostly
jsines Oct 3, 2023
4fdace4
Remove logs
jsines Oct 3, 2023
0aae19b
module and template route handlers
jsines Oct 5, 2023
dd8970e
Flesh out module and template previews, add a few error responses
jsines Oct 11, 2023
fbd4701
Remove filemapper preview changes for later
jsines Oct 12, 2023
b1fa76f
Clean up preview a little bit
jsines Oct 12, 2023
2626400
Fixes logic around watch stuff
jsines Oct 13, 2023
4c404b4
Make initial upload off by default
jsines Oct 16, 2023
dd2108d
Add express
jsines Oct 16, 2023
2eae394
Add express dep
jsines Oct 16, 2023
5ad2ed7
Merge branch 'js/hs-preview' into js/hs-preview-auto-refresh
jsines Oct 16, 2023
d06710b
Add auto refreshing
jsines Oct 17, 2023
4e20f17
Add auto refreshing
jsines Oct 17, 2023
a3bd4d9
Remove logs
jsines Oct 17, 2023
c7ec29b
Whitespace
jsines Oct 17, 2023
e05c847
Whitespace, remove logs
jsines Oct 17, 2023
2d6676c
use nodefetchcommonjs, add routes
jsines Oct 19, 2023
872e25b
proxyResourceRedirect.js
jsines Oct 19, 2023
caaf525
Error log
jsines Oct 19, 2023
81e65a2
Merge pull request #29 from HubSpot/js/hs-preview-auto-refresh
jsines Oct 23, 2023
4818e70
@preview folder support, module/template proxying/auto-refreshing
jsines Oct 24, 2023
8ce1d7e
Merge pull request #30 from HubSpot/js/hs-preview-resource-fetching
jsines Oct 27, 2023
d2b7a87
Merge pull request #31 from HubSpot/js/hs-preview-asset-proxy
jsines Oct 27, 2023
f0651dd
Add hslocal support, shadow dev server, https support
jsines Oct 27, 2023
2e0175c
Fix index linking, change hasJSBuildingBlocks to false, remove consol…
jsines Oct 27, 2023
02a651a
Remove net dep, add req
jsines Oct 30, 2023
b43f515
Committing before I leave...
jsines Nov 3, 2023
4a6b045
Cleanup some semicolons, preview tracking
jsines Nov 6, 2023
5cb6ae1
Add getauthtype
jsines Nov 6, 2023
57bd6c3
Add all changes for now...
jsines Nov 6, 2023
18b4cd5
Undo prettier
jsines Nov 6, 2023
3fddbe0
More remove
jsines Nov 6, 2023
bc206ad
Fix filemapperarg mess I made
jsines Nov 7, 2023
7af2be9
Remove unused args
jsines Nov 7, 2023
d0d181b
Prettier
jsines Nov 7, 2023
5f91643
Add check for gate
jsines Nov 7, 2023
cd01cda
External gate name casing is different
jsines Nov 7, 2023
ce57eff
Uncomment now that BE change merged
jsines Nov 8, 2023
8d95d02
Merge pull request #32 from HubSpot/js/hs-preview-hslocal
jsines Nov 15, 2023
5b3d5ce
Merge pull request #35 from HubSpot/js/hs-preview-improvements
jsines Nov 15, 2023
38280c4
Merge pull request #36 from HubSpot/js/hs-preview-prettier
jsines Nov 15, 2023
11210ad
remove random token gen while testing
jsines Nov 15, 2023
f5c3b13
Static uuid
jsines Nov 15, 2023
1515aab
Fix bad sessionToken staticing, fix .hubl.html
jsines Nov 16, 2023
c3c5865
Swap index routes to new endpoints
jsines Jan 4, 2024
6576623
Merge pull request #37 from HubSpot/js/hs-preview-gate
jsines Jan 4, 2024
ba84f0c
Merge pull request #41 from HubSpot/js/swap-index-routes
jsines Jan 4, 2024
94e6337
Move to cos-rend endpoint
jsines Jan 8, 2024
3a44f9c
Axe requestpage
jsines Jan 8, 2024
b32b15d
-
jsines Jan 8, 2024
33c1f30
Fix paths
jsines Jan 8, 2024
73166ab
Merge pull request #43 from HubSpot/js/swap-index-routes
jsines Jan 8, 2024
da5b43a
Swap render fetch
jsines Jan 23, 2024
404e06a
Proxy page
jsines Jan 23, 2024
f77eeba
Merge pull request #46 from HubSpot/js/renderchange
jsines Jan 23, 2024
e54ae21
Merge branch 'main' into js/hs-preview
jsines Feb 2, 2024
690484a
Changes from DPG review
jsines Feb 5, 2024
09f13a2
Changes for pre-empathy test
jsines Feb 7, 2024
cb5f80a
Fix resource redirect
jsines Feb 7, 2024
44abf0b
Update lib/preview.js
jsines Feb 8, 2024
7c07088
Fixes
jsines Feb 8, 2024
832ccae
Merge pull request #48 from HubSpot/js/hs-preview-preempathytest
jsines Feb 8, 2024
876be35
Move authtype stuff out of config
jsines Feb 8, 2024
0a64658
Merge main
jsines Feb 8, 2024
8662e8a
Missed a var on this callback
jsines Feb 8, 2024
c9e3704
Revert request package version bump
jsines Feb 8, 2024
dcd2068
Remove caching for the moment
jsines Feb 9, 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
14 changes: 14 additions & 0 deletions api/designManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,23 @@ async function fetchRawAssetByPath(accountId, path) {
});
}

async function fetchModulesByPath(accountId, path) {
return http.get(accountId, {
uri: `${DESIGN_MANAGER_API_PATH}/modules/by-path/${path}?portalId=${accountId}`
})
}

async function fetchTemplatesByPath(accountId, path) {
return http.get(accountId, {
uri: `${DESIGN_MANAGER_API_PATH}/templates/by-path/${path}?portalId=${accountId}`
})
}

module.exports = {
fetchBuiltinMapping,
fetchMenus,
fetchRawAssetByPath,
fetchThemes,
fetchModulesByPath,
fetchTemplatesByPath
};
20 changes: 20 additions & 0 deletions api/domains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const http = require('../http')

const DOMAINS_API_PATH = `/cms/v3/domains`;

async function fetchDomains(accountId) {
try {
const result = await http.get(accountId, {
uri: DOMAINS_API_PATH,
json: true
});

return result.results
} catch (err) {
throw err;
jsines marked this conversation as resolved.
Show resolved Hide resolved
}
}

module.exports = {
fetchDomains,
}
164 changes: 164 additions & 0 deletions api/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const { get } = require('../http')
const http = require('http');
const https = require('https');
const { getAccountId } = require('../lib/config');

const CONTENT_API_PATH = `/content/api/v4/contents`;

async function fetchPreviewInfo(accountId, contentId) {
try {
const content = await get(accountId, {
uri: `${CONTENT_API_PATH}/${contentId}`,
query: { portalId: accountId },
json: true
});

return {
previewDomain: content.previewDomain ?? content.resolvedDomain,
previewKey: content.previewKey,
};
} catch (err) {
throw err;
}
}

const requestContentPreview = async (url, portalId) => {
const urlObject = new URL(url);

const proxiedQueryParams = {};

// Convert searchParams to object param format hsGet/request expects
for (const queryKey of urlObject.searchParams.keys()) {
const values = urlObject.searchParams.getAll(queryKey);

if (values.length > 1) {
proxiedQueryParams[queryKey] = values;
} else {
proxiedQueryParams[queryKey] = values[0];
}
}

const accountId = getAccountId(portalId);

const response = await get(accountId, {
baseUrl: urlObject.origin,
uri: urlObject.pathname,
query: proxiedQueryParams,
json: false,
resolveWithFullResponse: true,
});

return response;
}

const requestPage = (url, redirects = 0, originalUrl=undefined) => {
if (redirects > 5) {
throw new Error(
`Hit too many redirects to HEAD requests for ${originalUrl}`
);
}

return new Promise((resolve, reject) => {
const protocolAPI = url.startsWith('https://') ? https : http;
protocolAPI
.request(
url,
{
method: 'HEAD',
headers: {
// Keep this user agent, so we don't get 403s from the request
['User-Agent']: 'cms-dev-server',
},
},
async res => {
// Use a lib to better follow various redirects?
if (
res.statusCode >= 300 &&
res.statusCode < 400 &&
res.headers.location
) {
console.log(`Redirecting to ${res.headers.location} (from ${url})`);
return resolve(
requestPage(
res.headers.location,
redirects + 1,
originalUrl ?? url
)
);
}

return resolve(res);
}
)
.on('error', err => {
console.error(err);
reject(err);
})
.end();
});
}

const fetchContentMetadata = async (
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much of this ripped straight from cms-js-platform

url,
portalId
) => {
let res;
if (url.includes('hs_preview')) {
res = await requestContentPreview(url, portalId);
} else {
res = await requestPage(url);
}

const portalIdHeader = res.headers['x-hs-hub-id'];
const contentId = res.headers['x-hs-content-id'];

if (Array.isArray(portalIdHeader) || Array.isArray(contentId)) {
throw new Error(
`There were multiple hub ID or content ID headers in the HEAD request to ${url}`
);
} else {
const portalIdFromResponse = parseInt(portalIdHeader, 10);
const pageAccount = await getAccountId(portalIdFromResponse);

if (!pageAccount) {
throw new Error(
`No CLI auth for portal ${portalIdFromResponse} found, please run \`hs auth\``
);
}

if (res.statusCode !== 200) {
throw new Error(
`${res.statusCode} ${
res.statusMessage
} - Unable to obtain HEAD information from ${url}. ${
res.statusCode === 429 && res.headers['retry-after']
? `Retry after ${res.headers['retry-after']} seconds.`
: ''
}`
);
} else if (!portalId || !contentId) {
throw new Error(
`Missing hub ID or content ID headers on HEAD request to ${url}`
);
} else if (isNaN(portalId)) {
throw new Error(
`Hub ID from the HEAD request is not a number: '${portalId}' (${url})`
);
}

// TODO, the hubs-hublets/hublets/find/<portalId> API is internal auth only.🤔...
// Prior implementation of fetchHubletForPortalId that would work execept for an internal auth issue:
// https://git.hubteam.com/HubSpot/cms-js-platform/blob/ef6e8029df6c09fe30d65a80073606f41ca324a6/cms-dev-server/src/proxyPage/fetchHubletForPortalId.ts
//
// const hublet = await fetchHubletForPortalId(portalId);

const hublet = 'na1';

return { portalId, contentId, hublet };
}
}

module.exports = {
fetchPreviewInfo,
fetchContentMetadata
}
Loading