Skip to content

Commit

Permalink
refactor: move away from deno and back to yarn
Browse files Browse the repository at this point in the history
  • Loading branch information
JustSamuel committed Oct 24, 2024
1 parent baf1085 commit b6e166b
Show file tree
Hide file tree
Showing 10 changed files with 2,039 additions and 164 deletions.
31 changes: 1 addition & 30 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,35 +1,6 @@
const { process } = require("node:process");

module.exports = {
root: true,
env: {
node: true,
mocha: true,
},
plugins: [
"chai-friendly",
"import",
],
extends: [
"airbnb-typescript/base",
"plugin:chai-expect/recommended",
"@gewis/eslint-config",
],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"linebreak-style": process.env.NODE_ENV === "production"
? ["error", "windows"]
: ["off", "windows"],
"@typescript-eslint/no-empty-function": ["error", {
allow: ["constructors"],
}],
"@typescript-eslint/no-unused-expressions": "off",
"chai-friendly/no-unused-expressions": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/await-thenable": "warn",
"class-methods-use-this": "off",
},
parserOptions: {
project: "./tsconfig.json",
},
};
53 changes: 2 additions & 51 deletions .github/workflows/lint-and-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,5 @@ on:
- main

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.0

- name: Install Yarn
run: npm install -g yarn

- name: Install Dependencies
run: yarn install

# TODO: Not sure how this should work, but we should not be removing the lock file.
- name: Remove deno.lock
run: rm -rf ./deno.lock

