Skip to content

Commit

Permalink
moved api client library to separate package, netlify
Browse files Browse the repository at this point in the history
  • Loading branch information
harrybrwn committed Apr 25, 2023
1 parent d960c1e commit a3e91df
Show file tree
Hide file tree
Showing 40 changed files with 781 additions and 509 deletions.
39 changes: 29 additions & 10 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,39 @@ jobs:
with:
node-version: '${{ steps.nvm.outputs.NVMRC }}'

publish:
needs: [build]
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
test:
runs-on: ubuntu-22.04
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
- name: Checkout
uses: actions/checkout@v3
- name: Read .nvmrc
run: echo ::set-output name=NVMRC::$(cat .nvmrc)
id: nvm
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ steps.nvm.outputs.NVMRC }}
- name: Install Dependencies
run: yarn
- name: Lint
run: yarn run astro check
- name: Test
run: yarn test

# publish:
# needs: [build]
# runs-on: ubuntu-latest
# environment:
# name: github-pages
# url: ${{ steps.deployment.outputs.page_url }}
# steps:
# - name: Deploy to GitHub Pages
# id: deployment
# uses: actions/deploy-pages@v1

docker:
runs-on: ubuntu-22.04
needs: [build]
needs: [build, test]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dist/
*.zip
.astro
.vercel
.netlify

# dependencies
node_modules/
Expand All @@ -19,4 +20,4 @@ pnpm-debug.log*

# Certificates
*.crt
*.key
*.key
15 changes: 12 additions & 3 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from "path";
import fs from "fs";

import node from "@astrojs/node";
import netlify from "@astrojs/netlify/functions";

import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
Expand All @@ -18,17 +19,24 @@ const site = `https://${domain}`;
const outDir = "./dist";
const siteMapFilter = new Set(["admin"]);

const output = process.env.ASTRO_OUTPUT || "static";
const isNetlify = process.env.NETLIFY === "true" ? true : false;
let output = process.env.ASTRO_OUTPUT || "static";
if (isNetlify) {
output = "server";
}

