Last active
April 20, 2021 12:33
-
-
Save andrewharvey/ff5e2c15b8a60249a593dc189192eb02 to your computer and use it in GitHub Desktop.
Lists fonts used within a Mapbox account, which fonts each Style is using, and which Styles are using each font. Useful for knowing which fonts you can clear out of your account to keep under the 100 fonts limit.
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
#!/usr/bin/env node | |
/* eslint-disable */ | |
const MapboxClient = require('.'); | |
const MapboxStyles = require('./services/styles'); | |
const MapboxFonts = require('./services/fonts'); | |
const fs = require('fs'); | |
const fontsService = MapboxFonts({ accessToken: process.env.MAPBOX_ACCESS_TOKEN }); | |
const stylesService = MapboxStyles({ accessToken: process.env.MAPBOX_ACCESS_TOKEN }); | |
fontsService.listFonts({ownerId: 'mapbox'}) | |
.send() | |
.then(response => { | |
const mapboxFonts = response.body | |
fontsService.listFonts({fresh: true}) | |
.send() | |
.then(response => { | |
const fonts = response.body | |
fs.writeFileSync('fonts.json', JSON.stringify(fonts, null, 2)) | |
console.log('fonts.json') | |
listStyles(stylesService, (err, stylesList) => { | |
fs.writeFileSync('stylesList.json', JSON.stringify(stylesList, null, 2)) | |
console.log('stylesList.json') | |
const fetchStyles = stylesList.map(style => { | |
return new Promise((resolve, reject) => { | |
stylesService.getStyle({ | |
styleId: style.id, | |
fresh: true | |
}) | |
.send() | |
.then(response => { | |
resolve(response.body) | |
}, error => { | |
console.error(error) | |
reject(error) | |
}) | |
}) | |
}) | |
Promise.all(fetchStyles) | |
.then(styles => { | |
const fontsPerStyle = styles.map(style => { | |
const fontsUsed = style.layers.map(layer => { | |
if (layer.layout && layer.layout['text-font']) { | |
const textFont = layer.layout['text-font'] | |
if (Array.isArray(textFont)) { | |
if (textFont[0] === 'step') { | |
return textFont.map(v => { | |
if (v && Array.isArray(v) && v[0] === 'literal') { | |
return v[1] | |
} else { | |
return [] | |
} | |
}).flat() | |
} else { | |
return textFont | |
} | |
return textFont | |
} else if (typeof textFont === 'object') { | |
if (textFont.stops) { | |
return textFont.stops.map(stop => { | |
return stop[1] | |
}).flat() | |
} else { | |
console.error('Unknown text-font value', textFont) | |
} | |
} else { | |
return [textFont] | |
} | |
} else { | |
return [] | |
} | |
}).flat() | |
const uniqueFontsUsed = [...new Set(fontsUsed)].sort() | |
return { | |
styleId: style.id, | |
styleName: style.name, | |
fonts: uniqueFontsUsed | |
} | |
}) | |
fs.writeFileSync('fontsPerStyle.json', JSON.stringify(fontsPerStyle, null, 2)) | |
console.log('fontsPerStyle.json') | |
// find which styles this font is used in | |
const stylesPerFont = {} | |
fonts.map(font => { | |
stylesPerFont[font] = [] | |
}) | |
// fonts found in styles but not found in the account | |
const styleFontsMissingInAccount = {} | |
fontsPerStyle.map(styleFonts => { | |
styleFonts.fonts.map(font => { | |
const style ={ | |
styleId: styleFonts.styleId, | |
styleName: styleFonts.styleName | |
} | |
if (font in stylesPerFont) { | |
stylesPerFont[font].push(style) | |
} else { | |
// the font ways not found in our account fonts, but also check to see if it is a Mapbox font | |
if (!mapboxFonts.includes(font)) { | |
if (!(font in styleFontsMissingInAccount)) { | |
styleFontsMissingInAccount[font] = [] | |
} | |
styleFontsMissingInAccount[font].push(style) | |
} | |
} | |
}) | |
}) | |
fs.writeFileSync('stylesPerFont.json', JSON.stringify(stylesPerFont, null, 2)) | |
console.log('fontsPerStyle.json') | |
fs.writeFileSync('styleFontsMissingInAccount.json', JSON.stringify(styleFontsMissingInAccount, null, 2)) | |
console.log('styleFontsMissingInAccount.json') | |
}) | |
}, error => { | |
console.error(error.message); | |
}); | |
}, error => { | |
console.error(error.message) | |
}) | |
}, error => { | |
console.error(error.message) | |
}) | |
/** | |
* Retrieve the styles and return them as an Array | |
*/ | |
function listStyles(stylesService, cb) { | |
process.stdout.write('Styles List'); | |
const styles = []; | |
stylesService.listStyles({ | |
fresh: true | |
}).eachPage((err, res, next) => { | |
process.stdout.write('.'); | |
if (err) { | |
console.error(err); | |
cb(err, null); | |
return; | |
} | |
const pageStyles = res.body; | |
styles.push(...pageStyles); | |
if (!res.hasNextPage()) { | |
// no more pages | |
console.log(`Fetched ${styles.length} styles`); | |
cb(null, styles); | |
} else { | |
// call the next page | |
next(); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment