diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..8c56e190
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+# Changelog
+
+## 0.2.0
+
+### Breaking Changes
+
+- Expose Typescript types
+
+### New Features
+
+- Migrate codebase to Typescript
+- Replace query-string with node's querystring
+
+## 0.1.0
+
+Initial release
diff --git a/README.md b/README.md
index 56735852..93526ccf 100644
--- a/README.md
+++ b/README.md
@@ -40,13 +40,13 @@ Next page tester will take care of:
## Options
-| Property | Description | type | Default |
-| ------------------ | ---------------------------------------------------------------------------------- | ------------------ | ------- |
-| **route** | Next route (must start with `/`) | - | - |
-| **pagesDirectory** | Absolute path of Next's `/pages` folder | - | - |
-| **req** | Override default mocked [request object][req-docs]
(`getServerSideProps` only) | `res => res` | - |
-| **res** | Override default mocked [response object][res-docs]
(`getServerSideProps` only) | `req => req` | - |
-| **router** | Override default mocked [Next router object][next-docs-router] | `router => router` | - |
+| Property | Description | type | Default |
+| ------------------ | -------------------------------------------------------------------------------- | ------------------ | ------- |
+| **route** | Next route (must start with `/`) | - | - |
+| **pagesDirectory** | Absolute path of Next's `/pages` folder | - | - |
+| **req** | Access default mocked [request object][req-docs]
(`getServerSideProps` only) | `res => res` | - |
+| **res** | Access default mocked [response object][res-docs]
(`getServerSideProps` only) | `req => req` | - |
+| **router** | Access default mocked [Next router object][next-docs-router] | `router => router` | - |
## Notes
@@ -61,6 +61,7 @@ It might be necessary to install `@types/react-dom` and `@types/webpack` when us
- Make available dynamic api routes under `/pages/api`
- Consider adding custom App and Document
- Consider adding a `getPage` factory
+- Consider reusing Next.js code parts (not only types)
[ci]: https://travis-ci.com/toomuchdesign/next-page-tester
[ci-badge]: https://travis-ci.com/toomuchdesign/next-page-tester.svg?branch=master
diff --git a/package-lock.json b/package-lock.json
index 4df010ca..53141a8a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3916,7 +3916,8 @@
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
},
"dedent": {
"version": "0.7.0",
@@ -7554,16 +7555,6 @@
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"dev": true
},
- "query-string": {
- "version": "6.13.1",
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.1.tgz",
- "integrity": "sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA==",
- "requires": {
- "decode-uri-component": "^0.2.0",
- "split-on-first": "^1.0.0",
- "strict-uri-encode": "^2.0.0"
- }
- },
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@@ -8912,11 +8903,6 @@
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
"dev": true
},
- "split-on-first": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
- "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
- },
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -9072,11 +9058,6 @@
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
"dev": true
},
- "strict-uri-encode": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
- "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
- },
"string-argv": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
diff --git a/package.json b/package.json
index 443dec04..95b064f2 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
"clean": "rm -rf dist",
"compile": "npm run clean && tsc",
"test": "jest ./src",
- "test:source": "npm t -- --coverage",
+ "test:source": "npm run test:ts && npm t -- --coverage",
+ "test:ts": "tsc --noEmit",
"prepare": "npm run test:source && npm run compile",
"preversion": "npm run prepare",
"version": "git add package.json",
@@ -61,7 +62,6 @@
"@types/express": "^4.17.8",
"@types/recursive-readdir": "^2.2.0",
"node-mocks-http": "^1.9.0",
- "query-string": "^6.13.1",
"recursive-readdir": "^2.2.2"
},
"peerDependencies": {
@@ -89,7 +89,7 @@
"lint-staged": {
"**/*.{js,ts,json}": [
"prettier",
- "npm t -- ."
+ "npm run test:source -- ."
],
"**/*.{md}": [
"prettier"
diff --git a/src/commonTypes.ts b/src/commonTypes.ts
index 8e739771..5ce1cf47 100644
--- a/src/commonTypes.ts
+++ b/src/commonTypes.ts
@@ -12,8 +12,8 @@ type Res = ReturnType;
export type Options = {
route: string;
pagesDirectory: string;
- req?: (req: Req) => { [name: string]: any };
- res?: (res: Res) => { [name: string]: any };
+ req?: (req: Req) => Req;
+ res?: (res: Res) => Res;
router?: (router: NextRouter) => NextRouter;
};
diff --git a/src/preparePage.ts b/src/preparePage.ts
index 2d364bef..7ae5a6e8 100644
--- a/src/preparePage.ts
+++ b/src/preparePage.ts
@@ -1,20 +1,19 @@
import React, { ReactNode } from 'react';
-import queryString from 'query-string';
import { RouterContext } from 'next/dist/next-server/lib/router-context';
import type { NextRouter } from 'next/router';
-import { parseRoute, removeFileExtension } from './utils';
+import { parseRoute, removeFileExtension, parseQueryString } from './utils';
import type { Options, PageObject } from './commonTypes';
// https://github.com/vercel/next.js/issues/7479#issuecomment-659859682
-function makeDefaultRouterMock(props = {}): NextRouter {
+function makeDefaultRouterMock(props?: Partial): NextRouter {
const routerMock = {
basePath: '',
pathname: '/',
route: '/',
asPath: '/',
query: {},
- push: async () => true,
- replace: async () => true,
+ push: /* istanbul ignore next */ async () => true,
+ replace: /* istanbul ignore next */ async () => true,
reload: () => {},
back: () => {},
prefetch: async () => {},
@@ -47,7 +46,7 @@ export default function preparePage({
makeDefaultRouterMock({
asPath: pathname + search + hash, // Includes querystring and anchor
pathname: removeFileExtension({ path: pagePath }), // Page component path without extension
- query: { ...params, ...queryString.parse(search) }, // Route params + parsed querystring
+ query: { ...params, ...parseQueryString({ queryString: search }) }, // Route params + parsed querystring
route: removeFileExtension({ path: pagePath }), // Page component path without extension
})
),
diff --git a/src/utils.ts b/src/utils.ts
index 9f51f144..e1c06087 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,7 +1,16 @@
-const url = require('url');
+import { URL } from 'url';
+import querystring from 'querystring';
export function parseRoute({ route }: { route: string }) {
- return url.parse(`http://test.com${route}`);
+ return new URL(`http://test.com${route}`);
+}
+
+export function parseQueryString({ queryString }: { queryString: string }) {
+ const qs = queryString.startsWith('?')
+ ? queryString.substring(1)
+ : queryString;
+
+ return querystring.parse(qs);
}
export function sleep(ms: number) {