mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-24 03:35:17 +03:00
Client-side TypeScript support (#824)
* Add typescript support to generator * Change jsconfig to tsconfig for client * Change Main.js to Main.tsx * Implement TypeScript support on client * Fix formatting * Fixes in actions/index.ts * Remove extra types from comments * Update waspc/src/Wasp/Generator/ServerGenerator.hs Co-authored-by: Martin Šošić <Martinsos@users.noreply.github.com> * Remove server-specific typescript stuff * Fix useQuery type * Add typeroots to client tsconfig * Improve TypeScript support on client * Remove tsx extension from template wasp file * Format code Co-authored-by: Martin Šošić <Martinsos@users.noreply.github.com>
This commit is contained in:
parent
ccf3c7199f
commit
31df276a25
@ -99,7 +99,7 @@ writeMainWaspFile waspProjectDir (ProjectInfo projectName appName) = writeFile a
|
||||
"",
|
||||
"route RootRoute { path: \"/\", to: MainPage }",
|
||||
"page MainPage {",
|
||||
" component: import Main from \"@client/MainPage.js\"",
|
||||
" component: import Main from \"@client/MainPage\"",
|
||||
"}"
|
||||
]
|
||||
|
||||
|
60
waspc/data/Cli/templates/new/src/client/react-app-env.d.ts
vendored
Normal file
60
waspc/data/Cli/templates/new/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;
|
||||
}
|
@ -1,5 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// JSX support
|
||||
"jsx": "preserve",
|
||||
// Enable default imports in TypeScript.
|
||||
"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
|
||||
// definition lookup. Don't change them unless you know what you're doing.
|
||||
@ -22,6 +32,8 @@
|
||||
// definitions.
|
||||
"node_modules/@types/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
|
||||
"typeRoots": ["../../.wasp/out/web-app/node_modules/@types"]
|
||||
}
|
||||
}
|
3
waspc/data/Generator/templates/react-app/src/actions/core.d.ts
vendored
Normal file
3
waspc/data/Generator/templates/react-app/src/actions/core.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export type Action<Input, Output> = (args?: Input) => Promise<Output>;
|
||||
|
||||
export function createAction<Input, Output>(actionRoute: string, entitiesUsed: unknown[]): Action<Input, Output>
|
@ -1,93 +1,57 @@
|
||||
import {
|
||||
QueryClient,
|
||||
QueryKey,
|
||||
useMutation,
|
||||
UseMutationOptions,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
export { configureQueryClient } from '../queryClient'
|
||||
import { Action } from './core';
|
||||
|
||||
/**
|
||||
* An options object passed into the `useAction` hook and used to enhance the
|
||||
* action with extra options.
|
||||
*
|
||||
* @typedef {Object} ActionOptions
|
||||
* @property {PublicOptimisticUpdateDefinition[]} optimisticUpdates
|
||||
*/
|
||||
export type ActionOptions<ActionInput, CacheItem> = {
|
||||
optimisticUpdates: OptimisticUpdateDefinition<ActionInput, CacheItem>[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A documented (public) way to define optimistic updates.
|
||||
*
|
||||
* @typedef {Object} PublicOptimisticUpdateDefinition
|
||||
* @property {GetQuerySpecifier} querySpecifier
|
||||
* @property {UpdateQuery} updateQuery
|
||||
*/
|
||||
export type OptimisticUpdateDefinition<ActionInput, CacheItem> = {
|
||||
getQuerySpecifier: GetQuerySpecifier<ActionInput>;
|
||||
updateQuery: UpdateQuery<ActionInput, CacheItem>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that takes an item and returns a Wasp Query specifier.
|
||||
*
|
||||
* @callback GetQuerySpecifier
|
||||
* @param {T} item
|
||||
* @returns {QuerySpecifier}
|
||||
*/
|
||||
export type GetQuerySpecifier<Item> = (item: Item) => QuerySpecifier
|
||||
|
||||
/**
|
||||
* A function that takes an item and the previous state of the cache, and returns
|
||||
* the desired (new) state of the cache.
|
||||
*
|
||||
* @callback UpdateQuery
|
||||
* @param {T} item
|
||||
* @param {T[]} oldData
|
||||
* @returns {T[]}
|
||||
*/
|
||||
export type UpdateQuery<ActionInput, CacheItem> = (item: ActionInput, oldData: CacheItem[]) => CacheItem[]
|
||||
|
||||
/**
|
||||
* A public query specifier used for addressing Wasp queries. See our docs for details:
|
||||
* https://wasp-lang.dev/docs/language/features#the-useaction-hook.
|
||||
*
|
||||
* @typedef {any[]} QuerySpecifier
|
||||
*/
|
||||
|
||||
/**
|
||||
* An internal (undocumented, private, desugared) way of defining optimistic updates.
|
||||
*
|
||||
* @typedef {Object} InternalOptimisticUpdateDefinition
|
||||
* @property {GetQuerySpecifier} querySpecifier
|
||||
* @property {UpdateQuery} updateQuery
|
||||
*/
|
||||
|
||||
/**
|
||||
* An UpdateQuery function "instantiated" with a specific item. It only takes
|
||||
* the current state of the cache and returns the desired (new) state of the
|
||||
* cache.
|
||||
*
|
||||
* @callback SpecificUpdateQuery
|
||||
* @param {any[]} oldData
|
||||
*/
|
||||
|
||||
/**
|
||||
* A specific, "instantiated" optimistic update definition which contains a
|
||||
* fully-constructed query key and a specific update function.
|
||||
*
|
||||
* @typedef {Object} SpecificOptimisticUpdateDefinition
|
||||
* @property {QueryKey} queryKey
|
||||
* @property {SpecificUpdateQuery} updateQuery
|
||||
*/
|
||||
|
||||
/**
|
||||
* An array React Query uses to address queries. See their docs for details:
|
||||
* https://react-query-v3.tanstack.com/guides/query-keys#array-keys.
|
||||
*
|
||||
* @typedef {any[]} QueryKey
|
||||
*/
|
||||
|
||||
export type QuerySpecifier = any[]
|
||||
|
||||
/**
|
||||
* A hook for adding extra behavior to a Wasp Action (e.g., optimistic updates).
|
||||
*
|
||||
* @param actionFn The Wasp Action you wish to enhance/decorate.
|
||||
* @param {ActionOptions} actionOptions An options object for enhancing/decorating the given Action.
|
||||
* @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(actionFn, actionOptions) {
|
||||
export function useAction<ActionInput, CacheItem = any>(
|
||||
actionFn: (item: ActionInput) => Promise<void>,
|
||||
actionOptions: ActionOptions<ActionInput, CacheItem>
|
||||
): typeof actionFn {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
let mutationFn = actionFn
|
||||
@ -110,14 +74,49 @@ export function useAction(actionFn, actionOptions) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates/Desugars a public optimistic update definition object into a definition object our
|
||||
* system uses internally.
|
||||
*
|
||||
* @param {PublicOptimisticUpdateDefinition} publicOptimisticUpdateDefinition An optimistic update definition
|
||||
* object that's a part of the public API: https://wasp-lang.dev/docs/language/features#the-useaction-hook.
|
||||
* @returns {InternalOptimisticUpdateDefinition} An internally-used optimistic update definition object.
|
||||
* An internal (undocumented, private, desugared) way of defining optimistic updates.
|
||||
*/
|
||||
function translateToInternalDefinition(publicOptimisticUpdateDefinition) {
|
||||
type InternalOptimisticUpdateDefinition<ActionInput, CacheItem> = {
|
||||
getQueryKey: (item: ActionInput) => QueryKey,
|
||||
updateQuery: UpdateQuery<ActionInput, CacheItem>;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An UpdateQuery function "instantiated" with a specific item. It only takes
|
||||
* the current state of the cache and returns the desired (new) state of the
|
||||
* cache.
|
||||
*/
|
||||
type SpecificUpdateQuery<Item> = (oldData: Item[]) => Item[]
|
||||
|
||||
/**
|
||||
* A specific, "instantiated" optimistic update definition which contains a
|
||||
* fully-constructed query key and a specific update function.
|
||||
*/
|
||||
type SpecificOptimisticUpdateDefinition<Item> = {
|
||||
queryKey: QueryKey;
|
||||
updateQuery: SpecificUpdateQuery<Item>;
|
||||
}
|
||||
|
||||
type InternalAction<Input, Output> = Action<Input, Output> & {
|
||||
internal<CacheItem extends unknown>(
|
||||
item: Input,
|
||||
optimisticUpdateDefinitions: SpecificOptimisticUpdateDefinition<CacheItem>[]
|
||||
): Promise<Output>
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates/Desugars a public optimistic update definition object into a
|
||||
* definition object our system uses internally.
|
||||
*
|
||||
* @param publicOptimisticUpdateDefinition An optimistic update definition
|
||||
* object that's a part of the public API:
|
||||
* 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> {
|
||||
const { getQuerySpecifier, updateQuery } = publicOptimisticUpdateDefinition
|
||||
|
||||
const definitionErrors = []
|
||||
@ -141,17 +140,19 @@ function translateToInternalDefinition(publicOptimisticUpdateDefinition) {
|
||||
* Creates a function that performs an action while telling it about the
|
||||
* optimistic updates it caused.
|
||||
*
|
||||
* @param actionFn - The Wasp Action.
|
||||
* @param {InternalOptimisticUpdateDefinition} optimisticUpdateDefinitions - The optimisitc updates the
|
||||
* action causes.
|
||||
* @returns A
|
||||
* @param actionFn The Wasp Action.
|
||||
* @param optimisticUpdateDefinitions The optimisitc updates the action causes.
|
||||
* @returns An decorated action which performs optimistic updates.
|
||||
*/
|
||||
function makeOptimisticUpdateMutationFn(actionFn, optimisticUpdateDefinitions) {
|
||||
function makeOptimisticUpdateMutationFn<Input, Output, CacheItem>(
|
||||
actionFn: Action<Input, Output>,
|
||||
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<Input, CacheItem>[]
|
||||
): typeof actionFn {
|
||||
return function performActionWithOptimisticUpdates(item) {
|
||||
const specificOptimisticUpdateDefinitions = optimisticUpdateDefinitions.map(
|
||||
generalDefinition => getOptimisticUpdateDefinitionForSpecificItem(generalDefinition, item)
|
||||
)
|
||||
return actionFn.internal(item, specificOptimisticUpdateDefinitions)
|
||||
return (actionFn as InternalAction<Input, Output>).internal(item, specificOptimisticUpdateDefinitions)
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,13 +164,18 @@ function makeOptimisticUpdateMutationFn(actionFn, optimisticUpdateDefinitions) {
|
||||
* optimistic updates definition. Check their docs for details:
|
||||
* https://tanstack.com/query/v4/docs/guides/optimistic-updates?from=reactQueryV3&original=https://react-query-v3.tanstack.com/guides/optimistic-updates
|
||||
*
|
||||
* @param {Object} queryClient The QueryClient instance used by React Query.
|
||||
* @param {InternalOptimisticUpdateDefinition} optimisticUpdateDefinitions A list containing internal optimistic updates definition objects
|
||||
* (i.e., a list where each object carries the instructions for performing particular optimistic update).
|
||||
* @returns {Object} An object containing 'onMutate' and 'onError' functions corresponding to the given optimistic update
|
||||
* definitions (check the docs linked above for details).
|
||||
* @param queryClient The QueryClient instance used by React Query.
|
||||
* @param optimisticUpdateDefinitions A list containing internal optimistic
|
||||
* updates definition objects (i.e., a list where each object carries the
|
||||
* instructions for performing particular optimistic update).
|
||||
* @returns An object containing 'onMutate' and 'onError' functions
|
||||
* corresponding to the given optimistic update definitions (check the docs
|
||||
* linked above for details).
|
||||
*/
|
||||
function makeRqOptimisticUpdateOptions(queryClient, optimisticUpdateDefinitions) {
|
||||
function makeRqOptimisticUpdateOptions<ActionInput, CacheItem>(
|
||||
queryClient: QueryClient,
|
||||
optimisticUpdateDefinitions: InternalOptimisticUpdateDefinition<ActionInput, CacheItem>[]
|
||||
): Pick<UseMutationOptions, "onMutate" | "onError"> {
|
||||
async function onMutate(item) {
|
||||
const specificOptimisticUpdateDefinitions = optimisticUpdateDefinitions.map(
|
||||
generalDefinition => getOptimisticUpdateDefinitionForSpecificItem(generalDefinition, item)
|
||||
@ -187,7 +193,7 @@ function makeRqOptimisticUpdateOptions(queryClient, optimisticUpdateDefinitions)
|
||||
const previousData = new Map()
|
||||
specificOptimisticUpdateDefinitions.forEach(({ queryKey, updateQuery }) => {
|
||||
// Snapshot the currently cached value.
|
||||
const previousDataForQuery = queryClient.getQueryData(queryKey)
|
||||
const previousDataForQuery: CacheItem[] = queryClient.getQueryData(queryKey)
|
||||
|
||||
// Attempt to optimistically update the cache using the new value.
|
||||
try {
|
||||
@ -227,13 +233,16 @@ function makeRqOptimisticUpdateOptions(queryClient, optimisticUpdateDefinitions)
|
||||
* uses a closure over the updated item to construct an item-specific query key
|
||||
* (e.g., useful when the query key depends on an ID).
|
||||
*
|
||||
* @param {InternalOptimisticUpdateDefinition} optimisticUpdateDefinition The general, "uninstantiated" optimistic
|
||||
* @param optimisticUpdateDefinition The general, "uninstantiated" optimistic
|
||||
* update definition with a function for constructing the query key.
|
||||
* @param item The item triggering the Action/optimistic update (i.e., the argument passed to the Action).
|
||||
* @returns {SpecificOptimisticUpdateDefinition} A specific optimistic update definition
|
||||
* which corresponds to the provided definition and closes over the provided item.
|
||||
* @param item The item triggering the Action/optimistic update (i.e., the
|
||||
* argument passed to the Action).
|
||||
* @returns A specific optimistic update definition which corresponds to the
|
||||
* provided definition and closes over the provided item.
|
||||
*/
|
||||
function getOptimisticUpdateDefinitionForSpecificItem(optimisticUpdateDefinition, item) {
|
||||
function getOptimisticUpdateDefinitionForSpecificItem<ActionInput, CacheItem>(
|
||||
optimisticUpdateDefinition: InternalOptimisticUpdateDefinition<ActionInput, CacheItem>, item: ActionInput
|
||||
): SpecificOptimisticUpdateDefinition<CacheItem> {
|
||||
const { getQueryKey, updateQuery } = optimisticUpdateDefinition
|
||||
return {
|
||||
queryKey: getQueryKey(item),
|
||||
@ -244,11 +253,11 @@ function getOptimisticUpdateDefinitionForSpecificItem(optimisticUpdateDefinition
|
||||
/**
|
||||
* Translates a Wasp query specifier to a query cache key used by React Query.
|
||||
*
|
||||
* @param {QuerySpecifier} querySpecifier A query specifier that's a part of the public API:
|
||||
* @param querySpecifier A query specifier that's a part of the public API:
|
||||
* https://wasp-lang.dev/docs/language/features#the-useaction-hook.
|
||||
* @returns {QueryKey} A cache key React Query internally uses for addressing queries.
|
||||
* @returns A cache key React Query internally uses for addressing queries.
|
||||
*/
|
||||
function getRqQueryKeyFromSpecifier(querySpecifier) {
|
||||
function getRqQueryKeyFromSpecifier(querySpecifier: QuerySpecifier): QueryKey {
|
||||
const [queryFn, ...otherKeys] = querySpecifier
|
||||
return [...queryFn.queryCacheKey, ...otherKeys]
|
||||
}
|
3
waspc/data/Generator/templates/react-app/src/queries/core.d.ts
vendored
Normal file
3
waspc/data/Generator/templates/react-app/src/queries/core.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export type Query<Input, Output> = (args: Input) => Promise<Output>
|
||||
|
||||
export function createQuery<Input, Output>(queryRoute: string, entitiesUsed: any[]): Query<Input, Output>
|
8
waspc/data/Generator/templates/react-app/src/queries/index.d.ts
vendored
Normal file
8
waspc/data/Generator/templates/react-app/src/queries/index.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { UseQueryResult } from "@tanstack/react-query";
|
||||
import { OutputHTMLAttributes } from "react";
|
||||
import { Query } from "./core";
|
||||
|
||||
export function useQuery<Input, Output>(
|
||||
queryFn: Query<Input, Output>,
|
||||
queryFnArgs?: Input, options?: any
|
||||
): UseQueryResult<Output, any>
|
25
waspc/data/Generator/templates/react-app/tsconfig.json
Normal file
25
waspc/data/Generator/templates/react-app/tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
@ -3,12 +3,14 @@ module Wasp.Generator.ExternalCodeGenerator
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Maybe (mapMaybe)
|
||||
import StrongPath (File', Path', Rel, (</>))
|
||||
import qualified StrongPath as SP
|
||||
import qualified System.FilePath as FP
|
||||
import qualified Wasp.AppSpec.ExternalCode as EC
|
||||
import qualified Wasp.Generator.ExternalCodeGenerator.Common as C
|
||||
import Wasp.Generator.ExternalCodeGenerator.Js (generateJsFile)
|
||||
import Wasp.Generator.ExternalCodeGenerator.Js (genSourceFile)
|
||||
import Wasp.Generator.FileDraft (FileDraft)
|
||||
import qualified Wasp.Generator.FileDraft as FD
|
||||
import Wasp.Generator.Monad (Generator)
|
||||
|
||||
@ -18,17 +20,22 @@ genExternalCodeDir ::
|
||||
C.ExternalCodeGeneratorStrategy ->
|
||||
[EC.File] ->
|
||||
Generator [FD.FileDraft]
|
||||
genExternalCodeDir strategy = mapM (genFile strategy)
|
||||
genExternalCodeDir strategy = sequence . mapMaybe (genFile strategy)
|
||||
|
||||
genFile :: C.ExternalCodeGeneratorStrategy -> EC.File -> Generator FD.FileDraft
|
||||
genFile :: C.ExternalCodeGeneratorStrategy -> EC.File -> Maybe (Generator FD.FileDraft)
|
||||
genFile strategy file
|
||||
| extension `elem` [".js", ".jsx"] = generateJsFile strategy file
|
||||
| otherwise =
|
||||
let relDstPath = C._extCodeDirInProjectRootDir strategy </> dstPathInGenExtCodeDir
|
||||
absSrcPath = EC.fileAbsPath file
|
||||
in return $ FD.createCopyFileDraft relDstPath absSrcPath
|
||||
| fileName == "tsconfig.json" = Nothing
|
||||
| extension `elem` [".js", ".jsx", ".ts", ".tsx"] = Just $ genSourceFile strategy file
|
||||
| otherwise = Just $ genResourceFile strategy file
|
||||
where
|
||||
extension = FP.takeExtension filePath
|
||||
fileName = FP.takeFileName filePath
|
||||
filePath = SP.toFilePath $ EC.filePathInExtCodeDir file
|
||||
|
||||
genResourceFile :: C.ExternalCodeGeneratorStrategy -> EC.File -> Generator FileDraft
|
||||
genResourceFile strategy file = return $ FD.createCopyFileDraft relDstPath absSrcPath
|
||||
where
|
||||
relDstPath = C._extCodeDirInProjectRootDir strategy </> dstPathInGenExtCodeDir
|
||||
absSrcPath = EC.fileAbsPath file
|
||||
dstPathInGenExtCodeDir :: Path' (Rel C.GeneratedExternalCodeDir) File'
|
||||
dstPathInGenExtCodeDir = C.castRelPathFromSrcToGenExtCodeDir $ EC.filePathInExtCodeDir file
|
||||
|
||||
extension = FP.takeExtension $ SP.toFilePath $ EC.filePathInExtCodeDir file
|
||||
|
@ -1,5 +1,5 @@
|
||||
module Wasp.Generator.ExternalCodeGenerator.Js
|
||||
( generateJsFile,
|
||||
( genSourceFile,
|
||||
resolveJsFileWaspImportsForExtCodeDir,
|
||||
)
|
||||
where
|
||||
@ -17,8 +17,8 @@ import qualified Wasp.Generator.ExternalCodeGenerator.Common as C
|
||||
import qualified Wasp.Generator.FileDraft as FD
|
||||
import Wasp.Generator.Monad (Generator)
|
||||
|
||||
generateJsFile :: C.ExternalCodeGeneratorStrategy -> EC.File -> Generator FD.FileDraft
|
||||
generateJsFile strategy file = return $ FD.createTextFileDraft dstPath text'
|
||||
genSourceFile :: C.ExternalCodeGeneratorStrategy -> EC.File -> Generator FD.FileDraft
|
||||
genSourceFile strategy file = return $ FD.createTextFileDraft dstPath text'
|
||||
where
|
||||
filePathInSrcExtCodeDir = EC.filePathInExtCodeDir file
|
||||
|
||||
|
@ -56,7 +56,7 @@ import Wasp.Util ((<++>))
|
||||
genServer :: AppSpec -> Generator [FileDraft]
|
||||
genServer spec =
|
||||
sequence
|
||||
[ genReadme,
|
||||
[ genFileCopy [relfile|README.md|],
|
||||
genPackageJson spec (npmDepsForWasp spec),
|
||||
genNpmrc,
|
||||
genGitignore
|
||||
@ -68,6 +68,7 @@ genServer spec =
|
||||
<++> genJobs spec
|
||||
<++> genJobExecutors
|
||||
<++> genPatches spec
|
||||
where genFileCopy = return . C.mkTmplFd
|
||||
|
||||
genDotEnv :: AppSpec -> Generator [FileDraft]
|
||||
genDotEnv spec = return $
|
||||
@ -83,9 +84,6 @@ genDotEnv spec = return $
|
||||
dotEnvInServerRootDir :: Path' (Rel C.ServerRootDir) File'
|
||||
dotEnvInServerRootDir = [relfile|.env|]
|
||||
|
||||
genReadme :: Generator FileDraft
|
||||
genReadme = return $ C.mkTmplFd (C.asTmplFile [relfile|README.md|])
|
||||
|
||||
genPackageJson :: AppSpec -> N.NpmDepsForWasp -> Generator FileDraft
|
||||
genPackageJson spec waspDependencies = do
|
||||
combinedDependencies <- N.genNpmDepsForPackage spec waspDependencies
|
||||
@ -157,10 +155,10 @@ genGitignore =
|
||||
genSrcDir :: AppSpec -> Generator [FileDraft]
|
||||
genSrcDir spec =
|
||||
sequence
|
||||
[ copyTmplFile [relfile|app.js|],
|
||||
copyTmplFile [relfile|utils.js|],
|
||||
copyTmplFile [relfile|core/AuthError.js|],
|
||||
copyTmplFile [relfile|core/HttpError.js|],
|
||||
[ genFileCopy [relfile|app.js|],
|
||||
genFileCopy [relfile|utils.js|],
|
||||
genFileCopy [relfile|core/AuthError.js|],
|
||||
genFileCopy [relfile|core/HttpError.js|],
|
||||
genDbClient spec,
|
||||
genConfigFile spec,
|
||||
genServerJs spec
|
||||
@ -170,7 +168,7 @@ genSrcDir spec =
|
||||
<++> genOperations spec
|
||||
<++> genAuth spec
|
||||
where
|
||||
copyTmplFile = return . C.mkSrcTmplFd
|
||||
genFileCopy = return . C.mkSrcTmplFd
|
||||
|
||||
genDbClient :: AppSpec -> Generator FileDraft
|
||||
genDbClient spec = return $ C.mkTmplFdWithDstAndData tmplFile dstFile (Just tmplData)
|
||||
|
@ -43,7 +43,8 @@ import Wasp.Util ((<++>))
|
||||
genWebApp :: AppSpec -> Generator [FileDraft]
|
||||
genWebApp spec = do
|
||||
sequence
|
||||
[ genReadme,
|
||||
[ genFileCopy [relfile|README.md|],
|
||||
genFileCopy [relfile|tsconfig.json|],
|
||||
genPackageJson spec (npmDepsForWasp spec),
|
||||
genNpmrc,
|
||||
genGitignore,
|
||||
@ -54,6 +55,8 @@ genWebApp spec = do
|
||||
<++> genExternalCodeDir extClientCodeGeneratorStrategy (AS.externalClientFiles spec)
|
||||
<++> genExternalCodeDir extSharedCodeGeneratorStrategy (AS.externalSharedFiles spec)
|
||||
<++> genDotEnv spec
|
||||
where
|
||||
genFileCopy = return . C.mkTmplFd
|
||||
|
||||
genDotEnv :: AppSpec -> Generator [FileDraft]
|
||||
genDotEnv spec = return $
|
||||
@ -69,9 +72,6 @@ genDotEnv spec = return $
|
||||
dotEnvInWebAppRootDir :: Path' (Rel C.WebAppRootDir) File'
|
||||
dotEnvInWebAppRootDir = [relfile|.env|]
|
||||
|
||||
genReadme :: Generator FileDraft
|
||||
genReadme = return $ C.mkTmplFd $ C.asTmplFile [relfile|README.md|]
|
||||
|
||||
genPackageJson :: AppSpec -> N.NpmDepsForWasp -> Generator FileDraft
|
||||
genPackageJson spec waspDependencies = do
|
||||
combinedDependencies <- N.genNpmDepsForPackage spec waspDependencies
|
||||
@ -114,7 +114,13 @@ npmDepsForWasp spec =
|
||||
-- See discussion here for more: https://github.com/wasp-lang/wasp/pull/621
|
||||
N.waspDevDependencies =
|
||||
AS.Dependency.fromList
|
||||
[]
|
||||
[ -- TODO: Allow users to choose whether they want to use TypeScript
|
||||
-- in their projects and install these dependencies accordingly.
|
||||
("typescript", "^4.8.4"),
|
||||
("@types/react", "^18.0.25"),
|
||||
("@types/react-dom", "^18.0.8"),
|
||||
("@types/react-router-dom", "^5.3.3")
|
||||
]
|
||||
}
|
||||
|
||||
depsRequiredByTailwind :: AppSpec -> [AS.Dependency.Dependency]
|
||||
|
@ -40,15 +40,18 @@ genQueries spec =
|
||||
mapM (genQuery spec) (AS.getQueries spec)
|
||||
<++> return
|
||||
[ C.mkSrcTmplFd [relfile|queries/index.js|],
|
||||
C.mkSrcTmplFd [relfile|queries/core.js|]
|
||||
C.mkSrcTmplFd [relfile|queries/index.d.ts|],
|
||||
C.mkSrcTmplFd [relfile|queries/core.js|],
|
||||
C.mkSrcTmplFd [relfile|queries/core.d.ts|]
|
||||
]
|
||||
|
||||
genActions :: AppSpec -> Generator [FileDraft]
|
||||
genActions spec =
|
||||
mapM (genAction spec) (AS.getActions spec)
|
||||
<++> return
|
||||
[ C.mkSrcTmplFd [relfile|actions/index.js|],
|
||||
C.mkSrcTmplFd [relfile|actions/core.js|]
|
||||
[ C.mkSrcTmplFd [relfile|actions/index.ts|],
|
||||
C.mkSrcTmplFd [relfile|actions/core.js|],
|
||||
C.mkSrcTmplFd [relfile|actions/core.d.ts|]
|
||||
]
|
||||
|
||||
genQuery :: AppSpec -> (String, AS.Query.Query) -> Generator FileDraft
|
||||
|
@ -33,6 +33,7 @@ data-files:
|
||||
Generator/templates/server/npmrc
|
||||
Generator/templates/**/*.prisma
|
||||
Generator/templates/**/*.toml
|
||||
Generator/templates/**/*.ts
|
||||
Generator/templates/**/*.json
|
||||
Generator/templates/**/*.ico
|
||||
Generator/templates/**/*.html
|
||||
@ -41,9 +42,10 @@ data-files:
|
||||
Generator/templates/**/*.png
|
||||
Cli/bash-completion
|
||||
Cli/templates/**/*.css
|
||||
Cli/templates/**/*.js
|
||||
Cli/templates/**/*.json
|
||||
Cli/templates/**/*.png
|
||||
Cli/templates/**/*.ts
|
||||
Cli/templates/**/*.tsx
|
||||
Cli/templates/new/.gitignore
|
||||
Cli/templates/new/.wasproot
|
||||
Cli/templates/new/src/.waspignore
|
||||
|
Loading…
Reference in New Issue
Block a user