Skip to content

Instantly share code, notes, and snippets.

@andrewharvey
Last active April 20, 2021 12:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewharvey/ff5e2c15b8a60249a593dc189192eb02 to your computer and use it in GitHub Desktop.
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.
#!/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