Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
28 changes: 6 additions & 22 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
name: Run tests
on: [push]
env:
NODE_VERSION: 20.x
on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest

permissions:
id-token: write
contents: read

steps:
- name: checkout commit
uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
submodules: true

- name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
node-version: 24
cache: npm

- name: install node deps
run: npm ci

- name: run tests
run: npm test
- run: npm ci
- run: npm test
Binary file modified fixtures/003/tile.mvt
Binary file not shown.
Binary file modified fixtures/004/tile.mvt
Binary file not shown.
Binary file modified fixtures/006/tile.mvt
Binary file not shown.
Binary file modified fixtures/007/tile.mvt
Binary file not shown.
Binary file modified fixtures/008/tile.mvt
Binary file not shown.
Binary file modified fixtures/009/tile.mvt
Binary file not shown.
Binary file modified fixtures/010/tile.mvt
Binary file not shown.
Binary file modified fixtures/012/tile.mvt
Binary file not shown.
Binary file modified fixtures/014/tile.mvt
Binary file not shown.
Binary file modified fixtures/016/tile.mvt
Binary file not shown.
Binary file modified fixtures/023/tile.mvt
Binary file not shown.
Binary file modified fixtures/024/tile.mvt
Binary file not shown.
Binary file modified fixtures/026/tile.mvt
Binary file not shown.
Binary file modified fixtures/027/tile.mvt
Binary file not shown.
Binary file modified fixtures/030/tile.mvt
Binary file not shown.
Binary file modified fixtures/039/tile.mvt
Binary file not shown.
Binary file modified fixtures/045/tile.mvt
Binary file not shown.
Binary file modified fixtures/046/tile.mvt
Binary file not shown.
Binary file modified fixtures/047/tile.mvt
Binary file not shown.
Binary file modified fixtures/048/tile.mvt
Binary file not shown.
Binary file modified fixtures/049/tile.mvt
Binary file not shown.
Binary file modified fixtures/050/tile.mvt
Binary file not shown.
Binary file modified fixtures/051/tile.mvt
Binary file not shown.
Binary file modified fixtures/052/tile.mvt
Binary file not shown.
Binary file modified fixtures/061/tile.mvt
Binary file not shown.
101 changes: 41 additions & 60 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,91 +1,75 @@
'use strict';
import fs from 'fs';
import path from 'path';
import {pathToFileURL} from 'url';
import {getID} from './lib/util.js';
import generateBuffer from './lib/generateBuffer.js';

const fs = require('fs');
const path = require('path');
const d3 = require('d3-queue');
const util = require('./lib/util');
const generateBuffer = require('./lib/generateBuffer');
const srcDir = path.join(import.meta.dirname, 'src');

/**
* Get a fixture by name
* @param {String|Number} id - the id of the fixture as specified in [FIXTURES.md](FIXTURES.md)
* @returns {Object} fixture - a fixture object
* @returns {Promise<Object>} fixture - a fixture object
* @example
* const mvtf = require('mvt-fixtures');
* import mvtf from '@mapbox/mvt-fixtures';
*
* const fixture = mvtf.get('001');
* const fixture = await mvtf.get('001');
* console.log(fixture.id); // => '001'
* console.log(fixture.description); // => ...
* console.log(fixture.specification_reference); // => url to Mapbox Vector Tile specification reference
* console.log(fixture.buffer); // => Buffer object
* console.log(fixture.json); // => json representation of the fixture
*/
function get(id) {
export async function get(id) {
if (!id) throw new Error('No fixture id provided');

// add prefix zeros if they don't exist
id = (typeof id === 'number') ? util.getID(id) : id;
id = (typeof id === 'number') ? getID(id) : id;

let final = {};
const fixturePath = path.join(srcDir, `${id}.js`);
let fixture;

const fixturePath = path.join(__dirname, 'src', `${id}.js`);
try {
fixture = require(fixturePath);
} catch(err) {
fixture = (await import(pathToFileURL(fixturePath).href)).default;
} catch (err) {
throw new Error(`Error loading fixture ${fixturePath}: ${err}`);
}

final.id = id;
final.description = fixture.description;
final.specification_reference = fixture.specification_reference;
final.json = fixture.json;
final.proto = fixture.proto;
final.validity = fixture.validity;

// generate buffer
let options = {};
const options = {};
if (fixture.syntax) options.syntax = fixture.syntax;
final.buffer = generateBuffer(fixture.json, fixture.proto, options);
let buffer = generateBuffer(fixture.json, fixture.proto, options);
if (fixture.manipulate) buffer = fixture.manipulate(buffer);

if (fixture.manipulate) {
final.buffer = fixture.manipulate(final.buffer);
}

return final;
};
return {
id,
description: fixture.description,
specification_reference: fixture.specification_reference,
json: fixture.json,
proto: fixture.proto,
validity: fixture.validity,
buffer
};
}

