Skip to content

Commit

Permalink
feat!: use fetch service
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The addon now requires a fetch service that handles
authentication. See `dummy/app/services/fetch.js` for an example
implementation.
  • Loading branch information
Yelinz authored and czosel committed Jan 11, 2024
1 parent 7fe77b8 commit 9f727db
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ constructor(...args) {
"session",
"intl",
"notification",
"fetch",
"alexandria-config",
],
},
Expand Down
8 changes: 2 additions & 6 deletions addon/components/document-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default class DocumentCardComponent extends Component {
@service notification;
@service intl;
@service("alexandria-config") config;
@service fetch;

get classes() {
const classes = [
Expand Down Expand Up @@ -76,12 +77,7 @@ export default class DocumentCardComponent extends Component {
)}`;
}

const transfer = yield fetch(url, {
mode: "cors",
headers: {
Authorization: `Bearer ${this.config.accessToken}`,
},
});
const transfer = yield this.fetch.fetch(url, { mode: "cors" });
const bytes = yield transfer.blob();
saveAs(bytes, `Download-${this.args.documents.length}-files.zip`);
}
Expand Down
2 changes: 1 addition & 1 deletion addon/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class EmberAlexandriaEngine extends Engine {
Resolver = Resolver;

dependencies = {
services: ["session", "intl", "notification", "alexandria-config"],
services: ["session", "intl", "notification", "fetch", "alexandria-config"],
};
}

Expand Down
8 changes: 7 additions & 1 deletion tests/dummy/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ export default class App extends Application {
engines = {
"ember-alexandria": {
dependencies: {
services: ["session", "intl", "notification", "alexandria-config"],
services: [
"session",
"intl",
"notification",
"fetch",
"alexandria-config",
],
},
},
};
Expand Down
54 changes: 54 additions & 0 deletions tests/dummy/app/services/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Service, { inject as service } from "@ember/service";
import { isEmpty } from "@ember/utils";
import fetch from "fetch";

const CONTENT_TYPE = "application/vnd.api+json";

const cleanObject = (obj) => {
return Object.entries(obj).reduce((clean, [key, value]) => {
return {
...clean,
...(isEmpty(value) ? {} : { [key]: value }),
};
}, {});
};

export default class FetchService extends Service {
@service session;

async fetch(resource, init = {}) {
init.headers = cleanObject({
...this.session.headers,
accept: CONTENT_TYPE,
"content-type": CONTENT_TYPE,
...(init.headers || {}),
});

const response = await fetch(resource, init);

if (!response.ok) {
if (response.status === 401) {
return this.session.handleUnauthorized();
}

const contentType = response.headers.map["content-type"];
let body = "";

if (
["application/json", "application/vnd.api+json"].includes(contentType)
) {
body = (await response.json())?.errors;
} else if (contentType === "text/plain") {
body = await response.text();
}

// throw an error containing a human readable message
throw new Error(
`Fetch request to URL ${response.url} returned ${response.status} ${response.statusText}:\n\n${body}`,
{ cause: body },
);
}

return response;
}
}
2 changes: 1 addition & 1 deletion tests/dummy/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function makeServer(config) {

this.put("/file-upload", () => new Response(201, {}, {}));

this.get("/files/multi", 200);
this.get("/files/multi", () => new Response(200, {}, {}));
},
});
}

0 comments on commit 9f727db

Please sign in to comment.