mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-23 10:14:08 +03:00
add todo app w/ typescript
This commit is contained in:
parent
b36e82d3d6
commit
5f63c76a38
3
examples/todo-typescript/.gitignore
vendored
Normal file
3
examples/todo-typescript/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/.wasp/
|
||||||
|
/.env.server
|
||||||
|
/.env.client
|
1
examples/todo-typescript/.wasproot
Normal file
1
examples/todo-typescript/.wasproot
Normal file
@ -0,0 +1 @@
|
|||||||
|
File marking the root of Wasp project.
|
67
examples/todo-typescript/main.wasp
Normal file
67
examples/todo-typescript/main.wasp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
app VideoTodoNotifier {
|
||||||
|
wasp: {
|
||||||
|
version: "^0.7.3"
|
||||||
|
},
|
||||||
|
title: "ToDo TypeScript",
|
||||||
|
|
||||||
|
auth: {
|
||||||
|
userEntity: User,
|
||||||
|
methods: {
|
||||||
|
usernameAndPassword: {},
|
||||||
|
},
|
||||||
|
onAuthFailedRedirectTo: "/login",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use Prisma Schema Language (PSL) to define our entities: https://www.prisma.io/docs/concepts/components/prisma-schema
|
||||||
|
// Run `wasp db migrate-dev` in the CLI to create the database tables
|
||||||
|
// Then run `wasp db studio` to open Prisma Studio and view your db models
|
||||||
|
entity User {=psl
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
username String @unique
|
||||||
|
password String
|
||||||
|
tasks Task[]
|
||||||
|
psl=}
|
||||||
|
|
||||||
|
entity Task {=psl
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
description String
|
||||||
|
isDone Boolean @default(false)
|
||||||
|
user User? @relation(fields: [userId], references: [id])
|
||||||
|
userId Int?
|
||||||
|
psl=}
|
||||||
|
|
||||||
|
route RootRoute { path: "/", to: MainPage }
|
||||||
|
page MainPage {
|
||||||
|
authRequired: true,
|
||||||
|
component: import Main from "@client/MainPage"
|
||||||
|
}
|
||||||
|
|
||||||
|
route LoginRoute { path: "/login", to: LoginPage }
|
||||||
|
page LoginPage {
|
||||||
|
component: import Login from "@client/LoginPage"
|
||||||
|
}
|
||||||
|
|
||||||
|
route SignupRoute { path: "/signup", to: SignupPage }
|
||||||
|
page SignupPage {
|
||||||
|
component: import Signup from "@client/SignupPage"
|
||||||
|
}
|
||||||
|
|
||||||
|
query getTasks {
|
||||||
|
// We specify the JS implementation of our query (which is an async JS function)
|
||||||
|
// which can be found in `server/queries.js` as a named export `getTasks`.
|
||||||
|
fn: import { getTasks } from "@server/queries.js",
|
||||||
|
// We tell Wasp that this query is doing something with the `Task` entity. With that, Wasp will
|
||||||
|
// automatically refresh the results of this query when tasks change.
|
||||||
|
entities: [Task]
|
||||||
|
}
|
||||||
|
|
||||||
|
action createTask {
|
||||||
|
fn: import { createTask } from "@server/actions.js",
|
||||||
|
entities: [Task]
|
||||||
|
}
|
||||||
|
|
||||||
|
action updateTask {
|
||||||
|
fn: import { updateTask } from "@server/actions.js",
|
||||||
|
entities: [Task]
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "User" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"username" TEXT NOT NULL,
|
||||||
|
"password" TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Task" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"isDone" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"userId" INTEGER,
|
||||||
|
CONSTRAINT "Task_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
3
examples/todo-typescript/migrations/migration_lock.toml
Normal file
3
examples/todo-typescript/migrations/migration_lock.toml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Please do not edit this file manually
|
||||||
|
# It should be added in your version-control system (i.e. Git)
|
||||||
|
provider = "sqlite"
|
3
examples/todo-typescript/src/.waspignore
Normal file
3
examples/todo-typescript/src/.waspignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Ignore editor tmp files
|
||||||
|
**/*~
|
||||||
|
**/#*#
|
19
examples/todo-typescript/src/client/LoginPage.tsx
Normal file
19
examples/todo-typescript/src/client/LoginPage.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import LoginForm from '@wasp/auth/forms/Login';
|
||||||
|
|
||||||
|
const LoginPage = () => {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<h1>Login</h1>
|
||||||
|
{/** Wasp has built-in auth forms & flows, which you can also opt-out of, if you wish :) */}
|
||||||
|
<LoginForm />
|
||||||
|
<br />
|
||||||
|
<span>
|
||||||
|
I don't have an account yet (<Link to='/signup'>go to signup</Link>).
|
||||||
|
</span>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoginPage;
|
53
examples/todo-typescript/src/client/Main.css
Normal file
53
examples/todo-typescript/src/client/Main.css
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
* {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 1rem 0;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
padding: 0;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main p {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0.2rem;
|
||||||
|
background: #efefef;
|
||||||
|
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
||||||
|
Bitstream Vera Sans Mono, Courier New, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-form h2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tasklist {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
width: 300px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
94
examples/todo-typescript/src/client/MainPage.tsx
Normal file
94
examples/todo-typescript/src/client/MainPage.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import './Main.css';
|
||||||
|
import React from 'react';
|
||||||
|
import logout from '@wasp/auth/logout.js';
|
||||||
|
import useAuth from '@wasp/auth/useAuth.js';
|
||||||
|
import { useQuery } from '@wasp/queries'; // Wasp uses a thin wrapper around react-query
|
||||||
|
import getTasks from '@wasp/queries/getTasks';
|
||||||
|
import createTask from '@wasp/actions/createTask';
|
||||||
|
import updateTask from '@wasp/actions/updateTask';
|
||||||
|
import waspLogo from './waspLogo.png';
|
||||||
|
import { Task } from './types'
|
||||||
|
|
||||||
|
const MainPage = () => {
|
||||||
|
const { data: user } = useAuth();
|
||||||
|
const { data: tasks, isLoading, error } = useQuery(getTasks);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
console.log(user);
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
if (isLoading) return 'Loading...';
|
||||||
|
if (error) return 'Error: ' + error;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<img src={waspLogo} alt='wasp logo' />
|
||||||
|
<h1>
|
||||||
|
{user.username}
|
||||||
|
{`'s tasks :)`}
|
||||||
|
</h1>
|
||||||
|
<NewTaskForm />
|
||||||
|
{tasks && <TasksList tasks={tasks} /> }
|
||||||
|
<button onClick={logout}> Logout </button>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Todo = ({task, number}: {task: Task, number: number}) => {
|
||||||
|
const handleIsDoneChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
try {
|
||||||
|
await updateTask({
|
||||||
|
taskId: task.id,
|
||||||
|
isDone: event.currentTarget.checked,
|
||||||
|
});
|
||||||
|
} catch (err: any) {
|
||||||
|
window.alert('Error while updating task: ' + err?.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{number + 1}
|
||||||
|
{''}
|
||||||
|
</span>
|
||||||
|
<input type='checkbox' id={task.id.toString()} checked={task.isDone} onChange={handleIsDoneChange} />
|
||||||
|
<span>{task.description}</span>{' '}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const TasksList = ({tasks}: { tasks: Task[] }) => {
|
||||||
|
if (tasks.length === 0) return <p>No tasks yet.</p>;
|
||||||
|
return (
|
||||||
|
<div className='tasklist'>
|
||||||
|
{tasks.map((tsk, idx) => (
|
||||||
|
<Todo task={tsk} number={idx} key={idx} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NewTaskForm = () => {
|
||||||
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const description = event.currentTarget.description.value;
|
||||||
|
console.log(description)
|
||||||
|
event.currentTarget.reset();
|
||||||
|
await createTask({ description });
|
||||||
|
} catch (err: any) {
|
||||||
|
window.alert('Error: ' + err?.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<input name='description' type='text' defaultValue='' />
|
||||||
|
<input type='submit' value='Create task' />
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MainPage;
|
19
examples/todo-typescript/src/client/SignupPage.tsx
Normal file
19
examples/todo-typescript/src/client/SignupPage.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import SignupForm from '@wasp/auth/forms/Signup';
|
||||||
|
|
||||||
|
const SignupPage = () => {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<h1>Sign Up</h1>
|
||||||
|
{/** Wasp has built-in auth forms & flows, which you can also opt-out of, if you wish :) */}
|
||||||
|
<SignupForm />
|
||||||
|
<br />
|
||||||
|
<span>
|
||||||
|
I already have an account (<Link to='/login'>go to login</Link>).
|
||||||
|
</span>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SignupPage;
|
60
examples/todo-typescript/src/client/react-app-env.d.ts
vendored
Normal file
60
examples/todo-typescript/src/client/react-app-env.d.ts
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
declare module '*.avif' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.bmp' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.gif' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpg' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpeg' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.png' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.webp' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.svg' {
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export const ReactComponent: React.FunctionComponent<React.SVGProps<
|
||||||
|
SVGSVGElement
|
||||||
|
> & { title?: string }>;
|
||||||
|
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.module.css' {
|
||||||
|
const classes: { readonly [key: string]: string };
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.module.scss' {
|
||||||
|
const classes: { readonly [key: string]: string };
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.module.sass' {
|
||||||
|
const classes: { readonly [key: string]: string };
|
||||||
|
export default classes;
|
||||||
|
}
|
55
examples/todo-typescript/src/client/tsconfig.json
Normal file
55
examples/todo-typescript/src/client/tsconfig.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// =============================== IMPORTANT =================================
|
||||||
|
//
|
||||||
|
// This file is only used for Wasp IDE support. You can change it to configure
|
||||||
|
// your IDE checks, but none of these options will affect the TypeScript
|
||||||
|
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// JSX support
|
||||||
|
"jsx": "preserve",
|
||||||
|
"strict": true,
|
||||||
|
// Allow default imports.
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
// Wasp needs the following settings enable IDE support in your source
|
||||||
|
// files. Editing them might break features like import autocompletion and
|
||||||
|
// definition lookup. Don't change them unless you know what you're doing.
|
||||||
|
//
|
||||||
|
// The relative path to the generated web app's root directory. This must be
|
||||||
|
// set to define the "paths" option.
|
||||||
|
"baseUrl": "../../.wasp/out/web-app/",
|
||||||
|
"paths": {
|
||||||
|
// Resolve all "@wasp" imports to the generated source code.
|
||||||
|
"@wasp/*": [
|
||||||
|
"src/*"
|
||||||
|
],
|
||||||
|
// Resolve all non-relative imports to the correct node module. Source:
|
||||||
|
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||||
|
"*": [
|
||||||
|
// Start by looking for the definiton inside the node modules root
|
||||||
|
// directory...
|
||||||
|
"node_modules/*",
|
||||||
|
// ... If that fails, try to find it inside definitely-typed type
|
||||||
|
// definitions.
|
||||||
|
"node_modules/@types/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
|
||||||
|
"typeRoots": [
|
||||||
|
"../../.wasp/out/web-app/node_modules/@types"
|
||||||
|
],
|
||||||
|
// Since this TS config is used only for IDE support and not for
|
||||||
|
// compilation, the following directory doesn't exist. We need to specify
|
||||||
|
// it to prevent this error:
|
||||||
|
// https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file
|
||||||
|
"outDir": "phantom"
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"phantom"
|
||||||
|
],
|
||||||
|
}
|
6
examples/todo-typescript/src/client/types.ts
Normal file
6
examples/todo-typescript/src/client/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export type Task = {
|
||||||
|
id: number;
|
||||||
|
description: string;
|
||||||
|
isDone: boolean;
|
||||||
|
userId: number | null;
|
||||||
|
};
|
BIN
examples/todo-typescript/src/client/waspLogo.png
Normal file
BIN
examples/todo-typescript/src/client/waspLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
33
examples/todo-typescript/src/server/actions.ts
Normal file
33
examples/todo-typescript/src/server/actions.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import HttpError from '@wasp/core/HttpError.js';
|
||||||
|
import { Context, Task } from './serverTypes'
|
||||||
|
|
||||||
|
type createArgs = { description: Task['description'] };
|
||||||
|
|
||||||
|
export const createTask = async ({ description }: createArgs, context: Context) => {
|
||||||
|
if (!context.user) {
|
||||||
|
throw new HttpError(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.entities.Task.create({
|
||||||
|
data: {
|
||||||
|
description,
|
||||||
|
user: { connect: { id: context.user.id } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
type updateArgs = { taskId: Task['id']; isDone: Task['isDone'] };
|
||||||
|
|
||||||
|
export const updateTask = async ({ taskId, isDone }: updateArgs, context: Context) => {
|
||||||
|
if (!context.user) {
|
||||||
|
throw new HttpError(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.entities.Task.updateMany({
|
||||||
|
where: {
|
||||||
|
id: taskId,
|
||||||
|
user: { id: context.user.id },
|
||||||
|
},
|
||||||
|
data: { isDone },
|
||||||
|
});
|
||||||
|
};
|
9
examples/todo-typescript/src/server/queries.ts
Normal file
9
examples/todo-typescript/src/server/queries.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import HttpError from '@wasp/core/HttpError.js';
|
||||||
|
import { Context, Task } from './serverTypes'
|
||||||
|
|
||||||
|
export const getTasks = async (args: null, context: Context): Promise<Task[]> => {
|
||||||
|
if (!context.user) {
|
||||||
|
throw new HttpError(401);
|
||||||
|
}
|
||||||
|
return context.entities.Task.findMany({ where: { user: { id: context.user.id } } });
|
||||||
|
};
|
11
examples/todo-typescript/src/server/serverTypes.ts
Normal file
11
examples/todo-typescript/src/server/serverTypes.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Task as TaskType, User, Prisma } from '@prisma/client';
|
||||||
|
|
||||||
|
export type Task = TaskType;
|
||||||
|
|
||||||
|
export type Context = {
|
||||||
|
user: User;
|
||||||
|
entities: {
|
||||||
|
Task: Prisma.TaskDelegate<{}>;
|
||||||
|
User: Prisma.UserDelegate<{}>;
|
||||||
|
};
|
||||||
|
};
|
48
examples/todo-typescript/src/server/tsconfig.json
Normal file
48
examples/todo-typescript/src/server/tsconfig.json
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// =============================== IMPORTANT =================================
|
||||||
|
//
|
||||||
|
// This file is only used for Wasp IDE support. You can change it to configure
|
||||||
|
// your IDE checks, but none of these options will affect the TypeScript
|
||||||
|
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Allows default imports.
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"strict": true,
|
||||||
|
// Wasp needs the following settings enable IDE support in your source
|
||||||
|
// files. Editing them might break features like import autocompletion and
|
||||||
|
// definition lookup. Don't change them unless you know what you're doing.
|
||||||
|
//
|
||||||
|
// The relative path to the generated web app's root directory. This must be
|
||||||
|
// set to define the "paths" option.
|
||||||
|
"baseUrl": "../../.wasp/out/server/",
|
||||||
|
"paths": {
|
||||||
|
// Resolve all "@wasp" imports to the generated source code.
|
||||||
|
"@wasp/*": [
|
||||||
|
"src/*"
|
||||||
|
],
|
||||||
|
// Resolve all non-relative imports to the correct node module. Source:
|
||||||
|
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||||
|
"*": [
|
||||||
|
// Start by looking for the definiton inside the node modules root
|
||||||
|
// directory...
|
||||||
|
"node_modules/*",
|
||||||
|
// ... If that fails, try to find it inside definitely-typed type
|
||||||
|
// definitions.
|
||||||
|
"node_modules/@types/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
|
||||||
|
"typeRoots": [
|
||||||
|
"../../.wasp/out/server/node_modules/@types"
|
||||||
|
],
|
||||||
|
// Since this TS config is used only for IDE support and not for
|
||||||
|
// compilation, the following directory doesn't exist. We need to specify
|
||||||
|
// it to prevent this error:
|
||||||
|
// https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file
|
||||||
|
"outDir": "phantom",
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"phantom"
|
||||||
|
],
|
||||||
|
}
|
28
examples/todo-typescript/src/shared/tsconfig.json
Normal file
28
examples/todo-typescript/src/shared/tsconfig.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Enable default imports in TypeScript.
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowJs": true,
|
||||||
|
// The following settings enable IDE support in user-provided source files.
|
||||||
|
// Editing them might break features like import autocompletion and
|
||||||
|
// definition lookup. Don't change them unless you know what you're doing.
|
||||||
|
//
|
||||||
|
// The relative path to the generated web app's root directory. This must be
|
||||||
|
// set to define the "paths" option.
|
||||||
|
"baseUrl": "../../.wasp/out/server/",
|
||||||
|
"paths": {
|
||||||
|
// Resolve all non-relative imports to the correct node module. Source:
|
||||||
|
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||||
|
"*": [
|
||||||
|
// Start by looking for the definiton inside the node modules root
|
||||||
|
// directory...
|
||||||
|
"node_modules/*",
|
||||||
|
// ... If that fails, try to find it inside definitely-typed type
|
||||||
|
// definitions.
|
||||||
|
"node_modules/@types/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
|
||||||
|
"typeRoots": ["../../.wasp/out/server/node_modules/@types"],
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user