Skip to content

Commit

Permalink
TypeScript fixes before Beta (#831)
Browse files Browse the repository at this point in the history
* Change typescript modules to esnext

* Fix tsconfigs and use recommended settings

* Fix server not loading env variables

* Fix TS output overwriting error

* Fix wrong types

* Change MainPage.tsx to MainPage.jsx

* Remove duplication for Node tsconfig

* Update e2e tests for TS fixes

* Fix formatting
  • Loading branch information
sodic authored Nov 25, 2022
1 parent 4a265a4 commit 5da642e
Show file tree
Hide file tree
Showing 78 changed files with 860 additions and 670 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const MainPage = () => {
<h2 className="welcome-title"> Welcome to Wasp - you just started a new app! </h2>
<h3 className="welcome-subtitle">
This is page <code>MainPage</code> located at route <code>/</code>.
Open <code>ext/MainPage.js</code> to edit it.
Open <code>src/client/MainPage.jsx</code> to edit it.
</h3>

<div className="buttons">
Expand Down
28 changes: 22 additions & 6 deletions waspc/data/Cli/templates/new/src/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
// =============================== 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",
// Enable default imports in TypeScript.
"strict": true,
// Allow default imports.
"esModuleInterop": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
// The following settings enable IDE support in user-provided source files.
// Editing them might break features like import autocompletion and
// 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
Expand All @@ -34,6 +40,16 @@
]
},
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
"typeRoots": ["../../.wasp/out/web-app/node_modules/@types"]
}
}
"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"
],
}
28 changes: 22 additions & 6 deletions waspc/data/Cli/templates/new/src/server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// =============================== 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": {
// Enable default imports in TypeScript.
// Allows default imports.
"esModuleInterop": true,
"allowJs": true,
// The following settings enable IDE support in user-provided source files.
// Editing them might break features like import autocompletion and
"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
Expand All @@ -27,6 +33,16 @@
]
},
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
"typeRoots": ["../../.wasp/out/server/node_modules/@types"]
}
}
"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"
],
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export type Action<Input, Output> = (args?: Input) => Promise<Output>;
import { Action } from '.'

export function createAction<Input, Output>(actionRoute: string, entitiesUsed: unknown[]): Action<Input, Output>
63 changes: 33 additions & 30 deletions waspc/data/Generator/templates/react-app/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,43 @@ import {
UseMutationOptions,
useQueryClient,
} from '@tanstack/react-query'
import { Action } from './core';
import { Query } from '../queries';

export type Action<Input, Output> = (args?: Input) => Promise<Output>;

