Skip to content

Commit 7ae5f19

Browse files
committed
Use the TypeScript v5.5+ JSDoc tag @import to import types in modules.
See: https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#the-jsdoc-import-tag Note that the JSDoc type imports have to be before the real module imports to workaround this TypeScript bug where sometimes the type imports are falsely considered unused: microsoft/TypeScript#58368 (comment) microsoft/TypeScript#58969
1 parent 240666b commit 7ae5f19

9 files changed

+93
-44
lines changed

Upload.mjs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// @ts-check
22

3-
/** @typedef {import("./GraphQLUpload.mjs").default} GraphQLUpload */
4-
/** @typedef {import("./processRequest.mjs").default} processRequest */
3+
/**
4+
* @import GraphQLUpload from "./GraphQLUpload.mjs"
5+
* @import processRequest, { FileUpload } from "./processRequest.mjs"
6+
*/
57

68
/**
79
* A file expected to be uploaded as it was declared in the `map` field of a
@@ -15,21 +17,20 @@ export default class Upload {
1517
/**
1618
* Promise that resolves file upload details. This should only be utilized
1719
* by {@linkcode GraphQLUpload}.
18-
* @type {Promise<import("./processRequest.mjs").FileUpload>}
20+
* @type {Promise<FileUpload>}
1921
*/
2022
this.promise = new Promise((resolve, reject) => {
2123
/**
2224
* Resolves the upload promise with the file upload details. This should
2325
* only be utilized by {@linkcode processRequest}.
24-
* @param {import("./processRequest.mjs").FileUpload} file File upload
25-
* details.
26+
* @param {FileUpload} file File upload details.
2627
*/
2728
this.resolve = (file) => {
2829
/**
2930
* The file upload details, available when the
3031
* {@linkcode Upload.promise} resolves. This should only be utilized by
3132
* {@linkcode processRequest}.
32-
* @type {import("./processRequest.mjs").FileUpload | undefined}
33+
* @type {FileUpload | undefined}
3334
*/
3435
this.file = file;
3536

changelog.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@
66

77
- Updated Node.js support to `^18.18.0 || ^20.9.0 || >=22.0.0`.
88
- Updated dev dependencies, some of which require newer Node.js versions than previously supported.
9+
- Use the TypeScript v5.5+ JSDoc tag `@import` to import types in modules.
10+
- Removed JSDoc tag `@typedef` that were unintentionally re-exporting types; to migrate import TypeScript types from the correct module:
11+
12+
```diff
13+
- import type { GraphQLUpload } from "graphql-upload/Upload.mjs";
14+
+ import type GraphQLUpload from "graphql-upload/GraphQLUpload.mjs";
15+
```
16+
17+
```diff
18+
- import type { processRequest } from "graphql-upload/Upload.mjs";
19+
+ import type processRequest from "graphql-upload/processRequest.mjs";
20+
```
21+
22+
```diff
23+
- import type { GraphQLUpload } from "graphql-upload/processRequest.mjs";
24+
+ import type GraphQLUpload from "graphql-upload/GraphQLUpload.mjs";
25+
```
26+
927
- Refactored tests to use the standard `AbortController`, `fetch`, `File`, and `FormData` APIs available in modern Node.js and removed the dev dependencies [`node-abort-controller`](https://npm.im/node-abort-controller) and [`node-fetch`](https://npm.im/node-fetch).
1028
- Replaced the test utility function `streamToString` with the function `text` from `node:stream/consumers` that’s available in modern Node.js.
1129
- Use the Node.js test runner API and remove the dev dependency [`test-director`](https://npm.im/test-director).

graphqlUploadExpress.mjs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// @ts-check
22

3+
/**
4+
* @import { NextFunction, Request, Response } from "express"
5+
* @import {
6+
* ProcessRequestFunction,
7+
* ProcessRequestOptions,
8+
* } from "./processRequest.mjs"
9+
*/
10+
311
import defaultProcessRequest from "./processRequest.mjs";
412

513
/**
@@ -8,8 +16,8 @@ import defaultProcessRequest from "./processRequest.mjs";
816
* using {@linkcode processRequest}, ignoring non multipart requests. It sets
917
* the request `body` to be similar to a conventional GraphQL POST request for
1018
* following GraphQL middleware to consume.
11-
* @param {import("./processRequest.mjs").ProcessRequestOptions & {
12-
* processRequest?: import("./processRequest.mjs").ProcessRequestFunction
19+
* @param {ProcessRequestOptions & {
20+
* processRequest?: ProcessRequestFunction,
1321
* }} options Options.
1422
* @returns Express middleware.
1523
* @example
@@ -41,9 +49,9 @@ export default function graphqlUploadExpress({
4149
* using {@linkcode processRequest}, ignoring non multipart requests. It sets
4250
* the request `body` to be similar to a conventional GraphQL POST request for
4351
* following GraphQL middleware to consume.
44-
* @param {import("express").Request} request
45-
* @param {import("express").Response} response
46-
* @param {import("express").NextFunction} next
52+
* @param {Request} request
53+
* @param {Response} response
54+
* @param {NextFunction} next
4755
*/
4856
function graphqlUploadExpressMiddleware(request, response, next) {
4957
if (!request.is("multipart/form-data")) return next();

graphqlUploadExpress.test.mjs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// @ts-check
22

3+
/**
4+
* @import { NextFunction, Request, Response } from "express"
5+
* @import Upload from "./Upload.mjs"
6+
*/
7+
38
import "./test/polyfillFile.mjs";
49

510
import { deepStrictEqual, ok, strictEqual } from "node:assert";
@@ -46,7 +51,7 @@ describe(
4651
/**
4752
* @type {{
4853
* variables: {
49-
* file: import("./Upload.mjs").default,
54+
* file: Upload,
5055
* },
5156
* } | undefined}
5257
*/
@@ -88,7 +93,7 @@ describe(
8893
/**
8994
* @type {{
9095
* variables: {
91-
* file: import("./Upload.mjs").default,
96+
* file: Upload,
9297
* },
9398
* } | undefined}
9499
*/
@@ -164,9 +169,9 @@ describe(
164169
.use(
165170
/**
166171
* @param {Error} error
167-
* @param {import("express").Request} request
168-
* @param {import("express").Response} response
169-
* @param {import("express").NextFunction} next
172+
* @param {Request} request
173+
* @param {Response} response
174+
* @param {NextFunction} next
170175
*/
171176
(error, request, response, next) => {
172177
expressError = error;
@@ -232,9 +237,9 @@ describe(
232237
.use(
233238
/**
234239
* @param {Error} error
235-
* @param {import("express").Request} request
236-
* @param {import("express").Response} response
237-
* @param {import("express").NextFunction} next
240+
* @param {Request} request
241+
* @param {Response} response
242+
* @param {NextFunction} next
238243
*/
239244
(error, request, response, next) => {
240245
expressError = error;

graphqlUploadKoa.mjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// @ts-check
22

3+
/**
4+
* @import { ParameterizedContext } from "koa"
5+
* @import {
6+
* ProcessRequestFunction,
7+
* ProcessRequestOptions,
8+
* } from "./processRequest.mjs"
9+
*/
10+
311
import defaultProcessRequest from "./processRequest.mjs";
412

513
/**
@@ -8,8 +16,8 @@ import defaultProcessRequest from "./processRequest.mjs";
816
* using {@linkcode processRequest}, ignoring non multipart requests. It sets
917
* the request `body` to be similar to a conventional GraphQL POST request for
1018
* following GraphQL middleware to consume.
11-
* @param {import("./processRequest.mjs").ProcessRequestOptions & {
12-
* processRequest?: import("./processRequest.mjs").ProcessRequestFunction
19+
* @param {ProcessRequestOptions & {
20+
* processRequest?: ProcessRequestFunction,
1321
* }} options Options.
1422
* @returns Koa middleware.
1523
* @example
@@ -42,7 +50,7 @@ export default function graphqlUploadKoa({
4250
* using {@linkcode processRequest}, ignoring non multipart requests. It sets
4351
* the request `body` to be similar to a conventional GraphQL POST request for
4452
* following GraphQL middleware to consume.
45-
* @param {import("koa").ParameterizedContext} ctx
53+
* @param {ParameterizedContext} ctx
4654
* @param {() => Promise<unknown>} next
4755
*/
4856
async function graphqlUploadKoaMiddleware(ctx, next) {

graphqlUploadKoa.test.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// @ts-check
22

3+
/** @import Upload from "./Upload.mjs" */
4+
35
import "./test/polyfillFile.mjs";
46

57
import { deepStrictEqual, ok, strictEqual } from "node:assert";
@@ -48,7 +50,7 @@ describe(
4850
/**
4951
* @type {{
5052
* variables: {
51-
* file: import("./Upload.mjs").default,
53+
* file: Upload,
5254
* },
5355
* } | undefined}
5456
*/
@@ -94,7 +96,7 @@ describe(
9496
/**
9597
* @type {{
9698
* variables: {
97-
* file: import("./Upload.mjs").default,
99+
* file: Upload,
98100
* },
99101
* } | undefined}
100102
*/

ignoreStream.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// @ts-check
22

3+
/** @import { Readable } from "node:stream" */
4+
35
/**
46
* Safely ignores a Node.js readable stream.
5-
* @param {import("node:stream").Readable} stream Node.js readable stream.
7+
* @param {Readable} stream Node.js readable stream.
68
*/
79
export default function ignoreStream(stream) {
810
// Prevent an unhandled error from crashing the process.

processRequest.mjs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// @ts-check
22

3+
/**
4+
* @import { IncomingMessage, ServerResponse } from "node:http"
5+
* @import { Readable } from "node:stream"
6+
* @import { ReadStreamOptions } from "fs-capacitor"
7+
* @import { ObjectPathBound } from "object-path"
8+
* @import GraphQLUpload from "./GraphQLUpload.mjs"
9+
*/
10+
311
import busboy from "busboy";
412
import { WriteStream } from "fs-capacitor";
513
import createError from "http-errors";
@@ -9,8 +17,6 @@ import GRAPHQL_MULTIPART_REQUEST_SPEC_URL from "./GRAPHQL_MULTIPART_REQUEST_SPEC
917
import ignoreStream from "./ignoreStream.mjs";
1018
import Upload from "./Upload.mjs";
1119

12-
/** @typedef {import("./GraphQLUpload.mjs").default} GraphQLUpload */
13-
1420
/**
1521
* Processes an incoming
1622
* [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec).
@@ -46,7 +52,7 @@ export default function processRequest(
4652
let operations;
4753

4854
/**
49-
* @type {import("object-path").ObjectPathBound<
55+
* @type {ObjectPathBound<
5056
* { [key: string]: unknown } | Array<{ [key: string]: unknown }>
5157
* >}
5258
*/
@@ -354,9 +360,8 @@ export default function processRequest(
354360
* @prop {string} mimetype File MIME type. Provided by the client and can’t be
355361
* trusted.
356362
* @prop {string} encoding File stream transfer encoding.
357-
* @prop {import("fs-capacitor").WriteStream} capacitor A private implementation
358-
* detail that shouldn’t be used outside
359-
* [`graphql-upload`](https://npm.im/graphql-upload).
363+
* @prop {WriteStream} capacitor A private implementation detail that shouldn’t
364+
* be used outside [`graphql-upload`](https://npm.im/graphql-upload).
360365
* @prop {FileUploadCreateReadStream} createReadStream Creates a
361366
* [Node.js readable stream](https://nodejs.org/api/stream.html#readable-streams)
362367
* of the file’s contents, for processing and storage.
@@ -370,7 +375,7 @@ export default function processRequest(
370375
* all resolvers have resolved, or after an error has interrupted the request.
371376
* @callback FileUploadCreateReadStream
372377
* @param {FileUploadCreateReadStreamOptions} [options] Options.
373-
* @returns {import("node:stream").Readable}
378+
* @returns {Readable}
374379
* [Node.js readable stream](https://nodejs.org/api/stream.html#readable-streams)
375380
* of the file’s contents.
376381
* @see [Node.js `Readable` stream constructor docs](https://nodejs.org/api/stream.html#new-streamreadableoptions).
@@ -380,28 +385,26 @@ export default function processRequest(
380385
/**
381386
* {@linkcode FileUploadCreateReadStream} options.
382387
* @typedef {object} FileUploadCreateReadStreamOptions
383-
* @prop {import("fs-capacitor")
384-
* .ReadStreamOptions["encoding"]} [options.encoding] Specify an encoding for
385-
* the [`data`](https://nodejs.org/api/stream.html#event-data) chunks to be
386-
* strings (without splitting multi-byte characters across chunks) instead of
387-
* Node.js [`Buffer`](https://nodejs.org/api/buffer.html#buffer) instances.
388+
* @prop {ReadStreamOptions["encoding"]} [options.encoding] Specify an encoding
389+
* for the [`data`](https://nodejs.org/api/stream.html#event-data) chunks to
390+
* be strings (without splitting multi-byte characters across chunks) instead
391+
* of Node.js [`Buffer`](https://nodejs.org/api/buffer.html#buffer) instances.
388392
* Supported values depend on the
389393
* [`Buffer` implementation](https://github.com/nodejs/node/blob/v18.1.0/lib/buffer.js#L590-L680)
390394
* and include `utf8`, `ucs2`, `utf16le`, `latin1`, `ascii`, `base64`,
391395
* `base64url`, or `hex`. Defaults to `utf8`.
392-
* @prop {import("fs-capacitor")
393-
* .ReadStreamOptions["highWaterMark"]} [options.highWaterMark] Maximum number
394-
* of bytes to store in the internal buffer before ceasing to read from the
395-
* underlying resource. Defaults to `16384`.
396+
* @prop {ReadStreamOptions["highWaterMark"]} [options.highWaterMark] Maximum
397+
* number of bytes to store in the internal buffer before ceasing to read from
398+
* the underlying resource. Defaults to `16384`.
396399
*/
397400

398401
/**
399402
* Processes an incoming
400403
* [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec).
401404
* @callback ProcessRequestFunction
402-
* @param {import("node:http").IncomingMessage} request
405+
* @param {IncomingMessage} request
403406
* [Node.js HTTP server request instance](https://nodejs.org/api/http.html#http_class_http_incomingmessage).
404-
* @param {import("node:http").ServerResponse} response
407+
* @param {ServerResponse} response
405408
* [Node.js HTTP server response instance](https://nodejs.org/api/http.html#http_class_http_serverresponse).
406409
* @param {ProcessRequestOptions} [options] Options.
407410
* @returns {Promise<

test/CountReadableStream.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// @ts-check
22

3+
/** @import { ReadableOptions } from "node:stream" */
4+
35
import { Readable } from "node:stream";
46

57
/**
68
* A count readable stream, for testing purposes.
79
* @see [Example counting stream in the Node.js docs](https://nodejs.org/api/stream.html#an-example-counting-stream).
810
*/
911
export default class CountReadableStream extends Readable {
10-
/** @param {import("node:stream").ReadableOptions} [options] */
12+
/** @param {ReadableOptions} [options] */
1113
constructor(options) {
1214
super(options);
1315
this._max = 1000000;

0 commit comments

Comments
 (0)