// https://astro.build/config
export default defineConfig({
site: site,
outDir: outDir,
output: output,
adapter: output === "server" ? node({ mode: "middleware" }) : undefined,
adapter: isNetlify
? netlify()
: output === "server"
? node({ mode: "middleware" })
: undefined,
build: {
assets: "a",
serverEntry: "index.js",
},
markdown: {
syntaxHighlight: "prism",
Expand All @@ -43,6 +51,7 @@ export default defineConfig({
assetsInlineLimit: 512,
rollupOptions: {
output: {
chunkFileNames: isNetlify ? "[hash].js" : undefined,
entryFileNames: "[hash].js",
assetFileNames: "a/[hash][extname]",
},
Expand Down
1 change: 0 additions & 1 deletion docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ group "default" {
targets = [
"static",
"nginx",
"server",
]
}

Expand Down
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,34 @@
"scripts": {
"dev": "node scripts/generate.js && astro dev",
"build": "astro build",
"build:all": "yarn workspaces run build",
"build:all": "yarn workspaces run build && astro build",
"preview": "astro preview",
"astro": "astro",
"clean": "rm -rf ./dist ./.vercel *.tar.gz *.zip && yarn workspaces run clean",
"test": "yarn workspaces run test:ci",
"clean": "rm -rf ./dist/ ./.vercel/ ./.netlify/ *.tar.gz *.zip && yarn workspaces run clean",
"new": "node packages/astro/new/index.js",
"gen": "node scripts/generate.js",
"dev:server": "node scripts/generate.js && ASTRO_OUTPUT=server astro dev",
"build:server": "scripts/build-server.sh",
"preview:server": "ASTRO_OUTPUT=server astro preview",
"container": "docker container run --rm -it -p 3000:3000 -e PORT=3000 --name astro-server harrybrwn/harrybrwn.github.io-server:latest",
"image": "docker buildx bake -f docker-bake.hcl"
"image": "docker buildx bake -f docker-bake.hcl",
"proxy": "docker compose -f docker-compose.yml -f docker-compose.local.yml up dev dev-tls-proxy"
},
"workspaces": [
"./packages/astro/*",
"./packages/server"
"./packages/hrry.me/api"
],
"dependencies": {
"@astro.hrry.dev/compress": "0.0.1",
"@astro.hrry.dev/new": "0.0.1",
"@astro.hrry.dev/obsidian": "0.0.1",
"@astro.hrry.dev/robots.txt": "0.0.1",
"@astro.hrry.dev/wikilink": "0.0.1",
"@hrry.dev/server": "0.0.1",
"@astrojs/cloudflare": "^6.0.0",
"@hrry.me/api": "0.0.1",
"@astrojs/mdx": "^0.15.0",
"@astrojs/netlify": "^2.2.2",
"@astrojs/node": "^5.0.0",
"@astrojs/rss": "^2.1.0",
"@astrojs/sitemap": "^1.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/astro/compress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
],
"scripts": {
"test": "vitest",
"test:ci": "vitest run",
"build": "tsc",
"clean": "rm -rf ./dist"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/new/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"author": "Harry Brown",
"private": true,
"scripts": {
"test": "true",
"test": "test -f index.js",
"test:ci": "yarn test",
"build": "true",
"clean": "true"
},
Expand Down
1 change: 1 addition & 0 deletions packages/astro/obsidian/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"private": true,
"scripts": {
"test": "true",
"test:ci": "yarn test",
"build": "tsc",
"clean": "rm -rf ./dist"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/robots.txt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"author": "Harry Brown",
"private": true,
"scripts": {
"test": "true",
"test": "test -f index.ts",
"test:ci": "yarn test",
"build": "tsc",
"clean": "rm -rf ./dist"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/wikilink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"author": "Harry Brown",
"private": true,
"scripts": {
"test": "true",
"test": "test -f index.js",
"test:ci": "yarn test",
"build": "true",
"clean": "true"
},
Expand Down
27 changes: 27 additions & 0 deletions packages/hrry.me/api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@hrry.me/api",
"version": "0.0.1",
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/harrybrwn/harrybrwn.github.io.git",
"directory": "packages/hrry.me/api"
},
"main": "src",
"author": "Harry Brown",
"private": true,
"files": [
"dist",
"src"
],
"scripts": {
"test": "vitest",
"build": "tsc",
"clean": "rm -rf ./dist",
"test:ci": "vitest run"
},
"devDependencies": {
"typescript": "^5.0.4",
"vitest": "^0.30.1"
}
}
45 changes: 40 additions & 5 deletions src/lib/api/client.ts → packages/hrry.me/api/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ import { storeToken, type Token } from "./token";

export class Client {
url: URL;
oidcUrl: URL;
oidcClientId?: string;

constructor(url: URL, oidcUrl?: URL | undefined, oidcClientId?: string) {
constructor(url: URL) {
this.url = url;
this.oidcUrl = oidcUrl || new URL(import.meta.env.PUBLIC_OIDC_URL);
this.oidcClientId = oidcClientId;
}

async login(req: LoginRequest) {
Expand Down Expand Up @@ -44,6 +40,45 @@ export class Client {
}
}

export interface Config {
url: URL;
}

export async function login(config: Config, req: LoginRequest) {
return fetch(new URL("/api/login", config.url), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(req),
credentials: "include",
}).then(handleResponse);
}

export async function token(
config: Config,
req: LoginRequest,
cookie?: boolean | undefined
) {
let u = new URL("/api/token", config.url);
if (cookie) u.searchParams.set("cookie", "true");
return fetch(u, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(req),
credentials: "include",
})
.then(handleResponse)
.then((blob: any) => {
let tok: Token = {
token: blob.token,
expires: blob.expires,
refresh: blob.refresh_token,
type: blob.token_type,
};
storeToken(tok);
return tok;
});
}

const handleResponse = async (res: Response) => {
if (!res.ok) {
try {
Expand Down
4 changes: 4 additions & 0 deletions packages/hrry.me/api/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { Client } from "./client";
export { RedirectTarget, consent } from "./oidc";
export { getCookie } from "./util";
export { Token } from "./token";
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions packages/hrry.me/api/src/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const getCookie = (name: string) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop()?.split(";").shift();
else return null;
};
92 changes: 92 additions & 0 deletions packages/hrry.me/api/test/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { describe, test, beforeEach, afterEach, expect, vi } from "vitest";
import { Client } from "../src";
import MockFetch, { response } from "./fetch";

let localStorageMock = {
clear: vi.fn(),
getItem: vi.fn(),
key: vi.fn(),
removeItem: vi.fn(),
setItem: vi.fn(),
length: 0,
};
vi.stubGlobal("localStorage", localStorageMock);

test("failed test", () => {
expect(false).to.be.true;
});

describe("client", () => {
let api: Client;
const base = new URL("http://localhost:8080/");
let mockFetch: MockFetch;

beforeEach(() => {
api = new Client(new URL(base));
mockFetch = new MockFetch();
mockFetch.start();
});

afterEach(() => {
mockFetch.finish();
vi.restoreAllMocks();
});

test("new", () => {
expect(api.url).toStrictEqual(base);
expect(api.url.origin).to.eq("http://localhost:8080");
expect(api.url.protocol).to.eq("http:");
expect(api.url.host).to.eq("localhost:8080");
expect(api.url.port).to.eq("8080");
expect(api.url.pathname).to.eq("/");
});

test("login", () => {
const input = { username: "jim", password: "fdsafdsa" };
mockFetch
.expect(new URL("/api/login", new URL(base)), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(input),
credentials: "include",
})
.returns(response(200, { msg: "yee", result: true }));
api.login(input).then((result) => {
expect(result.msg).to.eq("yee");
expect(result.result).to.eq(true);
});
});

test("token", () => {
const input = { username: "jimmy", password: "abcdefg" };
mockFetch
.expect(new URL("/api/token", base), {
method: "POST",
body: JSON.stringify(input),
headers: { "Content-Type": "application/json" },
credentials: "include",
})
.returns(
response(200, {
token: "<token>",
refresh_token: "sample-refresh-token",
token_type: "bearer",
expires: 1,
})
);

localStorageMock.getItem = vi.fn((k: string): string | null => {
if (k === "_refresh") return "sample-refresh-token";
return null;
});

api.token(input).then((token) => {
expect(token.expires).to.eq(1);
expect(token.type).to.eq("bearer");
expect(token.refresh).to.eq("sample-refresh-token");
expect(token.token).to.eq("<token>");
expect(localStorageMock.getItem).toHaveBeenCalledOnce();
expect(localStorageMock.setItem).toHaveBeenCalledTimes(1);
});
});
});
Loading

0 comments on commit a3e91df

Please sign in to comment.