Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CARTO: Remove mapsUrl #8308

Merged
merged 12 commits into from
Nov 29, 2023
65 changes: 48 additions & 17 deletions modules/carto/src/api/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,68 @@ import {MapType} from './types';

export type V3Endpoint = 'maps' | 'stats' | 'sql';

function buildUrlFromBase(apiBaseUrl: string, endpoint: V3Endpoint) {
let suffix = `/v3/${endpoint}`;
if (apiBaseUrl.endsWith('/')) {
suffix = suffix.substring(1);
}

return `${apiBaseUrl}${suffix}`;
function joinPath(...args: string[]): string {
return args.map(part => (part.endsWith('/') ? part.slice(0, -1) : part)).join('/');
}

export function buildMapsUrlFromBase(apiBaseUrl: string): string {
return buildUrlFromBase(apiBaseUrl, 'maps');
function buildV3Path(
apiBaseUrl: string,
version: 'v3',
endpoint: V3Endpoint,
...rest: string[]
): string {
return joinPath(apiBaseUrl, version, endpoint, ...rest);
}

export function buildStatsUrlFromBase(apiBaseUrl: string): string {
return buildUrlFromBase(apiBaseUrl, 'stats');
export function buildPublicMapUrl({
apiBaseUrl,
cartoMapId
}: {
apiBaseUrl: string;
cartoMapId: string;
}): string {
return buildV3Path(apiBaseUrl, 'v3', 'maps', 'public', cartoMapId);
}

export function buildQueryUrlFromBase(apiBaseUrl: string): string {
return buildUrlFromBase(apiBaseUrl, 'sql');
export function buildStatsUrl({
attribute,
apiBaseUrl,
connectionName,
source,
type
}: {
attribute: string;
apiBaseUrl: string;
connectionName: string;
source: string;
type: MapType;
}): string {
if (type === 'query') {
return buildV3Path(apiBaseUrl, 'v3', 'stats', connectionName, attribute);
}

// type === 'table'
return buildV3Path(apiBaseUrl, 'v3', 'stats', connectionName, source, attribute);
}

export function buildSourceUrl({
apiBaseUrl,
connectionName,
endpoint,
mapsUrl
endpoint
}: {
apiBaseUrl: string;
connectionName: string;
endpoint: MapType;
mapsUrl?: string;
}): string {
return `${mapsUrl || buildMapsUrlFromBase(apiBaseUrl)}/${connectionName}/${endpoint}`;
return buildV3Path(apiBaseUrl, 'v3', 'maps', connectionName, endpoint);
}

export function buildQueryUrl({
apiBaseUrl,
connectionName
}: {
apiBaseUrl: string;
connectionName: string;
}): string {
return buildV3Path(apiBaseUrl, 'v3', 'sql', connectionName, 'query');
}
31 changes: 13 additions & 18 deletions modules/carto/src/api/fetch-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import {CartoAPIError} from './carto-api-error';
import {DEFAULT_API_BASE_URL, DEFAULT_CLIENT} from './common';
import {buildMapsUrlFromBase, buildStatsUrlFromBase} from './endpoints';
import {buildPublicMapUrl, buildStatsUrl} from './endpoints';
import {
GeojsonResult,
JsonResult,
Expand Down Expand Up @@ -108,26 +108,23 @@ async function _fetchMapDataset(
}

async function _fetchTilestats(
attribute,
attribute: string,
dataset: Dataset,
accessToken: string,
apiBaseUrl: string
) {
const {connectionName: connection, data, id, source, type, queryParameters} = dataset;
const errorContext: APIErrorContext = {requestType: 'Tile stats', connection, type, source};
const {connectionName, data, id, source, type, queryParameters} = dataset;
const errorContext: APIErrorContext = {
requestType: 'Tile stats',
connection: connectionName,
type,
source
};
if (!('tilestats' in data)) {
throw new CartoAPIError(new Error(`Invalid dataset for tilestats: ${id}`), errorContext);
}

const statsUrl = buildStatsUrlFromBase(apiBaseUrl);
let baseUrl = `${statsUrl}/${connection}/`;
if (type === 'query') {
baseUrl += attribute;
} else {
// MAP_TYPE.TABLE
baseUrl += `${source}/${attribute}`;
}

const baseUrl = buildStatsUrl({attribute, apiBaseUrl, ...dataset});
const headers = {Authorization: `Bearer ${accessToken}`};
const parameters: Record<string, string> = {};
if (type === 'query') {
Expand Down Expand Up @@ -166,7 +163,7 @@ async function fillInTileStats(
{datasets, keplerMapConfig, token}: {datasets: Dataset[]; keplerMapConfig: any; token: string},
apiBaseUrl: string
) {
const attributes: {attribute?: string; dataset?: any}[] = [];
const attributes: {attribute: string; dataset: any}[] = [];
const {layers} = keplerMapConfig.config.visState;
for (const layer of layers) {
for (const channel of Object.keys(layer.visualChannels)) {
Expand All @@ -181,7 +178,7 @@ async function fillInTileStats(
}
}
// Remove duplicates to avoid repeated requests
const filteredAttributes: {attribute?: string; dataset?: any}[] = [];
const filteredAttributes: {attribute: string; dataset: any}[] = [];
for (const a of attributes) {
if (
!filteredAttributes.find(
Expand All @@ -203,7 +200,6 @@ export type FetchMapOptions = {
cartoMapId: string;
clientId?: string;
headers?: Record<string, string>;
mapsUrl?: string;
autoRefresh?: number;
onNewData?: (map: any) => void;
};
Expand All @@ -214,7 +210,6 @@ export async function fetchMap({
cartoMapId,
clientId = DEFAULT_CLIENT,
headers = {},
mapsUrl,
autoRefresh,
onNewData
}: FetchMapOptions) {
Expand All @@ -230,7 +225,7 @@ export async function fetchMap({
);
}

const baseUrl = `${mapsUrl || buildMapsUrlFromBase(apiBaseUrl)}/public/${cartoMapId}`;
const baseUrl = buildPublicMapUrl({apiBaseUrl, cartoMapId});
const errorContext: APIErrorContext = {requestType: 'Public map', mapId: cartoMapId};
const map = await requestWithParameters({baseUrl, headers, errorContext});

Expand Down
12 changes: 8 additions & 4 deletions modules/carto/src/api/query.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import {SOURCE_DEFAULTS} from '../sources';
import type {SourceOptions, QuerySourceOptions, QueryResult} from '../sources/types';
import {buildQueryUrlFromBase} from './endpoints';
import {buildQueryUrl} from './endpoints';
import {requestWithParameters} from './request-with-parameters';
import {APIErrorContext} from './types';

export type QueryOptions = SourceOptions & Omit<QuerySourceOptions, 'spatialDataColumn'>;
type UrlParameters = {q: string; queryParameters?: string};

export const query = async function (options: QueryOptions): Promise<QueryResult> {
const {apiBaseUrl, connectionName, sqlQuery, queryParameters} = options;
const {
apiBaseUrl = SOURCE_DEFAULTS.apiBaseUrl,
connectionName,
sqlQuery,
queryParameters
} = options;
const urlParameters: UrlParameters = {q: sqlQuery};

if (queryParameters) {
urlParameters.queryParameters = JSON.stringify(queryParameters);
}

const queryUrl = buildQueryUrlFromBase(apiBaseUrl || SOURCE_DEFAULTS.apiBaseUrl);
const baseUrl = `${queryUrl}/${connectionName}/query`;
const baseUrl = buildQueryUrl({apiBaseUrl, connectionName});
const headers = {Authorization: `Bearer ${options.accessToken}`, ...options.headers};

const errorContext: APIErrorContext = {
Expand Down
1 change: 0 additions & 1 deletion modules/carto/src/sources/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export type SourceOptionalOptions = {
/** @deprecated use `query` instead **/
format: Format;
headers: Record<string, string>;
mapsUrl?: string;
};

export type SourceOptions = SourceRequiredOptions & Partial<SourceOptionalOptions>;
Expand Down
17 changes: 12 additions & 5 deletions test/apps/carto-dynamic-tile/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,22 @@ function Root() {
}

function useBoundaryLayer(datasource) {
const {getFillColor, source, boundaryId, columns, matchingColumn, sqlQuery, tableName} =
datasource;
const {
getFillColor,
source,
tilesetTableName,
columns,
matchingColumn,
propertiesSqlQuery,
propertiesTableName
} = datasource;
const tilejson = source({
...globalOptions,
boundaryId,
tilesetTableName,
columns,
matchingColumn,
tableName,
sqlQuery
propertiesTableName,
propertiesSqlQuery
});

return new VectorTileLayer({
Expand Down
18 changes: 4 additions & 14 deletions test/apps/carto-dynamic-tile/datasets.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
boundaryQuerySource,
boundaryTableSource,
boundaryTilesetSource,
h3TilesetSource,
h3TableSource,
h3QuerySource,
Expand All @@ -18,9 +17,9 @@ import {
export default {
'boundary-query': {
source: boundaryQuerySource,
boundaryId: 'usa_pos4',
tilesetTableName: 'carto-boundaries.us.usa_zip_code_v1',
matchingColumn: 'geoid',
sqlQuery:
propertiesSqlQuery:
'select * from `cartodb-on-gcp-backend-team.juanra.geography_usa_zcta5_2019_clustered`',
getFillColor: colorBins({
// TODO remove parseFloat, only needed as binary format encodes as strings
Expand All @@ -31,25 +30,16 @@ export default {
},
'boundary-table': {
source: boundaryTableSource,
boundaryId: 'usa_pos4',
tilesetTableName: 'carto-boundaries.us.usa_zip_code_v1',
matchingColumn: 'geoid',
columns: ['do_label', 'do_perimeter'],
tableName: 'cartodb-on-gcp-backend-team.juanra.geography_usa_zcta5_2019_clustered',
propertiesTableName: 'cartodb-on-gcp-backend-team.juanra.geography_usa_zcta5_2019_clustered',
getFillColor: colorBins({
attr: d => parseFloat(d!.properties!['do_perimeter']),
domain: [0, 1, 5, 10, 25, 50, 100].map(n => 10000 * n),
colors: 'Purp'
})
},
'boundary-tileset': {
source: boundaryTilesetSource,
boundaryId: 'usa_pos4',
getFillColor: colorBins({
attr: d => parseFloat(d!.properties!['do_perimeter']),
domain: [0, 1, 5, 10, 25, 50, 100].map(n => 10000 * n),
colors: 'Burg'
})
},
'h3-query': {
source: h3QuerySource,
sqlQuery:
Expand Down
Loading