Skip to content

Instantly share code, notes, and snippets.

@jeffquach
Last active January 3, 2023 00:30
Show Gist options
  • Save jeffquach/7badd4c05a3780d119d448345fb6c69f to your computer and use it in GitHub Desktop.
Save jeffquach/7badd4c05a3780d119d448345fb6c69f to your computer and use it in GitHub Desktop.
Sample code: https://shopify.dev/apps/online-store/verify-support contains bugs. The code should be checking `templateJSONFiles.length > 0` but doesn't. The gist also doesn't not use Shopify's node library and HTTP requests are made to Shopify's REST API using node-fetch, but any HTTP library can be used instead
const fetch = require('node-fetch');
try {
// Specify the name of the template the app will integrate with
const APP_BLOCK_TEMPLATES = ['product', 'collection'];
const getOptions = { method: 'GET', headers: { 'X-Shopify-Access-Token': accessToken } };
// Get published theme
const themeResponse = await fetch(`https://${shop}/admin/api/${API_VERSION}/themes.json`, getOptions);
this.checkError(themeResponse, 'ThemeFetchFailure');
const { themes } = await themeResponse.json();
const themeId = themes.filter(t => t.role === 'main').map(t => t.id);
// Retrieve a list of assets in the published theme
let themeAssetsResponse = await fetch(`https://${shop}/admin/api/${API_VERSION}/themes/${themeId}/assets.json`, getOptions);
const { assets } = await themeAssetsResponse.json();
// Check if JSON template files exist for the template specified in APP_BLOCK_TEMPLATES
const templateJSONFiles = assets.filter((file) => { return APP_BLOCK_TEMPLATES.some(template => file.key === `templates/${template}.json`); });
if (templateJSONFiles.length > 0) {
if (templateJSONFiles.length === APP_BLOCK_TEMPLATES.length) {
console.log('All desired templates support sections everywhere!')
} else if (templateJSONFiles.length) {
console.log('Only some of the desired templates support sections everywhere.')
}
}
// Retrieve the body of JSON templates and find what section is set as `main`
const templateMainSections = (await Promise.all(templateJSONFiles.map(async (file, index) => {
let themeAssetsResponse = await fetch(`https://${shop}/admin/api/${API_VERSION}/themes/${themeId}/assets.json?asset[key]=${file.key}`, getOptions);
const { asset } = await themeAssetsResponse.json();
const json = JSON.parse(asset.value)
const main = Object.entries(json.sections).find(([id, section]) => id === 'main' || section.type.startsWith("main-"))
if (main) {
return assets.find((file) => file.key === `sections/${main[1].type}.liquid`);
}
}))).filter((value) => value)
// Request the content of each section and check if it has a schema that contains a block of type '@app'
const sectionsWithAppBlock = (await Promise.all(templateMainSections.map(async (file, index) => {
let acceptsAppBlock = false;
let themeAssetsResponse = await fetch(`https://${shop}/admin/api/${API_VERSION}/themes/${themeId}/assets.json?asset[key]=${file.key}`, getOptions);
const { asset } = await themeAssetsResponse.json();
const match = asset.value.match(/\{\%\s+schema\s+\%\}([\s\S]*?)\{\%\s+endschema\s+\%\}/m)
const schema = JSON.parse(match[1]);
if (schema && schema.blocks) {
acceptsAppBlock = schema.blocks.some((b => b.type === '@app'));
}
return acceptsAppBlock ? file : null
}))).filter((value) => value);
if (templateJSONFiles.length > 0) {
if (templateJSONFiles.length === sectionsWithAppBlock.length) {
console.log('All desired templates have main sections that support app blocks!');
} else if (sectionsWithAppBlock.length) {
console.log('Only some of the desired templates support app blocks.');
}
} else {
console.log("None of the desired templates support app blocks");
}
} catch (error) {
console.log(error);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment