Skip to content

Commit

Permalink
chore: add issue test
Browse files Browse the repository at this point in the history
  • Loading branch information
cyco130 committed Mar 5, 2022
1 parent 8f47faf commit b9dce60
Show file tree
Hide file tree
Showing 22 changed files with 908 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/issue-32.yml
@@ -0,0 +1,37 @@
name: issue-32

on: workflow_dispatch

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest]
node_version: [16]
fail-fast: false
name: "Test on node-${{ matrix.node_version }}, ${{ matrix.os }}"
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install pnpm
uses: pnpm/action-setup@v2.1.0
with:
version: 6

- name: Set node version to ${{ matrix.node_version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node_version }}
cache: "pnpm"

- name: Install
run: pnpm install

- name: Build
run: pnpm run build-packages

- name: Run CI tests
working-directory: ./issue-testbed/issue-32
run: pnpm run ci
51 changes: 51 additions & 0 deletions issue-testbed/issue-32/README.md
@@ -0,0 +1,51 @@
# Rakkas TypeScript Starter

## Quick start

```sh
# Start development server on localhost:3000
npm run dev

# Start a development server on port 4000 and make it externally accessible
npm run dev -- --host=0.0.0.0 --port=4000

# Build a production server
npm run build

# Start production server on 0.0.0.0:3000
# and trust x-forwarded-* headers set by your reverse proxy
HOST=0.0.0.0 PORT=3000 TRUST_FORWARDED_ORIGIN=1 npm start
```

## Important files and directories

| Path | Description |
| ------------------ | --------------------------------------------- |
| `rakkas.config.ts` | Rakkas configuration |
| `public` | Static files to be served from `/` |
| `src/client.ts` | Client-side cusomization hooks |
| `src/server.ts` | Server-side customization hooks |
| `src/pages` | Pages and layouts (client-side routes) |
| `src/api` | Endpoints and middleware (server-side routes) |
| `src/ambient.d.ts` | Ambient type declarations |

## All development scripts

Some of them might not be available depending on the features you selected when generating his project.

| Script | Description |
| -------------------------- | ------------------------------------------------------- |
| `npm run dev` | Start development server on localhost:3000 |
| `npm run build` | Build a production server |
| `npm start` | Start the production server |
| `npm run check` | Run all checks (linters, typecheckers, tests) |
| `npm test` | Run all tests |
| `npm run test:unit` | Run unit tests |
| `npm run test:e2e` | Start the server and run end-to-end tests (build first) |
| `npm run test:e2e:api` | Run end-to-end API tests (start the server first) |
| `npm run test:e2e:browser` | Run end-to-end browser tests (start the server first) |
| `npm run typecheck` | Check the types |
| `npm run lint` | Run all linters |
| `npm run lint:ts` | Lint TypeScript files |
| `npm run lint:css` | Lint CSS files |
| `npm run format` | Format source files with Prettier |
34 changes: 34 additions & 0 deletions issue-testbed/issue-32/package.json
@@ -0,0 +1,34 @@
{
"private": true,
"name": "rakkas-ci",
"description": "Rakkas.js CI",
"scripts": {
"dev": "rakkas dev",
"build": "rakkas build",
"start": "node dist/server",
"ci": "cross-env CI=1 vitest",
"check": "run-p typecheck",
"typecheck": "tsc -p tsconfig.json --noEmit",
"format": "prettier . --write"
},
"dependencies": {
"rakkasjs": "workspace:*",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet-async": "^1.2.2"
},
"devDependencies": {
"@rakkasjs/cli": "workspace:*",
"@types/node": "^16.11.12",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"cross-env": "^7.0.3",
"kill-port": "^1.6.1",
"node-fetch": "^2.6.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
"typescript-plugin-css-modules": "^3.4.0",
"vitest": "^0.5.9"
}
}
Binary file added issue-testbed/issue-32/public/favicon.ico
Binary file not shown.
36 changes: 36 additions & 0 deletions issue-testbed/issue-32/rakkas.config.ts
@@ -0,0 +1,36 @@
import { defineConfig } from "@rakkasjs/cli";

// Edit this file to change default configuration options.
// You may delete it if you're happy with the default config options.

// Rakkas bundles this file with esbuild before loading, so you can use TypeScript.

// defineConfig is a helper to ensure IDE code-completion.
export default defineConfig({
//
// File extensions for pages and layouts
// pageExtensions: ["jsx", "tsx"],
//
// Directory that contains pages and layouts
// pagesDir: "pages",
//
// File extensions for endpoints and middleware
// endpointExtensions: ["js", "ts"],
//
// Directory that contains endpoints and middleware
// apiDir: "api",
//
// Base URL for endpoints
// apiRoot: "/api",
//
// Trust the x-forwarded-host and x-forwarded-proto headers in dev server.
// This is useful behind a reverse proxy. Set env variable TRUST_FORWARDED_ORIGIN to
// a non-empty string if you want the same in production.
// trustForwardedOrigin: false,
//
// Vite configuration (not all options are supported)
// vite: {},
//
// Babel options passed to Vite's React plugin */
// babel: {},
});
18 changes: 18 additions & 0 deletions issue-testbed/issue-32/src/ambient.d.ts
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import "rakkasjs";

