Skip to content

Commit

Permalink
Work around missing promisified overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
swsnr committed Sep 7, 2024
1 parent 1163ee6 commit 16bff5a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
49 changes: 49 additions & 0 deletions src/lib/fixes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,64 @@
// GNU General Public License for more details.

import type GLib from "gi://GLib";
import type Gio from "gi://Gio";
import type Soup from "gi://Soup";

/**
* This module provides workarounds and fixes for various incomplete type
* declarations in Gnome shell types and its dependencies.
*/

type Promisified<AsyncFN, FinishFN> = AsyncFN extends (
...args: infer Args
) => void
? FinishFN extends (result: Gio.AsyncResult) => infer TReturn
? (...args: Args) => Promise<TReturn>
: never
: never;

/**
* @see https://github.com/gjsify/ts-for-gir/issues/196
*/
export interface GLibErrorWithStack extends GLib.Error {
readonly stack: string;
}

/**
* @see https://github.com/gjsify/ts-for-gir/issues/171#issuecomment-2117301067
*/
export interface PromisifiedFileOutputStream extends Gio.FileOutputStream {
splice_async: Promisified<

Check failure on line 48 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'FileOutputStream'

Check failure on line 48 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'FileOutputStream'
Gio.OutputStream["splice_async"],
Gio.OutputStream["splice_finish"]
>;
}

/**
* @see https://github.com/gjsify/ts-for-gir/issues/171#issuecomment-2117301067
*/
export interface PromisifiedGioFile extends Gio.File {
create_async: Promisified<

Check failure on line 58 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'File'

Check failure on line 58 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'File'
Gio.File["create_async"],
Gio.File["create_finish"]
>;
delete_async: Promisified<

Check failure on line 62 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'File'

Check failure on line 62 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'File'
Gio.File["delete_async"],
Gio.File["delete_finish"]
>;
}

/**
* @see https://github.com/gjsify/ts-for-gir/issues/171#issuecomment-2117301067
*/
export interface PromisifiedSoupSession extends Soup.Session {
send_async: Promisified<

Check failure on line 72 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'Session'

Check failure on line 72 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'Session'
Soup.Session["send_async"],
Soup.Session["send_finish"]
>;

send_and_read_async: Promisified<

Check failure on line 77 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'Session'

Check failure on line 77 in src/lib/fixes.ts

View workflow job for this annotation

GitHub Actions / lint

Promise-returning method provided where a void return was expected by extended/implemented type 'Session'
Soup.Session["send_and_read_async"],
Soup.Session["send_and_read_finish"]
>;
}
15 changes: 10 additions & 5 deletions src/lib/network/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import Soup from "gi://Soup";
import { IOError } from "../common/gio.js";

import type { ExtensionMetadata } from "resource:///org/gnome/shell/extensions/extension.js";
import {
PromisifiedFileOutputStream,
PromisifiedGioFile,
PromisifiedSoupSession,
} from "../fixes.js";

export const createSession = (
extensionMetadata: ExtensionMetadata,
Expand Down Expand Up @@ -83,7 +88,7 @@ export const getString = async (
cancellable: Gio.Cancellable,
): Promise<string> => {
const message = Soup.Message.new("GET", url);
const response = await session
const response = await (session as PromisifiedSoupSession)
.send_and_read_async(message, 0, cancellable)
.catch((cause: unknown) => {
throw new HttpRequestError(url, `Failed to get data from ${url}`, {
Expand Down Expand Up @@ -146,7 +151,7 @@ const deletePartialDownloadIgnoreError = async (
cancellable: Gio.Cancellable | null,
): Promise<void> => {
try {
await file.delete_async(0, cancellable);
await (file as PromisifiedGioFile).delete_async(0, cancellable);
} catch (error) {
console.warn(
`Failed to delete result of partial download at ${file.get_path() ?? ""}`,
Expand All @@ -173,7 +178,7 @@ export const downloadToFile = async (
return;
}
const message = Soup.Message.new("GET", url);
const source = await session
const source = await (session as PromisifiedSoupSession)
.send_async(message, 0, cancellable)
.catch((cause: unknown) => {
throw new HttpRequestError(url, `Failed to make GET request to ${url}`, {
Expand Down Expand Up @@ -215,15 +220,15 @@ export const downloadToFile = async (
}
// Now open the target file for reading, and safely delete it in case of error.
try {
const sink = await target
const sink = await (target as PromisifiedGioFile)
.create_async(Gio.FileCreateFlags.NONE, 0, null)
.catch((cause: unknown) => {
throw new IOError(
`Failed to open target file at ${target.get_path() ?? ""} to download from ${url}`,
{ cause },
);
});
await sink
await (sink as PromisifiedFileOutputStream)
.splice_async(
source,
Gio.OutputStreamSpliceFlags.CLOSE_SOURCE |
Expand Down

0 comments on commit 16bff5a

Please sign in to comment.