mirror of
https://github.com/barthuijgen/factorio-sites.git
synced 2024-11-21 18:16:33 +02:00
commit
468c40ce44
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@ -9,3 +9,8 @@ updates:
|
||||
target-branch: develop
|
||||
ignore:
|
||||
- dependency-name: "@fbe/editor"
|
||||
- dependency-name: "factorio-wasm"
|
||||
- dependency-name: "react-map-interaction"
|
||||
- dependency-name: "pako" # v2 does not support required use case
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-patch"]
|
||||
|
1
.github/workflows/deploy_dev.yml
vendored
1
.github/workflows/deploy_dev.yml
vendored
@ -25,7 +25,6 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- run: yarn
|
||||
- run: yarn db-gen
|
||||
- run: yarn nx build blueprints
|
||||
env:
|
||||
CF_WEB_ANALYTICS: 6c563c1e5db141129a5fc95d5c459722
|
||||
|
1
.github/workflows/deploy_prd.yml
vendored
1
.github/workflows/deploy_prd.yml
vendored
@ -25,7 +25,6 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- run: yarn
|
||||
- run: yarn db-gen
|
||||
- run: yarn nx build blueprints
|
||||
env:
|
||||
PUBLIC_URL: https://factorio-blueprints-assets.storage.googleapis.com/public
|
||||
|
1
.github/workflows/validate.yml
vendored
1
.github/workflows/validate.yml
vendored
@ -21,7 +21,6 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- run: yarn --prefer-offline
|
||||
- run: yarn db-gen
|
||||
- run: yarn nx run-many --all --target=lint
|
||||
- run: yarn nx run-many --all --target=test "--ci"
|
||||
- run: yarn nx build blueprints
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -33,6 +33,7 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
*.tsbuildinfo
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
@ -45,3 +46,5 @@ Thumbs.db
|
||||
.local.env
|
||||
.env
|
||||
local.readme.md
|
||||
|
||||
/bin/
|
||||
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "blueprint-image-function",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"postinstall": "yarn prisma generate"
|
||||
},
|
||||
"dependencies": {
|
||||
"puppeteer": "7.1.0",
|
||||
"tslib": "2.1.0",
|
||||
"sharp": "0.27.2",
|
||||
"prisma": "2.18.0",
|
||||
"@prisma/client": "2.18.0",
|
||||
"@google-cloud/pubsub": "2.9.0",
|
||||
"@google-cloud/secret-manager": "3.4.0",
|
||||
"@google-cloud/storage": "5.7.4",
|
||||
"cookie": "0.4.1",
|
||||
"pako": "1.0.11",
|
||||
"bcrypt": "5.0.0"
|
||||
}
|
||||
}
|
1
apps/blueprint-image-function/jest.config.js
vendored
1
apps/blueprint-image-function/jest.config.js
vendored
@ -11,4 +11,5 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ["ts", "js", "html"],
|
||||
coverageDirectory: "../../coverage/apps/blueprint-image-function",
|
||||
testEnvironment: "node",
|
||||
};
|
||||
|
24
apps/blueprint-image-function/post-build-script.ts
Normal file
24
apps/blueprint-image-function/post-build-script.ts
Normal file
@ -0,0 +1,24 @@
|
||||
console.log("POST BUILD SCRIPT", __dirname);
|
||||
|
||||
/*
|
||||
|
||||
yarn nx build blueprint-image-function
|
||||
|
||||
1. Add to package.json
|
||||
|
||||
"scripts": {
|
||||
"postinstall": "yarn prisma generate"
|
||||
},
|
||||
|
||||
2. Add to dependencies
|
||||
|
||||
"prisma": "3.6.0",
|
||||
|
||||
2. Replace prisma generate header
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native", "debian-openssl-1.1.x"]
|
||||
}
|
||||
|
||||
*/
|
83
apps/blueprint-image-function/src/fetch-handlers.ts
Normal file
83
apps/blueprint-image-function/src/fetch-handlers.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import * as phin from "phin";
|
||||
import {
|
||||
getBlueprintById,
|
||||
hasBlueprintImage,
|
||||
saveBlueprintImage,
|
||||
init,
|
||||
} from "@factorio-sites/database";
|
||||
import { jsonReplaceErrors } from "@factorio-sites/node-utils";
|
||||
import { optimise } from "./image-optimiser";
|
||||
|
||||
// {"blueprintId":"ee9b98eb-313a-4401-8aee-d6e970b76aad"}
|
||||
// ^ image_hash: 6f78c0a93c20fe99076e8defe4e396923f42753b
|
||||
|
||||
/** message body for pubsub triggered function */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type Message = Record<string, any>;
|
||||
|
||||
/** context for pubsub triggered function */
|
||||
interface Context {
|
||||
eventId: string;
|
||||
eventType: string;
|
||||
timestamp: string;
|
||||
resource: { service: string; name: string };
|
||||
}
|
||||
|
||||
type PubSubHandler = (
|
||||
message: Message,
|
||||
context: Context,
|
||||
callback: (error?: string) => void
|
||||
) => void;
|
||||
|
||||
export const functionPubSubHandler: PubSubHandler = async (message, _context, callback) => {
|
||||
const error = (message: string, data: Record<string, unknown> = {}) => {
|
||||
console.error(JSON.stringify({ message, ...data }, jsonReplaceErrors));
|
||||
callback(message);
|
||||
};
|
||||
const log = (message: string, data: Record<string, unknown> = {}) => {
|
||||
console.log(JSON.stringify({ message, ...data }));
|
||||
};
|
||||
|
||||
try {
|
||||
const data = message.data
|
||||
? JSON.parse(Buffer.from(message.data, "base64").toString())
|
||||
: message;
|
||||
|
||||
const blueprintId = data.blueprintId;
|
||||
|
||||
if (!blueprintId) {
|
||||
return error("No blueprintId in body");
|
||||
}
|
||||
|
||||
await init();
|
||||
const blueprint = await getBlueprintById(blueprintId);
|
||||
|
||||
if (!blueprint) {
|
||||
return error(`Blueprint ${blueprintId} not found`);
|
||||
}
|
||||
|
||||
if (await hasBlueprintImage(blueprint.image_hash, "300")) {
|
||||
log(`Image already exists ${blueprint.image_hash}`);
|
||||
return callback();
|
||||
}
|
||||
|
||||
console.log(`Fetching https://fbsr.factorio.workers.dev/${blueprint.blueprint_hash}?size=300`);
|
||||
const response = await phin(
|
||||
`https://fbsr.factorio.workers.dev/${blueprint.blueprint_hash}?size=300`
|
||||
);
|
||||
const image = response.body;
|
||||
console.log("Image fetched");
|
||||
|
||||
// Make thumbnail, max size 300px
|
||||
const min_image = await optimise(image, 300);
|
||||
|
||||
await saveBlueprintImage(blueprint.image_hash, min_image, "300");
|
||||
log(`Saved image with image hash ${blueprint.image_hash}`);
|
||||
|
||||
// await saveBlueprintImage(blueprint.image_hash, image, "original");
|
||||
|
||||
callback();
|
||||
} catch (reason) {
|
||||
error(`Error rendering image ${reason}`, { error: reason });
|
||||
}
|
||||
};
|
@ -58,7 +58,7 @@ export const functionHttpHandler: Handler = async (req, res) => {
|
||||
}
|
||||
|
||||
if (await hasBlueprintImage(blueprint.image_hash, "300")) {
|
||||
return res.status(200).send("Image already exists");
|
||||
return res.status(200).send(`Image already exists ${blueprint.image_hash}`);
|
||||
}
|
||||
|
||||
const blueprint_string = await getBlueprintStringByHash(blueprint.blueprint_hash);
|
||||
@ -75,7 +75,8 @@ export const functionHttpHandler: Handler = async (req, res) => {
|
||||
await saveBlueprintImage(blueprint.image_hash, min_image, "300");
|
||||
|
||||
res.status(200).send("Done");
|
||||
} catch (reason) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (reason: any) {
|
||||
res.status(500).send(`Error rendering image ${reason.stack || reason}`);
|
||||
}
|
||||
};
|
||||
@ -100,13 +101,11 @@ export const functionPubSubHandler: PubSubHandler = async (message, _context, ca
|
||||
return error("No blueprintId in body");
|
||||
}
|
||||
|
||||
log(`generating image for ${blueprintId}`);
|
||||
|
||||
await init();
|
||||
const blueprint = await getBlueprintById(blueprintId);
|
||||
|
||||
if (!blueprint) {
|
||||
return error("Blueprint not found");
|
||||
return error(`Blueprint ${blueprintId} not found`);
|
||||
}
|
||||
|
||||
if (await hasBlueprintImage(blueprint.image_hash, "300")) {
|
||||
@ -114,6 +113,8 @@ export const functionPubSubHandler: PubSubHandler = async (message, _context, ca
|
||||
return callback();
|
||||
}
|
||||
|
||||
log(`generating image for ${blueprintId}`);
|
||||
|
||||
const blueprint_string = await getBlueprintStringByHash(blueprint.blueprint_hash);
|
||||
if (!blueprint_string) {
|
||||
return error("Blueprint string not found");
|
||||
|
@ -1,11 +1,8 @@
|
||||
import { functionHttpHandler, functionPubSubHandler } from "./function-handler";
|
||||
// import { local_test } from "./local-test";
|
||||
// import { functionHttpHandler, functionPubSubHandler } from "./function-handler";
|
||||
import { functionPubSubHandler } from "./fetch-handlers";
|
||||
// import { rePublishAllBlueprints } from "./republish-pubsub";
|
||||
|
||||
// import { subscribeToPubSub } from "./pubsub-render";
|
||||
// subscribeToPubSub().catch((reason) => console.error("Fatal error:", reason));
|
||||
// rePublishAllBlueprints().catch((reason) => console.error("Fatal error:", reason));
|
||||
|
||||
exports.renderImageHttp = functionHttpHandler;
|
||||
// exports.renderImageHttp = functionHttpHandler;
|
||||
exports.renderImagePubSub = functionPubSubHandler;
|
||||
|
||||
// local_test("8737437e-f15b-459c-8c1d-d0074f3a89ca");
|
||||
// rePublishAllBlueprints();
|
||||
|
@ -60,7 +60,8 @@ export async function subscribeToPubSub() {
|
||||
await saveBlueprintImage(blueprint.image_hash, min_image, "300");
|
||||
|
||||
return ack("[pubsub] image saved", true);
|
||||
} catch (reason) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (reason: any) {
|
||||
return ack(`[pubsub:error] ${reason.stack || reason}`, false);
|
||||
}
|
||||
};
|
||||
|
@ -1,22 +1,70 @@
|
||||
// import { getBlueprintImageRequestTopic, getPaginatedBlueprints } from "@factorio-sites/database";
|
||||
import {
|
||||
getBlueprintBookById,
|
||||
getBlueprintById,
|
||||
getBlueprintImageRequestTopic,
|
||||
hasBlueprintImage,
|
||||
init,
|
||||
searchBlueprintPages,
|
||||
} from "@factorio-sites/database";
|
||||
import { getFirstBlueprintFromChildTree } from "@factorio-sites/node-utils";
|
||||
import { BlueprintPage } from "@factorio-sites/types";
|
||||
|
||||
// export async function rePublishAllBlueprints() {
|
||||
// const topic = getBlueprintImageRequestTopic();
|
||||
// const fetchPage = async (page = 1) => {
|
||||
// const blueprints = await getPaginatedBlueprints(page);
|
||||
// if (blueprints.length === 0) {
|
||||
// return console.log("No more blueprints found");
|
||||
// }
|
||||
// console.log(`Publishing page ${page} with ${blueprints.length} blueprints`);
|
||||
const perPage = 10;
|
||||
const pageLimit = 99;
|
||||
|
||||
// await Promise.all(
|
||||
// blueprints.map((blueprint) => {
|
||||
// return topic.publishJSON({ blueprintId: blueprint.id });
|
||||
// })
|
||||
// );
|
||||
// fetchPage(page + 1);
|
||||
// };
|
||||
// await fetchPage();
|
||||
// }
|
||||
async function getBlueprintPageFirstBlueprint(page: BlueprintPage) {
|
||||
if (page.blueprint_id) {
|
||||
return getBlueprintById(page.blueprint_id);
|
||||
} else if (page.blueprint_book_id) {
|
||||
const book = await getBlueprintBookById(page.blueprint_book_id);
|
||||
if (!book) return null;
|
||||
const blueprint = getFirstBlueprintFromChildTree(book.child_tree);
|
||||
return getBlueprintById(blueprint);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export {};
|
||||
export async function rePublishAllBlueprints() {
|
||||
const topic = getBlueprintImageRequestTopic();
|
||||
if (!topic) throw Error("Topic not found");
|
||||
|
||||
let exists = 0;
|
||||
let published = 0;
|
||||
|
||||
await init();
|
||||
|
||||
const fetchPage = async (page = 1) => {
|
||||
const blueprintPages = await searchBlueprintPages({
|
||||
page,
|
||||
perPage,
|
||||
mode: "AND",
|
||||
order: "date",
|
||||
});
|
||||
|
||||
if (blueprintPages.rows.length === 0) {
|
||||
return console.log("No more blueprints found");
|
||||
}
|
||||
console.log(`Publishing page ${page} with ${blueprintPages.rows.length} blueprints`);
|
||||
|
||||
await Promise.all(
|
||||
blueprintPages.rows.map(async (blueprintPage) => {
|
||||
const blueprint = await getBlueprintPageFirstBlueprint(blueprintPage);
|
||||
if (!blueprint) {
|
||||
console.log(`Error: blueprint not found for page ${blueprintPage.id}`);
|
||||
return;
|
||||
}
|
||||
if (await hasBlueprintImage(blueprint.image_hash, "300")) {
|
||||
exists++;
|
||||
return;
|
||||
}
|
||||
published++;
|
||||
return topic.publishMessage({ json: { blueprintId: blueprint.id } });
|
||||
})
|
||||
);
|
||||
|
||||
if (page < pageLimit) await fetchPage(page + 1);
|
||||
};
|
||||
await fetchPage();
|
||||
|
||||
console.log(`done fetching, ${exists} already existed, ${published} published`);
|
||||
}
|
||||
|
@ -5,6 +5,6 @@
|
||||
"target": "ES2019",
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,5 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"]
|
||||
}
|
||||
|
4
apps/blueprints-e2e/src/plugins/index.js
vendored
4
apps/blueprints-e2e/src/plugins/index.js
vendored
@ -11,12 +11,10 @@
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor');
|
||||
const { preprocessTypescript } = require("@nrwl/cypress/plugins/preprocessor");
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
// Preprocess Typescript file using Nx helper
|
||||
on('file:preprocessor', preprocessTypescript(config));
|
||||
};
|
||||
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"next/babel",
|
||||
{
|
||||
"preset-react": {
|
||||
"runtime": "automatic",
|
||||
"importSource": "@emotion/react"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": ["@emotion/babel-plugin"]
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json", "plugin:@next/next/recommended"],
|
||||
"extends": [
|
||||
"plugin:@nrwl/nx/react-typescript",
|
||||
"../../.eslintrc.json",
|
||||
"plugin:@next/next/recommended"
|
||||
],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"env": {
|
||||
"browser": true,
|
||||
@ -281,7 +285,9 @@
|
||||
"parserOptions": {
|
||||
"project": ["apps/blueprints/tsconfig(.*)?.json"]
|
||||
},
|
||||
"rules": {}
|
||||
"rules": {
|
||||
"@next/next/no-html-link-for-pages": ["error", "apps/blueprints/src/pages"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
|
@ -9,6 +9,6 @@
|
||||
}
|
||||
],
|
||||
"@babel/preset-typescript",
|
||||
"@babel/preset-react"
|
||||
["@babel/preset-react", { "runtime": "automatic" }]
|
||||
]
|
||||
}
|
||||
|
1
apps/blueprints/jest.config.js
vendored
1
apps/blueprints/jest.config.js
vendored
@ -7,5 +7,4 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
|
||||
coverageDirectory: "../../coverage/apps/blueprints",
|
||||
snapshotSerializers: ["@emotion/jest/serializer"],
|
||||
};
|
||||
|
5
apps/blueprints/next-env.d.ts
vendored
5
apps/blueprints/next-env.d.ts
vendored
@ -1,3 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="@emotion/react/types/css-prop" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
|
5
apps/blueprints/next.config.js
vendored
5
apps/blueprints/next.config.js
vendored
@ -20,6 +20,11 @@ module.exports = {
|
||||
config.plugins.push(new ForkTsCheckerWebpackPlugin());
|
||||
}
|
||||
|
||||
if (!config.experiments) {
|
||||
config.experiments = {};
|
||||
}
|
||||
config.experiments.asyncWebAssembly = true;
|
||||
|
||||
return config;
|
||||
},
|
||||
async headers() {
|
||||
|
@ -3,7 +3,6 @@ jest.mock("next/config", () => () => ({
|
||||
publicRuntimeConfig: {},
|
||||
}));
|
||||
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import Index from "../src/pages/index";
|
||||
import * as nextRouter from "next/router";
|
||||
|
@ -109,7 +109,7 @@ export const BlueprintTile: React.FC<BlueprintTileProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div css={linkStyles}>
|
||||
<Box css={linkStyles}>
|
||||
<Link
|
||||
href={editLink ? `/user/blueprint/${blueprint.id}` : `/blueprint/${blueprint.id}`}
|
||||
passHref
|
||||
@ -127,6 +127,7 @@ export const BlueprintTile: React.FC<BlueprintTileProps> = ({
|
||||
objectFit="contain"
|
||||
alt={blueprint.title}
|
||||
onError={onImageError}
|
||||
unoptimized
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -150,6 +151,6 @@ export const BlueprintTile: React.FC<BlueprintTileProps> = ({
|
||||
</Box>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { memo } from "react";
|
||||
import { css } from "@emotion/react";
|
||||
import Link, { LinkProps } from "next/link";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
import { FactorioIcon } from "./FactorioIcon";
|
||||
import { FactorioCode } from "./FactorioCode";
|
||||
import { BlueprintBookData, BlueprintStringData, ChildTree, Icon } from "@factorio-sites/types";
|
||||
@ -132,11 +133,11 @@ const InnerBookChildTree: React.FC<BookChildTreeProps> = ({ book_item, base_url,
|
||||
export const BookChildTree: React.FC<BookChildTreeProps> = memo(
|
||||
({ book_item, base_url, selected_id }) => {
|
||||
return (
|
||||
<div css={componentStyles}>
|
||||
<Box css={componentStyles}>
|
||||
<div className="child-tree-wrapper ">
|
||||
<InnerBookChildTree book_item={book_item} base_url={base_url} selected_id={selected_id} />
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box } from "@chakra-ui/layout";
|
||||
import { Box, Text } from "@chakra-ui/layout";
|
||||
import styled from "@emotion/styled";
|
||||
import { IconSignalTypes } from "@factorio-sites/types";
|
||||
import { ReactNode } from "react";
|
||||
@ -49,7 +49,7 @@ const parseFactorioCode = (string: string): ReactNode => {
|
||||
if (match.start > lastHandledIndex) {
|
||||
let content = string.substr(lastHandledIndex, match.start - lastHandledIndex);
|
||||
content = content.replace(/ /g, "\u00A0");
|
||||
result.push(<span key={lastHandledIndex}>{content}</span>);
|
||||
result.push(<Text key={lastHandledIndex}>{content}</Text>);
|
||||
}
|
||||
|
||||
if (match.groups.color && match.groups.content) {
|
||||
@ -57,12 +57,12 @@ const parseFactorioCode = (string: string): ReactNode => {
|
||||
match.groups.color = `rgb(${match.groups.color})`;
|
||||
}
|
||||
result.push(
|
||||
<span
|
||||
<Text
|
||||
key={match.start}
|
||||
css={{ color: match.groups.color, display: "inline-flex", alignItems: "center" }}
|
||||
>
|
||||
{parseFactorioCode(match.groups.content)}
|
||||
</span>
|
||||
</Text>
|
||||
);
|
||||
} else if (match.groups.type && match.groups.icon) {
|
||||
if (match.groups.type === "img") {
|
||||
@ -88,7 +88,7 @@ const parseFactorioCode = (string: string): ReactNode => {
|
||||
});
|
||||
|
||||
if (lastHandledIndex < string.length) {
|
||||
result.push(<span key={lastHandledIndex}>{string.substr(lastHandledIndex)}</span>);
|
||||
result.push(<Text key={lastHandledIndex}>{string.substr(lastHandledIndex)}</Text>);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Box } from "@chakra-ui/layout";
|
||||
import { IconSignalTypes } from "@factorio-sites/types";
|
||||
|
||||
interface FactorioIconProps {
|
||||
@ -40,7 +41,7 @@ export const FactorioIcon: React.FC<FactorioIconProps> = ({ type, icon, size })
|
||||
return <span css={{ color: "#ffa700" }}>[{icon}]</span>;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
<Box
|
||||
css={{
|
||||
display: "inline-block",
|
||||
width: `${size}px`,
|
||||
|
@ -71,7 +71,7 @@ export const FullscreenImage: React.FC<FullscreenImageProps> = ({ alt, src }) =>
|
||||
/>
|
||||
</StyledImage>
|
||||
{open && (
|
||||
<div
|
||||
<Box
|
||||
css={elementStyle}
|
||||
onClick={(e) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -89,7 +89,7 @@ export const FullscreenImage: React.FC<FullscreenImageProps> = ({ alt, src }) =>
|
||||
<MapInteractionCSS value={state} onChange={setState}>
|
||||
<img alt={alt} src={src} />
|
||||
</MapInteractionCSS>
|
||||
</div>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import { css } from "@emotion/react";
|
||||
import { parseBlueprintStringClient } from "@factorio-sites/web-utils";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { PUBLIC_URL } from "../utils/env";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
|
||||
type FBE = typeof import("@fbe/editor");
|
||||
type Editor = InstanceType<FBE["Editor"]>;
|
||||
@ -89,7 +90,7 @@ export const ImageEditor: React.FC<ImageEditorProps> = ({ string, onError }) =>
|
||||
|
||||
// const picture = await editor.getPicture();
|
||||
// setImage(URL.createObjectURL(picture));
|
||||
} catch (reason) {
|
||||
} catch (reason: any) {
|
||||
setRenderError(true);
|
||||
if (onError) onError();
|
||||
if (Array.isArray(reason.errors)) {
|
||||
@ -101,7 +102,7 @@ export const ImageEditor: React.FC<ImageEditorProps> = ({ string, onError }) =>
|
||||
}, [string, editorLoaded, onError]);
|
||||
|
||||
return (
|
||||
<div css={editorCss}>
|
||||
<Box css={editorCss}>
|
||||
{renderError && (
|
||||
<div className="error">
|
||||
<h3>Failed to render blueprint</h3>
|
||||
@ -113,6 +114,6 @@ export const ImageEditor: React.FC<ImageEditorProps> = ({ string, onError }) =>
|
||||
)}
|
||||
<canvas id="pbe" ref={canvasRef} style={{ width: "100%", height: "auto" }} />
|
||||
{/* <img src={image} alt="blueprint" style={{ width: "500px" }}></img> */}
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,12 @@
|
||||
import React from "react";
|
||||
import styled from "@emotion/styled";
|
||||
import SimpleMDE, { SimpleMDEEditorProps } from "react-simplemde-editor";
|
||||
import React, { Suspense } from "react";
|
||||
import { css } from "@emotion/react";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
import type { SimpleMDEReactProps } from "react-simplemde-editor";
|
||||
import "easymde/dist/easymde.min.css";
|
||||
|
||||
const StyledSimpleMDE = styled(SimpleMDE)`
|
||||
const SimpleMDE = React.lazy(() => import("react-simplemde-editor"));
|
||||
|
||||
const styles = css`
|
||||
.editor-toolbar {
|
||||
button.active,
|
||||
button:hover {
|
||||
@ -34,8 +37,12 @@ const StyledSimpleMDE = styled(SimpleMDE)`
|
||||
}
|
||||
`;
|
||||
|
||||
export const MDEditor: React.FC<SimpleMDEEditorProps> = (props) => {
|
||||
export const MDEditor: React.FC<SimpleMDEReactProps> = (props) => {
|
||||
return (
|
||||
<StyledSimpleMDE options={{ spellChecker: false, sideBySideFullscreen: false }} {...props} />
|
||||
<Suspense fallback={null}>
|
||||
<Box css={styles}>
|
||||
<SimpleMDE options={{ spellChecker: false, sideBySideFullscreen: false }} {...props} />
|
||||
</Box>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
@ -2,6 +2,7 @@ import { css } from "@emotion/react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import rehypeSanitize from "rehype-sanitize";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
|
||||
const markdownStyle = css`
|
||||
overflow: auto;
|
||||
@ -19,7 +20,7 @@ const markdownStyle = css`
|
||||
`;
|
||||
|
||||
export const Markdown: React.FC<{ children: string }> = ({ children, ...props }) => (
|
||||
<div css={markdownStyle} {...props}>
|
||||
<Box css={markdownStyle} {...props}>
|
||||
<ReactMarkdown rehypePlugins={[rehypeRaw, rehypeSanitize]}>{children}</ReactMarkdown>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import MultiSelect from "react-multi-select-component";
|
||||
import { MultiSelect } from "react-multi-select-component";
|
||||
import styled from "@emotion/styled";
|
||||
import { ISelectProps } from "react-multi-select-component/dist/lib/interfaces";
|
||||
|
||||
type ISelectProps = Parameters<typeof MultiSelect>[0];
|
||||
|
||||
interface Tag {
|
||||
value: string;
|
||||
|
@ -1,5 +1,10 @@
|
||||
import MultiSelect from "react-multi-select-component";
|
||||
import { MultiSelect } from "react-multi-select-component";
|
||||
import { useFbeData } from "../hooks/fbe.hook";
|
||||
import styled from "@emotion/styled";
|
||||
|
||||
const MultiSelectStyled = styled(MultiSelect)`
|
||||
color: black;
|
||||
`;
|
||||
|
||||
interface Tag {
|
||||
value: string;
|
||||
@ -25,8 +30,7 @@ export const TagsSelect: React.FC<TagsSelectProps> = ({ value, onChange, classNa
|
||||
});
|
||||
|
||||
return (
|
||||
<MultiSelect
|
||||
css={{ color: "black" }}
|
||||
<MultiSelectStyled
|
||||
className={className}
|
||||
options={TAGS}
|
||||
value={value.map((value) => ({ value, label: value.replace(/[_-]/g, " ") }))}
|
||||
|
@ -1,10 +1,9 @@
|
||||
/* eslint-disable no-irregular-whitespace */
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { FactorioCode } from "../FactorioCode";
|
||||
import { createSerializer } from "@emotion/jest";
|
||||
|
||||
expect.addSnapshotSerializer(createSerializer({ DOMElements: false }));
|
||||
expect.addSnapshotSerializer(createSerializer());
|
||||
|
||||
const cleanUpElement = (element: Element) => {
|
||||
const el = element.querySelector("div > div");
|
||||
@ -30,7 +29,7 @@ describe("FactorioCode", () => {
|
||||
const { baseElement } = render(<FactorioCode code="Blueprint [color=red]red[/color]" />);
|
||||
|
||||
expect(cleanUpElement(baseElement)).toMatchInlineSnapshot(`
|
||||
.emotion-0 {
|
||||
.emotion-1 {
|
||||
color: red;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
@ -45,14 +44,16 @@ describe("FactorioCode", () => {
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<span>
|
||||
<p
|
||||
class="chakra-text emotion-0"
|
||||
>
|
||||
Blueprint
|
||||
</span>
|
||||
<span
|
||||
class="emotion-0"
|
||||
</p>
|
||||
<p
|
||||
class="chakra-text emotion-1"
|
||||
>
|
||||
red
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
@ -61,46 +62,6 @@ describe("FactorioCode", () => {
|
||||
const { baseElement } = render(<FactorioCode code="Blueprint [item=iron-ore]" />);
|
||||
|
||||
expect(cleanUpElement(baseElement)).toMatchInlineSnapshot(`
|
||||
.emotion-0 {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url('https://storage.googleapis.com/factorio-blueprints-assets/factorio/graphics/icons/iron-ore.png');
|
||||
-webkit-background-size: 38px;
|
||||
background-size: 38px;
|
||||
}
|
||||
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<span>
|
||||
Blueprint
|
||||
</span>
|
||||
<div
|
||||
class="emotion-0"
|
||||
/>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
|
||||
it("should render icons in colors", () => {
|
||||
const { baseElement } = render(
|
||||
<FactorioCode code="Blueprint [color=white]hello [item=iron-ore][/color]" />
|
||||
);
|
||||
|
||||
expect(cleanUpElement(baseElement)).toMatchInlineSnapshot(`
|
||||
.emotion-0 {
|
||||
color: white;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.emotion-1 {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
@ -113,19 +74,65 @@ describe("FactorioCode", () => {
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<span>
|
||||
Blueprint
|
||||
</span>
|
||||
<span
|
||||
class="emotion-0"
|
||||
<p
|
||||
class="chakra-text emotion-0"
|
||||
>
|
||||
<span>
|
||||
Blueprint
|
||||
</p>
|
||||
<div
|
||||
class="emotion-1"
|
||||
/>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
|
||||
it("should render icons in colors", () => {
|
||||
const { baseElement } = render(
|
||||
<FactorioCode code="Blueprint [color=white]hello [item=iron-ore][/color]" />
|
||||
);
|
||||
|
||||
expect(cleanUpElement(baseElement)).toMatchInlineSnapshot(`
|
||||
.emotion-1 {
|
||||
color: white;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.emotion-3 {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url('https://storage.googleapis.com/factorio-blueprints-assets/factorio/graphics/icons/iron-ore.png');
|
||||
-webkit-background-size: 38px;
|
||||
background-size: 38px;
|
||||
}
|
||||
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<p
|
||||
class="chakra-text emotion-0"
|
||||
>
|
||||
Blueprint
|
||||
</p>
|
||||
<p
|
||||
class="chakra-text emotion-1"
|
||||
>
|
||||
<p
|
||||
class="chakra-text emotion-0"
|
||||
>
|
||||
hello
|
||||
</span>
|
||||
</p>
|
||||
<div
|
||||
class="emotion-1"
|
||||
class="emotion-3"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
|
@ -102,7 +102,7 @@ export const BlueprintSubPage: React.FC<BlueprintProps> = ({
|
||||
<img
|
||||
src={`${PUBLIC_URL}/fbe.svg`}
|
||||
alt="Factorio blueprint editor"
|
||||
css={{ display: "inline-block", height: "24px", marginLeft: "10px" }}
|
||||
style={{ display: "inline-block", height: "24px", marginLeft: "10px" }}
|
||||
/>
|
||||
)}
|
||||
<Box css={{ display: "inline-block", flexGrow: 1, textAlign: "right" }}>
|
||||
|
@ -175,7 +175,7 @@ export const BlueprintBookSubPage: React.FC<BlueprintBookSubPageProps> = ({
|
||||
<img
|
||||
src={`${PUBLIC_URL}/fbe.svg`}
|
||||
alt="Factorio blueprint editor"
|
||||
css={{ display: "inline-block", height: "24px", marginLeft: "10px" }}
|
||||
style={{ display: "inline-block", height: "24px", marginLeft: "10px" }}
|
||||
/>
|
||||
)}
|
||||
<Box css={{ display: "inline-block", flexGrow: 1, textAlign: "right" }}>
|
||||
|
@ -25,7 +25,7 @@ export const useFetch = <T>(
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
dataState.nested(url).set(data);
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
setError(error);
|
||||
}
|
||||
setLoading(false);
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import { SimpleGrid, Box, Text, Image, Link } from "@chakra-ui/react";
|
||||
import { Panel } from "../components/Panel";
|
||||
@ -25,10 +24,10 @@ export const Index: NextPage = () => {
|
||||
})}
|
||||
>
|
||||
<Box>
|
||||
<h2 css={{ fontSize: "30px" }}>Factorio Blueprints by Barry</h2>
|
||||
<h2 style={{ fontSize: "30px" }}>Factorio Blueprints by Barry</h2>
|
||||
</Box>
|
||||
<Box css={{ marginRight: "1rem" }}>
|
||||
<h3 css={{ color: "orange" }}>
|
||||
<h3 style={{ color: "orange" }}>
|
||||
Work in progress! <IoIosConstruct css={{ display: "inline-block" }} />
|
||||
</h3>
|
||||
</Box>
|
||||
@ -67,7 +66,7 @@ export const Index: NextPage = () => {
|
||||
Factorio Blueprints uses the work of Teoxoy with the
|
||||
<a
|
||||
href="https://github.com/Teoxoy/factorio-blueprint-editor"
|
||||
css={{
|
||||
style={{
|
||||
textDecoration: "underline",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
@ -78,7 +77,7 @@ export const Index: NextPage = () => {
|
||||
<img
|
||||
src={`${PUBLIC_URL}/fbe.svg`}
|
||||
alt="Factorio blueprint editor"
|
||||
css={{ display: "inline-block", height: "18px" }}
|
||||
style={{ display: "inline-block", height: "18px" }}
|
||||
/>
|
||||
Factorio Blueprints Editor
|
||||
</a>
|
||||
@ -88,7 +87,7 @@ export const Index: NextPage = () => {
|
||||
And the{" "}
|
||||
<a
|
||||
href="https://github.com/demodude4u/Factorio-FBSR"
|
||||
css={{ textDecoration: "underline" }}
|
||||
style={{ textDecoration: "underline" }}
|
||||
>
|
||||
FBSR
|
||||
</a>{" "}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { NextPage } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
@ -97,9 +97,8 @@ export const Index: NextPage<IndexProps> = ({
|
||||
const [blueprints, setBlueprints] = useState<BlueprintPageWithUserFavorite[]>([]);
|
||||
const routerQueryToHref = useRouterQueryToHref();
|
||||
const data = useFbeData();
|
||||
const searchOptions = useFetch<{ entities: string[]; items: string[]; recipes: string[] }>(
|
||||
"/api/searchoptions"
|
||||
);
|
||||
const searchOptions =
|
||||
useFetch<{ entities: string[]; items: string[]; recipes: string[] }>("/api/searchoptions");
|
||||
|
||||
useEffect(() => {
|
||||
setSearchQuery((router.query.q as string) || "");
|
||||
@ -250,7 +249,7 @@ export const Index: NextPage<IndexProps> = ({
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<p css={{ marginTop: "10px" }}>No results found</p>
|
||||
<Text css={{ marginTop: "10px" }}>No results found</Text>
|
||||
)}
|
||||
</Box>
|
||||
<Box css={{ marginTop: "15px" }}>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import {
|
||||
FormControl,
|
||||
|
@ -47,7 +47,7 @@ export const fetchSteamProfile = async (steam_id: string, api_key: string) => {
|
||||
} else {
|
||||
throw Error("No players found for the given SteamID.");
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
throw Error("Steam server error: " + error.message);
|
||||
}
|
||||
};
|
||||
|
@ -14,7 +14,9 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"jsxImportSource": "@emotion/react",
|
||||
"incremental": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
@ -26,4 +28,4 @@
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,13 @@
|
||||
},
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
1
apps/factorioprints-scraper/jest.config.js
vendored
1
apps/factorioprints-scraper/jest.config.js
vendored
@ -11,4 +11,5 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ["ts", "js", "html"],
|
||||
coverageDirectory: "../../coverage/apps/factorioprints-scraper",
|
||||
testEnvironment: "node",
|
||||
};
|
||||
|
@ -4,6 +4,6 @@
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,5 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"]
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ RUN yarn
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN yarn run db-gen
|
||||
RUN yarn nx build blueprints --prod
|
||||
|
||||
FROM node:14-slim
|
||||
|
15
jest.config.js
vendored
15
jest.config.js
vendored
@ -1,12 +1,3 @@
|
||||
module.exports = {
|
||||
projects: [
|
||||
"<rootDir>/apps/blueprints",
|
||||
"<rootDir>/apps/blueprint-image-function",
|
||||
"<rootDir>/apps/factorioprints-scraper",
|
||||
"<rootDir>/libs/database",
|
||||
"<rootDir>/libs/utils",
|
||||
"<rootDir>/libs/common-utils",
|
||||
"<rootDir>/libs/web-utils",
|
||||
"<rootDir>/libs/types",
|
||||
],
|
||||
};
|
||||
const { getJestProjects } = require("@nrwl/jest");
|
||||
|
||||
module.exports = { projects: [...getJestProjects(), "<rootDir>/libs/utils"] };
|
||||
|
@ -6,6 +6,6 @@
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,15 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"]
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ const mapBlueprintInstanceToEntry = (entity: BlueprintModel): Blueprint => ({
|
||||
created_at: entity.created_at && entity.created_at.getTime() / 1000,
|
||||
updated_at: entity.updated_at && entity.updated_at.getTime() / 1000,
|
||||
game_version: entity.game_version || null,
|
||||
data: (entity.data as unknown) as DbBlueprintData,
|
||||
data: entity.data as unknown as DbBlueprintData,
|
||||
});
|
||||
|
||||
export async function getBlueprintById(id: string): Promise<Blueprint | null> {
|
||||
@ -31,6 +31,17 @@ export async function getBlueprintByHash(hash: string): Promise<Blueprint | null
|
||||
return result ? mapBlueprintInstanceToEntry(result) : null;
|
||||
}
|
||||
|
||||
export async function getPaginatedBlueprints({
|
||||
skip = 0,
|
||||
take = 30,
|
||||
}: {
|
||||
skip: number;
|
||||
take: number;
|
||||
}): Promise<Blueprint[]> {
|
||||
const results = await prisma.blueprint.findMany({ skip, take });
|
||||
return results.map(mapBlueprintInstanceToEntry);
|
||||
}
|
||||
|
||||
export async function createBlueprint(
|
||||
blueprint: BlueprintData,
|
||||
extraInfo: {
|
||||
|
@ -92,6 +92,7 @@ export const createSession = async (user: user, useragent: string, ip: string) =
|
||||
};
|
||||
|
||||
export const getSessionByToken = async (token: string) => {
|
||||
if (token.length !== 36 && token.length !== 32) return null;
|
||||
return await prisma.session.findUnique({
|
||||
where: { session_token: token },
|
||||
include: {
|
||||
|
@ -6,6 +6,6 @@
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,15 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"]
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
@ -6,6 +6,6 @@
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,15 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"]
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { comment, blueprint, user } from "@prisma/client";
|
||||
import { Icon, Signal } from "./blueprint-string";
|
||||
import { Signal } from "./blueprint-string";
|
||||
|
||||
export interface ChildTreeBlueprint {
|
||||
type: "blueprint";
|
||||
|
@ -6,6 +6,6 @@
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,15 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"]
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
@ -4,6 +4,6 @@
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": []
|
||||
},
|
||||
"exclude": ["**/*.spec.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -5,5 +5,15 @@
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"]
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
190
migrations.json
190
migrations.json
@ -1,28 +1,188 @@
|
||||
{
|
||||
"migrations": [
|
||||
{
|
||||
"version": "12.5.0-beta.1",
|
||||
"description": "Rename the workspace-schematic script into workspace-generator script",
|
||||
"factory": "./src/migrations/update-12-5-0/add-target-dependencies",
|
||||
"cli": "nx",
|
||||
"version": "12.0.0-beta.0",
|
||||
"description": "Migrate tsconfig.json to allow new jsx transform to be used. Removes the need for `import React from 'react'`",
|
||||
"factory": "./src/migrations/update-12-0-0/use-react-jsx-in-tsconfig",
|
||||
"package": "@nrwl/react",
|
||||
"name": "use-react-jsx-in-tsconfig-12.0.0"
|
||||
"package": "@nrwl/workspace",
|
||||
"name": "add-target-dependencies"
|
||||
},
|
||||
{
|
||||
"version": "13.0.0-beta.1",
|
||||
"description": "Add default base to nx.json if its not currently set",
|
||||
"factory": "./src/migrations/update-13-0-0/set-default-base-if-not-set",
|
||||
"cli": "nx",
|
||||
"package": "@nrwl/workspace",
|
||||
"name": "set-default-base-if-not-set"
|
||||
},
|
||||
{
|
||||
"version": "13.0.0-beta.4",
|
||||
"description": "Move global settings into nx.json, and project specific settings into workspace.json",
|
||||
"cli": "nx",
|
||||
"implementation": "./src/migrations/update-13-0-0/config-locations/config-locations",
|
||||
"package": "@nrwl/workspace",
|
||||
"name": "13-0-0-config-locations"
|
||||
},
|
||||
{
|
||||
"version": "13.2.0",
|
||||
"description": "Set --parallel=1 for existing repos to preserve the existing behavior",
|
||||
"cli": "nx",
|
||||
"implementation": "./src/migrations/update-13-2-0/set-parallel-default",
|
||||
"package": "@nrwl/workspace",
|
||||
"name": "set-parallel-default"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "12.0.0-beta.0",
|
||||
"description": "Update workspace to use `@emotion/babel-plugin` instead of `@emotion/babel-preset-css-prop` to support new jsx transform",
|
||||
"factory": "./src/migrations/update-12-0-0/update-emotion-setup",
|
||||
"package": "@nrwl/react",
|
||||
"name": "update-emotion-setup-12.0.0"
|
||||
"version": "12.8.0-beta.0",
|
||||
"description": "Remove Typescript Preprocessor Plugin",
|
||||
"factory": "./src/migrations/update-12-8-0/remove-typescript-plugin",
|
||||
"package": "@nrwl/cypress",
|
||||
"name": "remove-typescript-plugin"
|
||||
},
|
||||
{
|
||||
"version": "12.1.0-beta.1",
|
||||
"cli": "nx",
|
||||
"description": "Update jest-preset-angular to version 8.4.0",
|
||||
"factory": "./src/migrations/update-12-1-2/update-jest-preset-angular",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "update-jest-preset-angular-8-4-0"
|
||||
},
|
||||
{
|
||||
"version": "12.1.2-beta.1",
|
||||
"cli": "nx",
|
||||
"description": "Replace tsConfig with tsconfig for ts-jest in jest.config.js",
|
||||
"factory": "./src/migrations/update-12-1-2/update-ts-jest",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "update-ts-jest-6-5-5"
|
||||
},
|
||||
{
|
||||
"version": "12.4.0-beta.1",
|
||||
"cli": "nx",
|
||||
"description": "Add testEnvironment: 'jsdom' in web apps + libraries",
|
||||
"factory": "./src/migrations/update-12-4-0/add-test-environment-for-node",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "support-jest-27"
|
||||
},
|
||||
{
|
||||
"version": "12.4.0-beta.1",
|
||||
"cli": "nx",
|
||||
"description": "Support for Jest 27 via updating ts-jest + jest-preset-angular",
|
||||
"factory": "./src/migrations/update-12-4-0/update-jest-preset-angular",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "update-ts-jest-and-jest-preset-angular"
|
||||
},
|
||||
{
|
||||
"version": "12.6.0-beta.0",
|
||||
"cli": "nx",
|
||||
"description": "Uses `getJestProjects()` to populate projects array in root level `jest.config.js` file.",
|
||||
"factory": "./src/migrations/update-12-6-0/update-base-jest-config",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "update-jest-config-to-use-util"
|
||||
},
|
||||
{
|
||||
"version": "13.1.2-beta.0",
|
||||
"cli": "nx",
|
||||
"description": "Support .test. file names in tsconfigs",
|
||||
"factory": "./src/migrations/update-13-1-2/update-tsconfigs-for-tests",
|
||||
"package": "@nrwl/jest",
|
||||
"name": "update-ts-config-for-test-filenames"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "12.0.0-beta.0",
|
||||
"description": "Remove @types/react-redux from package.json since react-redux installs the package automatically now",
|
||||
"factory": "./src/migrations/update-12-0-0/remove-react-redux-types-package",
|
||||
"version": "12.6.0-beta.0",
|
||||
"description": "Add 'next' eslint config",
|
||||
"factory": "./src/migrations/update-12-6-0/add-next-eslint",
|
||||
"package": "@nrwl/next",
|
||||
"name": "add-next-eslint-12.6.0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "12.8.0-beta.11",
|
||||
"description": "Adjust the Next.js lib babel configuration for styled-jsx",
|
||||
"factory": "./src/migrations/update-12-8-0/remove-styled-jsx-babel-plugin",
|
||||
"package": "@nrwl/next",
|
||||
"name": "fix-nextjs-lib-babel-config-12.8.0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "12.10.0-beta.1",
|
||||
"description": "Updates .eslintrc.json file to use the correct pages directory for '@next/next/no-html-link-for-pages'.",
|
||||
"factory": "./src/migrations/update-12-10-0/fix-page-dir-for-eslint",
|
||||
"package": "@nrwl/next",
|
||||
"name": "fix-page-dir-for-eslint"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.0",
|
||||
"description": "Update tsconfig.json to use `jsxImportSource` to support css prop",
|
||||
"factory": "./src/migrations/update-13-0-0/update-emotion-setup",
|
||||
"package": "@nrwl/next",
|
||||
"name": "update-emotion-setup-13.0.0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.1",
|
||||
"description": "Set `webpack5: true` for all next.js projects.",
|
||||
"factory": "./src/migrations/update-13-0-0/update-to-webpack-5",
|
||||
"package": "@nrwl/next",
|
||||
"name": "update-to-webpack-5"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.3-beta.1",
|
||||
"description": "Fix setup for less stylesheets",
|
||||
"factory": "./src/migrations/update-13-0-3/fix-less",
|
||||
"package": "@nrwl/next",
|
||||
"name": "fix-less"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.1.1-beta.1",
|
||||
"description": "Enables SWC for Next.js apps.",
|
||||
"factory": "./src/migrations/update-13-1-1/enable-swc",
|
||||
"package": "@nrwl/next",
|
||||
"name": "enable-swc"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.1",
|
||||
"description": "Remove packages installed by Nx 12's `@nrwl/node:webpack5` generator.",
|
||||
"factory": "./src/migrations/update-13-0-0/remove-webpack-5-packages-13-0-0",
|
||||
"package": "@nrwl/node",
|
||||
"name": "remove-webpack-5-packages"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.0",
|
||||
"description": "Update tsconfig.json to use `jsxImportSource` to support css prop",
|
||||
"factory": "./src/migrations/update-13-0-0/update-emotion-setup",
|
||||
"package": "@nrwl/react",
|
||||
"name": "remove-react-redux-types-package-12.0.0"
|
||||
"name": "update-emotion-setup-13.0.0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.0",
|
||||
"description": "Migrate Storybook to use webpack 5",
|
||||
"factory": "./src/migrations/update-13-0-0/migrate-storybook-to-webpack-5",
|
||||
"package": "@nrwl/react",
|
||||
"name": "migrate-storybook-to-webpack-5-13.0.0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.1",
|
||||
"description": "Removes deprecated node-sass package (sass is already a dependency of @nrwl/web).",
|
||||
"factory": "./src/migrations/update-13-0-0/remove-node-sass-13-0-0",
|
||||
"package": "@nrwl/web",
|
||||
"name": "remove-node-sass-13-0-0"
|
||||
},
|
||||
{
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.1",
|
||||
"description": "Remove packages installed by Nx 12's `@nrwl/web:webpack5` generator.",
|
||||
"factory": "./src/migrations/update-13-0-0/remove-webpack-5-packages-13-0-0",
|
||||
"package": "@nrwl/web",
|
||||
"name": "remove-webpack-5-packages"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
48
nx.json
48
nx.json
@ -1,9 +1,14 @@
|
||||
{
|
||||
"npmScope": "factorio-sites",
|
||||
"affected": { "defaultBase": "master" },
|
||||
"affected": {
|
||||
"defaultBase": "master"
|
||||
},
|
||||
"implicitDependencies": {
|
||||
"workspace.json": "*",
|
||||
"package.json": { "dependencies": "*", "devDependencies": "*" },
|
||||
"package.json": {
|
||||
"dependencies": "*",
|
||||
"devDependencies": "*"
|
||||
},
|
||||
"tsconfig.base.json": "*",
|
||||
"tslint.json": "*",
|
||||
".eslintrc.json": "*",
|
||||
@ -12,18 +17,35 @@
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "@nrwl/workspace/tasks-runners/default",
|
||||
"options": { "cacheableOperations": ["build", "lint", "test", "e2e"] }
|
||||
"options": {
|
||||
"cacheableOperations": ["build", "lint", "test", "e2e"],
|
||||
"parallel": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"blueprints": { "tags": [] },
|
||||
"blueprints-e2e": { "tags": [], "implicitDependencies": ["blueprints"] },
|
||||
"blueprint-image-function": { "tags": [] },
|
||||
"factorioprints-scraper": { "tags": [] },
|
||||
"database": { "tags": [] },
|
||||
"node-utils": { "tags": [] },
|
||||
"common-utils": { "tags": [] },
|
||||
"web-utils": { "tags": [] },
|
||||
"types": { "tags": [] }
|
||||
"targetDependencies": {
|
||||
"build": [
|
||||
{
|
||||
"target": "build",
|
||||
"projects": "dependencies"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cli": {
|
||||
"defaultCollection": "@nrwl/next"
|
||||
},
|
||||
"defaultProject": "blueprints",
|
||||
"generators": {
|
||||
"@nrwl/react": {
|
||||
"application": {
|
||||
"babel": true
|
||||
}
|
||||
},
|
||||
"@nrwl/next": {
|
||||
"application": {
|
||||
"style": "@emotion/styled",
|
||||
"linter": "eslint"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
143
package.json
143
package.json
@ -25,99 +25,102 @@
|
||||
"workspace-schematic": "nx workspace-schematic",
|
||||
"dep-graph": "nx dep-graph",
|
||||
"help": "nx help",
|
||||
"db-gen": "npx prisma generate --schema=./apps/blueprints/prisma/schema.prisma"
|
||||
"postinstall": "npx prisma generate --schema=./apps/blueprints/prisma/schema.prisma"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/react": "1.5.2",
|
||||
"@emotion/react": "11.1.5",
|
||||
"@emotion/server": "11.0.0",
|
||||
"@emotion/styled": "11.3.0",
|
||||
"@chakra-ui/react": "1.7.2",
|
||||
"@emotion/react": "11.7.0",
|
||||
"@emotion/server": "11.4.0",
|
||||
"@emotion/styled": "11.6.0",
|
||||
"@fbe/editor": "file:.yalc/@fbe/editor",
|
||||
"@google-cloud/datastore": "6.3.1",
|
||||
"@google-cloud/pubsub": "2.11.0",
|
||||
"@google-cloud/secret-manager": "3.6.0",
|
||||
"@google-cloud/storage": "5.8.3",
|
||||
"@hookstate/core": "3.0.6",
|
||||
"@prisma/client": "2.21.2",
|
||||
"@google-cloud/datastore": "6.6.2",
|
||||
"@google-cloud/pubsub": "2.18.3",
|
||||
"@google-cloud/secret-manager": "3.10.1",
|
||||
"@google-cloud/storage": "5.16.1",
|
||||
"@hookstate/core": "3.0.13",
|
||||
"@prisma/client": "3.6.0",
|
||||
"bcrypt": "5.0.1",
|
||||
"clsx": "1.1.1",
|
||||
"cookie": "0.4.1",
|
||||
"date-fns": "2.21.1",
|
||||
"date-fns": "2.27.0",
|
||||
"document-register-element": "1.14.10",
|
||||
"easymde": "2.15.0",
|
||||
"factorio-wasm": "file:.yalc/factorio-wasm",
|
||||
"formik": "2.2.6",
|
||||
"framer-motion": "4.1.8",
|
||||
"next": "10.1.3",
|
||||
"formik": "2.2.9",
|
||||
"framer-motion": "5.3.3",
|
||||
"next": "12.0.4",
|
||||
"nprogress": "0.2.0",
|
||||
"openid": "2.0.8",
|
||||
"openid": "2.0.10",
|
||||
"pako": "1.0.11",
|
||||
"pg": "8.6.0",
|
||||
"phin": "3.5.1",
|
||||
"puppeteer": "8.0.0",
|
||||
"pg": "8.7.1",
|
||||
"phin": "3.6.1",
|
||||
"puppeteer": "12.0.1",
|
||||
"react": "17.0.2",
|
||||
"react-cookie": "4.0.3",
|
||||
"react-cookie": "4.1.1",
|
||||
"react-dom": "17.0.2",
|
||||
"react-icons": "4.2.0",
|
||||
"react-icons": "4.3.1",
|
||||
"react-map-interaction": "file:.yalc/react-map-interaction",
|
||||
"react-markdown": "6.0.0",
|
||||
"react-multi-select-component": "4.0.1",
|
||||
"react-paginate": "7.1.2",
|
||||
"react-simplemde-editor": "4.1.3",
|
||||
"rehype-raw": "5.1.0",
|
||||
"rehype-sanitize": "4.0.0",
|
||||
"sharp": "0.28.1",
|
||||
"ws": "7.4.4"
|
||||
"react-markdown": "7.1.1",
|
||||
"react-multi-select-component": "4.1.14",
|
||||
"react-paginate": "8.0.2",
|
||||
"react-simplemde-editor": "5.0.2",
|
||||
"rehype-raw": "6.1.0",
|
||||
"rehype-sanitize": "5.0.0",
|
||||
"sharp": "0.29.3",
|
||||
"ws": "8.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.13.15",
|
||||
"@babel/preset-env": "7.13.15",
|
||||
"@babel/preset-react": "7.13.13",
|
||||
"@babel/preset-typescript": "7.13.0",
|
||||
"@emotion/jest": "11.3.0",
|
||||
"@emotion/jest": "11.6.0",
|
||||
"@next/eslint-plugin-next": "10.1.3",
|
||||
"@nrwl/cli": "12.0.6",
|
||||
"@nrwl/cypress": "12.0.6",
|
||||
"@nrwl/eslint-plugin-nx": "12.0.6",
|
||||
"@nrwl/jest": "12.0.6",
|
||||
"@nrwl/next": "12.0.6",
|
||||
"@nrwl/node": "12.0.6",
|
||||
"@nrwl/react": "12.0.6",
|
||||
"@nrwl/web": "12.0.6",
|
||||
"@nrwl/workspace": "12.0.6",
|
||||
"@testing-library/react": "11.2.6",
|
||||
"@types/bcrypt": "3.0.1",
|
||||
"@types/cookie": "0.4.0",
|
||||
"@types/jest": "26.0.22",
|
||||
"@types/node": "14.14.41",
|
||||
"@nrwl/cli": "13.2.1",
|
||||
"@nrwl/cypress": "13.2.1",
|
||||
"@nrwl/eslint-plugin-nx": "13.2.1",
|
||||
"@nrwl/jest": "13.2.1",
|
||||
"@nrwl/next": "13.2.1",
|
||||
"@nrwl/node": "13.2.1",
|
||||
"@nrwl/react": "13.2.1",
|
||||
"@nrwl/web": "13.2.1",
|
||||
"@nrwl/workspace": "13.2.1",
|
||||
"@testing-library/react": "12.1.2",
|
||||
"@types/bcrypt": "5.0.0",
|
||||
"@types/cookie": "0.4.1",
|
||||
"@types/jest": "27.0.3",
|
||||
"@types/node": "16.11.11",
|
||||
"@types/nprogress": "0.2.0",
|
||||
"@types/openid": "2.0.1",
|
||||
"@types/pako": "1.0.1",
|
||||
"@types/puppeteer": "5.4.3",
|
||||
"@types/react": "17.0.3",
|
||||
"@types/react-dom": "17.0.3",
|
||||
"@types/react-paginate": "6.2.1",
|
||||
"@types/sharp": "0.28.0",
|
||||
"@types/ws": "7.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "4.22.0",
|
||||
"@typescript-eslint/parser": "4.22.0",
|
||||
"babel-jest": "26.6.3",
|
||||
"@types/openid": "2.0.2",
|
||||
"@types/pako": "1.0.2",
|
||||
"@types/puppeteer": "5.4.4",
|
||||
"@types/react": "17.0.37",
|
||||
"@types/react-dom": "17.0.11",
|
||||
"@types/react-paginate": "7.1.1",
|
||||
"@types/sharp": "0.29.4",
|
||||
"@types/ws": "8.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.5.0",
|
||||
"@typescript-eslint/parser": "5.5.0",
|
||||
"babel-jest": "27.4.2",
|
||||
"cypress": "7.1.0",
|
||||
"dotenv": "8.2.0",
|
||||
"dotenv": "10.0.0",
|
||||
"eslint": "7.24.0",
|
||||
"eslint-config-prettier": "8.2.0",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"fork-ts-checker-webpack-plugin": "6.2.1",
|
||||
"jest": "26.6.3",
|
||||
"prettier": "2.2.1",
|
||||
"prisma": "2.21.2",
|
||||
"ts-jest": "26.5.5",
|
||||
"ts-node": "9.1.1",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-react": "7.27.1",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"fork-ts-checker-webpack-plugin": "6.5.0",
|
||||
"jest": "27.4.3",
|
||||
"prettier": "2.5.1",
|
||||
"prisma": "3.6.0",
|
||||
"ts-jest": "27.0.7",
|
||||
"ts-node": "10.4.0",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "4.2.4",
|
||||
"wasm-loader": "1.3.0"
|
||||
"typescript": "4.5.2",
|
||||
"wasm-loader": "1.3.0",
|
||||
"@pulumi/pulumi": "3.0.0",
|
||||
"@pulumi/gcp": "5.0.0"
|
||||
}
|
||||
}
|
||||
|
2
pulumi/Pulumi.dev.yaml
Normal file
2
pulumi/Pulumi.dev.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
config:
|
||||
gcp:project: factorio-sites-dev
|
2
pulumi/Pulumi.production.yaml
Normal file
2
pulumi/Pulumi.production.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
config:
|
||||
gcp:project: factorio-sites
|
3
pulumi/Pulumi.yaml
Normal file
3
pulumi/Pulumi.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
name: factorio-sites
|
||||
runtime: nodejs
|
||||
description: Factorio blueprints mono repo
|
66
pulumi/dev.index.ts
Normal file
66
pulumi/dev.index.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import * as path from "path";
|
||||
import * as dotenv from "dotenv";
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as gcp from "@pulumi/gcp";
|
||||
|
||||
dotenv.config({ path: path.join(__dirname, ".env") });
|
||||
|
||||
const account = new gcp.serviceaccount.Account("factorio-blueprints", {
|
||||
accountId: "factorio-blueprints",
|
||||
displayName: "Factorio blueprints service account",
|
||||
});
|
||||
// Can't get service account roles sorted, manual steps
|
||||
// 1. Add a member in IAM with the same email as the service account
|
||||
// 2. Assign roles to that member in IAM
|
||||
// Roles used: Pub/Sub Editor, Secret Manager Secret Accessor, Storage Object Admin
|
||||
|
||||
const postgresPasswordSecret = new gcp.secretmanager.Secret("prd-postgres-password", {
|
||||
replication: { automatic: true },
|
||||
secretId: "prd-postgres-password",
|
||||
});
|
||||
|
||||
const postgresPasswordSecretVersion = new gcp.secretmanager.SecretVersion(
|
||||
"prd-postgres-password-version",
|
||||
{
|
||||
secret: postgresPasswordSecret.id,
|
||||
secretData: process.env.DATABASE_PASSWORD,
|
||||
}
|
||||
);
|
||||
|
||||
const functionsBucket = new gcp.storage.Bucket("blueprint-thumbnail-render-code", {
|
||||
storageClass: "STANDARD",
|
||||
location: "EUROPE-WEST1",
|
||||
});
|
||||
|
||||
const blueprintImagesBucket = new gcp.storage.Bucket("blueprint-thumbnail-images", {
|
||||
storageClass: "STANDARD",
|
||||
location: "EUROPE-WEST1",
|
||||
});
|
||||
|
||||
const archive = new gcp.storage.BucketObject("archive", {
|
||||
bucket: functionsBucket.name,
|
||||
source: new pulumi.asset.FileArchive("../dist/apps/blueprint-image-function"),
|
||||
});
|
||||
|
||||
const renderTopic = new gcp.pubsub.Topic("blueprint-thumbnail-render");
|
||||
|
||||
new gcp.cloudfunctions.Function("blueprint-image-render", {
|
||||
eventTrigger: {
|
||||
eventType: "google.pubsub.topic.publish",
|
||||
resource: renderTopic.name,
|
||||
},
|
||||
sourceArchiveBucket: functionsBucket.name,
|
||||
sourceArchiveObject: archive.name,
|
||||
entryPoint: "renderImagePubSub",
|
||||
runtime: "nodejs14",
|
||||
region: "europe-west1",
|
||||
timeout: 60,
|
||||
environmentVariables: {
|
||||
POSTGRES_DB: "factorio-blueprints",
|
||||
POSTGRES_USER: "factorio-blueprints",
|
||||
POSTGRES_HOST: process.env.POSTGRES_HOST,
|
||||
POSTGRES_PASSWORD: postgresPasswordSecretVersion.id,
|
||||
GCP_BLUEPRINT_IMAGES_BUCKET: blueprintImagesBucket.id,
|
||||
},
|
||||
serviceAccountEmail: account.email,
|
||||
});
|
66
pulumi/index.ts
Normal file
66
pulumi/index.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import * as path from "path";
|
||||
import * as dotenv from "dotenv";
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as gcp from "@pulumi/gcp";
|
||||
|
||||
dotenv.config({ path: path.join(__dirname, ".env") });
|
||||
|
||||
// const account = new gcp.serviceaccount.Account("factorio-blueprints", {
|
||||
// accountId: "factorio-blueprints",
|
||||
// displayName: "Factorio blueprints service account",
|
||||
// });
|
||||
// Can't get service account roles sorted, manual steps
|
||||
// 1. Add a member in IAM with the same email as the service account
|
||||
// 2. Assign roles to that member in IAM
|
||||
// Roles used: Pub/Sub Editor, Secret Manager Secret Accessor, Storage Object Admin
|
||||
|
||||
// const postgresPasswordSecret = new gcp.secretmanager.Secret("prd-postgres-password", {
|
||||
// replication: { automatic: true },
|
||||
// secretId: "prd-postgres-password",
|
||||
// });
|
||||
|
||||
// const postgresPasswordSecretVersion = new gcp.secretmanager.SecretVersion(
|
||||
// "prd-postgres-password-version",
|
||||
// {
|
||||
// secret: postgresPasswordSecret.id,
|
||||
// secretData: process.env.DATABASE_PASSWORD,
|
||||
// }
|
||||
// );
|
||||
|
||||
const functionsBucket = new gcp.storage.Bucket("blueprint-thumbnail-render-code", {
|
||||
storageClass: "STANDARD",
|
||||
location: "EUROPE-WEST1",
|
||||
});
|
||||
|
||||
// const blueprintImagesBucket = new gcp.storage.Bucket("blueprint-thumbnail-images", {
|
||||
// storageClass: "STANDARD",
|
||||
// location: "EUROPE-WEST1",
|
||||
// });
|
||||
|
||||
const archive = new gcp.storage.BucketObject("archive", {
|
||||
bucket: functionsBucket.name,
|
||||
source: new pulumi.asset.FileArchive("../dist/apps/blueprint-image-function"),
|
||||
});
|
||||
|
||||
// const renderTopic = new gcp.pubsub.Topic("blueprint-thumbnail-render");
|
||||
|
||||
new gcp.cloudfunctions.Function("blueprint-image-render", {
|
||||
eventTrigger: {
|
||||
eventType: "google.pubsub.topic.publish",
|
||||
resource: process.env.IMAGE_RENDER_TOPIC,
|
||||
},
|
||||
sourceArchiveBucket: functionsBucket.name,
|
||||
sourceArchiveObject: archive.name,
|
||||
entryPoint: "renderImagePubSub",
|
||||
runtime: "nodejs14",
|
||||
region: "europe-west1",
|
||||
timeout: 60,
|
||||
environmentVariables: {
|
||||
POSTGRES_DB: "factorio-blueprints",
|
||||
POSTGRES_USER: "factorio-blueprints",
|
||||
POSTGRES_HOST: process.env.POSTGRES_HOST,
|
||||
POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
|
||||
GCP_BLUEPRINT_IMAGES_BUCKET: "blueprint-images",
|
||||
},
|
||||
serviceAccountEmail: process.env.RENDER_FUNCTION_SERVICE_ACCOUNT,
|
||||
});
|
13
pulumi/package.json
Normal file
13
pulumi/package.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "factorio-sites",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"pulumi:up": "pulumi up"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pulumi/pulumi": "^3.0.0",
|
||||
"@pulumi/gcp": "^5.0.0"
|
||||
}
|
||||
}
|
@ -17,11 +17,11 @@
|
||||
"strict": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@factorio-sites/common-utils": ["libs/common-utils/src/index.ts"],
|
||||
"@factorio-sites/database": ["libs/database/src/index.ts"],
|
||||
"@factorio-sites/node-utils": ["libs/node-utils/src/index.ts"],
|
||||
"@factorio-sites/common-utils": ["libs/common-utils/src/index.ts"],
|
||||
"@factorio-sites/web-utils": ["libs/web-utils/src/index.ts"],
|
||||
"@factorio-sites/types": ["libs/types/src/index.ts"]
|
||||
"@factorio-sites/types": ["libs/types/src/index.ts"],
|
||||
"@factorio-sites/web-utils": ["libs/web-utils/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "tmp"]
|
||||
|
252
workspace.json
252
workspace.json
@ -1,6 +1,64 @@
|
||||
{
|
||||
"version": 1,
|
||||
"projects": {
|
||||
"blueprint-image-function": {
|
||||
"root": "apps/blueprint-image-function",
|
||||
"sourceRoot": "apps/blueprint-image-function/src",
|
||||
"projectType": "application",
|
||||
"prefix": "blueprint-image-function",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@nrwl/node:build",
|
||||
"options": {
|
||||
"outputPath": "dist/apps/blueprint-image-function",
|
||||
"main": "apps/blueprint-image-function/src/main.ts",
|
||||
"tsConfig": "apps/blueprint-image-function/tsconfig.app.json",
|
||||
"assets": [
|
||||
{
|
||||
"input": "apps/blueprints/prisma",
|
||||
"glob": "schema.prisma",
|
||||
"output": "./prisma"
|
||||
}
|
||||
],
|
||||
"generatePackageJson": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"extractLicenses": true,
|
||||
"inspect": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/blueprint-image-function/src/environments/environment.ts",
|
||||
"with": "apps/blueprint-image-function/src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@nrwl/node:execute",
|
||||
"options": {
|
||||
"buildTarget": "blueprint-image-function:build"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/blueprint-image-function/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "apps/blueprint-image-function/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"blueprints": {
|
||||
"root": "apps/blueprints",
|
||||
"sourceRoot": "apps/blueprints",
|
||||
@ -39,9 +97,7 @@
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"apps/blueprints/**/*.{ts,tsx}"
|
||||
]
|
||||
"lintFilePatterns": ["apps/blueprints/**/*.{ts,tsx}"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
@ -51,7 +107,8 @@
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"blueprints-e2e": {
|
||||
"root": "apps/blueprints-e2e",
|
||||
@ -74,64 +131,56 @@
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"apps/blueprints-e2e/**/*.{js,ts}"
|
||||
]
|
||||
"lintFilePatterns": ["apps/blueprints-e2e/**/*.{js,ts}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"implicitDependencies": ["blueprints"]
|
||||
},
|
||||
"blueprint-image-function": {
|
||||
"root": "apps/blueprint-image-function",
|
||||
"sourceRoot": "apps/blueprint-image-function/src",
|
||||
"projectType": "application",
|
||||
"prefix": "blueprint-image-function",
|
||||
"common-utils": {
|
||||
"root": "libs/common-utils",
|
||||
"sourceRoot": "libs/common-utils/src",
|
||||
"projectType": "library",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@nrwl/node:build",
|
||||
"options": {
|
||||
"outputPath": "dist/apps/blueprint-image-function",
|
||||
"main": "apps/blueprint-image-function/src/main.ts",
|
||||
"tsConfig": "apps/blueprint-image-function/tsconfig.app.json",
|
||||
"assets": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"extractLicenses": true,
|
||||
"inspect": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/blueprint-image-function/src/environments/environment.ts",
|
||||
"with": "apps/blueprint-image-function/src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@nrwl/node:execute",
|
||||
"options": {
|
||||
"buildTarget": "blueprint-image-function:build"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"apps/blueprint-image-function/**/*.ts"
|
||||
]
|
||||
"lintFilePatterns": ["libs/common-utils/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "apps/blueprint-image-function/jest.config.js",
|
||||
"jestConfig": "libs/common-utils/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"database": {
|
||||
"root": "libs/database",
|
||||
"sourceRoot": "libs/database/src",
|
||||
"projectType": "library",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": ["libs/database/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "libs/database/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"factorioprints-scraper": {
|
||||
"root": "apps/factorioprints-scraper",
|
||||
@ -146,9 +195,7 @@
|
||||
"outputPath": "dist/apps/factorioprints-scraper",
|
||||
"main": "apps/factorioprints-scraper/src/main.ts",
|
||||
"tsConfig": "apps/factorioprints-scraper/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/factorioprints-scraper/src/assets"
|
||||
]
|
||||
"assets": ["apps/factorioprints-scraper/src/assets"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@ -173,9 +220,7 @@
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"apps/factorioprints-scraper/**/*.ts"
|
||||
]
|
||||
"lintFilePatterns": ["apps/factorioprints-scraper/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
@ -185,30 +230,8 @@
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"database": {
|
||||
"root": "libs/database",
|
||||
"sourceRoot": "libs/database/src",
|
||||
"projectType": "library",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/database/**/*.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "libs/database/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"node-utils": {
|
||||
"root": "libs/node-utils",
|
||||
@ -219,9 +242,7 @@
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/node-utils/**/*.ts"
|
||||
]
|
||||
"lintFilePatterns": ["libs/node-utils/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
@ -231,30 +252,30 @@
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"common-utils": {
|
||||
"root": "libs/common-utils",
|
||||
"sourceRoot": "libs/common-utils/src",
|
||||
"types": {
|
||||
"root": "libs/types",
|
||||
"sourceRoot": "libs/types/src",
|
||||
"projectType": "library",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/common-utils/**/*.ts"
|
||||
]
|
||||
"lintFilePatterns": ["libs/types/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/libs/types"],
|
||||
"options": {
|
||||
"jestConfig": "libs/common-utils/jest.config.js",
|
||||
"jestConfig": "libs/types/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"web-utils": {
|
||||
"root": "libs/web-utils",
|
||||
@ -265,9 +286,7 @@
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/web-utils/**/*.ts"
|
||||
]
|
||||
"lintFilePatterns": ["libs/web-utils/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
@ -277,49 +296,8 @@
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"types": {
|
||||
"root": "libs/types",
|
||||
"sourceRoot": "libs/types/src",
|
||||
"projectType": "library",
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/types/**/*.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"outputs": [
|
||||
"coverage/libs/types"
|
||||
],
|
||||
"options": {
|
||||
"jestConfig": "libs/types/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"defaultCollection": "@nrwl/next"
|
||||
},
|
||||
"schematics": {
|
||||
"@nrwl/react": {
|
||||
"application": {
|
||||
"babel": true
|
||||
}
|
||||
},
|
||||
"@nrwl/next": {
|
||||
"application": {
|
||||
"style": "@emotion/styled",
|
||||
"linter": "eslint"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "blueprints"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user