- name: Lint
run: deno lint ./src/*.ts

build:
runs-on: ubuntu-latest
needs: lint

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.0

- name: Install Yarn
run: npm install -g yarn

- name: Install Dependencies
run: yarn install

# TODO: Not sure how this should work, but we should not be removing the lock file.
- name: Remove deno.lock
run: rm -rf ./deno.lock

- name: Compile Deno Project
run: |
deno compile --output plankapi --unstable --no-check ./src/index.ts
build-and-lint:
uses: GEWIS/actions/.github/workflows/typescript/yarn/lint-and-build/action.yml@1d62561ea67009e78af7d90a0888ba96d1609501
28 changes: 0 additions & 28 deletions deno.json

This file was deleted.

14 changes: 0 additions & 14 deletions deno.lock

This file was deleted.

31 changes: 29 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
{
"devDependencies": {
"name": "plankapi",
"version": "0.0.0",
"description": "Planka API service",
"main": "src/index.js",
"scripts": {
"start": "node src/index.ts",
"start:env": "node -r dotenv/config src/index.js",
"build": "tsc",
"lint": "eslint . --ext .vue,.js,.jsx,.mjs,.ts,.tsx,.cts,.mts,.json --ignore-path .gitignore",
"lint:fix": "eslint . --fix --ext .vue,.js,.jsx,.mjs,.ts,.tsx,.cts,.mts,.json --ignore-path .gitignore"
},
"dependencies": {
"@gewis/planka-client": "github:GEWIS/planka-client#3bb88c2a8d86a9ba8f4fccf0a70e534047c6f88c",
"@hey-api/client-fetch": "^0.4.2",
"imapflow": "^1.0.164"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
"devDependencies": {
"@gewis/eslint-config": "https://github.com/GEWIS/eslint-config",
"@types/node": "^22.7.9",
"dotenv": "^16.0.0",
"typescript": "^5.2.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/GEWIS/plankapi.git"
},
"author": "GEWIS GEFLITST",
"license": "ISC",
"bugs": {
"url": "https://github.com/GEWIS/plankapi/issues"
},
"homepage": "https://github.com/GEWIS/plankapi#readme",
"packageManager": "yarn@1.22.22"
}
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Mailer from "./mailer.ts";
import Planka from "./planka.ts";
import Mailer from "./mailer";
import Planka from "./planka";

// Main workflow
async function main() {
Expand All @@ -17,6 +17,6 @@ async function main() {
}

// Execute main if this is the main module
if (import.meta.main) {
if (require.main === module) {
void main();
}
28 changes: 11 additions & 17 deletions src/mailer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ImapFlow } from "imapflow";
import type { Readable } from "node:stream";

export interface CardEmail {
title: string;
Expand All @@ -12,7 +11,7 @@ export interface CardEmail {

/**
* Extracts the Planka board ID from email headers.
* @param {string} headers - The email headers as a string.
* @param {string} headers - The ema il headers as a string.
* @returns {string | null} The extracted board ID, or null if not found.
*/
function extractPlankaBoardId(headers: string): string | null {
Expand Down Expand Up @@ -42,6 +41,7 @@ function extractDate(subject: string): Date | null {
const match = subject.match(datePattern);

if (match) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, day, month, year, hour, minute] = match;
return new Date(`${year}-${month}-${day}T${hour}:${minute}:00`);
} else {
Expand All @@ -51,18 +51,12 @@ function extractDate(subject: string): Date | null {

/**
* Converts a readable stream to a string.
* @param {Readable} readable - The readable stream.
* @param {Readable} stream - The readable stream.
* @returns {Promise<string>} The content of the stream as a string.
*/
const readableToString = async (readable: Readable): Promise<string> => {
let result = "";

for await (const chunk of readable) {
result += chunk;
}

return result;
};
export async function streamToString(stream: ReadableStream<string>): Promise<string> {
return await new Response(stream).text();
}

/**
* Downloads the body of an email message.
Expand All @@ -75,7 +69,7 @@ const downloadEmailBody = async (
messageId: string,
): Promise<string> => {
const { content } = await client.download(messageId, "1", { uid: true }); // part '1' is typically the plain text part
return readableToString(content);
return streamToString(content);
};

export default class Mailer {
Expand All @@ -84,12 +78,12 @@ export default class Mailer {

constructor() {
this.client = new ImapFlow({
host: Deno.env.get("IMAP_HOST") || "localhost",
port: Number(Deno.env.get("IMAP_PORT") || "993"),
host: process.env["IMAP_HOST"] || "localhost",
port: Number(process.env["IMAP_PORT"] || "993"),
secure: true,
auth: {
user: Deno.env.get("IMAP_USERNAME") || "user",
pass: Deno.env.get("IMAP_PASSWORD"),
user: process.env["IMAP_USERNAME"] || "user",
pass: process.env["IMAP_PASSWORD"],
},
});
}
Expand Down
42 changes: 26 additions & 16 deletions src/planka.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { client, createCard, getBoard, updateCard } from "planka-client";
import type { Board, Card, List } from "@gewis/planka-client";
import type { Client } from "@hey-api/client-fetch";
import {
client,
createCard,
CreateCardRequest,
UpdateCardRequest,
getBoard,
updateCard, GetBoardRequest, GetBoardResponse
} from "@gewis/planka-client";
import type { List } from "@gewis/planka-client";
import type { Client, Options } from "@hey-api/client-fetch";
import type { CardEmail } from "./mailer.ts";

const DEFAULT_PLANKA_URL = Deno.env.get("PLANKA_URL") ||
const DEFAULT_PLANKA_URL = process.env["PLANKA_URL"] ||
"http://localhost:3000";

interface CacheEntry {
board: Board;
board: GetBoardResponse;
preferredList: List; // Preference is: header if present, list called 'mail' if present, otherwise first list
}

Expand All @@ -31,7 +38,7 @@ export default class Planka {
if (!Planka.client) {
const plankaUrl = this.settings.plankaUrl || DEFAULT_PLANKA_URL;
const plankaApiKey = this.settings.plankaApiKey ||
Deno.env.get("PLANKA_API_KEY");
process.env["PLANKA_API_KEY"];

client.setConfig({
baseUrl: plankaUrl,
Expand Down Expand Up @@ -96,10 +103,11 @@ export default class Planka {
continue;
}

const board = await getBoard({ path: { id } });
const board = await getBoard({ path: { id: id.toString() } } as Options<GetBoardRequest, false>);
const status = board.response.status;

if (status === 200) {
if (status === 200 && board.data) {

// Find the preferred list, which is the list named 'mail' or the first list available
const preferredList = board.data.included.lists.find((list: List) =>
list.name.toLowerCase() === "mail"
Expand All @@ -121,7 +129,7 @@ export default class Planka {
static async processCards(
cards: CardEmail[],
): Promise<
{ result: { card: CardEmail; state: "ACCEPTED" | "REJECTED" }[] }
{ card: CardEmail; state: "ACCEPTED" | "REJECTED" }[]
> {
Planka.pre();

Expand Down Expand Up @@ -149,24 +157,26 @@ export default class Planka {
body: {
name: card.title,
position: 0,
},
}).then(async (cardResponse: Card) => {
const status = cardResponse.response.status;
if (status !== 200) return;
}
} as Options<CreateCardRequest, false>).then(async (result) => {
const cardResult = result.data;
const status = result.response.status;

if (status !== 200 || !cardResult) return;

results.push({ card, state: "ACCEPTED" });

// Update the card's description and due date if provided
if (card.body) {
await updateCard({
path: {
id: cardResponse.data.item.id,
id: cardResult.item.id,
},
body: {
description: card.body,
dueDate: card.date ? card.date.toISOString() : null,
dueDate: card.date ? card.date : null,
},
});
} as Options<UpdateCardRequest>);
}
});
}
Expand Down
3 changes: 1 addition & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"outDir": "./dist",
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts"],
"include": ["src/**/*.ts", "src/**/*.d.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Loading

0 comments on commit b6e166b

Please sign in to comment.