declare module "rakkasjs" {
interface RootContext {
// Define the your root context type here. (see https://rakkasjs.org/guide/layout-context#root-context)
}

interface LoadHelpers {
// Define the type for your load helpers here. (see https://rakkasjs.org/guide/load-helpers)
}
}

// This is necessary for TypeScript compiler to ignore CSS module imports
declare module "*.module.css" {
const styles: { [key: string]: string };
export default styles;
}
20 changes: 20 additions & 0 deletions issue-testbed/issue-32/src/api/middleware.ts
@@ -0,0 +1,20 @@
import { RakkasMiddleware } from "rakkasjs";

// Middleware to ensure the body type is JSON
const ensureJson: RakkasMiddleware = (req, next) => {
if (
req.body &&
req.body.length &&
req.headers.get("content-type") !== "application/json"
) {
return {
// Unsupported Media Type
status: 415,
body: { error: "Only JSON is accepted" },
};
}

return next(req);
};

export default ensureJson;
29 changes: 29 additions & 0 deletions issue-testbed/issue-32/src/api/todo/[todoId].endpoint.ts
@@ -0,0 +1,29 @@
import { RakkasRequest, RakkasResponse } from "rakkasjs";
import { deleteTodo, updateTodo } from "./crud";

/** Delete a todo item */
export function del({ params }: RakkasRequest): RakkasResponse {
// In a real app you should validate all user input
deleteTodo(Number(params.todoId));

return {
body: null,
};
}

/** Update a todo item */
export function patch({ params, body }: RakkasRequest): RakkasResponse {
// In a real app you should validate all user input!
const updated = updateTodo(Number(params.todoId), body);

if (!updated) {
return {
status: 404,
};
}

return {
status: 200,
body: updated,
};
}
49 changes: 49 additions & 0 deletions issue-testbed/issue-32/src/api/todo/crud.ts
@@ -0,0 +1,49 @@
// This is our mock data store. The data won't persist between server restarts
// and it won't work in a serverless function. Just a simple way to
// demonstrate a CRUD app.

export interface TodoItem {
id: number;
text: string;
done: boolean;
}

let todoItems: TodoItem[] = [
{
id: 1,
text: "Learn React",
done: true,
},
{
id: 2,
text: "Learn Rakkas.JS",
done: false,
},
];

let nextId = 3;

// Simple CRUD functions

export function readAllTodos(): TodoItem[] {
return todoItems;
}

export function createTodo(item: Omit<TodoItem, "id">): number {
todoItems.push({ ...item, id: nextId });
return nextId++;
}

export function updateTodo(id: number, data: TodoItem): TodoItem | undefined {
const found = todoItems.find((x) => x.id === id);

if (found) {
Object.assign(found, data);
}

return found;
}

export function deleteTodo(id: number): void {
todoItems = todoItems.filter((x) => x.id !== id);
}
17 changes: 17 additions & 0 deletions issue-testbed/issue-32/src/api/todo/endpoint.ts
@@ -0,0 +1,17 @@
import { RequestHandler } from "rakkasjs";
import { readAllTodos, createTodo } from "./crud";

// Any of the following functions may also return a promise

// Return all todo items
export const get: RequestHandler = () => ({ body: readAllTodos() });

// Add a todo item and return its ID
export const post: RequestHandler = ({ body }) => {
// In a real app you should validate all user input
return {
// "201 Created". Default status is 200.
status: 201,
body: createTodo(body),
};
};
24 changes: 24 additions & 0 deletions issue-testbed/issue-32/src/client.ts
@@ -0,0 +1,24 @@
// Client-side customization hooks (see: https://rakkasjs.org/guide/customization-hooks#client-side)
// You may delete this file if you don't need to customize anything

// import { LoadHelpers } from "rakkasjs";

// export function beforeStartClient(): void {
// // Do initialization work before hydration
// // If you return a promise, Rakkas will delay hydration until it resolves
// }

// export function wrap(app: JSX.Element): JSX.Element {
// // You can wrap the client-side app in a provider here.
// // Useful for integrating with, e.g., Redux, Apolle client etc.
// return <SomeProvider>{app}</SomeProvider>;
// }

// export function createLoadHelpers(): LoadHelpers {
// return {
// // Initialize your client-side load helpers here (see: https://rakkasjs.org/guide/load-helpers)
// };
// }

// Must be module
export {};
29 changes: 29 additions & 0 deletions issue-testbed/issue-32/src/pages/about.page.tsx
@@ -0,0 +1,29 @@
import React, { FC } from "react";

const AboutPage: FC = () => (
<main>
<h1>About</h1>
<p>
<b>Rakkas</b> aims to be a{" "}
<a href="https://reactjs.org" target="_blank" rel="noreferrer">
React
</a>{" "}
framework powered by{" "}
<a href="https://vitejs.dev" target="_blank" rel="noreferrer">
Vite
</a>
, with a developer experience inspired by{" "}
<a href="https://nextjs.org" target="_blank" rel="noreferrer">
Next.js
</a>{" "}
and{" "}
<a href="https://kit.svelte.dev" target="_blank" rel="noreferrer">
Svelte Kit
</a>
. Pages of a Rakkas web applications are rendered on the server-side and
hydrated on the client side.
</p>
</main>
);

export default AboutPage;

0 comments on commit b9dce60

Please sign in to comment.