/**
* An options object passed into the `useAction` hook and used to enhance the
* action with extra options.
*
*/
export type ActionOptions<ActionInput, CacheItem> = {
optimisticUpdates: OptimisticUpdateDefinition<ActionInput, CacheItem>[];
export type ActionOptions<ActionInput, CachedData> = {
optimisticUpdates: OptimisticUpdateDefinition<ActionInput, CachedData>[]
}

/**
* A documented (public) way to define optimistic updates.
*/
export type OptimisticUpdateDefinition<ActionInput, CacheItem> = {
getQuerySpecifier: GetQuerySpecifier<ActionInput>;
updateQuery: UpdateQuery<ActionInput, CacheItem>;
export type OptimisticUpdateDefinition<ActionInput, CachedData = unknown> = {
getQuerySpecifier: GetQuerySpecifier<ActionInput, CachedData>
updateQuery: UpdateQuery<ActionInput, CachedData>
}

/**
* A function that takes an item and returns a Wasp Query specifier.
*/
export type GetQuerySpecifier<Item> = (item: Item) => QuerySpecifier
export type GetQuerySpecifier<ActionInput, CachedData> = (item: ActionInput) => QuerySpecifier<unknown, CachedData>

/**
* A function that takes an item and the previous state of the cache, and returns
* the desired (new) state of the cache.
*/
export type UpdateQuery<ActionInput, CacheItem> = (item: ActionInput, oldData: CacheItem[]) => CacheItem[]
export type UpdateQuery<ActionInput, CachedData> = (item: ActionInput, oldData: CachedData | undefined) => CachedData

/**
* A public query specifier used for addressing Wasp queries. See our docs for details:
* https://wasp-lang.dev/docs/language/features#the-useaction-hook.
*/
export type QuerySpecifier = any[]
export type QuerySpecifier<Input, Output> = [Query<Input, Output>, ...any[]]

/**
* A hook for adding extra behavior to a Wasp Action (e.g., optimistic updates).
Expand All @@ -48,9 +50,9 @@ export type QuerySpecifier = any[]
* @param actionOptions An options object for enhancing/decorating the given Action.
* @returns A decorated Action with added behavior but an unchanged API.
*/
export function useAction<ActionInput, CacheItem = any>(
actionFn: (item: ActionInput) => Promise<void>,
actionOptions: ActionOptions<ActionInput, CacheItem>
export function useAction<Input = unknown, Output = unknown, CachedData = unknown>(
actionFn: Action<Input, Output>,
actionOptions?: ActionOptions<Input, CachedData>
): typeof actionFn {
const queryClient = useQueryClient();

Expand All @@ -76,9 +78,9 @@ export function useAction<ActionInput, CacheItem = any>(
/**
* An internal (undocumented, private, desugared) way of defining optimistic updates.
*/
type InternalOptimisticUpdateDefinition<ActionInput, CacheItem> = {
type InternalOptimisticUpdateDefinition<ActionInput, CachedData> = {
getQueryKey: (item: ActionInput) => QueryKey,
updateQuery: UpdateQuery<ActionInput, CacheItem>;
updateQuery: UpdateQuery<ActionInput, CachedData>;

}

Expand All @@ -87,7 +89,7 @@ type InternalOptimisticUpdateDefinition<ActionInput, CacheItem> = {
* the current state of the cache and returns the desired (new) state of the
* cache.
*/
type SpecificUpdateQuery<Item> = (oldData: Item[]) => Item[]
type SpecificUpdateQuery<CachedData> = (oldData: CachedData) => CachedData

/**
* A specific, "instantiated" optimistic update definition which contains a
Expand All @@ -99,9 +101,9 @@ type SpecificOptimisticUpdateDefinition<Item> = {
}

type InternalAction<Input, Output> = Action<Input, Output> & {
internal<CacheItem extends unknown>(
internal<CachedData extends unknown>(
item: Input,
optimisticUpdateDefinitions: SpecificOptimisticUpdateDefinition<CacheItem>[]
optimisticUpdateDefinitions: SpecificOptimisticUpdateDefinition<CachedData>[]
): Promise<Output>
}

Expand All @@ -114,9 +116,9 @@ type InternalAction<Input, Output> = Action<Input, Output> & {
* https://wasp-lang.dev/docs/language/features#the-useaction-hook.
* @returns An internally-used optimistic update definition object.
*/
function translateToInternalDefinition<Item, CacheItem>(
publicOptimisticUpdateDefinition: OptimisticUpdateDefinition<Item, CacheItem>
): InternalOptimisticUpdateDefinition<Item, CacheItem> {
function translateToInternalDefinition<Item, CachedData>(
publicOptimisticUpdateDefinition: OptimisticUpdateDefinition<Item, CachedData>
): InternalOptimisticUpdateDefinition<Item, CachedData> {
const { getQuerySpecifier, updateQuery } = publicOptimisticUpdateDefinition

const definitionErrors = []
Expand Down Expand Up @@ -144,9 +146,9 @@ function translateToInternalDefinition<Item, CacheItem>(
* @param optimisticUpdateDefinitions The optimisitc updates the action causes.
* @returns An decorated action which performs optimistic updates.
*/
function makeOptimisticUpdateMutationFn<Input, Output, CacheItem>(
function makeOptimisticUpdateMutationFn<Input, Output, CachedData>(
actionFn: Action<Input, Output>,
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<Input, CacheItem>[]
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<Input, CachedData>[]
): typeof actionFn {
return function performActionWithOptimisticUpdates(item) {
const specificOptimisticUpdateDefinitions = optimisticUpdateDefinitions.map(
Expand All @@ -172,9 +174,9 @@ function makeOptimisticUpdateMutationFn<Input, Output, CacheItem>(
* corresponding to the given optimistic update definitions (check the docs
* linked above for details).
*/
function makeRqOptimisticUpdateOptions<ActionInput, CacheItem>(
function makeRqOptimisticUpdateOptions<ActionInput, CachedData>(
queryClient: QueryClient,
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<ActionInput, CacheItem>[]
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<ActionInput, CachedData>[]
): Pick<UseMutationOptions, "onMutate" | "onError"> {
async function onMutate(item) {
const specificOptimisticUpdateDefinitions = optimisticUpdateDefinitions.map(
Expand All @@ -193,7 +195,7 @@ function makeRqOptimisticUpdateOptions<ActionInput, CacheItem>(
const previousData = new Map()
specificOptimisticUpdateDefinitions.forEach(({ queryKey, updateQuery }) => {
// Snapshot the currently cached value.
const previousDataForQuery: CacheItem[] = queryClient.getQueryData(queryKey)
const previousDataForQuery: CachedData = queryClient.getQueryData(queryKey)

// Attempt to optimistically update the cache using the new value.
try {
Expand Down Expand Up @@ -240,9 +242,10 @@ function makeRqOptimisticUpdateOptions<ActionInput, CacheItem>(
* @returns A specific optimistic update definition which corresponds to the
* provided definition and closes over the provided item.
*/
function getOptimisticUpdateDefinitionForSpecificItem<ActionInput, CacheItem>(
optimisticUpdateDefinition: InternalOptimisticUpdateDefinition<ActionInput, CacheItem>, item: ActionInput
): SpecificOptimisticUpdateDefinition<CacheItem> {
function getOptimisticUpdateDefinitionForSpecificItem<ActionInput, CachedData>(
optimisticUpdateDefinition: InternalOptimisticUpdateDefinition<ActionInput, CachedData>,
item: ActionInput
): SpecificOptimisticUpdateDefinition<CachedData> {
const { getQueryKey, updateQuery } = optimisticUpdateDefinition
return {
queryKey: getQueryKey(item),
Expand All @@ -257,7 +260,7 @@ function getOptimisticUpdateDefinitionForSpecificItem<ActionInput, CacheItem>(
* https://wasp-lang.dev/docs/language/features#the-useaction-hook.
* @returns A cache key React Query internally uses for addressing queries.
*/
function getRqQueryKeyFromSpecifier(querySpecifier: QuerySpecifier): QueryKey {
function getRqQueryKeyFromSpecifier(querySpecifier: QuerySpecifier<unknown, unknown>): QueryKey {
const [queryFn, ...otherKeys] = querySpecifier
return [...queryFn.queryCacheKey, ...otherKeys]
return [...(queryFn as any).queryCacheKey, ...otherKeys]
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UseQueryResult } from "@tanstack/react-query";
import { OutputHTMLAttributes } from "react";
import { Query } from "./core";

export function useQuery<Input, Output>(
export type Query<Input, Output> = (args: Input) => Promise<Output>

export function useQuery<Input, Output, Error = unknown>(
queryFn: Query<Input, Output>,
queryFnArgs?: Input, options?: any
): UseQueryResult<Output, any>
): UseQueryResult<Output, Error>
21 changes: 3 additions & 18 deletions waspc/data/Generator/templates/react-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
{
"extends": "@tsconfig/create-react-app/tsconfig.json",
"compilerOptions": {
"target": "es2018",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
// Overriding this until we implement more complete TypeScript support.
"strict": false,
},
"include": [
"src"
Expand Down
5 changes: 3 additions & 2 deletions waspc/data/Generator/templates/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"name": "server",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "npx tsc",
"start": "NODE_PATH=dist node dist/server.js",
"start": "NODE_PATH=dist node -r dotenv/config dist/server.js",
"build-and-start": "npm run build && npm run start",
"watch": "nodemon -r dotenv/config --exec 'npm run build-and-start || exit 1'",
"watch": "nodemon --exec 'npm run build-and-start || exit 1'",
"db-migrate-prod": "prisma migrate deploy --schema=../db/schema.prisma",
"db-migrate-dev": "prisma migrate dev --schema=../db/schema.prisma",
"start-production": "{=& startProductionScript =}",
Expand Down
16 changes: 12 additions & 4 deletions waspc/data/Generator/templates/server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"compilerOptions": {
// Overriding this until we implement more complete TypeScript support.
"strict": false,
// Overriding this because we want to use top-level await
"module": "esnext",
// Enable source map for debugging
"sourceMap": true,

// The remaining settings should match node18/tsconfig.json, but I kept
// them here to be explicit.

// Enable default imports in TypeScript.
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"allowJs": true,
// Enable source map for debugging
"sourceMap": true
"allowJs": true
}
}
4 changes: 2 additions & 2 deletions waspc/e2e-test/test-outputs/waspBuild-golden/files.manifest

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5da642e

Please sign in to comment.