/**
* Loops through all fixtures and provides the fixture object from get()
* @param {Function} function - a synchronously running function to execute on each fixture
* @param {Function} fn - a function (sync or async) to execute on each fixture
* @example
* const mvtf = require('mvt-fixtures');
* const assert = require('assert');
* import mvtf from '@mapbox/mvt-fixtures';
* import assert from 'assert';
*
* mvtf.each(function(fixture) {
* await mvtf.each(fixture => {
* assert.ok(Buffer.isBuffer(fixture.buffer), 'is a buffer');
* });
*/
function each(fn) {
export async function each(fn) {
if (!fn) throw new Error('must provide a function argument in .each()');
if (typeof fn !== 'function') throw new Error('argument is not a function');

const sourcePath = path.join(__dirname, 'src');
const files = fs.readdirSync(sourcePath);
const queue = d3.queue(1);
files.forEach(function(file) {
queue.defer(function(next) {
let name = path.parse(file).name;
let fixture = get(name);
fn(fixture);
next();
});
});

queue.awaitAll(function(err) {
if (err) throw err;
// do nothing?
});
const files = fs.readdirSync(srcDir);
for (const file of files) {
const name = path.parse(file).name;
const fixture = await get(name);
await fn(fixture);
}
}

/**
Expand All @@ -95,14 +79,11 @@ function each(fn) {
* @param {Object} [options]
* @param {string} [options.proto="2.1"] - optional vector tile spec version
*/
function create(definition, options) {
export function create(definition, options = {}) {
if (!definition) throw new Error('No definition provided to mvt-fixtures#create method.');
options = options || {};
return {
buffer: generateBuffer(definition, options.proto || '2.1', options)
}
};
}

module.exports = {
get, each, create
};
export default {get, each, create};
45 changes: 20 additions & 25 deletions lib/generateBuffer.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
'use strict';
import fs from 'fs';
import path from 'path';
import schema from 'protocol-buffers-schema';
import {PbfWriter} from 'pbf';
import {compile} from 'pbf/compile';
import {replace} from './util.js';

const fs = require('fs');
const path = require('path');
const schema = require('protocol-buffers-schema');
const Pbf = require('pbf');
const Compile = require('pbf/compile');
const replace = require('./util').replace;

const MVT_SPEC_VERSIONS = fs.readdirSync(path.join(__dirname, '..', 'vector-tile-spec')).filter(s => {
return fs.lstatSync(path.join(__dirname, '..', 'vector-tile-spec', s)).isDirectory();
const MVT_SPEC_VERSIONS = fs.readdirSync(path.join(import.meta.dirname, '..', 'vector-tile-spec')).filter(s => {
return fs.lstatSync(path.join(import.meta.dirname, '..', 'vector-tile-spec', s)).isDirectory();
});

/**
Expand All @@ -18,24 +16,21 @@ const MVT_SPEC_VERSIONS = fs.readdirSync(path.join(__dirname, '..', 'vector-tile
* OR a complete string representing a .proto file. If no string is provided, defaults to version 2.1
* @param {Object} [options] - an optional object
* @param {String} [options.syntax='2'] - the protocol buffer syntax version to parse with
* @returns {Object} buffer - a protocol encoded buffere representing a valid or invalid Mapbox Vector Tile
* @returns {Object} buffer - a protocol encoded buffer representing a valid or invalid Mapbox Vector Tile
*/
module.exports = function(json, proto, opts) {
export default function generateBuffer(json, proto, opts = {}) {
if (!opts.syntax) opts.syntax = '2';
const replaceWith = `syntax = "proto${opts.syntax}";\n\npackage vector_tile;`;

let proto_schema, protoString;
if (!proto) throw new Error('Please provide the proto file or version to generate this buffer from');
if (MVT_SPEC_VERSIONS.indexOf(proto) > -1) {
protoString = replace(proto, 'package vector_tile;', replaceWith);
proto_schema = schema.parse(protoString);
} else {
protoString = proto.replace('package vector_tile;', replaceWith);
proto_schema = schema.parse(protoString);
}

const mvt = Compile(proto_schema);
const pbf = new Pbf();
mvt.Tile.write(json, pbf);
return new Buffer.from(pbf.finish());
};
const protoString = MVT_SPEC_VERSIONS.indexOf(proto) > -1
? replace(proto, 'package vector_tile;', replaceWith)
: proto.replace('package vector_tile;', replaceWith);

const proto_schema = schema.parse(protoString);
const mvt = compile(proto_schema);
const pbf = new PbfWriter();
mvt.writeTile(json, pbf);
return Buffer.from(pbf.finish());
}
4 changes: 1 addition & 3 deletions lib/real-world-extents.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use strict';

module.exports = {
export default {
chicago: {
bbox: [-87.797928,41.783345,-87.590561,41.957448],
zoom: 13,
Expand Down
27 changes: 8 additions & 19 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';

const fs = require('fs');
const path = require('path');
import fs from 'fs';
import path from 'path';

/**
* Replace part of a protocol buffer spec with a new string
Expand All @@ -10,23 +8,14 @@ const path = require('path');
* @param {String} after - the string to replace with
* @returns {String} schema - returns a .proto schema string to be used in protocol-buffers-schema parse() method
*/
function replace(version, before, after) {
let schema = fs.readFileSync(path.join(__dirname, '..', 'vector-tile-spec', version, 'vector_tile.proto'), 'utf8');
export function replace(version, before, after) {
const schema = fs.readFileSync(path.join(import.meta.dirname, '..', 'vector-tile-spec', version, 'vector_tile.proto'), 'utf8');
if (schema.indexOf(before) === -1) throw new Error(`${before} not found in ${version} schema`);
return schema.replace(before, after);
}

function getID(number) {
if (number < 10) {
return `00${number}`;
} else if (number < 100 && number > 9) {
return `0${number}`;
} else {
return `${number}`;
}
export function getID(number) {
if (number < 10) return `00${number}`;
if (number < 100) return `0${number}`;
return `${number}`;
}

module.exports = {
replace: replace,
getID: getID
};
Loading
Loading