Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(test-project): Switch tui-tasks to TypeScript #11926

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions tasks/test-project/codemods/models.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/* eslint-env node, es6*/

const post = `model Post {
export const post = `model Post {
id Int @id @default(autoincrement())
title String
body String
Expand All @@ -9,15 +7,15 @@ const post = `model Post {
createdAt DateTime @default(now())
}`

const contact = `model Contact {
export const contact = `model Contact {
id Int @id @default(autoincrement())
name String
email String
message String
createdAt DateTime @default(now())
}`

const user = `model User {
export const user = `model User {
id Int @id @default(autoincrement())
email String @unique
hashedPassword String
Expand All @@ -29,7 +27,7 @@ const user = `model User {
posts Post[]
}`

const produce = `model Produce {
export const produce = `model Produce {
id String @id @default(cuid())
name String @unique
quantity Int
Expand All @@ -48,11 +46,9 @@ const produce = `model Produce {
stallId String
}`

const stall = `model Stall {
export const stall = `model Stall {
id String @id @default(cuid())
name String
stallNumber String @unique
produce Produce[]
}`

module.exports = { post, contact, user, produce, stall }
14 changes: 7 additions & 7 deletions tasks/test-project/rebuild-fragments-test-project-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
copyFrameworkPackages,
} from './frameworkLinking'
import { webTasks, apiTasks, fragmentsTasks } from './tui-tasks'
import { isAwaitable } from './typing'
import { isAwaitable, isTuiError } from './typing'
import type { TuiTaskDef } from './typing'
import {
getExecaOptions as utilGetExecaOptions,
Expand Down Expand Up @@ -140,13 +140,16 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) {
'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr,
)
} else {
const message = isTuiError(e) ? e.message : ''

tui.displayError(
'Failed ' + title.toLowerCase().replace('...', ''),
e.message,
message || '',
)
}

process.exit(e.exitCode)
const exitCode = isTuiError(e) ? e.exitCode : undefined
process.exit(exitCode)
}

if (isAwaitable(promise)) {
Expand Down Expand Up @@ -197,11 +200,8 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) {
/**
* Function that returns a string to show when skipping the task, or just
* true|false to indicate whether the task should be skipped or not.
*
* @param {string} startStep
* @param {string} currentStep
*/
function skipFn(startStep, currentStep) {
function skipFn(startStep: string, currentStep: string) {
const startStepNrs = startStep.split('.').map((s) => parseInt(s, 10))
const currentStepNrs = currentStep.split('.').map((s) => parseInt(s, 10))

Expand Down
14 changes: 7 additions & 7 deletions tasks/test-project/rebuild-test-project-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
copyFrameworkPackages,
} from './frameworkLinking'
import { webTasks, apiTasks } from './tui-tasks'
import { isAwaitable } from './typing'
import { isAwaitable, isTuiError } from './typing'
import type { TuiTaskDef } from './typing'
import {
getExecaOptions as utilGetExecaOptions,
Expand Down Expand Up @@ -140,13 +140,16 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) {
'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr,
)
} else {
const message = isTuiError(e) ? e.message : ''

tui.displayError(
'Failed ' + title.toLowerCase().replace('...', ''),
e.message,
message || '',
)
}

process.exit(e.exitCode)
const exitCode = isTuiError(e) ? e.exitCode : undefined
process.exit(exitCode)
}

if (isAwaitable(promise)) {
Expand Down Expand Up @@ -197,11 +200,8 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) {
/**
* Function that returns a string to show when skipping the task, or just
* true|false to indicate whether the task should be skipped or not.
*
* @param {string} startStep
* @param {string} currentStep
*/
function skipFn(startStep, currentStep) {
function skipFn(startStep: string, currentStep: string) {
const startStepNrs = startStep.split('.').map((s) => parseInt(s, 10))
const currentStepNrs = currentStep.split('.').map((s) => parseInt(s, 10))

Expand Down
1 change: 0 additions & 1 deletion tasks/test-project/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,6 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) {
await execa(
'yarn rw g dbAuth --no-webauthn --username-label=username --password-label=password',
[],
execaOptions,
)

// update directive in contacts.sdl.ts
Expand Down
61 changes: 30 additions & 31 deletions tasks/test-project/tui-tasks.js → tasks/test-project/tui-tasks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
/* eslint-env node, es2021*/
//@ts-check
const fs = require('fs')
const path = require('path')

import fs from 'node:fs'
import path from 'node:path'

import type { Options as ExecaOptions, ExecaChildProcess } from 'execa'

import type { TuiTaskList } from './typing.js'

const {
getExecaOptions: utilGetExecaOptions,
Expand All @@ -10,18 +14,17 @@ const {
exec,
} = require('./util')

/** @type {(string) => import('execa').Options} */
function getExecaOptions(cwd) {
function getExecaOptions(cwd: string): ExecaOptions {
return { ...utilGetExecaOptions(cwd), stdio: 'pipe' }
}

// This variable gets used in other functions
// and is set when webTasks or apiTasks are called
let OUTPUT_PATH
let OUTPUT_PATH: string

const RW_FRAMEWORK_PATH = path.join(__dirname, '../../')

function fullPath(name, { addExtension } = { addExtension: true }) {
function fullPath(name: string, { addExtension } = { addExtension: true }) {
if (addExtension) {
if (name.startsWith('api')) {
name += '.ts'
Expand All @@ -34,7 +37,7 @@ function fullPath(name, { addExtension } = { addExtension: true }) {
}

// TODO: Import from ./util.js when everything is using @rwjs/tui
async function applyCodemod(codemod, target) {
async function applyCodemod(codemod: string, target: string) {
const args = [
'--fail-on-error',
'-t',
Expand All @@ -56,14 +59,14 @@ async function applyCodemod(codemod, target) {
}

/**
* @param {string} cmd The command to run
* @returns {((positionalArguments: string | string[]) => import('execa').ExecaChildProcess<string>)
* & (() => import('execa').ExecaChildProcess<string>)}
* @param cmd The command to run
*/
const createBuilder = (cmd) => {
function createBuilder(cmd: string) {
const execaOptions = getExecaOptions(OUTPUT_PATH)

return function (positionalArguments) {
return function (
positionalArguments?: string | string[],
): ExecaChildProcess<string> {
const subprocess = exec(
cmd,
Array.isArray(positionalArguments)
Expand All @@ -76,16 +79,18 @@ const createBuilder = (cmd) => {
}
}

async function webTasks(outputPath, { linkWithLatestFwBuild }) {
export async function webTasks(
outputPath: string,
{ linkWithLatestFwBuild }: { linkWithLatestFwBuild: boolean },
) {
OUTPUT_PATH = outputPath

const execaOptions = getExecaOptions(outputPath)

const createPages = async () => {
const createPage = createBuilder('yarn redwood g page')

/** @type import('./typing').TuiTaskList */
const tuiTaskList = [
const tuiTaskList: TuiTaskList = [
{
title: 'Creating home page',
task: async () => {
Expand Down Expand Up @@ -317,8 +322,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild }) {
)
}

/** @type import('./typing').TuiTaskList */
const tuiTaskList = [
const tuiTaskList: TuiTaskList = [
{
title: 'Creating pages',
task: () => createPages(),
Expand Down Expand Up @@ -389,15 +393,18 @@ async function webTasks(outputPath, { linkWithLatestFwBuild }) {
return tuiTaskList
}

async function addModel(schema) {
async function addModel(schema: string) {
const path = `${OUTPUT_PATH}/api/db/schema.prisma`

const current = fs.readFileSync(path, 'utf-8')

fs.writeFileSync(path, `${current.trim()}\n\n${schema}\n`)
}

async function apiTasks(outputPath, { linkWithLatestFwBuild }) {
export async function apiTasks(
outputPath: string,
{ linkWithLatestFwBuild }: { linkWithLatestFwBuild: boolean },
) {
OUTPUT_PATH = outputPath

const execaOptions = getExecaOptions(outputPath)
Expand Down Expand Up @@ -714,8 +721,7 @@ export default DoublePage`

const generateScaffold = createBuilder('yarn rw g scaffold')

/** @type import('./typing').TuiTaskList */
const tuiTaskList = [
const tuiTaskList: TuiTaskList = [
{
title: 'Adding post and user model to prisma',
task: async () => {
Expand Down Expand Up @@ -917,11 +923,10 @@ export default DoublePage`
* Tasks to add GraphQL Fragments support to the test-project, and some queries
* to test fragments
*/
async function fragmentsTasks(outputPath) {
export async function fragmentsTasks(outputPath: string) {
OUTPUT_PATH = outputPath

/** @type import('./typing').TuiTaskList */
const tuiTaskList = [
const tuiTaskList: TuiTaskList = [
{
title: 'Enable fragments',
task: async () => {
Expand Down Expand Up @@ -1029,9 +1034,3 @@ async function fragmentsTasks(outputPath) {

return tuiTaskList
}

module.exports = {
apiTasks,
webTasks,
fragmentsTasks,
}
14 changes: 14 additions & 0 deletions tasks/test-project/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export interface TuiTaskDef {
task: () => Promise<unknown> | void
}

interface TuiTaskListItem {
title: string
enabled?: boolean | (() => boolean)
task: () => Promise<unknown> | void
}

export type TuiTaskList = TuiTaskListItem[]

export function isAwaitable(promise: unknown): promise is Promise<unknown> {
return (
!!promise &&
Expand All @@ -24,3 +32,9 @@ export function isAwaitable(promise: unknown): promise is Promise<unknown> {
typeof promise.then === 'function'
)
}

export function isTuiError(
error: unknown,
): error is { message?: string; exitCode?: number } {
return error instanceof Object
}
3 changes: 2 additions & 1 deletion tasks/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "../tsconfig.compilerOption.json",
"compilerOptions": {
"moduleResolution": "NodeNext",
"module": "NodeNext"
"module": "NodeNext",
"allowJs": true
}
}
Loading