Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3d5abc9a2 | ||
|
|
ea7a5da1c1 | ||
|
|
2e063cc2d2 | ||
|
|
decd9077e4 | ||
|
|
f6c47bf85e | ||
|
|
423191c13b | ||
|
|
7a5928d957 | ||
|
|
436c334f5a | ||
|
|
4f84138ade | ||
|
|
a0d86ac5dc | ||
|
|
e2be4f1275 | ||
|
|
9a393fa793 | ||
|
|
7614f72df6 | ||
|
|
ef2db78567 | ||
|
|
8708468444 | ||
|
|
cd28a4fbcc | ||
|
|
19f488095b | ||
|
|
cd65c6dd0e | ||
|
|
0c670cfdfd | ||
|
|
27ff1ac4f6 | ||
|
|
3f06de93f7 | ||
|
|
0da6495330 | ||
|
|
bf24347328 | ||
|
|
7a5d73f9df | ||
|
|
0d9f34fd48 | ||
|
|
da55a3bdd2 | ||
|
|
333334e598 | ||
|
|
7168e4410c | ||
|
|
3ff8571f4a | ||
|
|
75ddcbbd01 | ||
|
|
9b3e18f333 | ||
|
|
fcb0a4a7e6 | ||
|
|
94e38cef9d | ||
|
|
9e30f05e7d | ||
|
|
0df725112b | ||
|
|
9ea2029f81 | ||
|
|
2715f47a22 | ||
|
|
90d0b23441 | ||
|
|
b59e0a00a0 | ||
|
|
790571fd2c | ||
|
|
6ecebae110 | ||
|
|
849470a3c0 | ||
|
|
74d0a6f183 | ||
|
|
61c134215a | ||
|
|
b7218d8832 | ||
|
|
63e19427af | ||
|
|
d4f8578fd6 | ||
|
|
eaccd062d3 | ||
|
|
5f2d5931f4 | ||
|
|
ce40fa608e | ||
|
|
0979c75852 | ||
|
|
f01e8e0866 | ||
|
|
a4e303ab63 | ||
|
|
c5137c9c29 | ||
|
|
9bce88f9b1 | ||
|
|
68c70effec | ||
|
|
ebae218219 | ||
|
|
6685b759b2 | ||
|
|
539b0496bf | ||
|
|
3c33fac8f4 | ||
|
|
9613f76ef5 | ||
|
|
3f0d344313 | ||
|
|
823ee63c25 | ||
|
|
d5d76f9c63 | ||
|
|
dfc9a6fbb4 | ||
|
|
2bd9aece35 | ||
|
|
21870c9fa2 | ||
|
|
7c315b3afd | ||
|
|
da0cdb081d | ||
|
|
9bd0a3f1c9 | ||
|
|
83992895e4 | ||
|
|
aa3b336e46 | ||
|
|
e17b374fde | ||
|
|
61158b62f1 | ||
|
|
88ed43a92e | ||
|
|
e5fff6b452 | ||
|
|
044d49c53a | ||
|
|
69abf8d9b1 | ||
|
|
14e13899a6 | ||
|
|
488c246222 | ||
|
|
654905a79c | ||
|
|
12cb199803 | ||
|
|
8759cf726b | ||
|
|
7a45c9e434 | ||
|
|
9ee69dea55 | ||
|
|
c97c65de34 | ||
|
|
25ae09b2c5 | ||
|
|
853c2b4b85 |
98
NEWS.md
98
NEWS.md
@@ -1,5 +1,103 @@
|
||||
# Changelog
|
||||
|
||||
## 2.9.0
|
||||
|
||||
Released 2015-08-06
|
||||
|
||||
New features:
|
||||
- Send memory usage stats
|
||||
|
||||
|
||||
## 2.8.0
|
||||
|
||||
Released 2015-07-15
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.48.0](https://github.com/CartoDB/Windshaft/releases/tag/0.48.0)
|
||||
|
||||
|
||||
## 2.7.2
|
||||
|
||||
Released 2015-07-14
|
||||
|
||||
Enhancements:
|
||||
- Replaces `CDB_QueryTables` with `CDB_QueryTablesText` to avoid issues with long schema+table names
|
||||
|
||||
|
||||
## 2.7.1
|
||||
|
||||
Released 2015-07-06
|
||||
|
||||
Bug fixes:
|
||||
- redis-mpool `noReadyCheck` and `unwatchOnRelease` options from config and defaulted
|
||||
|
||||
|
||||
## 2.7.0
|
||||
|
||||
Released 2015-07-06
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.47.0](https://github.com/CartoDB/Windshaft/releases/tag/0.47.0)
|
||||
- Upgrades redis-mpool to [0.4.0](https://github.com/CartoDB/node-redis-mpool/releases/tag/0.4.0)
|
||||
|
||||
New features:
|
||||
- Exposes redis `noReadyCheck` config
|
||||
|
||||
Bug fixes:
|
||||
- Fixes `unwatchOnRelease` redis config
|
||||
|
||||
|
||||
## 2.6.1
|
||||
|
||||
Released 2015-07-02
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.46.1](https://github.com/CartoDB/Windshaft/releases/tag/0.46.1)
|
||||
|
||||
|
||||
## 2.6.0
|
||||
|
||||
Released 2015-07-02
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.46.0](https://github.com/CartoDB/Windshaft/releases/tag/0.46.0)
|
||||
- New config to set metatile by format
|
||||
|
||||
|
||||
## 2.5.0
|
||||
|
||||
Released 2015-06-18
|
||||
|
||||
New features:
|
||||
- Named maps names can start with numbers and can contain dashes (-).
|
||||
- Adds layergroupid header in map instantiations
|
||||
|
||||
Bug fixes:
|
||||
- Named maps error responses with `{ "errors": ["message"] }` format (#305)
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.45.0](https://github.com/CartoDB/Windshaft/releases/tag/0.45.0)
|
||||
|
||||
Enhancements:
|
||||
- Fix documentation style and error examples
|
||||
|
||||
|
||||
## 2.4.1
|
||||
|
||||
Released 2015-06-01
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.44.1](https://github.com/CartoDB/Windshaft/releases/tag/0.44.1)
|
||||
|
||||
|
||||
## 2.4.0
|
||||
|
||||
Released 2015-05-26
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to [0.44.0](https://github.com/CartoDB/Windshaft/releases/tag/0.44.0)
|
||||
|
||||
|
||||
## 2.3.0
|
||||
|
||||
Released 2015-05-18
|
||||
|
||||
@@ -59,6 +59,14 @@ happen to have startup errors you may need to force rebuilding those
|
||||
modules. At any time just wipe out the node_modules/ directory and run
|
||||
```npm install``` again.
|
||||
|
||||
Upgrading
|
||||
---------
|
||||
|
||||
Checkout your commit/branch. If you need to reinstall dependencies (you can check [NEWS](NEWS.md)) do the following:
|
||||
|
||||
```
|
||||
rm -rf node_modules; npm install
|
||||
```
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
15
app.js
15
app.js
@@ -65,8 +65,12 @@ if ( global.environment.log_filename ) {
|
||||
global.log4js.configure(log4js_config, { cwd: __dirname });
|
||||
global.logger = global.log4js.getLogger();
|
||||
|
||||
var redisOpts = _.extend(global.environment.redis, { name: 'windshaft' }),
|
||||
redisPool = new RedisPool(redisOpts);
|
||||
var redisOpts = _.defaults(global.environment.redis, {
|
||||
name: 'windshaft',
|
||||
unwatchOnRelease: false,
|
||||
noReadyCheck: true
|
||||
});
|
||||
var redisPool = new RedisPool(redisOpts);
|
||||
|
||||
// Include cartodb_windshaft only _after_ the "global" variable is set
|
||||
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/28
|
||||
@@ -82,6 +86,13 @@ if (global.statsClient) {
|
||||
global.statsClient.gauge(keyPrefix + 'unused', status.unused);
|
||||
global.statsClient.gauge(keyPrefix + 'waiting', status.waiting);
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
var memoryUsage = process.memoryUsage();
|
||||
Object.keys(memoryUsage).forEach(function(k) {
|
||||
global.statsClient.gauge('windshaft.memory.' + k, memoryUsage[k]);
|
||||
});
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// Maximum number of connections for one process
|
||||
|
||||
@@ -2,6 +2,9 @@ var config = {
|
||||
environment: 'development'
|
||||
,port: 8181
|
||||
,host: '127.0.0.1'
|
||||
// Size of the threadpool which can be used to run user code and get notified in the loop thread
|
||||
// Its default size is 4, but it can be changed at startup time (the absolute maximum is 128).
|
||||
// See http://docs.libuv.org/en/latest/threadpool.html
|
||||
,uv_threadpool_size: undefined
|
||||
// Regular expression pattern to extract username
|
||||
// from hostname. Must have a single grabbing block.
|
||||
@@ -86,8 +89,10 @@ var config = {
|
||||
cache_ttl: 60000,
|
||||
statsInterval: 5000, // milliseconds between each report to statsd about number of renderers and mapnik pool status
|
||||
mapnik: {
|
||||
// The size of the pool of internal mapnik renderers
|
||||
// Check the configuration of uv_threadpool_size to use suitable value
|
||||
// The size of the pool of internal mapnik backend
|
||||
// This pool size is per mapnik renderer created in Windshaft's RendererFactory
|
||||
// See https://github.com/CartoDB/Windshaft/blob/master/lib/windshaft/renderers/renderer_factory.js
|
||||
// Important: check the configuration of uv_threadpool_size to use suitable value
|
||||
poolSize: 8,
|
||||
|
||||
// Metatile is the number of tiles-per-side that are going
|
||||
@@ -96,6 +101,12 @@ var config = {
|
||||
// wasted time.
|
||||
metatile: 2,
|
||||
|
||||
// Override metatile behaviour depending on the format
|
||||
formatMetatile: {
|
||||
png: 2,
|
||||
'grid.json': 1
|
||||
},
|
||||
|
||||
// Buffer size is the tickness in pixel of a buffer
|
||||
// around the rendered (meta?)tile.
|
||||
//
|
||||
@@ -170,7 +181,9 @@ var config = {
|
||||
},
|
||||
emitter: {
|
||||
statusInterval: 5000 // time, in ms, between each status report is emitted from the pool, status is sent to statsd
|
||||
}
|
||||
},
|
||||
unwatchOnRelease: false, // Send unwatch on release, see http://github.com/CartoDB/Windshaft-cartodb/issues/161
|
||||
noReadyCheck: true // Check `no_ready_check` at https://github.com/mranney/node_redis/tree/v0.12.1#overloading
|
||||
}
|
||||
,varnish: {
|
||||
host: 'localhost',
|
||||
|
||||
@@ -2,6 +2,9 @@ var config = {
|
||||
environment: 'production'
|
||||
,port: 8181
|
||||
,host: '127.0.0.1'
|
||||
// Size of the threadpool which can be used to run user code and get notified in the loop thread
|
||||
// Its default size is 4, but it can be changed at startup time (the absolute maximum is 128).
|
||||
// See http://docs.libuv.org/en/latest/threadpool.html
|
||||
,uv_threadpool_size: undefined
|
||||
// Regular expression pattern to extract username
|
||||
// from hostname. Must have a single grabbing block.
|
||||
@@ -80,8 +83,10 @@ var config = {
|
||||
cache_ttl: 60000,
|
||||
statsInterval: 5000, // milliseconds between each report to statsd about number of renderers and mapnik pool status
|
||||
mapnik: {
|
||||
// The size of the pool of internal mapnik renderers
|
||||
// Check the configuration of uv_threadpool_size to use suitable value
|
||||
// The size of the pool of internal mapnik backend
|
||||
// This pool size is per mapnik renderer created in Windshaft's RendererFactory
|
||||
// See https://github.com/CartoDB/Windshaft/blob/master/lib/windshaft/renderers/renderer_factory.js
|
||||
// Important: check the configuration of uv_threadpool_size to use suitable value
|
||||
poolSize: 8,
|
||||
|
||||
// Metatile is the number of tiles-per-side that are going
|
||||
@@ -90,6 +95,12 @@ var config = {
|
||||
// wasted time.
|
||||
metatile: 2,
|
||||
|
||||
// Override metatile behaviour depending on the format
|
||||
formatMetatile: {
|
||||
png: 2,
|
||||
'grid.json': 1
|
||||
},
|
||||
|
||||
// Buffer size is the tickness in pixel of a buffer
|
||||
// around the rendered (meta?)tile.
|
||||
//
|
||||
@@ -164,7 +175,9 @@ var config = {
|
||||
},
|
||||
emitter: {
|
||||
statusInterval: 5000 // time, in ms, between each status report is emitted from the pool, status is sent to statsd
|
||||
}
|
||||
},
|
||||
unwatchOnRelease: false, // Send unwatch on release, see http://github.com/CartoDB/Windshaft-cartodb/issues/161
|
||||
noReadyCheck: true // Check `no_ready_check` at https://github.com/mranney/node_redis/tree/v0.12.1#overloading
|
||||
}
|
||||
,varnish: {
|
||||
host: 'localhost',
|
||||
|
||||
@@ -2,6 +2,9 @@ var config = {
|
||||
environment: 'production'
|
||||
,port: 8181
|
||||
,host: '127.0.0.1'
|
||||
// Size of the threadpool which can be used to run user code and get notified in the loop thread
|
||||
// Its default size is 4, but it can be changed at startup time (the absolute maximum is 128).
|
||||
// See http://docs.libuv.org/en/latest/threadpool.html
|
||||
,uv_threadpool_size: undefined
|
||||
// Regular expression pattern to extract username
|
||||
// from hostname. Must have a single grabbing block.
|
||||
@@ -80,8 +83,10 @@ var config = {
|
||||
cache_ttl: 60000,
|
||||
statsInterval: 5000, // milliseconds between each report to statsd about number of renderers and mapnik pool status
|
||||
mapnik: {
|
||||
// The size of the pool of internal mapnik renderers
|
||||
// Check the configuration of uv_threadpool_size to use suitable value
|
||||
// The size of the pool of internal mapnik backend
|
||||
// This pool size is per mapnik renderer created in Windshaft's RendererFactory
|
||||
// See https://github.com/CartoDB/Windshaft/blob/master/lib/windshaft/renderers/renderer_factory.js
|
||||
// Important: check the configuration of uv_threadpool_size to use suitable value
|
||||
poolSize: 8,
|
||||
|
||||
// Metatile is the number of tiles-per-side that are going
|
||||
@@ -90,6 +95,12 @@ var config = {
|
||||
// wasted time.
|
||||
metatile: 2,
|
||||
|
||||
// Override metatile behaviour depending on the format
|
||||
formatMetatile: {
|
||||
png: 2,
|
||||
'grid.json': 1
|
||||
},
|
||||
|
||||
// Buffer size is the tickness in pixel of a buffer
|
||||
// around the rendered (meta?)tile.
|
||||
//
|
||||
@@ -164,7 +175,9 @@ var config = {
|
||||
},
|
||||
emitter: {
|
||||
statusInterval: 5000 // time, in ms, between each status report is emitted from the pool, status is sent to statsd
|
||||
}
|
||||
},
|
||||
unwatchOnRelease: false, // Send unwatch on release, see http://github.com/CartoDB/Windshaft-cartodb/issues/161
|
||||
noReadyCheck: true // Check `no_ready_check` at https://github.com/mranney/node_redis/tree/v0.12.1#overloading
|
||||
}
|
||||
,varnish: {
|
||||
host: 'localhost',
|
||||
|
||||
@@ -2,6 +2,9 @@ var config = {
|
||||
environment: 'test'
|
||||
,port: 8888
|
||||
,host: '127.0.0.1'
|
||||
// Size of the threadpool which can be used to run user code and get notified in the loop thread
|
||||
// Its default size is 4, but it can be changed at startup time (the absolute maximum is 128).
|
||||
// See http://docs.libuv.org/en/latest/threadpool.html
|
||||
,uv_threadpool_size: undefined
|
||||
// Regular expression pattern to extract username
|
||||
// from hostname. Must have a single grabbing block.
|
||||
@@ -80,8 +83,10 @@ var config = {
|
||||
cache_ttl: 60000,
|
||||
statsInterval: 5000, // milliseconds between each report to statsd about number of renderers and mapnik pool status
|
||||
mapnik: {
|
||||
// The size of the pool of internal mapnik renderers
|
||||
// Check the configuration of uv_threadpool_size to use suitable value
|
||||
// The size of the pool of internal mapnik backend
|
||||
// This pool size is per mapnik renderer created in Windshaft's RendererFactory
|
||||
// See https://github.com/CartoDB/Windshaft/blob/master/lib/windshaft/renderers/renderer_factory.js
|
||||
// Important: check the configuration of uv_threadpool_size to use suitable value
|
||||
poolSize: 8,
|
||||
|
||||
// Metatile is the number of tiles-per-side that are going
|
||||
@@ -90,6 +95,12 @@ var config = {
|
||||
// wasted time.
|
||||
metatile: 2,
|
||||
|
||||
// Override metatile behaviour depending on the format
|
||||
formatMetatile: {
|
||||
png: 2,
|
||||
'grid.json': 1
|
||||
},
|
||||
|
||||
// Buffer size is the tickness in pixel of a buffer
|
||||
// around the rendered (meta?)tile.
|
||||
//
|
||||
@@ -166,7 +177,9 @@ var config = {
|
||||
},
|
||||
emitter: {
|
||||
statusInterval: 5000 // time, in ms, between each status report is emitted from the pool, status is sent to statsd
|
||||
}
|
||||
},
|
||||
unwatchOnRelease: false, // Send unwatch on release, see http://github.com/CartoDB/Windshaft-cartodb/issues/161
|
||||
noReadyCheck: true // Check `no_ready_check` at https://github.com/mranney/node_redis/tree/v0.12.1#overloading
|
||||
}
|
||||
,varnish: {
|
||||
host: '',
|
||||
|
||||
181
docs/Map-API.md
181
docs/Map-API.md
@@ -18,7 +18,7 @@ Here is an example of how to create an anonymous map with JavaScript:
|
||||
|
||||
```javascript
|
||||
var mapconfig = {
|
||||
"version": "1.0.1",
|
||||
"version": "1.3.1",
|
||||
"layers": [{
|
||||
"type": "cartodb",
|
||||
"options": {
|
||||
@@ -57,7 +57,7 @@ The following map config sets up a map of European countries that have a white f
|
||||
},
|
||||
"layergroup": {
|
||||
"layers": [{
|
||||
"type": "cartodb",
|
||||
"type": "mapnik",
|
||||
"options": {
|
||||
"cartocss_version": "2.1.1",
|
||||
"cartocss": "#layer { polygon-fill: #FFF; }",
|
||||
@@ -82,14 +82,23 @@ To get the `URL` to fetch the tiles you need to instantiate the map, where `temp
|
||||
curl -X POST 'https://{account}.cartodb.com/api/v1/map/named/:template_id' -H 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
The response will return JSON with properties for the `layergroupid` and the timestamp (`last_updated`) of the last data modification.
|
||||
The response will return JSON with properties for the `layergroupid`, the timestamp (`last_updated`) of the last data modification and some key/value pairs with `metadata` for the `layers`.
|
||||
Note: all `layers` in `metadata` will always have a `type` string and a `meta` dictionary with the key/value pairs.
|
||||
|
||||
Here is an example response:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"layergroupid": "c01a54877c62831bb51720263f91fb33:0",
|
||||
"last_updated": "1970-01-01T00:00:00.000Z"
|
||||
"last_updated": "1970-01-01T00:00:00.000Z",
|
||||
"metadata": {
|
||||
"layers": [
|
||||
{
|
||||
"type": "mapnik",
|
||||
"meta": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -144,9 +153,9 @@ POST /api/v1/map
|
||||
|
||||
```javascript
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"version": "1.3.0",
|
||||
"layers": [{
|
||||
"type": "cartodb",
|
||||
"type": "mapnik",
|
||||
"options": {
|
||||
"cartocss_version": "2.1.1",
|
||||
"cartocss": "#layer { polygon-fill: #FFF; }",
|
||||
@@ -157,7 +166,7 @@ POST /api/v1/map
|
||||
}
|
||||
```
|
||||
|
||||
Should be a [Mapconfig](https://github.com/CartoDB/Windshaft/blob/0.19.1/doc/MapConfig-1.1.0.md).
|
||||
Should be a [Mapconfig](https://github.com/CartoDB/Windshaft/blob/0.44.1/doc/MapConfig-1.3.0.md).
|
||||
|
||||
#### Response
|
||||
|
||||
@@ -173,8 +182,9 @@ The response includes:
|
||||
- **updated_at**
|
||||
The ISO date of the last time the data involved in the query was updated.
|
||||
|
||||
- **metadata** *(optional)*
|
||||
Includes information about the layers. Some layers may not have metadata.
|
||||
- **metadata**
|
||||
Includes information about the layers.
|
||||
-
|
||||
|
||||
- **cdn_url**
|
||||
URLs to fetch the data using the best CDN for your zone.
|
||||
@@ -189,8 +199,16 @@ curl 'https://documentation.cartodb.com/api/v1/map' -H 'Content-Type: applicatio
|
||||
<div class="code-title">RESPONSE</div>
|
||||
```javascript
|
||||
{
|
||||
"layergroupid":"c01a54877c62831bb51720263f91fb33:0",
|
||||
"last_updated":"1970-01-01T00:00:00.000Z"
|
||||
"layergroupid": "c01a54877c62831bb51720263f91fb33:0",
|
||||
"last_updated": "1970-01-01T00:00:00.000Z",
|
||||
"metadata": {
|
||||
"layers": [
|
||||
{
|
||||
"type": "mapnik",
|
||||
"meta": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"cdn_url": {
|
||||
"http": "http://cdb.com",
|
||||
"https": "https://cdb.com"
|
||||
@@ -198,19 +216,35 @@ curl 'https://documentation.cartodb.com/api/v1/map' -H 'Content-Type: applicatio
|
||||
}
|
||||
```
|
||||
|
||||
The tiles can be accessed using:
|
||||
##### Retrieve resources from the layergroup
|
||||
|
||||
###### Mapnik tiles can be accessed using:
|
||||
|
||||
These tiles will get just the mapnik layers. To get individual layers see next section.
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/{z}/{x}/{y}.png
|
||||
```
|
||||
|
||||
For UTF grid tiles:
|
||||
###### Individual layers
|
||||
|
||||
The MapConfig specification holds the layers definition in a 0-based index. Layers can be requested individually in different formats depending on the layer type.
|
||||
|
||||
Individual layers can be accessed using that 0-based index. For UTF grid tiles:
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/:layer/{z}/{x}/{y}.grid.json
|
||||
```
|
||||
|
||||
For attributes defined in `attributes` section:
|
||||
In this case, `:layer` as 0 returns the UTF grid tiles/attributes for layer 0, the only layer in the example MapConfig.
|
||||
|
||||
If the MapConfig had a Torque layer at index 1 it could be possible to request it with:
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/1/{z}/{x}/{y}.torque.json
|
||||
```
|
||||
|
||||
###### Attributes defined in `attributes` section:
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/:layer/attributes/:feature_id
|
||||
@@ -219,10 +253,44 @@ https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/
|
||||
Which returns JSON with the attributes defined, like:
|
||||
|
||||
```javascript
|
||||
{ c: 1, d: 2 }
|
||||
{ "c": 1, "d": 2 }
|
||||
```
|
||||
|
||||
Notice UTF Grid and attributes endpoints need an integer parameter, ``layer``. That number is the 0-based index of the layer inside the mapconfig. In this case, 0 returns the UTF grid tiles/attributes for layer 0, the only layer in the example mapconfig. If a second layer was available it could be returned with 1, a third layer with 2, etc.
|
||||
###### Blending and layer selection
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/:layer_filter/{z}/{x}/{y}.png
|
||||
```
|
||||
|
||||
Note: currently format is limited to `png`.
|
||||
|
||||
`:layer_filter` can be used to select some layers to be rendered together. `:layer_filter` supports two formats:
|
||||
|
||||
- `all` alias
|
||||
|
||||
Using `all` as `:layer_filter` will blend all layers in the layergroup
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/all/{z}/{x}/{y}.png
|
||||
```
|
||||
|
||||
- Filter by layer index
|
||||
|
||||
A list of comma separated layer indexes can be used to just render a subset of layers. For example `0,3,4` will filter and blend layers with indexes 0, 3, and 4.
|
||||
|
||||
```bash
|
||||
https://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/0,3,4/{z}/{x}/{y}.png
|
||||
```
|
||||
|
||||
Some notes about filtering:
|
||||
|
||||
- Invalid index values or out of bounds indexes will end in `Invalid layer filtering` errors.
|
||||
- Once a mapnik layer is selected, all mapnik layers will get blended. As this may change in the future **it is
|
||||
recommended** to always select all mapnik layers if you want to select at least one so you will get a consistent
|
||||
behavior in the future.
|
||||
- Ordering is not considered. So right now filtering layers 0,3,4 is the very same thing as filtering 3,4,0. As this
|
||||
may change in the future **it is recommended** to always select the layers in ascending order so you will get a
|
||||
consistent behavior in the future.
|
||||
|
||||
### Create JSONP
|
||||
|
||||
@@ -272,7 +340,7 @@ Anonymous maps cannot be removed by an API call. They will expire after about fi
|
||||
|
||||
## Named Maps
|
||||
|
||||
Named maps are essentially the same as anonymous maps except the mapconfig is stored on the server and the map is given a unique name. Two other big differences are: you can create named maps from private data and that users without an API Key can see them even though they are from that private data.
|
||||
Named maps are essentially the same as anonymous maps except the MapConfig is stored on the server and the map is given a unique name. Two other big differences are: you can create named maps from private data and that users without an API Key can see them even though they are from that private data.
|
||||
|
||||
The main two differences compared to anonymous maps are:
|
||||
|
||||
@@ -280,7 +348,7 @@ The main two differences compared to anonymous maps are:
|
||||
This allows you to control who is able to see the map based on a token auth
|
||||
|
||||
- **templates**
|
||||
Since the mapconfig is static it can contain some variables so the client can modify the map's appearance using those variables.
|
||||
Since the MapConfig is static it can contain some variables so the client can modify the map's appearance using those variables.
|
||||
|
||||
Template maps are persistent with no preset expiration. They can only be created or deleted by a CartoDB user with a valid API_KEY (see auth section).
|
||||
|
||||
@@ -331,18 +399,41 @@ POST /api/v1/map/named
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"view": {
|
||||
"zoom": 4,
|
||||
"center": {
|
||||
"lng": 0,
|
||||
"lat": 0
|
||||
},
|
||||
"bounds": {
|
||||
"west": -45,
|
||||
"south": -45,
|
||||
"east": 45,
|
||||
"north": 45
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Arguments
|
||||
|
||||
- **name**: There can be at most _one_ template with the same name for any user. Valid names start with a letter, and only contain letters, numbers, or underscores (_).
|
||||
- **name**: There can be at most _one_ template with the same name for any user. Valid names start with a letter or a number, and only contain letters, numbers, dashes (-) or underscores (_).
|
||||
- **auth**:
|
||||
- **method** `"token"` or `"open"` (the default if no `"method"` is given).
|
||||
- **valid_tokens** when `"method"` is set to `"token"`, the values listed here allow you to instantiate the named map.
|
||||
- **placeholders**: Variables not listed here are not substituted. Variables not provided at instantiation time trigger an error. A default is required for optional variables. Type specification is used for quoting, to avoid injections see template format section below.
|
||||
- **layergroup**: the layer list definition. This is the MapConfig explained in anonymous maps. See [MapConfig documentation](https://github.com/CartoDB/Windshaft/blob/master/doc/MapConfig-1.1.0.md) for more info.
|
||||
- **layergroup**: the layer list definition. This is the MapConfig explained in anonymous maps. See [MapConfig documentation](https://github.com/CartoDB/Windshaft/blob/0.44.1/doc/MapConfig-1.3.0.md) for more info.
|
||||
- **view** (optional): extra keys to specify the compelling area for the map. It can be used to have a static preview of a named map without having to instantiate it. It is possible to specify it with `center` + `zoom` or with a bounding box `bbox`. Center+zoom takes precedence over bounding box.
|
||||
- **zoom** The zoom level to use
|
||||
- **center**
|
||||
- **lng** The longitude to use for the center
|
||||
- **lat** The latitude to use for the center
|
||||
- **bounds**
|
||||
- **west**: LowerCorner longitude for the bounding box, in decimal degrees (aka most western)
|
||||
- **south**: LowerCorner latitude for the bounding box, in decimal degrees (aka most southern)
|
||||
- **east**: UpperCorner longitude for the bounding box, in decimal degrees (aka most eastern)
|
||||
- **north**: UpperCorner latitude for the bounding box, in decimal degrees (aka most northern)
|
||||
|
||||
#### Template Format
|
||||
|
||||
@@ -438,7 +529,7 @@ curl -X POST \
|
||||
<div class="code-title">Error</div>
|
||||
```javascript
|
||||
{
|
||||
"error": "Some error string here"
|
||||
"errors" : ["Some error string here"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -539,7 +630,7 @@ If a template with the same name does NOT exist, a 400 HTTP response is generate
|
||||
|
||||
```javascript
|
||||
{
|
||||
"error": "error string here"
|
||||
"errors" : ["error string here"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -568,7 +659,7 @@ curl -X DELETE 'https://documentation.cartodb.com/api/v1/map/named/:template_nam
|
||||
<div class="code-title">RESPONSE</div>
|
||||
```javascript
|
||||
{
|
||||
"error": "Some error string here"
|
||||
"errors" : ["Some error string here"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -606,7 +697,7 @@ curl -X GET 'https://documentation.cartodb.com/api/v1/map/named?api_key=APIKEY'
|
||||
<div class="code-title">ERROR</div>
|
||||
```javascript
|
||||
{
|
||||
"error": "Some error string here"
|
||||
"errors" : ["Some error string here"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -642,7 +733,7 @@ curl -X GET 'https://documentation.cartodb.com/api/v1/map/named/:template_name?a
|
||||
<div class="code-title">ERROR</div>
|
||||
```javascript
|
||||
{
|
||||
"error": "Some error string here"
|
||||
"errors" : ["Some error string here"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -672,13 +763,15 @@ cartodb.createLayer('map_dom_id',layerSource)
|
||||
1. [layer.setParams()](http://docs.cartodb.com/cartodb-platform/cartodb-js.html#layersetparamskey-value) allows you to change the template variables (in the placeholders object) via JavaScript
|
||||
2. [layer.setAuthToken()](http://docs.cartodb.com/cartodb-platform/cartodb-js.html#layersetauthtokenauthtoken) allows you to set the auth tokens to create the layer
|
||||
|
||||
##Static Maps API
|
||||
## Static Maps API
|
||||
|
||||
The Static Maps API can be initiated using both named and anonymous maps using the 'layergroupid' token. The API can be used to create static images of parts of maps and thumbnails for use in web design, graphic design, print, field work, and many other applications that require standard image formats.
|
||||
|
||||
### Maps API endpoints
|
||||
|
||||
Begin by instantiating either a named or anonymous map using the `layergroupid token` as demonstrated in the Maps API documentation above. The `layergroupsid token` calls to the map and allows for parameters in the definition to generate static images.
|
||||
Begin by instantiating either a named or anonymous map using the `layergroupid token` as demonstrated in the Maps API documentation above. The `layergroupid` token calls to the map and allows for parameters in the definition to generate static images.
|
||||
|
||||
#### Zoom + center
|
||||
|
||||
##### Definition
|
||||
|
||||
@@ -726,6 +819,25 @@ Note: you can see this endpoint as:
|
||||
GET /api/v1/map/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format`
|
||||
```
|
||||
|
||||
#### Named map
|
||||
|
||||
##### Definition
|
||||
|
||||
<div class="code-title notitle code-request"></div>
|
||||
```bash
|
||||
GET /api/v1/map/static/named/:name/:width/:height.:format
|
||||
```
|
||||
|
||||
##### Params
|
||||
|
||||
* **:name**: the name of the named map
|
||||
* **:width**: the width in pixels for the output image
|
||||
* **:height**: the height in pixels for the output image
|
||||
* **:format**: the format for the image, supported types: `png`, `jpg`
|
||||
* **jpg** will have a default quality of 85.
|
||||
|
||||
A named maps static image will get its constraints from the [view in the template](#Arguments), if `view` is not present it will estimate the extent based on the involved tables otherwise it fallback to `"zoom": 1`, `"lng": 0` and `"lat": 0`.
|
||||
|
||||
####Layers
|
||||
|
||||
The Static Maps API allows for multiple layers of incorporation into the `MapConfig` to allow for maximum versatility in creating a static map. The examples below were used to generate the static image example in the next section, and appear in the specific order designated.
|
||||
@@ -768,6 +880,8 @@ By manipulating the `"urlTemplate"` custom basemaps can be used in generating st
|
||||
|
||||
**CartoDB**
|
||||
|
||||
As described in the [Mapconfig documentation](https://github.com/CartoDB/Windshaft/blob/0.44.1/doc/MapConfig-1.3.0.md), a "cartodb" type layer is now just an alias to a "mapnik" type layer as above, intended for backwards compatibility.
|
||||
|
||||
```javascript
|
||||
{
|
||||
"type": "cartodb",
|
||||
@@ -779,14 +893,14 @@ By manipulating the `"urlTemplate"` custom basemaps can be used in generating st
|
||||
},
|
||||
```
|
||||
|
||||
Additoinally, static images from Torque maps and other map layers can be used together to generate highly customizable and versatile static maps.
|
||||
Additionally, static images from Torque maps and other map layers can be used together to generate highly customizable and versatile static maps.
|
||||
|
||||
|
||||
####Caching
|
||||
#### Caching
|
||||
|
||||
It is important to note that generated images are cached from the live data referenced with the `layergroupid token` on the specified CartoDB account. This means that if the data changes, the cached image will also change. When linking dynamically, it is important to take into consideration the state of the data and longevity of the static image to avoid broken images or changes in how the image is displayed. To obtain a static snapshot of the map as it is today and preserve the image long-term regardless of changes in data, the image must be saved and stored locally.
|
||||
|
||||
####Limits
|
||||
#### Limits
|
||||
|
||||
* While images can encompass an entirety of a map, the default limit for pixel range is 8192 x 8192.
|
||||
* Image resolution by default is set to 72 DPI
|
||||
@@ -803,10 +917,11 @@ After instantiating a map from a CartoDB account:
|
||||
GET /api/v1/map/static/center/4b615ff367e498e770e7d05e99181873:1420231989550.8699/14/40.71502926732618/-73.96039009094238/600/400.png
|
||||
```
|
||||
|
||||
####Response
|
||||
<div clas="wrap"><p class="wrap-border"><img src="https://raw.githubusercontent.com/namessanti/Pictures/master/static_api.png" alt="static-api"/></p>,</div>
|
||||
#### Response
|
||||
|
||||
####MapConfig
|
||||
<p class="wrap-border"><img src="https://raw.githubusercontent.com/namessanti/Pictures/master/static_api.png" alt="static-api"/></p>
|
||||
|
||||
#### MapConfig
|
||||
|
||||
For this map, the multiple layers, order, and stylings are defined by the MapConfig.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The Windshaft-CartoDB MultiLayer API extends the [Windshaft MultiLayer API](https://github.com/Vizzuality/Windshaft/wiki/Multilayer-API) in a few ways.
|
||||
The Windshaft-CartoDB MultiLayer API extends the [Windshaft MultiLayer API](https://github.com/CartoDB/Windshaft/blob/master/doc/Multilayer-API.md) in a few ways.
|
||||
|
||||
## Last modification timestamp embedded in the token
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ This document list all routes available in Windshaft-cartodb Maps API server.
|
||||
1. `GET (?:/api/v1/map/named|/user/:user/api/v1/map/named|/tiles/template) {:user(f)} (1)`
|
||||
<br/>Notes: List named maps (w/ API KEY) [1]
|
||||
|
||||
1. `GET (?:/api/v1/map|/user/:user/api/v1/map|/tiles/layergroup)/static/named/:template_id/:width/:height.:format {:user(f),:template_id(f),:width(f),:height(f),:format(f)} (1)`
|
||||
<br/>Notes: Static map for named maps
|
||||
|
||||
1. `GET /health {} (1)`
|
||||
<br/>Notes: Healt check
|
||||
|
||||
@@ -73,10 +76,10 @@ Something like the following patch should do the trick
|
||||
|
||||
```javascript
|
||||
diff --git a/lib/cartodb/cartodb_windshaft.js b/lib/cartodb/cartodb_windshaft.js
|
||||
index 477a4c2..f69eebb 100644
|
||||
index b9429a2..e6cc5f9 100644
|
||||
--- a/lib/cartodb/cartodb_windshaft.js
|
||||
+++ b/lib/cartodb/cartodb_windshaft.js
|
||||
@@ -242,6 +242,20 @@ var CartodbWindshaft = function(serverOptions) {
|
||||
@@ -212,6 +212,20 @@ var CartodbWindshaft = function(serverOptions) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module.exports = QueryTablesApi;
|
||||
|
||||
QueryTablesApi.prototype.getAffectedTablesInQuery = function (username, sql, callback) {
|
||||
|
||||
var query = 'SELECT CDB_QueryTables($windshaft$' + prepareSql(sql) + '$windshaft$)';
|
||||
var query = 'SELECT CDB_QueryTablesText($windshaft$' + prepareSql(sql) + '$windshaft$)';
|
||||
|
||||
this.pgQueryRunner.run(username, query, handleAffectedTablesInQueryRows, callback);
|
||||
};
|
||||
@@ -25,9 +25,9 @@ function handleAffectedTablesInQueryRows(err, rows, callback) {
|
||||
callback(new Error('could not fetch source tables: ' + msg));
|
||||
return;
|
||||
}
|
||||
var qtables = rows[0].cdb_querytables;
|
||||
var tableNames = qtables.split(/^\{(.*)\}$/)[1];
|
||||
tableNames = tableNames ? tableNames.split(',') : [];
|
||||
|
||||
// This is an Array, so no need to split into parts
|
||||
var tableNames = rows[0].cdb_querytablestext;
|
||||
callback(null, tableNames);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ QueryTablesApi.prototype.getAffectedTablesAndLastUpdatedTime = function (usernam
|
||||
|
||||
var query = [
|
||||
'WITH querytables AS (',
|
||||
'SELECT * FROM CDB_QueryTables($windshaft$' + prepareSql(sql) + '$windshaft$) as tablenames',
|
||||
'SELECT * FROM CDB_QueryTablesText($windshaft$' + prepareSql(sql) + '$windshaft$) as tablenames',
|
||||
')',
|
||||
'SELECT (SELECT tablenames FROM querytables), EXTRACT(EPOCH FROM max(updated_at)) as max',
|
||||
'FROM CDB_TableMetadata m',
|
||||
@@ -54,8 +54,8 @@ function handleAffectedTablesAndLastUpdatedTimeRows(err, rows, callback) {
|
||||
|
||||
var result = rows[0];
|
||||
|
||||
var tableNames = result.tablenames.split(/^\{(.*)\}$/)[1];
|
||||
tableNames = tableNames ? tableNames.split(',') : [];
|
||||
// This is an Array, so no need to split into parts
|
||||
var tableNames = result.tablenames;
|
||||
|
||||
var lastUpdatedTime = result.max || 0;
|
||||
|
||||
|
||||
2
lib/cartodb/cache/backend/fastly.js
vendored
2
lib/cartodb/cache/backend/fastly.js
vendored
@@ -14,5 +14,3 @@ module.exports = FastlyCacheBackend;
|
||||
FastlyCacheBackend.prototype.invalidate = function(cacheObject, callback) {
|
||||
this.fastlyPurge.key(this.serviceId, cacheObject.key(), callback);
|
||||
};
|
||||
|
||||
module.exports = FastlyCacheBackend;
|
||||
|
||||
2
lib/cartodb/cache/backend/varnish_http.js
vendored
2
lib/cartodb/cache/backend/varnish_http.js
vendored
@@ -28,5 +28,3 @@ VarnishHttpCacheBackend.prototype.invalidate = function(cacheObject, callback) {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = VarnishHttpCacheBackend;
|
||||
@@ -315,23 +315,23 @@ NamedMapsController.prototype.instantiateTemplate = function(req, res, template_
|
||||
},
|
||||
function prepareResponse(err, layergroup) {
|
||||
if ( err ) {
|
||||
throw err;
|
||||
return callback(err, { errors: [''+err] });
|
||||
}
|
||||
var tplhash = self.templateMaps.fingerPrint(template).substring(0,8);
|
||||
layergroup.layergroupid = cdbuser + '@' + tplhash + '@' + layergroup.layergroupid;
|
||||
res.header('X-Layergroup-Id', layergroup.layergroupid);
|
||||
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, template.name));
|
||||
|
||||
return layergroup;
|
||||
},
|
||||
callback
|
||||
callback(null, layergroup);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
NamedMapsController.prototype.finish_instantiation = function(err, response, res) {
|
||||
if (err) {
|
||||
var statusCode = 400;
|
||||
response = { error: ''+err };
|
||||
response = { errors: [''+err] };
|
||||
if ( ! _.isUndefined(err.http_status) ) {
|
||||
statusCode = err.http_status;
|
||||
}
|
||||
@@ -346,7 +346,7 @@ function finishFn(app, res, description, okResponse) {
|
||||
var statusCode = 200;
|
||||
if (err) {
|
||||
statusCode = 400;
|
||||
response = { error: '' + err };
|
||||
response = { errors: ['' + err] };
|
||||
if ( ! _.isUndefined(err.http_status) ) {
|
||||
statusCode = err.http_status;
|
||||
}
|
||||
|
||||
@@ -362,17 +362,22 @@ module.exports = function(redisPool) {
|
||||
var cacheChannel = me.buildCacheChannel(dbName, result.affectedTables);
|
||||
me.channelCache[cacheKey] = cacheChannel;
|
||||
|
||||
if (req.res && req.method == 'GET') {
|
||||
var res = req.res;
|
||||
var ttl = global.environment.varnish.layergroupTtl || 86400;
|
||||
res.header('Cache-Control', 'public,max-age='+ttl+',must-revalidate');
|
||||
res.header('Last-Modified', (new Date()).toUTCString());
|
||||
res.header('X-Cache-Channel', cacheChannel);
|
||||
}
|
||||
|
||||
// last update for layergroup cache buster
|
||||
response.layergroupid = response.layergroupid + ':' + result.lastUpdatedTime;
|
||||
response.last_updated = new Date(result.lastUpdatedTime).toISOString();
|
||||
|
||||
var res = req.res;
|
||||
if (res) {
|
||||
if (req.method === 'GET') {
|
||||
var ttl = global.environment.varnish.layergroupTtl || 86400;
|
||||
res.header('Cache-Control', 'public,max-age='+ttl+',must-revalidate');
|
||||
res.header('Last-Modified', (new Date()).toUTCString());
|
||||
res.header('X-Cache-Channel', cacheChannel);
|
||||
}
|
||||
|
||||
res.header('X-Layergroup-Id', response.layergroupid);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
function finish(err) {
|
||||
|
||||
@@ -88,7 +88,8 @@ o._redisCmd = function(redisFunc, redisArgs, callback) {
|
||||
);
|
||||
};
|
||||
|
||||
var _reValidIdentifier = /^[a-zA-Z][0-9a-zA-Z_]*$/;
|
||||
var _reValidNameIdentifier = /^[a-z0-9][0-9a-z_\-]*$/i;
|
||||
var _reValidPlaceholderIdentifier = /^[a-z][0-9a-z_]*$/i;
|
||||
// jshint maxcomplexity:15
|
||||
o._checkInvalidTemplate = function(template) {
|
||||
if ( template.version != '0.0.1' ) {
|
||||
@@ -98,7 +99,7 @@ o._checkInvalidTemplate = function(template) {
|
||||
if ( ! tplname ) {
|
||||
return new Error("Missing template name");
|
||||
}
|
||||
if ( ! tplname.match(_reValidIdentifier) ) {
|
||||
if ( ! tplname.match(_reValidNameIdentifier) ) {
|
||||
return new Error("Invalid characters in template name '" + tplname + "'");
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ o._checkInvalidTemplate = function(template) {
|
||||
for (var i = 0, len = placeholderKeys.length; i < len; i++) {
|
||||
var placeholderKey = placeholderKeys[i];
|
||||
|
||||
if (!placeholderKey.match(_reValidIdentifier)) {
|
||||
if (!placeholderKey.match(_reValidPlaceholderIdentifier)) {
|
||||
return new Error("Invalid characters in placeholder name '" + placeholderKey + "'");
|
||||
}
|
||||
if ( ! placeholders[placeholderKey].hasOwnProperty('default') ) {
|
||||
|
||||
270
npm-shrinkwrap.json
generated
270
npm-shrinkwrap.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.3.0",
|
||||
"version": "2.9.0",
|
||||
"dependencies": {
|
||||
"cartodb-psql": {
|
||||
"version": "0.4.0",
|
||||
@@ -76,9 +76,9 @@
|
||||
"from": "fastly-purge@~1.0.0",
|
||||
"dependencies": {
|
||||
"request": {
|
||||
"version": "2.55.0",
|
||||
"version": "2.58.0",
|
||||
"from": "request@^2.55.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.58.0.tgz",
|
||||
"dependencies": {
|
||||
"bl": {
|
||||
"version": "0.9.4",
|
||||
@@ -114,9 +114,14 @@
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.9.0",
|
||||
"from": "caseless@~0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz"
|
||||
"version": "0.10.0",
|
||||
"from": "caseless@~0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.10.0.tgz"
|
||||
},
|
||||
"extend": {
|
||||
"version": "2.0.1",
|
||||
"from": "extend@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz"
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
@@ -124,31 +129,43 @@
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "0.2.0",
|
||||
"from": "form-data@~0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
|
||||
"version": "1.0.0-rc1",
|
||||
"from": "form-data@~1.0.0-rc1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc1.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
"from": "async@~0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
|
||||
"version": "1.3.0",
|
||||
"from": "async@^1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.3.0.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.3",
|
||||
"from": "mime-types@^2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.3.tgz",
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.15.0",
|
||||
"from": "mime-db@~1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.15.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"from": "json-stringify-safe@~5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.14",
|
||||
"from": "mime-types@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.11.tgz",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.9.1",
|
||||
"from": "mime-db@~1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.9.1.tgz"
|
||||
"version": "1.12.0",
|
||||
"from": "mime-db@~1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -158,24 +175,24 @@
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
|
||||
},
|
||||
"qs": {
|
||||
"version": "2.4.2",
|
||||
"from": "qs@~2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz"
|
||||
"version": "3.1.0",
|
||||
"from": "qs@~3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz"
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.1",
|
||||
"from": "tunnel-agent@~0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "1.1.0",
|
||||
"version": "2.0.0",
|
||||
"from": "tough-cookie@>=0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-1.1.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "0.10.1",
|
||||
"from": "http-signature@~0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
|
||||
"version": "0.11.0",
|
||||
"from": "http-signature@~0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz",
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "0.1.5",
|
||||
@@ -195,9 +212,9 @@
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.6.0",
|
||||
"from": "oauth-sign@~0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz"
|
||||
"version": "0.8.0",
|
||||
"from": "oauth-sign@~0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.0.tgz"
|
||||
},
|
||||
"hawk": {
|
||||
"version": "2.3.1",
|
||||
@@ -205,14 +222,14 @@
|
||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz",
|
||||
"dependencies": {
|
||||
"hoek": {
|
||||
"version": "2.13.0",
|
||||
"version": "2.14.0",
|
||||
"from": "hoek@2.x.x",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.13.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.14.0.tgz"
|
||||
},
|
||||
"boom": {
|
||||
"version": "2.7.1",
|
||||
"version": "2.8.0",
|
||||
"from": "boom@2.x.x",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.7.1.tgz"
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.8.0.tgz"
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.4",
|
||||
@@ -237,14 +254,14 @@
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz"
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "0.0.7",
|
||||
"from": "combined-stream@~0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
|
||||
"version": "1.0.5",
|
||||
"from": "combined-stream@~1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
||||
"dependencies": {
|
||||
"delayed-stream": {
|
||||
"version": "0.0.5",
|
||||
"from": "delayed-stream@0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
|
||||
"version": "1.0.0",
|
||||
"from": "delayed-stream@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -254,24 +271,24 @@
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "1.7.0",
|
||||
"from": "har-validator@^1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.7.0.tgz",
|
||||
"version": "1.8.0",
|
||||
"from": "har-validator@^1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
|
||||
"dependencies": {
|
||||
"bluebird": {
|
||||
"version": "2.9.25",
|
||||
"from": "bluebird@^2.9.25",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.25.tgz"
|
||||
"version": "2.9.33",
|
||||
"from": "bluebird@^2.9.30",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.33.tgz"
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"from": "chalk@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.0.1",
|
||||
"from": "ansi-styles@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.0.1.tgz"
|
||||
"version": "2.1.0",
|
||||
"from": "ansi-styles@^2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz"
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.3",
|
||||
@@ -279,38 +296,33 @@
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz"
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "1.0.3",
|
||||
"from": "has-ansi@^1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-1.0.3.tgz",
|
||||
"version": "2.0.0",
|
||||
"from": "has-ansi@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "1.1.1",
|
||||
"from": "ansi-regex@^1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz"
|
||||
},
|
||||
"get-stdin": {
|
||||
"version": "4.0.1",
|
||||
"from": "get-stdin@^4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
|
||||
"version": "2.0.0",
|
||||
"from": "ansi-regex@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "2.0.1",
|
||||
"from": "strip-ansi@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz",
|
||||
"version": "3.0.0",
|
||||
"from": "strip-ansi@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "1.1.1",
|
||||
"from": "ansi-regex@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz"
|
||||
"version": "2.0.0",
|
||||
"from": "ansi-regex@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "1.3.1",
|
||||
"from": "supports-color@^1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.3.1.tgz"
|
||||
"version": "2.0.0",
|
||||
"from": "supports-color@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -328,7 +340,7 @@
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.12.0",
|
||||
"from": "is-my-json-valid@^2.10.1",
|
||||
"from": "is-my-json-valid@^2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.0.tgz",
|
||||
"dependencies": {
|
||||
"generate-function": {
|
||||
@@ -367,7 +379,7 @@
|
||||
}
|
||||
},
|
||||
"log4js": {
|
||||
"version": "0.6.21",
|
||||
"version": "0.6.25",
|
||||
"from": "https://github.com/CartoDB/log4js-node/tarball/cdb",
|
||||
"resolved": "https://github.com/CartoDB/log4js-node/tarball/cdb",
|
||||
"dependencies": {
|
||||
@@ -401,6 +413,16 @@
|
||||
"from": "inherits@~2.0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "4.3.6",
|
||||
"from": "semver@~4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.8.2",
|
||||
"from": "underscore@1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.2.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -415,9 +437,8 @@
|
||||
"resolved": "https://registry.npmjs.org/queue-async/-/queue-async-1.0.7.tgz"
|
||||
},
|
||||
"redis-mpool": {
|
||||
"version": "0.3.0",
|
||||
"from": "redis-mpool@~0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-mpool/-/redis-mpool-0.3.0.tgz",
|
||||
"version": "0.4.0",
|
||||
"from": "redis-mpool@~0.4.0",
|
||||
"dependencies": {
|
||||
"generic-pool": {
|
||||
"version": "2.1.1",
|
||||
@@ -454,9 +475,9 @@
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.9.203.tgz"
|
||||
},
|
||||
"step": {
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"from": "step@~0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/step/-/step-0.0.5.tgz"
|
||||
"resolved": "https://registry.npmjs.org/step/-/step-0.0.6.tgz"
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.6.0",
|
||||
@@ -464,9 +485,9 @@
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
|
||||
},
|
||||
"windshaft": {
|
||||
"version": "0.43.0",
|
||||
"from": "windshaft@0.43.0",
|
||||
"resolved": "https://registry.npmjs.org/windshaft/-/windshaft-0.43.0.tgz",
|
||||
"version": "0.48.0",
|
||||
"from": "windshaft@0.48.0",
|
||||
"resolved": "https://registry.npmjs.org/windshaft/-/windshaft-0.48.0.tgz",
|
||||
"dependencies": {
|
||||
"chronograph": {
|
||||
"version": "0.1.0",
|
||||
@@ -474,44 +495,9 @@
|
||||
"resolved": "git://github.com/CartoDB/chronographjs.git#0b8c35eee510cfa14a16be24d70533b38ecc1d2d"
|
||||
},
|
||||
"grainstore": {
|
||||
"version": "0.23.0",
|
||||
"from": "grainstore@~0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/grainstore/-/grainstore-0.23.0.tgz",
|
||||
"version": "1.0.0",
|
||||
"from": "grainstore@~1.0.0",
|
||||
"dependencies": {
|
||||
"redis-mpool": {
|
||||
"version": "0.1.0",
|
||||
"from": "https://github.com/CartoDB/node-redis-mpool/tarball/0.1.0",
|
||||
"resolved": "https://github.com/CartoDB/node-redis-mpool/tarball/0.1.0",
|
||||
"dependencies": {
|
||||
"generic-pool": {
|
||||
"version": "2.1.1",
|
||||
"from": "generic-pool@~2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.1.1.tgz"
|
||||
},
|
||||
"redis": {
|
||||
"version": "0.12.1",
|
||||
"from": "redis@~0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-0.12.1.tgz"
|
||||
},
|
||||
"hiredis": {
|
||||
"version": "0.1.17",
|
||||
"from": "hiredis@~0.1.17",
|
||||
"resolved": "https://registry.npmjs.org/hiredis/-/hiredis-0.1.17.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"from": "bindings@*",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "1.1.2",
|
||||
"from": "nan@~1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.1.2.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"carto": {
|
||||
"version": "0.9.5-cdb2",
|
||||
"from": "https://github.com/CartoDB/carto/tarball/0.9.5-cdb2",
|
||||
@@ -579,9 +565,9 @@
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz"
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"from": "json-stringify-safe@~5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.5.2",
|
||||
@@ -594,9 +580,9 @@
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "1.1.0",
|
||||
"version": "2.0.0",
|
||||
"from": "tough-cookie@>=0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-1.1.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "0.1.4",
|
||||
@@ -616,9 +602,9 @@
|
||||
}
|
||||
},
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.2",
|
||||
"from": "async@~0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2307,8 +2293,8 @@
|
||||
},
|
||||
"tilelive-mapnik": {
|
||||
"version": "0.6.15",
|
||||
"from": "https://github.com/CartoDB/tilelive-mapnik/tarball/cdb",
|
||||
"resolved": "https://github.com/CartoDB/tilelive-mapnik/tarball/cdb",
|
||||
"from": "https://github.com/CartoDB/tilelive-mapnik/tarball/upgrade-mapnik",
|
||||
"resolved": "https://github.com/CartoDB/tilelive-mapnik/tarball/upgrade-mapnik",
|
||||
"dependencies": {
|
||||
"generic-pool": {
|
||||
"version": "2.1.1",
|
||||
@@ -2317,15 +2303,15 @@
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.2.11",
|
||||
"from": "mime@~1.2.9",
|
||||
"from": "mime@~1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mapnik": {
|
||||
"version": "1.4.15-cdb1",
|
||||
"from": "https://github.com/CartoDB/node-mapnik/tarball/1.4.15-cdb1",
|
||||
"resolved": "https://github.com/CartoDB/node-mapnik/tarball/1.4.15-cdb1",
|
||||
"version": "1.4.15-cdb2",
|
||||
"from": "https://github.com/CartoDB/node-mapnik/tarball/1.4.15-cdb2",
|
||||
"resolved": "https://github.com/CartoDB/node-mapnik/tarball/1.4.15-cdb2",
|
||||
"dependencies": {
|
||||
"nan": {
|
||||
"version": "1.2.0",
|
||||
@@ -2817,16 +2803,16 @@
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
|
||||
},
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.2",
|
||||
"from": "async@~0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"from": "json-stringify-safe@~5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "1.0.2",
|
||||
@@ -2844,14 +2830,14 @@
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz"
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.1",
|
||||
"from": "tunnel-agent@~0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "1.1.0",
|
||||
"version": "2.0.0",
|
||||
"from": "tough-cookie@>=0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-1.1.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "0.10.1",
|
||||
@@ -2933,8 +2919,8 @@
|
||||
},
|
||||
"abaculus": {
|
||||
"version": "1.1.0",
|
||||
"from": "https://github.com/CartoDB/abaculus/tarball/cdb",
|
||||
"resolved": "https://github.com/CartoDB/abaculus/tarball/cdb"
|
||||
"from": "https://github.com/CartoDB/abaculus/tarball/upgrade-mapnik",
|
||||
"resolved": "https://github.com/CartoDB/abaculus/tarball/upgrade-mapnik"
|
||||
},
|
||||
"sphericalmercator": {
|
||||
"version": "1.0.2",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.3.0",
|
||||
"version": "2.9.0",
|
||||
"description": "A map tile server for CartoDB",
|
||||
"keywords": [
|
||||
"cartodb"
|
||||
@@ -24,14 +24,14 @@
|
||||
"dependencies": {
|
||||
"underscore" : "~1.6.0",
|
||||
"dot": "~1.0.2",
|
||||
"windshaft": "0.43.0",
|
||||
"windshaft": "0.48.0",
|
||||
"step": "~0.0.5",
|
||||
"queue-async": "~1.0.7",
|
||||
"request": "~2.9.203",
|
||||
"cartodb-redis": "~0.13.0",
|
||||
"cartodb-psql": "~0.4.0",
|
||||
"fastly-purge": "~1.0.0",
|
||||
"redis-mpool": "~0.3.0",
|
||||
"redis-mpool": "~0.4.0",
|
||||
"lzma": "~1.3.7",
|
||||
"log4js": "https://github.com/CartoDB/log4js-node/tarball/cdb"
|
||||
},
|
||||
|
||||
@@ -174,7 +174,7 @@ describe('render limits', function() {
|
||||
},
|
||||
function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.deepEqual(parsed, { error: 'Render timed out' });
|
||||
assert.deepEqual(parsed, { errors: ['Render timed out'] });
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -69,6 +69,7 @@ suite(suiteName, function() {
|
||||
assert.equal(parsedBody.last_updated, expected_last_updated);
|
||||
if ( expected_token ) {
|
||||
assert.equal(parsedBody.layergroupid, expected_token + ':' + expected_last_updated_epoch);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsedBody.layergroupid);
|
||||
}
|
||||
else expected_token = parsedBody.layergroupid.split(':')[0];
|
||||
next(null, res);
|
||||
@@ -131,7 +132,7 @@ suite(suiteName, function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 403, res.statusCode + ':' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
var msg = parsed.error; // TODO: should it be "errors" ?
|
||||
var msg = parsed.errors[0];
|
||||
assert.ok(msg.match(/permission denied/i), msg);
|
||||
next(err);
|
||||
});
|
||||
@@ -1011,6 +1012,7 @@ suite(suiteName, function() {
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
if ( expected_token ) {
|
||||
assert.equal(parsedBody.layergroupid, expected_token + ':' + expected_last_updated_epoch);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsedBody.layergroupid);
|
||||
}
|
||||
else {
|
||||
var token_components = parsedBody.layergroupid.split(':');
|
||||
@@ -1091,6 +1093,7 @@ suite(suiteName, function() {
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
if ( expected_token ) {
|
||||
assert.equal(parsedBody.layergroupid, expected_token + ':' + expected_last_updated_epoch);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsedBody.layergroupid);
|
||||
}
|
||||
else {
|
||||
var token_components = parsedBody.layergroupid.split(':');
|
||||
|
||||
@@ -108,6 +108,7 @@ describe('tests from old api translated to multilayer', function() {
|
||||
function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.layergroupid);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
done();
|
||||
}
|
||||
);
|
||||
@@ -128,6 +129,7 @@ describe('tests from old api translated to multilayer', function() {
|
||||
function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.layergroupid);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
|
||||
global.environment.postgres.host = backupDBHost;
|
||||
done();
|
||||
@@ -150,6 +152,7 @@ describe('tests from old api translated to multilayer', function() {
|
||||
function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.layergroupid);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
|
||||
global.environment.postgres_auth_pass = backupDBPass;
|
||||
done();
|
||||
@@ -246,6 +249,43 @@ describe('tests from old api translated to multilayer', function() {
|
||||
assert.ok(res.headers.hasOwnProperty('x-cache-channel'));
|
||||
assert.equal(res.headers['x-cache-channel'], expectedCacheChannel);
|
||||
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// https://github.com/CartoDB/cartodb-postgresql/issues/86
|
||||
it.skip("should not fail with long table names because table name length limit", function(done) {
|
||||
var tableName = 'long_table_name_with_enough_chars_to_break_querytables_function';
|
||||
var expectedCacheChannel = _.template('<%= databaseName %>:public.<%= tableName %>', {
|
||||
databaseName: _.template(global.environment.postgres_auth_user, {user_id:1}) + '_db',
|
||||
tableName: tableName
|
||||
});
|
||||
|
||||
var layergroup = singleLayergroupConfig('select * from ' + tableName, '#layer { marker-fill: red; }');
|
||||
|
||||
assert.response(server,
|
||||
{
|
||||
url: layergroupUrl + '?config=' + encodeURIComponent(JSON.stringify(layergroup)),
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'localhost'
|
||||
}
|
||||
},
|
||||
{
|
||||
status: 200
|
||||
},
|
||||
function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.layergroupid);
|
||||
|
||||
assert.ok(res.headers.hasOwnProperty('x-cache-channel'));
|
||||
assert.equal(res.headers['x-cache-channel'], expectedCacheChannel);
|
||||
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -44,6 +44,7 @@ describe('named_layers', function() {
|
||||
},
|
||||
layergroup: {
|
||||
layers: [
|
||||
wadusLayer,
|
||||
wadusLayer
|
||||
]
|
||||
}
|
||||
@@ -634,6 +635,88 @@ describe('named_layers', function() {
|
||||
|
||||
});
|
||||
|
||||
it('should return metadata for named layers', function(done) {
|
||||
|
||||
var layergroup = {
|
||||
version: '1.3.0',
|
||||
layers: [
|
||||
{
|
||||
type: 'plain',
|
||||
options: {
|
||||
color: '#fabada'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: 'select * from test_table',
|
||||
cartocss: '#layer { marker-fill: #cc3300; }',
|
||||
cartocss_version: '2.3.0'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'named',
|
||||
options: {
|
||||
name: templateName
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'torque',
|
||||
options: {
|
||||
sql: "select * from test_table LIMIT 0",
|
||||
cartocss: "Map { -torque-frame-count:1; -torque-resolution:1; " +
|
||||
"-torque-aggregation-function:'count(*)'; -torque-time-attribute:'updated_at'; }"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
step(
|
||||
function createLayergroup() {
|
||||
var next = this;
|
||||
assert.response(server,
|
||||
{
|
||||
url: '/api/v1/map',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
host: 'localhost',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: JSON.stringify(layergroup)
|
||||
},
|
||||
{
|
||||
status: 200
|
||||
},
|
||||
function(res, err) {
|
||||
next(err, res);
|
||||
}
|
||||
);
|
||||
},
|
||||
function checkLayergroup(err, response) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var parsedBody = JSON.parse(response.body);
|
||||
assert.ok(parsedBody.metadata);
|
||||
assert.ok(parsedBody.metadata.layers);
|
||||
assert.equal(parsedBody.metadata.layers.length, 5);
|
||||
assert.equal(parsedBody.metadata.layers[0].type, 'plain');
|
||||
assert.equal(parsedBody.metadata.layers[1].type, 'mapnik');
|
||||
assert.equal(parsedBody.metadata.layers[2].type, 'mapnik');
|
||||
assert.equal(parsedBody.metadata.layers[3].type, 'mapnik');
|
||||
assert.equal(parsedBody.metadata.layers[4].type, 'torque');
|
||||
|
||||
return null;
|
||||
},
|
||||
function finish(err) {
|
||||
done(err);
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
after(function(done) {
|
||||
global.environment.enabledFeatures = {cdbQueryTablesFromPostgres: false};
|
||||
|
||||
@@ -88,8 +88,8 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 403);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'), res.body);
|
||||
err = parsed.error;
|
||||
assert.ok(parsed.hasOwnProperty('errors'), res.body);
|
||||
err = parsed.errors[0];
|
||||
assert.ok(err.match(/only.*authenticated.*user/i),
|
||||
'Unexpected error response: ' + err);
|
||||
post_request_1.url += '?api_key=1234';
|
||||
@@ -113,9 +113,9 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.error.match(/already exists/i),
|
||||
'Unexpected error for pre-existing template name: ' + parsedBody.error);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
assert.ok(parsedBody.errors[0].match(/already exists/i),
|
||||
'Unexpected error for pre-existing template name: ' + parsedBody.errors);
|
||||
return null;
|
||||
},
|
||||
function finish(err) {
|
||||
@@ -172,10 +172,10 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
var re = /invalid.*authentication.*missing/i;
|
||||
assert.ok(parsedBody.error.match(re),
|
||||
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.error);
|
||||
assert.ok(parsedBody.errors[0].match(re),
|
||||
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.errors);
|
||||
return null;
|
||||
},
|
||||
function postTemplate2(err)
|
||||
@@ -202,10 +202,10 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
var re = new RegExp(/invalid.*authentication.*missing/i);
|
||||
assert.ok(parsedBody.error.match(re),
|
||||
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.error);
|
||||
assert.ok(parsedBody.errors[0].match(re),
|
||||
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.errors);
|
||||
return null;
|
||||
},
|
||||
function postTemplateValid(err)
|
||||
@@ -253,12 +253,12 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.statusCode + ": " + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
var re = /invalid.*authentication.*missing/i;
|
||||
assert.ok(parsed.error.match(re),
|
||||
assert.ok(parsed.errors[0].match(re),
|
||||
'Error for invalid authentication on PUT does not match ' +
|
||||
re + ': ' + parsed.error);
|
||||
re + ': ' + parsed.errors);
|
||||
var del_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?api_key=1234',
|
||||
method: 'DELETE',
|
||||
@@ -425,9 +425,9 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 403, res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
'Missing error from response: ' + res.body);
|
||||
err = parsed.error;
|
||||
err = parsed.errors[0];
|
||||
assert.ok(err.match(/authenticated user/), err);
|
||||
var next = this;
|
||||
var get_request = {
|
||||
@@ -523,9 +523,9 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.statusCode + ": " + res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.error.match(/cannot update name/i),
|
||||
'Unexpected error for invalid update: ' + parsedBody.error);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
assert.ok(parsedBody.errors[0].match(/cannot update name/i),
|
||||
'Unexpected error for invalid update: ' + parsedBody.errors);
|
||||
var put_request = {
|
||||
url: '/api/v1/map/named/unexistent/?api_key=1234',
|
||||
method: 'PUT',
|
||||
@@ -541,9 +541,9 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 400, res.statusCode + ": " + res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.error.match(/cannot update name/i),
|
||||
'Unexpected error for invalid update: ' + parsedBody.error);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
assert.ok(parsedBody.errors[0].match(/cannot update name/i),
|
||||
'Unexpected error for invalid update: ' + parsedBody.errors);
|
||||
var put_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '/?api_key=1234',
|
||||
method: 'PUT',
|
||||
@@ -630,9 +630,9 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 403, res.statusCode + ": " + res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
|
||||
assert.ok(parsedBody.error.match(/only.*authenticated.*user/i),
|
||||
'Unexpected error for unauthenticated template get: ' + parsedBody.error);
|
||||
assert.ok(parsedBody.hasOwnProperty('errors'), res.body);
|
||||
assert.ok(parsedBody.errors[0].match(/only.*authenticated.*user/i),
|
||||
'Unexpected error for unauthenticated template get: ' + parsedBody.errors);
|
||||
var get_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?api_key=1234',
|
||||
method: 'GET',
|
||||
@@ -735,10 +735,10 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 403, res.statusCode + ": " + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/only.*authenticated.*user/i),
|
||||
'Unexpected error for unauthenticated template get: ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/only.*authenticated.*user/i),
|
||||
'Unexpected error for unauthenticated template get: ' + parsed.errors);
|
||||
var del_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?api_key=1234',
|
||||
method: 'DELETE',
|
||||
@@ -767,10 +767,10 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 404, res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/cannot find/i),
|
||||
'Unexpected error for missing template: ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/cannot find/i),
|
||||
'Unexpected error for missing template: ' + parsed.errors);
|
||||
return null;
|
||||
},
|
||||
function finish(err) {
|
||||
@@ -863,10 +863,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Unexpected success instanciating template with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.errors);
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?auth_token=valid2',
|
||||
method: 'POST',
|
||||
@@ -882,8 +882,8 @@ describe('template_api', function() {
|
||||
if ( err ) throw err;
|
||||
assert.equal(res.statusCode, 404, res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'), "Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/not found/i), 'Unexpected error for forbidden instance : ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'), "Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/not found/i), 'Unexpected error for forbidden instance : ' + parsed.errors);
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?auth_token=valid2',
|
||||
method: 'POST',
|
||||
@@ -922,10 +922,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Fetching tile with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/permission denied/i),
|
||||
'Unexpected error for unauthorized instance (expected /permission denied/): ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/permission denied/i),
|
||||
'Unexpected error for unauthorized instance (expected /permission denied/): ' + parsed.errors);
|
||||
var get_request = {
|
||||
url: '/api/v1/map/' + layergroupid + '/0/0/0.png?auth_token=valid1',
|
||||
method: 'GET',
|
||||
@@ -962,10 +962,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Unexpected error for authorized instance: ' + res.statusCode + ' -- ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/cannot use/i),
|
||||
'Unexpected error for unauthorized instance (expected /cannot use/): ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/cannot use/i),
|
||||
'Unexpected error for unauthorized instance (expected /cannot use/): ' + parsed.errors);
|
||||
return null;
|
||||
},
|
||||
function deleteTemplate(err)
|
||||
@@ -1089,10 +1089,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Unexpected success instanciating template with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.errors);
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?auth_token=valid2',
|
||||
method: 'POST',
|
||||
@@ -1131,10 +1131,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Fetching tile with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/permission denied/i),
|
||||
'Unexpected error for unauthorized instance (expected /permission denied): ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/permission denied/i),
|
||||
'Unexpected error for unauthorized instance (expected /permission denied): ' + parsed.errors);
|
||||
var get_request = {
|
||||
url: '/api/v1/map/' + layergroupid + ':cb1/0/0/0/0.json.torque?auth_token=valid1',
|
||||
method: 'GET',
|
||||
@@ -1297,10 +1297,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Unexpected success instanciating template with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/unauthorized/i),
|
||||
'Unexpected error for unauthorized instance : ' + parsed.errors);
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named/' + tpl_id + '?auth_token=valid2',
|
||||
method: 'POST',
|
||||
@@ -1321,6 +1321,7 @@ describe('template_api', function() {
|
||||
layergroupid = parsed.layergroupid;
|
||||
assert.ok(layergroupid.match(/^localhost@/),
|
||||
"Returned layergroupid does not start with signer name: " + layergroupid);
|
||||
assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid);
|
||||
assert.ok(parsed.hasOwnProperty('last_updated'),
|
||||
"Missing 'last_updated' from response body: " + res.body);
|
||||
// TODO: check value of last_updated ?
|
||||
@@ -1339,10 +1340,10 @@ describe('template_api', function() {
|
||||
assert.equal(res.statusCode, 403,
|
||||
'Fetching tile with no auth: ' + res.statusCode + ': ' + res.body);
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(parsed.hasOwnProperty('error'),
|
||||
"Missing 'error' from response body: " + res.body);
|
||||
assert.ok(parsed.error.match(/permission denied/i),
|
||||
'Unexpected error for unauthorized getAttributes (expected /permission denied/): ' + parsed.error);
|
||||
assert.ok(parsed.hasOwnProperty('errors'),
|
||||
"Missing 'errors' from response body: " + res.body);
|
||||
assert.ok(parsed.errors[0].match(/permission denied/i),
|
||||
'Unexpected error for unauthorized getAttributes (expected /permission denied/): ' + parsed.errors);
|
||||
var get_request = {
|
||||
url: '/api/v1/map/' + layergroupid + ':cb1/0/attributes/5?auth_token=valid2',
|
||||
method: 'GET',
|
||||
@@ -1608,7 +1609,6 @@ describe('template_api', function() {
|
||||
function checkInstanciation(err, res)
|
||||
{
|
||||
if ( err ) throw err;
|
||||
console.log(err, res.body, res.headers);
|
||||
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
||||
// See https://github.com/CartoDB/Windshaft-cartodb/issues/176
|
||||
helper.checkCache(res);
|
||||
@@ -2072,7 +2072,7 @@ describe('template_api', function() {
|
||||
return done(err);
|
||||
}
|
||||
assert.deepEqual(JSON.parse(res.body), {
|
||||
error: "Invalid or nonexistent map configuration token '" + nonexistentToken + "'"
|
||||
errors: ["Invalid or nonexistent map configuration token '" + nonexistentToken + "'"]
|
||||
});
|
||||
|
||||
done();
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
--
|
||||
-- Requires PostgreSQL 9.x+
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION CDB_QueryTables(query text)
|
||||
RETURNS name[]
|
||||
CREATE OR REPLACE FUNCTION CDB_QueryTablesText(query text)
|
||||
RETURNS text[]
|
||||
AS $$
|
||||
DECLARE
|
||||
exp XML;
|
||||
tables NAME[];
|
||||
tables text[];
|
||||
rec RECORD;
|
||||
rec2 RECORD;
|
||||
BEGIN
|
||||
@@ -41,11 +41,11 @@ BEGIN
|
||||
xpath('//x:Relation-Name/text()', exp, ARRAY[ARRAY['x', 'http://www.postgresql.org/2009/explain']]) as x,
|
||||
xpath('//x:Relation-Name/../x:Schema/text()', exp, ARRAY[ARRAY['x', 'http://www.postgresql.org/2009/explain']]) as s
|
||||
)
|
||||
SELECT unnest(x)::name as p, unnest(s)::name as sc from inp
|
||||
SELECT unnest(x) as p, unnest(s) as sc from inp
|
||||
LOOP
|
||||
-- RAISE DEBUG 'tab: %', rec2.p;
|
||||
-- RAISE DEBUG 'sc: %', rec2.sc;
|
||||
tables := array_append(tables, (rec2.sc || '.' || rec2.p)::name);
|
||||
tables := array_append(tables, (rec2.sc || '.' || rec2.p));
|
||||
END LOOP;
|
||||
|
||||
-- RAISE DEBUG 'Tables: %', tables;
|
||||
@@ -65,3 +65,14 @@ BEGIN
|
||||
return tables;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
|
||||
|
||||
|
||||
-- Keep CDB_QueryTables with same signature for backwards compatibility.
|
||||
-- It should probably be removed in the future.
|
||||
CREATE OR REPLACE FUNCTION CDB_QueryTables(query text)
|
||||
RETURNS name[]
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN CDB_QueryTablesText(query)::name[];
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
|
||||
|
||||
@@ -189,3 +189,31 @@ INSERT INTO CDB_TableMetadata (tabname, updated_at) VALUES ('test_table_private_
|
||||
|
||||
-- GRANT SELECT ON CDB_TableMetadata TO :PUBLICUSER;
|
||||
GRANT SELECT ON CDB_TableMetadata TO :TESTUSER;
|
||||
|
||||
-- long name table
|
||||
CREATE TABLE
|
||||
long_table_name_with_enough_chars_to_break_querytables_function
|
||||
(
|
||||
updated_at timestamp without time zone DEFAULT now(),
|
||||
created_at timestamp without time zone DEFAULT now(),
|
||||
cartodb_id integer NOT NULL,
|
||||
name character varying,
|
||||
address character varying,
|
||||
the_geom geometry,
|
||||
the_geom_webmercator geometry
|
||||
);
|
||||
|
||||
INSERT INTO long_table_name_with_enough_chars_to_break_querytables_function SELECT * from test_table;
|
||||
|
||||
ALTER TABLE ONLY long_table_name_with_enough_chars_to_break_querytables_function
|
||||
ADD CONSTRAINT long_table_name_with_enough_chars_to_break_querytables_func_pkey PRIMARY KEY (cartodb_id);
|
||||
|
||||
CREATE INDEX long_table_name_the_geom_idx
|
||||
ON long_table_name_with_enough_chars_to_break_querytables_function USING gist (the_geom);
|
||||
CREATE INDEX long_table_name_the_geom_webmercator_idx
|
||||
ON long_table_name_with_enough_chars_to_break_querytables_function USING gist (the_geom_webmercator);
|
||||
|
||||
GRANT ALL ON TABLE long_table_name_with_enough_chars_to_break_querytables_function TO :TESTUSER;
|
||||
GRANT SELECT ON TABLE long_table_name_with_enough_chars_to_break_querytables_function TO :PUBLICUSER;
|
||||
|
||||
INSERT INTO CDB_TableMetadata (tabname, updated_at) VALUES ('long_table_name_with_enough_chars_to_break_querytables_function'::regclass, '2009-02-13T23:31:30.123Z');
|
||||
|
||||
@@ -59,30 +59,50 @@ describe('template_maps', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('does not accept template with invalid name', function(done) {
|
||||
var tmap = new TemplateMaps(redis_pool);
|
||||
assert.ok(tmap);
|
||||
var tpl = { version:'0.0.1',
|
||||
auth: {}, layergroup: {layers:[wadusLayer]} };
|
||||
var invalidnames = [ "ab|", "a b", "a@b", "1ab", "_x", "", " x", "x " ];
|
||||
var testNext = function() {
|
||||
if ( ! invalidnames.length ) { done(); return; }
|
||||
var n = invalidnames.pop();
|
||||
tpl.name = n;
|
||||
tmap.addTemplate('me', tpl, function(err) {
|
||||
if ( ! err ) {
|
||||
done(new Error("Unexpected success with invalid name '" + n + "'"));
|
||||
describe('naming', function() {
|
||||
|
||||
function createTemplate(name) {
|
||||
return {
|
||||
version:'0.0.1',
|
||||
name: name,
|
||||
auth: {},
|
||||
layergroup: {
|
||||
layers: [
|
||||
wadusLayer
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
else if ( ! err.message.match(/template.*name/i) ) {
|
||||
done(new Error("Unexpected error message with invalid name '" + n + "': " + err));
|
||||
}
|
||||
else {
|
||||
testNext();
|
||||
}
|
||||
});
|
||||
};
|
||||
testNext();
|
||||
});
|
||||
var templateMaps = new TemplateMaps(redis_pool);
|
||||
|
||||
var invalidNames = [ "ab|", "a b", "a@b", "-1ab", "_x", "", " x", "x " ];
|
||||
invalidNames.forEach(function(invalidName) {
|
||||
it('should NOT accept template with invalid name: ' + invalidName, function(done) {
|
||||
templateMaps.addTemplate('me', createTemplate(invalidName), function(err) {
|
||||
assert.ok(err, "Unexpected success with invalid name '" + invalidName + "'");
|
||||
assert.ok(
|
||||
err.message.match(/template.*name/i),
|
||||
"Unexpected error message with invalid name '" + invalidName + "': " + err.message
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var validNames = [
|
||||
"AB", "1ab", "DFD19A1A-0AC6-11E5-B0CA-6476BA93D4F6", "25ad8300-0ac7-11e5-b93f-6476ba93d4f6"
|
||||
];
|
||||
validNames.forEach(function(validName) {
|
||||
it('should accept template with valid name: ' + validName, function(done) {
|
||||
templateMaps.addTemplate('me', createTemplate(validName), function(err) {
|
||||
assert.ok(!err, "Unexpected error with valid name '" + validName + "': " + err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
it('does not accept template with invalid placeholder name', function(done) {
|
||||
var tmap = new TemplateMaps(redis_pool);
|
||||
|
||||
8
tools/README.md
Normal file
8
tools/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
Deprecated tools
|
||||
================
|
||||
|
||||
All tools and scripts found in this directory are deprecated and no longer maintained.
|
||||
|
||||
Use at your own peril.
|
||||
|
||||
In future releases they might get removed.
|
||||
Reference in New Issue
Block a user