Skip to content

Commit

Permalink
Parameterize UrlDefinedSource construction with the URL authority part
Browse files Browse the repository at this point in the history
Allows the associated Dataset and Narrative subclasses to be simpler and
similar to other sources by using source.baseUrl.
  • Loading branch information
tsibley committed Apr 8, 2021
1 parent 8db5659 commit 610c877
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 36 deletions.
11 changes: 11 additions & 0 deletions src/getDatasetHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ const splitPrefixIntoParts = (prefix) => {
source = new Source(...prefixParts.splice(0, 2));
break;

// UrlDefined source requires a URL authority part
case "fetch":
source = new Source(prefixParts.shift());
break;

default:
source = new Source();
}
Expand Down Expand Up @@ -102,6 +107,12 @@ const joinPartsIntoPrefix = ({source, prefixParts, isNarrative = false}) => {
case "community":
leadingParts.push(source.owner, source.repoNameWithBranch);
break;

// UrlDefined source requires a URL authority part
case "fetch":
leadingParts.push(source.authority);
break;

// no default
}

Expand Down
56 changes: 20 additions & 36 deletions src/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,19 @@ class CommunityNarrative extends Narrative {


class UrlDefinedSource extends Source {

static get _name() { return "fetch"; }
get baseUrl() {
throw new Error("UrlDefinedSource does not use `this.baseUrl`");

constructor(authority) {
super();

if (!authority) throw new Error(`Cannot construct a ${this.constructor.name} without a URL authority`);

this.authority = authority;
}

get baseUrl() {
return `https://${this.authority}`;
}
dataset(pathParts) {
return new UrlDefinedDataset(this, pathParts);
}
Expand All @@ -316,49 +323,26 @@ class UrlDefinedSource extends Source {
}

class UrlDefinedDataset extends Dataset {
get baseParts() {
return this.pathParts;
}
get isRequestValidWithoutDataset() {
return false;
}
baseNameFor(type) {
// mandate https
const datasetUrl = "https://" + this.baseParts.join("/");
if (type==="main") {
return datasetUrl;
}
// if the request is for A.json, then return A_<type>.json.
if (datasetUrl.endsWith(".json")) {
return `${datasetUrl.replace(/\.json$/, '')}_${type}.json`;
const baseName = this.baseParts.join("/");

if (type === "main") {
return baseName;
}
// if the request if for B, where B doesn't end with `.json`, then return B_<type>
return `${datasetUrl}_${type}`;
}
urlFor(type) {
// when `parsePrefix()` runs (which it does for each /charon/getDataset API request), it preemtively defines
// a `urlFor` tree, meta and main types. For `UrlDefinedDataset`s we can only serve v2 datasets, but be aware
// the `urlFor` function is still called for tree + meta "types".
if (type==="tree" || type==="meta") return undefined;
const url = new URL(this.baseNameFor(type));
return url.toString();

return baseName.endsWith(".json")
? `${baseName.replace(/\.json$/, '')}_${type}.json`
: `${baseName}_${type}`;
}
}

class UrlDefinedNarrative extends Narrative {
get baseParts() {
return this.pathParts;
}
get baseName() {
// mandate https
return "https://" + this.baseParts.join("/");
}
url() {
const url = new URL(this.baseName);
return url.toString();
return this.baseParts.join("/");
}
}


class S3Source extends Source {
get bucket() {
throw new InvalidSourceImplementation("bucket() must be implemented by subclasses");
Expand Down

0 comments on commit 610c877

Please sign in to comment.