Working runtime with ESM compatibility. Now for the tests...

master
Kuba Orlik 11 months ago
parent 4a2baa8dcd
commit 46e70efcb3

2
package-lock.json generated

@ -50,7 +50,7 @@
"prettier": "^2.2.1", "prettier": "^2.2.1",
"ts-loader": "^8.0.14", "ts-loader": "^8.0.14",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
"typescript": "^4.1.3" "typescript": "^4.7"
}, },
"engines": { "engines": {
"node": ">=17.0.0" "node": ">=17.0.0"

@ -3,6 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"description": "", "description": "",
"main": "./dist/back/index.js", "main": "./dist/back/index.js",
"type": "module",
"scripts": { "scripts": {
"start": "docker-compose up -d db && node .", "start": "docker-compose up -d db && node .",
"typecheck:back": "npx tsc --noEmit --target es6 --lib es2015,dom -p src/back", "typecheck:back": "npx tsc --noEmit --target es6 --lib es2015,dom -p src/back",
@ -32,7 +33,7 @@
"@hotwired/turbo": "^7.1.0", "@hotwired/turbo": "^7.1.0",
"@koa/router": "^12.0.1", "@koa/router": "^12.0.1",
"@playwright/test": "^1.36.1", "@playwright/test": "^1.36.1",
"@sealcode/sealgen": "^0.8.52", "@sealcode/sealgen": "^0.9.0",
"@sealcode/ts-predicates": "^0.4.3", "@sealcode/ts-predicates": "^0.4.3",
"@types/kill-port": "^2.0.0", "@types/kill-port": "^2.0.0",
"hint": "^7.0.1", "hint": "^7.0.1",
@ -68,7 +69,7 @@
"prettier": "^2.2.1", "prettier": "^2.2.1",
"ts-loader": "^8.0.14", "ts-loader": "^8.0.14",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
"typescript": "^4.1.3" "typescript": "^4.7"
}, },
"nyc": { "nyc": {
"extends": "@istanbuljs/nyc-config-typescript", "extends": "@istanbuljs/nyc-config-typescript",

@ -1,9 +1,10 @@
import _locreq from "locreq"; import _locreq from "locreq";
import { default as Sealious, App, LoggerMailer, SMTPMailer } from "sealious"; import Sealious, { App, LoggerMailer, SMTPMailer } from "sealious";
import { LoggerLevel } from "sealious/@types/src/app/logger"; import type { LoggerLevel } from "sealious/@types/src/app/logger.js";
import { collections } from "./collections/collections"; import { collections } from "./collections/collections.js";
import ADMIN_CREDENTIALS from "./default-admin-credentials"; import ADMIN_CREDENTIALS from "./default-admin-credentials.js";
const locreq = _locreq(__dirname); import { module_dirname } from "./util.js";
const locreq = _locreq.default(module_dirname(import.meta.url));
const PORT = process.env.SEALIOUS_PORT ? parseInt(process.env.SEALIOUS_PORT) : 8080; const PORT = process.env.SEALIOUS_PORT ? parseInt(process.env.SEALIOUS_PORT) : 8080;
const base_url = process.env.SEALIOUS_BASE_URL || `http://localhost:${PORT}`; const base_url = process.env.SEALIOUS_BASE_URL || `http://localhost:${PORT}`;

@ -1,13 +1,13 @@
// DO NOT EDIT! This file is generated automaticaly with 'npm run generate-collections' // DO NOT EDIT! This file is generated automaticaly with 'npm run generate-collections'
import { App } from "sealious"; import { App } from "sealious";
import _GroupsToUsers from "./groups-to-users"; import _GroupsToUsers from "./groups-to-users.js";
import _Groups from "./groups"; import _Groups from "./groups.js";
import _PasswordResetIntents from "./password-reset-intents"; import _PasswordResetIntents from "./password-reset-intents.js";
import _Secrets from "./secrets"; import _Secrets from "./secrets.js";
import _Tasks from "./tasks"; import _Tasks from "./tasks.js";
import _UserRoles from "./user-roles"; import _UserRoles from "./user-roles.js";
import _Users from "./users"; import _Users from "./users.js";
export const GroupsToUsers = new _GroupsToUsers(); export const GroupsToUsers = new _GroupsToUsers();
export const Groups = new _Groups(); export const Groups = new _Groups();

@ -1,5 +1,5 @@
import { Collection, FieldTypes, Policies } from "sealious"; import { Collection, FieldTypes, Policies } from "sealious";
import { Roles } from "../policy-types/roles"; import { Roles } from "../policy-types/roles.js";
export default class GroupsToUsers extends Collection { export default class GroupsToUsers extends Collection {
fields = { fields = {

@ -1,5 +1,5 @@
import { Collection, FieldTypes, Policies } from "sealious"; import { Collection, FieldTypes, Policies } from "sealious";
import { Roles } from "../policy-types/roles"; import { Roles } from "../policy-types/roles.js";
export default class Groups extends Collection { export default class Groups extends Collection {
fields = { fields = {

@ -1,7 +1,7 @@
import axios from "axios"; import axios from "axios";
import assert from "assert"; import assert from "assert";
import TheApp from "../app"; import TheApp from "../app.js";
import { withProdApp } from "../test_utils/with-prod-app"; import { withProdApp } from "../test_utils/with-prod-app.js";
describe("password-reset-intents", function () { describe("password-reset-intents", function () {
//ts-ignore //ts-ignore
@ -18,7 +18,7 @@ describe("password-reset-intents", function () {
return withProdApp(async ({ app, base_url }) => { return withProdApp(async ({ app, base_url }) => {
const email = "fake@example.com"; const email = "fake@example.com";
try { try {
await axios.post( await axios.default.post(
`${base_url}/api/v1/collections/password-reset-intents`, `${base_url}/api/v1/collections/password-reset-intents`,
{ {
email: email, email: email,
@ -39,7 +39,7 @@ describe("password-reset-intents", function () {
withProdApp(async ({ app, base_url }) => { withProdApp(async ({ app, base_url }) => {
await createAUser(app); await createAUser(app);
const { email, token } = ( const { email, token } = (
await axios.post( await axios.default.post(
`${base_url}/api/v1/collections/password-reset-intents`, `${base_url}/api/v1/collections/password-reset-intents`,
{ {
email: "user@example.com", email: "user@example.com",
@ -59,7 +59,7 @@ describe("password-reset-intents", function () {
withProdApp(async ({ app, base_url }) => { withProdApp(async ({ app, base_url }) => {
const email = "incorrect-address"; const email = "incorrect-address";
try { try {
await axios.post( await axios.default.post(
`${base_url}/api/v1/collections/password-reset-intents`, `${base_url}/api/v1/collections/password-reset-intents`,
{ {
email: email, email: email,
@ -78,9 +78,12 @@ describe("password-reset-intents", function () {
it("sends an email with the reset password link", async () => it("sends an email with the reset password link", async () =>
withProdApp(async ({ app, base_url, mail_api }) => { withProdApp(async ({ app, base_url, mail_api }) => {
await createAUser(app); await createAUser(app);
await axios.post(`${base_url}/api/v1/collections/password-reset-intents`, { await axios.default.post(
`${base_url}/api/v1/collections/password-reset-intents`,
{
email: "user@example.com", email: "user@example.com",
}); }
);
const messages = (await mail_api.getMessages()).filter( const messages = (await mail_api.getMessages()).filter(
(message) => message.recipients[0] == "<user@example.com>" (message) => message.recipients[0] == "<user@example.com>"
); );

@ -1,7 +1,7 @@
import { App, Collection, CollectionItem, Context, FieldTypes, Policies } from "sealious"; import { App, Collection, CollectionItem, Context, FieldTypes, Policies } from "sealious";
import assert from "assert"; import assert from "assert";
import PasswordResetTemplate from "../email-templates/password-reset"; import PasswordResetTemplate from "../email-templates/password-reset.js";
import TheApp from "../app"; import TheApp from "../app.js";
import { assertType, predicates } from "@sealcode/ts-predicates"; import { assertType, predicates } from "@sealcode/ts-predicates";
export default class PasswordResetIntents extends Collection { export default class PasswordResetIntents extends Collection {

@ -1,5 +1,5 @@
import { Collection, FieldTypes } from "sealious"; import { Collection, FieldTypes } from "sealious";
import { Roles } from "../policy-types/roles"; import { Roles } from "../policy-types/roles.js";
/* For testing the Roles policy */ /* For testing the Roles policy */
export default class Secrets extends Collection { export default class Secrets extends Collection {

@ -1,9 +1,9 @@
import assert from "assert"; import assert from "assert";
import axios from "axios"; import axios from "axios";
import { Context, TestUtils } from "sealious"; import { Context, TestUtils } from "sealious";
import { withProdApp } from "../test_utils/with-prod-app"; import { withProdApp } from "../test_utils/with-prod-app.js";
import { createAdmin, createAUser } from "../test_utils/users"; import { createAdmin, createAUser } from "../test_utils/users.js";
import Users from "./users"; import Users from "./users.js";
describe("user-roles", () => { describe("user-roles", () => {
it("rejects when given an empty role", async () => it("rejects when given an empty role", async () =>
@ -31,7 +31,7 @@ describe("user-roles", () => {
it("accepts correct dataset", async () => it("accepts correct dataset", async () =>
withProdApp(async ({ app, base_url, rest_api }) => { withProdApp(async ({ app, base_url, rest_api }) => {
const [user, session] = await createAdmin(app, rest_api); const [user, session] = await createAdmin(app, rest_api);
const response = await axios.post( const response = await axios.default.post(
`${base_url}/api/v1/collections/user-roles`, `${base_url}/api/v1/collections/user-roles`,
{ {
user: user.id, user: user.id,

@ -1,5 +1,5 @@
import { App, Collection, FieldTypes, Policies, Policy } from "sealious"; import { App, Collection, FieldTypes, Policies, Policy } from "sealious";
import { Roles } from "../policy-types/roles"; import { Roles } from "../policy-types/roles.js";
export default class UserRoles extends Collection { export default class UserRoles extends Collection {
name = "user-roles"; name = "user-roles";

@ -1,7 +1,7 @@
import { App, Collections, Context, FieldTypes, Policies } from "sealious"; import { App, Collections, Context, FieldTypes, Policies } from "sealious";
import assert from "assert"; import assert from "assert";
import TheApp from "../app"; import TheApp from "../app.js";
import ADMIN_CREDENTIALS from "../default-admin-credentials"; import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
export default class Users extends Collections.users { export default class Users extends Collections.users {
fields = { fields = {

@ -1,5 +1,5 @@
import { EmailTemplates, Errors } from "sealious"; import { EmailTemplates, Errors } from "sealious";
import TheApp from "../app"; import TheApp from "../app.js";
export default async function PasswordResetTemplate( export default async function PasswordResetTemplate(
app: TheApp, app: TheApp,

@ -1,7 +1,7 @@
import { Templatable, tempstream } from "tempstream"; import { Templatable, tempstream } from "tempstream";
import { Readable } from "stream"; import { Readable } from "stream";
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import navbar from "./routes/common/navbar"; import navbar from "./routes/common/navbar.js";
export const defaultHead = (ctx: BaseContext, title: string) => /* HTML */ `<title> export const defaultHead = (ctx: BaseContext, title: string) => /* HTML */ `<title>
${title} · ${ctx.$app.manifest.name} ${title} · ${ctx.$app.manifest.name}

@ -1,8 +1,9 @@
import kill from "kill-port"; import kill from "kill-port";
import _locreq from "locreq"; import _locreq from "locreq";
import TheApp from "./app"; import TheApp from "./app.js";
import { mainRouter } from "./routes"; import { mainRouter } from "./routes/index.js";
const locreq = _locreq(__dirname); import { module_dirname } from "./util.js";
const locreq = _locreq.default(module_dirname(import.meta.url));
const app = new TheApp(); const app = new TheApp();

@ -1,4 +1,4 @@
import { withProdApp } from "../test_utils/with-prod-app"; import { withProdApp } from "../test_utils/with-prod-app.js";
describe("roles", () => { describe("roles", () => {
it("allows access to users with designated role and denies access to users without it", async () => it("allows access to users with designated role and denies access to users without it", async () =>

@ -1,4 +1,4 @@
import html from "../../html"; import html from "../../html.js";
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import { Readable } from "stream"; import { Readable } from "stream";
import { tempstream } from "tempstream"; import { tempstream } from "tempstream";

@ -1,5 +1,5 @@
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import { SignUpURL, SignInURL, TodoURL, LogoutURL } from "../urls"; import { SignUpURL, SignInURL, TodoURL, LogoutURL } from "../urls.js";
export default async function navbar(ctx: BaseContext) { export default async function navbar(ctx: BaseContext) {
const isLoggedIn = !!ctx.$context.session_id; const isLoggedIn = !!ctx.$context.session_id;
@ -17,7 +17,7 @@ export default async function navbar(ctx: BaseContext) {
const linksHTML = linkData const linksHTML = linkData
.map((link) => .map((link) =>
link.url === new URL(ctx.url, "https://a.com").pathname link.url === new URL(ctx.url, "https://a.com").pathname
? `<li>${link.text}</li>` ? `<li class="active"><span>${link.text}</span></li>`
: /* HTML */ `<li><a href="${link.url}">${link.text}</a></li>` : /* HTML */ `<li><a href="${link.url}">${link.text}</a></li>`
) )
.join("\n"); .join("\n");
@ -30,7 +30,7 @@ export default async function navbar(ctx: BaseContext) {
width="50" width="50"
height="50" height="50"
/> />
Sealious App ${ctx.$app.manifest.name}
</a> </a>
<ul> <ul>
${linksHTML} ${linksHTML}

@ -1,7 +1,7 @@
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import { CollectionItem } from "sealious"; import { CollectionItem } from "sealious";
import frame from "../../frame"; import frame from "../../frame.js";
import { Tasks } from "../../collections/collections"; import { Tasks } from "../../collections/collections.js";
export function Task(task: CollectionItem<typeof Tasks>) { export function Task(task: CollectionItem<typeof Tasks>) {
return frame( return frame(

@ -1,6 +1,6 @@
import { withProdApp } from "../test_utils/with-prod-app"; import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint"; import { withProdApp } from "../test_utils/with-prod-app.js";
import { HelloURL } from "./urls"; import { HelloURL } from "./urls.js";
describe("Hello", () => { describe("Hello", () => {
it("doesn't crash", async function () { it("doesn't crash", async function () {

@ -1,5 +1,5 @@
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint"; import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app"; import { withProdApp } from "../test_utils/with-prod-app.js";
describe("homepage", function () { describe("homepage", function () {
this.timeout(VERY_LONG_TEST_TIMEOUT); this.timeout(VERY_LONG_TEST_TIMEOUT);

@ -1,7 +1,7 @@
import Router from "@koa/router"; import Router from "@koa/router";
import { Middlewares } from "sealious"; import { Middlewares } from "sealious";
import { MainView } from "./common/main-view"; import { MainView } from "./common/main-view.js";
import mountAutoRoutes from "./routes"; import mountAutoRoutes from "./routes.js";
export const mainRouter = (router: Router): void => { export const mainRouter = (router: Router): void => {
router.get("/", Middlewares.extractContext(), async (ctx) => { router.get("/", Middlewares.extractContext(), async (ctx) => {

@ -1,10 +1,10 @@
import assert from "assert"; import assert from "assert";
import { withProdApp } from "../test_utils/with-prod-app";
import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint";
import { LogoutURL, SignInURL } from "./urls";
import { Browser, BrowserContext, Page } from "@playwright/test"; import { Browser, BrowserContext, Page } from "@playwright/test";
import { getBrowser } from "../test_utils/browser-creator"; import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
import ADMIN_CREDENTIALS from "../default-admin-credentials"; import { getBrowser } from "../test_utils/browser-creator.js";
import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app.js";
import { LogoutURL, SignInURL } from "./urls.js";
describe("Logout", () => { describe("Logout", () => {
let page: Page; let page: Page;

@ -2,13 +2,13 @@
import Router from "@koa/router"; import Router from "@koa/router";
import { mount } from "@sealcode/sealgen"; import { mount } from "@sealcode/sealgen";
import * as URLs from "./urls"; import * as URLs from "./urls.js";
import { default as Hello } from "./hello.page"; import { default as Hello } from "./hello.page.js";
import { default as Logout } from "./logout.redirect"; import { default as Logout } from "./logout.redirect.js";
import { default as SignIn } from "./signIn.form"; import { default as SignIn } from "./signIn.form.js";
import { default as SignUp } from "./signUp.form"; import { default as SignUp } from "./signUp.form.js";
import { default as Todo } from "./todo.form"; import { default as Todo } from "./todo.form.js";
export default function mountAutoRoutes(router: Router) { export default function mountAutoRoutes(router: Router) {
mount(router, URLs.HelloURL, Hello); mount(router, URLs.HelloURL, Hello);

@ -7,10 +7,10 @@ import {
Controls, Controls,
FormReaction, FormReaction,
} from "@sealcode/sealgen"; } from "@sealcode/sealgen";
import html from "../html";
import { Users } from "../collections/collections";
import { FlatTemplatable, tempstream } from "tempstream"; import { FlatTemplatable, tempstream } from "tempstream";
import { PageErrorMessage } from "@sealcode/sealgen/@types/page/mountable-with-fields"; import { Users } from "../collections/collections.js";
import type { PageErrorMessage } from "@sealcode/sealgen/@types/page/mountable-with-fields.js";
import html from "../html.js";
export const actionName = "SignIn"; export const actionName = "SignIn";

@ -1,9 +1,9 @@
import { withProdApp } from "../test_utils/with-prod-app";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint";
import { SignInURL, LogoutURL } from "./urls";
import { Browser, BrowserContext, Page } from "@playwright/test"; import { Browser, BrowserContext, Page } from "@playwright/test";
import { getBrowser } from "../test_utils/browser-creator"; import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
import ADMIN_CREDENTIALS from "../default-admin-credentials"; import { getBrowser } from "../test_utils/browser-creator.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app.js";
import { LogoutURL, SignInURL } from "./urls.js";
describe("SignIn", () => { describe("SignIn", () => {
let page: Page; let page: Page;

@ -7,8 +7,8 @@ import {
Controls, Controls,
FormReaction, FormReaction,
} from "@sealcode/sealgen"; } from "@sealcode/sealgen";
import html from "../html"; import { Users } from "../collections/collections.js";
import { Users } from "../collections/collections"; import html from "../html.js";
export const actionName = "SignUp"; export const actionName = "SignUp";

@ -1,9 +1,9 @@
import { withProdApp } from "../test_utils/with-prod-app";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint";
import { SignUpURL, LogoutURL, SignInURL } from "./urls";
import { Browser, BrowserContext, Page } from "@playwright/test"; import { Browser, BrowserContext, Page } from "@playwright/test";
import { getBrowser } from "../test_utils/browser-creator"; import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
import ADMIN_CREDENTIALS from "../default-admin-credentials"; import { getBrowser } from "../test_utils/browser-creator.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app.js";
import { LogoutURL, SignInURL, SignUpURL } from "./urls.js";
describe("SignUp", () => { describe("SignUp", () => {
let page: Page; let page: Page;

@ -1,9 +1,9 @@
import { Tasks } from "./../collections/collections";
import { tempstream } from "tempstream"; import { tempstream } from "tempstream";
import { Context } from "koa"; import { Context } from "koa";
import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen"; import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen";
import html from "../html"; import { Tasks } from "../collections/collections.js";
import { TaskList } from "./common/tasks-view"; import html from "../html.js";
import { TaskList } from "./common/tasks-view.js";
export const actionName = "Todo"; export const actionName = "Todo";

@ -1,10 +1,10 @@
import assert from "assert"; import assert from "assert";
import { withProdApp } from "../test_utils/with-prod-app";
import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint";
import { SignInURL, TodoURL } from "./urls";
import { Browser, BrowserContext, Page } from "@playwright/test"; import { Browser, BrowserContext, Page } from "@playwright/test";
import { getBrowser } from "../test_utils/browser-creator"; import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
import ADMIN_CREDENTIALS from "../default-admin-credentials"; import { getBrowser } from "../test_utils/browser-creator.js";
import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app.js";
import { SignInURL, TodoURL } from "./urls.js";
describe("Todo", function () { describe("Todo", function () {
let page: Page; let page: Page;

@ -1,6 +1,6 @@
import { Users } from "../collections/collections";
import { CollectionItem, TestUtils } from "sealious"; import { CollectionItem, TestUtils } from "sealious";
import TheApp from "../app"; import TheApp from "../app.js";
import Users from "../collections/users.js";
type Unpromisify<T> = T extends Promise<infer R> ? R : T; type Unpromisify<T> = T extends Promise<infer R> ? R : T;
@ -16,9 +16,7 @@ export function createAUser(app: TheApp, username: string) {
export async function createAdmin( export async function createAdmin(
app: TheApp, app: TheApp,
rest_api: TestUtils.MockRestApi rest_api: TestUtils.MockRestApi
): Promise< ): Promise<[CollectionItem<Users>, Unpromisify<ReturnType<typeof rest_api.login>>]> {
[CollectionItem<typeof Users>, Unpromisify<ReturnType<typeof rest_api.login>>]
> {
const user = await createAUser(app, "super_user"); const user = await createAUser(app, "super_user");
await app.collections["user-roles"].suCreate({ await app.collections["user-roles"].suCreate({
user: user.id, user: user.id,

@ -1,5 +1,5 @@
import _locreq from "locreq"; import _locreq from "locreq";
const locreq = _locreq(__dirname); const locreq = _locreq.default(__dirname);
import { spawn } from "child_process"; import { spawn } from "child_process";
import { hasShape, is, predicates } from "@sealcode/ts-predicates"; import { hasShape, is, predicates } from "@sealcode/ts-predicates";
import { promises as fs } from "fs"; import { promises as fs } from "fs";

@ -1,11 +1,12 @@
import TheApp from "../app";
import { mainRouter } from "../routes";
import _locreq from "locreq"; import _locreq from "locreq";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
const locreq = _locreq(__dirname); const locreq = _locreq.default(module_dirname(import.meta.url));
import { SMTPMailer } from "sealious"; import { SMTPMailer } from "sealious";
import { TestUtils } from "sealious"; import { TestUtils } from "sealious";
import TheApp from "../app.js";
import { mainRouter } from "../routes/index.js";
import { module_dirname } from "../util.js";
export async function withProdApp( export async function withProdApp(
callback: (args: { callback: (args: {

@ -1,7 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "CommonJS", "module": "node16",
"moduleResolution": "node", "moduleResolution": "node16",
"noImplicitAny": true, "noImplicitAny": true,
"noImplicitThis": true, "noImplicitThis": true,
"strictNullChecks": true, "strictNullChecks": true,

@ -1,5 +1,6 @@
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import qs from "qs"; import qs from "qs";
import { dirname } from "node:path";
export async function sleep(time: number) { export async function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time)); return new Promise((resolve) => setTimeout(resolve, time));
@ -20,3 +21,7 @@ export function UrlWithNewParams(
): string { ): string {
return `${ctx.path}?${qs.stringify(query_params)}`; return `${ctx.path}?${qs.stringify(query_params)}`;
} }
export function module_dirname(module_url: string): string {
return dirname(module_url).replace(/^file:\/\//, "");
}

Loading…
Cancel
Save