Switch to deno
This commit is contained in:
parent
5ec05e3db7
commit
b81144153b
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
|
||||||
|
**/dist/**/*
|
||||||
|
39
deno.json
Normal file
39
deno.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"lock": false,
|
||||||
|
"tasks": {
|
||||||
|
"build": "deno run -A tools/build.ts",
|
||||||
|
"serve": "deno run -A src/server/index.ts"
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"rules": {
|
||||||
|
"tags": [
|
||||||
|
"recommended"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"imports": {
|
||||||
|
"react/": "https://esm.sh/react@18.3.1/",
|
||||||
|
"react-dom/": "https://esm.sh/react-dom@18.3.1/client/",
|
||||||
|
"react": "https://esm.sh/react@18.3.1",
|
||||||
|
"react-dom": "https://esm.sh/react-dom@18.3.1/client",
|
||||||
|
"canvas": "https://esm.sh/canvas@3.0.0"
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["deno.ns", "DOM"],
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react",
|
||||||
|
"strict": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"allowUnusedLabels": false
|
||||||
|
},
|
||||||
|
"fmt": {
|
||||||
|
"useTabs": true
|
||||||
|
}
|
||||||
|
}
|
1048
package-lock.json
generated
1048
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"canvas": "^2.11.2"
|
|
||||||
}
|
|
||||||
}
|
|
3
root.ts
Normal file
3
root.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { dirname, fromFileUrl } from "jsr:@std/path";
|
||||||
|
|
||||||
|
export const projectRootDir = dirname(fromFileUrl(import.meta.url));
|
6
src/client/App.tsx
Normal file
6
src/client/App.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { sampleCard } from "../sampleData.ts";
|
||||||
|
import { Card } from "./Card.tsx";
|
||||||
|
|
||||||
|
export const App = () => {
|
||||||
|
return <div><Card card={sampleCard}/></div>;
|
||||||
|
};
|
26
src/client/Card.tsx
Normal file
26
src/client/Card.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { drawCard } from "../draw.ts";
|
||||||
|
import { DominionCard } from "../types.ts";
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
card: {
|
||||||
|
width: 1403,
|
||||||
|
height: 2151,
|
||||||
|
},
|
||||||
|
landscape: {
|
||||||
|
width: 2151,
|
||||||
|
height: 1403,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Card = (props: {card: DominionCard}) => {
|
||||||
|
const {card} = props;
|
||||||
|
const {width, height} = sizeMap[card.orientation];
|
||||||
|
return <canvas style={{width: "2.5in"}} width={width} height={height} ref={(canvasElement) => {
|
||||||
|
if (canvasElement) {
|
||||||
|
const context = canvasElement.getContext("2d");
|
||||||
|
if (context) {
|
||||||
|
drawCard(context, card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}></canvas>
|
||||||
|
}
|
14
src/client/index.tsx
Normal file
14
src/client/index.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { StrictMode } from "react";
|
||||||
|
import { createRoot } from "react-dom";
|
||||||
|
import { App } from "./App.tsx";
|
||||||
|
|
||||||
|
const rootElement = document.getElementById("root");
|
||||||
|
if (!rootElement) {
|
||||||
|
throw Error("No root element to attach react to.");
|
||||||
|
}
|
||||||
|
|
||||||
|
createRoot(rootElement).render(
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>,
|
||||||
|
);
|
39
src/draw.ts
39
src/draw.ts
@ -1,22 +1,31 @@
|
|||||||
import { DominionCard } from "./types"
|
import { DominionCard } from "./types.ts";
|
||||||
import { createCanvas } from "canvas"
|
|
||||||
|
|
||||||
export const drawCard = (card: DominionCard): Promise<string> => {
|
export const drawCard = (
|
||||||
|
context: CanvasRenderingContext2D,
|
||||||
|
card: DominionCard
|
||||||
|
): Promise<void> => {
|
||||||
if (card.orientation === "card") {
|
if (card.orientation === "card") {
|
||||||
return drawStandardCard(card);
|
return drawStandardCard(context, card);
|
||||||
} else {
|
} else {
|
||||||
return drawLandscapeCard(card);
|
return drawLandscapeCard(context, card);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const drawStandardCard = async (card: DominionCard): Promise<string> => {
|
const drawStandardCard = async (
|
||||||
const canvas = createCanvas(1403, 2151);
|
context: CanvasRenderingContext2D,
|
||||||
const context = canvas.getContext("2d");
|
card: DominionCard
|
||||||
|
): Promise<void> => {
|
||||||
|
const w = context.canvas.width;
|
||||||
|
const h = context.canvas.height;
|
||||||
|
context.save();
|
||||||
|
context.fillStyle = "brown";
|
||||||
|
context.fillRect(0, 0, w, h);
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
return "";
|
const drawLandscapeCard = async (
|
||||||
}
|
context: CanvasRenderingContext2D,
|
||||||
|
card: DominionCard
|
||||||
const drawLandscapeCard = async (card: DominionCard): Promise<string> => {
|
): Promise<void> => {
|
||||||
// TODO: everything
|
// TODO: everything
|
||||||
return "";
|
};
|
||||||
}
|
|
||||||
|
0
src/isocanvas.ts
Normal file
0
src/isocanvas.ts
Normal file
@ -1,4 +1,4 @@
|
|||||||
import { DominionCard, TYPE_ACTION } from "./types";
|
import { DominionCard, TYPE_ACTION } from "./types.ts";
|
||||||
|
|
||||||
export const sampleCard: DominionCard = {
|
export const sampleCard: DominionCard = {
|
||||||
orientation: "card",
|
orientation: "card",
|
||||||
@ -11,4 +11,4 @@ export const sampleCard: DominionCard = {
|
|||||||
version: "",
|
version: "",
|
||||||
price: "",
|
price: "",
|
||||||
preview: "",
|
preview: "",
|
||||||
}
|
};
|
||||||
|
14
src/server/index.ts
Normal file
14
src/server/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { serveDir, serveFile } from "jsr:@std/http/file-server";
|
||||||
|
|
||||||
|
Deno.serve((req: Request) => {
|
||||||
|
const pathname = new URL(req.url).pathname;
|
||||||
|
|
||||||
|
if (pathname.startsWith("/static")) {
|
||||||
|
return serveDir(req, {
|
||||||
|
fsRoot: "src/static",
|
||||||
|
urlRoot: "static",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return serveFile(req, "src/static/index.html");
|
||||||
|
}
|
||||||
|
});
|
12
src/static/index.html
Normal file
12
src/static/index.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Dominionator</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script src="/static/dist/bundle.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
67
src/types.ts
67
src/types.ts
@ -9,7 +9,16 @@ export type DominionColor = {
|
|||||||
|
|
||||||
export type DominionBasicCardType = {
|
export type DominionBasicCardType = {
|
||||||
typeType: "basic";
|
typeType: "basic";
|
||||||
name: "Action" | "Treasure" | "Victory" | "Reaction" | "Duration" | "Reserve" | "Night" | "Attack" | "Command";
|
name:
|
||||||
|
| "Action"
|
||||||
|
| "Treasure"
|
||||||
|
| "Victory"
|
||||||
|
| "Reaction"
|
||||||
|
| "Duration"
|
||||||
|
| "Reserve"
|
||||||
|
| "Night"
|
||||||
|
| "Attack"
|
||||||
|
| "Command";
|
||||||
color: null | DominionColor;
|
color: null | DominionColor;
|
||||||
};
|
};
|
||||||
export type DominionBasicLandscapeType = {
|
export type DominionBasicLandscapeType = {
|
||||||
@ -19,9 +28,12 @@ export type DominionBasicLandscapeType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type DominionCardType = DominionBasicCardType | DominionCustomCardType;
|
export type DominionCardType = DominionBasicCardType | DominionCustomCardType;
|
||||||
export type DominionLandscapeType = DominionBasicLandscapeType | DominionCustomLandscapeType;
|
export type DominionLandscapeType =
|
||||||
|
| DominionBasicLandscapeType
|
||||||
|
| DominionCustomLandscapeType;
|
||||||
|
|
||||||
export type DominionCard = {
|
export type DominionCard =
|
||||||
|
| {
|
||||||
orientation: "card";
|
orientation: "card";
|
||||||
title: string;
|
title: string;
|
||||||
description: DominionText;
|
description: DominionText;
|
||||||
@ -32,7 +44,8 @@ export type DominionCard = {
|
|||||||
version: string;
|
version: string;
|
||||||
price: DominionText;
|
price: DominionText;
|
||||||
preview?: DominionText;
|
preview?: DominionText;
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
orientation: "landscape";
|
orientation: "landscape";
|
||||||
title: string;
|
title: string;
|
||||||
description: DominionText;
|
description: DominionText;
|
||||||
@ -42,7 +55,7 @@ export type DominionCard = {
|
|||||||
author: string;
|
author: string;
|
||||||
version: string;
|
version: string;
|
||||||
price: DominionText;
|
price: DominionText;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DominionCustomSymbol = {
|
export type DominionCustomSymbol = {
|
||||||
image: string;
|
image: string;
|
||||||
@ -51,12 +64,12 @@ export type DominionCustomSymbol = {
|
|||||||
export type DominionCustomCardType = {
|
export type DominionCustomCardType = {
|
||||||
typeType: "custom";
|
typeType: "custom";
|
||||||
name: string;
|
name: string;
|
||||||
color: DominionColor
|
color: DominionColor;
|
||||||
};
|
};
|
||||||
export type DominionCustomLandscapeType = {
|
export type DominionCustomLandscapeType = {
|
||||||
typeType: "custom";
|
typeType: "custom";
|
||||||
name: string;
|
name: string;
|
||||||
color: DominionColor
|
color: DominionColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DominionExpansion = {
|
export type DominionExpansion = {
|
||||||
@ -65,7 +78,7 @@ export type DominionExpansion = {
|
|||||||
customSymbols: Array<DominionCustomSymbol>;
|
customSymbols: Array<DominionCustomSymbol>;
|
||||||
customCardTypes: Array<DominionCustomCardType>;
|
customCardTypes: Array<DominionCustomCardType>;
|
||||||
customLandscapeTypes: Array<DominionCustomLandscapeType>;
|
customLandscapeTypes: Array<DominionCustomLandscapeType>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_ACTION: DominionBasicCardType = {
|
export const TYPE_ACTION: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -73,8 +86,8 @@ export const TYPE_ACTION: DominionBasicCardType = {
|
|||||||
color: {
|
color: {
|
||||||
value: "white",
|
value: "white",
|
||||||
priority: 6,
|
priority: 6,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_TREASURE: DominionBasicCardType = {
|
export const TYPE_TREASURE: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -82,8 +95,8 @@ export const TYPE_TREASURE: DominionBasicCardType = {
|
|||||||
color: {
|
color: {
|
||||||
value: "yellow",
|
value: "yellow",
|
||||||
priority: 5,
|
priority: 5,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_VICTORY: DominionBasicCardType = {
|
export const TYPE_VICTORY: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -91,8 +104,8 @@ export const TYPE_VICTORY: DominionBasicCardType = {
|
|||||||
color: {
|
color: {
|
||||||
value: "green",
|
value: "green",
|
||||||
priority: 4,
|
priority: 4,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_REACTION: DominionBasicCardType = {
|
export const TYPE_REACTION: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -101,8 +114,8 @@ export const TYPE_REACTION: DominionBasicCardType = {
|
|||||||
value: "blue",
|
value: "blue",
|
||||||
priority: 1,
|
priority: 1,
|
||||||
overridesAction: true,
|
overridesAction: true,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_DURATION: DominionBasicCardType = {
|
export const TYPE_DURATION: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -111,18 +124,18 @@ export const TYPE_DURATION: DominionBasicCardType = {
|
|||||||
value: "orange",
|
value: "orange",
|
||||||
priority: 3,
|
priority: 3,
|
||||||
overridesAction: true,
|
overridesAction: true,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_RESERVE: DominionBasicCardType = {
|
export const TYPE_RESERVE: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
name: "Duration",
|
name: "Duration",
|
||||||
color: {
|
color: {
|
||||||
value: "orange",
|
value: "brown",
|
||||||
priority: 2, // unknown whether this should be above or below reaction/duration?
|
priority: 2, // unknown whether this should be above or below reaction/duration?
|
||||||
overridesAction: true,
|
overridesAction: true,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_NIGHT: DominionBasicCardType = {
|
export const TYPE_NIGHT: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
@ -131,17 +144,17 @@ export const TYPE_NIGHT: DominionBasicCardType = {
|
|||||||
value: "black",
|
value: "black",
|
||||||
priority: 6,
|
priority: 6,
|
||||||
onConflictDescriptionOnly: true,
|
onConflictDescriptionOnly: true,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_ATTACK: DominionBasicCardType = {
|
export const TYPE_ATTACK: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
name: "Attack",
|
name: "Attack",
|
||||||
color: null
|
color: null,
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TYPE_COMMAND: DominionBasicCardType = {
|
export const TYPE_COMMAND: DominionBasicCardType = {
|
||||||
typeType: "basic",
|
typeType: "basic",
|
||||||
name: "Command",
|
name: "Command",
|
||||||
color: null
|
color: null,
|
||||||
}
|
};
|
||||||
|
28
tools/build.ts
Normal file
28
tools/build.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import * as esbuild from "npm:esbuild";
|
||||||
|
import { denoPlugins } from "jsr:@luca/esbuild-deno-loader";
|
||||||
|
import browserslist from "npm:browserslist";
|
||||||
|
import { projectRootDir } from "../root.ts";
|
||||||
|
|
||||||
|
const browsers = browserslist([
|
||||||
|
"last 4 Chrome versions",
|
||||||
|
"last 4 Edge versions",
|
||||||
|
"last 4 Opera versions",
|
||||||
|
"last 4 Firefox versions",
|
||||||
|
"last 4 Safari versions",
|
||||||
|
]).map((browser: string) => browser.replace(" ", ""));
|
||||||
|
|
||||||
|
// esbuild target is fine-grained: https://esbuild.github.io/api/#target
|
||||||
|
const target = [...browsers, "ios18", "ios17", "ios16", "ios14"];
|
||||||
|
await esbuild.build({
|
||||||
|
plugins: [...denoPlugins()],
|
||||||
|
absWorkingDir: projectRootDir,
|
||||||
|
entryPoints: ["src/client/index.tsx"],
|
||||||
|
outfile: "src/static/dist/bundle.js",
|
||||||
|
bundle: true,
|
||||||
|
format: "esm",
|
||||||
|
target,
|
||||||
|
jsx: "automatic",
|
||||||
|
jsxImportSource: "react",
|
||||||
|
});
|
||||||
|
|
||||||
|
esbuild.stop();
|
Loading…
x
Reference in New Issue
Block a user