chore(create-mcfly, config): migrate to typescript

- initial migration before we do the core
This commit is contained in:
Ayo Ayco 2025-02-28 21:50:28 +01:00
parent 332dbd1f88
commit 280e2f6150
12 changed files with 113 additions and 60 deletions

View file

@ -6,8 +6,9 @@
"preinstall": "npx only-allow pnpm", "preinstall": "npx only-allow pnpm",
"start": "pnpm --filter site start", "start": "pnpm --filter site start",
"site": "pnpm --filter site start", "site": "pnpm --filter site start",
"build": "pnpm --filter site build", "build": "pnpm -F './packages/**' build",
"build:preview": "pnpm --filter site build:preview", "build:site": "pnpm --filter site build",
"build:site:preview": "pnpm --filter site build:preview",
"template:basic": "pnpm --filter @templates/basic dev", "template:basic": "pnpm --filter @templates/basic dev",
"create": "node ./packages/create-mcfly", "create": "node ./packages/create-mcfly",
"cli": "node ./packages/core/cli/index.js", "cli": "node ./packages/core/cli/index.js",
@ -28,6 +29,7 @@
"husky": "^9.1.7", "husky": "^9.1.7",
"netlify-cli": "^18.0.0", "netlify-cli": "^18.0.0",
"prettier": "^3.4.2", "prettier": "^3.4.2",
"typescript": "^5.7.3",
"vitest": "^2.1.8" "vitest": "^2.1.8"
}, },
"lint-staged": { "lint-staged": {

View file

@ -1,24 +0,0 @@
/**
* @typedef {import('nitropack').NitroConfig} NitroConfig
* @typedef {object} ServerConfig
* @property {boolean} logs
* Set to true if you want to see server logs
* @typedef {object} McFlyConfig
* @property {'js' | 'lit'} components
* Type of components used:
* - `'js'` = Vanilla
* - `'lit'` = Lit (in-progress)
* - `'enhance'` = Enhance (in-progress)
* - `'webc'` = WebC (in-progress)
* @property {NitroConfig} nitro
* @property {ServerConfig} server
*/
/**
* Define the configuration for the McFly project
* @param {McFlyConfig} config
* @returns {function(): McFlyConfig}
*/
export function defineMcFlyConfig(config) {
return () => config
}

View file

@ -3,8 +3,15 @@
"version": "0.2.7", "version": "0.2.7",
"description": "Nitro configuration for McFly apps", "description": "Nitro configuration for McFly apps",
"type": "module", "type": "module",
"main": "index.js", "main": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"scripts": { "scripts": {
"build": "tsc --build tsconfig.json",
"version": "npm version", "version": "npm version",
"publish": "npm publish", "publish": "npm publish",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"

View file

@ -0,0 +1,15 @@
import type { NitroConfig } from 'nitropack'
export type McFlyConfig = {
components: 'js' | 'lit'
nitro: NitroConfig
}
/**
* Define the configuration for the McFly project
* @param {McFlyConfig} config
* @returns {function(): McFlyConfig}
*/
export function defineMcFlyConfig(config: McFlyConfig) {
return () => config
}

View file

@ -1,15 +1,16 @@
export { defineMcFlyConfig } from './define-mcfly-config.js'
import { nitroConfig } from './nitro-config.js' import { nitroConfig } from './nitro-config.js'
/** import type { NitroConfig } from 'nitropack'
* @typedef {import('nitropack').NitroConfig} NitroConfig
* @typedef {import('./define-mcfly-config.js').McFlyConfig} McFlyConfig
*/
/** /**
* Returns the Nitro configuration for a McFly project * Returns the Nitro configuration for a McFly project
* @returns {NitroConfig} * @returns {NitroConfig}
*/ */
export default function () { export default function (): NitroConfig {
return nitroConfig return nitroConfig
} }
export { defineMcFlyConfig } from './define-mcfly-config.js'
export type { McFlyConfig } from './define-mcfly-config.js'
export const hello = 'world'

View file

@ -1,8 +1,10 @@
import type { NitroConfig } from 'nitropack'
/** /**
* @typedef {import('nitropack').NitroConfig} NitroConfig * @typedef {import('nitropack').NitroConfig} NitroConfig
* @type {NitroConfig} * @type {NitroConfig}
*/ */
export const nitroConfig = { export const nitroConfig: NitroConfig = {
framework: { framework: {
name: 'McFly', name: 'McFly',
}, },

View file

@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src"],
"compilerOptions": {
"allowJs": true,
"emitDeclarationOnly": true,
"declarationDir": "./dist",
"outDir": "./dist"
}
}

View file

@ -8,9 +8,13 @@
}, },
"main": "index.js", "main": "index.js",
"exports": { "exports": {
".": "./index.js" ".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}, },
"scripts": { "scripts": {
"build": "tsc --build tsconfig.json",
"version": "npm version", "version": "npm version",
"publish": "npm publish", "publish": "npm publish",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"

View file

@ -4,20 +4,18 @@ import { consola } from 'consola'
import { colorize } from 'consola/utils' import { colorize } from 'consola/utils'
import { downloadTemplate } from 'giget' import { downloadTemplate } from 'giget'
import { spawnSync } from 'node:child_process' import { spawnSync } from 'node:child_process'
import path from 'node:path' import * as path from 'node:path'
const [, , directoryArg] = process.argv const [, , directoryArg] = process.argv
/** type PromptAction = {
* @typedef {{ prompt: string
* prompt: string, info?: string
* info?: string, startMessage: string
* startMessage: string, command: string
* command: string, subCommand: string
* subCommand: string, error: string
* error: string }
* }} PromptAction
**/
/** /**
* Create McFly App * Create McFly App
@ -44,10 +42,7 @@ async function create() {
const hasErrors = await downloadTemplateToDirectory(directory) const hasErrors = await downloadTemplateToDirectory(directory)
if (!hasErrors) { if (!hasErrors) {
/** const prompts: PromptAction[] = [
* @type Array<PromptAction>
*/
const prompts = [
{ {
prompt: `Would you like to install the dependencies to ${colorize( prompt: `Would you like to install the dependencies to ${colorize(
'bold', 'bold',
@ -83,9 +78,9 @@ async function create() {
/** /**
* Returns string that is safe for commands * Returns string that is safe for commands
* @param {string} directory * @param {string} directory
* @returns string | undefined * @returns string
*/ */
function getSafeDirectory(directory) { function getSafeDirectory(directory: string): string {
const { platform } = process const { platform } = process
const locale = path[platform === `win32` ? `win32` : `posix`] const locale = path[platform === `win32` ? `win32` : `posix`]
const localePath = directory.split(path.sep).join(locale.sep) const localePath = directory.split(path.sep).join(locale.sep)
@ -97,7 +92,9 @@ function getSafeDirectory(directory) {
* @param {string} directory * @param {string} directory
* @returns Promise<boolean> hasErrors * @returns Promise<boolean> hasErrors
*/ */
async function downloadTemplateToDirectory(directory) { async function downloadTemplateToDirectory(
directory: string
): Promise<boolean> {
let hasErrors = false let hasErrors = false
try { try {
@ -108,7 +105,11 @@ async function downloadTemplateToDirectory(directory) {
dir: directory, dir: directory,
}) })
} catch (_ㆆ) { } catch (_ㆆ) {
consola.error(_ㆆ.message) if (_ㆆ instanceof Error) {
consola.error(_ㆆ.message)
} else {
consola.error(_ㆆ)
}
consola.info('Try a different name.\n') consola.info('Try a different name.\n')
hasErrors = true hasErrors = true
} }
@ -117,13 +118,16 @@ async function downloadTemplateToDirectory(directory) {
} }
/** /**
* * Iterate over an array of prompts and ask for user intention
* @param {Array<PromptAction>} prompts * @param {Array<PromptAction>} prompts
* @param {string} cwd * @param {string} cwd
* @returns Array<boolean> | undefined * @returns Promise<Array<boolean> | undefined>
*/ */
async function askPrompts(prompts, cwd) { async function askPrompts(
const results = [] prompts: PromptAction[],
cwd: string
): Promise<boolean[] | undefined> {
const results: boolean[] = []
for (const p of prompts) { for (const p of prompts) {
const userIntends = await consola.prompt(p.prompt, { const userIntends = await consola.prompt(p.prompt, {
@ -146,7 +150,11 @@ async function askPrompts(prompts, cwd) {
}) })
consola.success('Done!') consola.success('Done!')
} catch (_ㆆ) { } catch (_ㆆ) {
consola.error(_ㆆ.message) if (_ㆆ instanceof Error) {
consola.error(_ㆆ.message)
} else {
consola.error(_ㆆ)
}
consola.info(p.error + '\n') consola.info(p.error + '\n')
} }
} }
@ -161,7 +169,7 @@ async function askPrompts(prompts, cwd) {
* @param {string} directory * @param {string} directory
* @param {boolean} installDeps * @param {boolean} installDeps
*/ */
function showResults(directory, installDeps) { function showResults(directory: string, installDeps: boolean) {
let nextActions = [ let nextActions = [
`Go to your project by running ${colorize('yellow', `cd ${directory}`)}`, `Go to your project by running ${colorize('yellow', `cd ${directory}`)}`,
] ]

View file

@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src"],
"compilerOptions": {
"allowJs": true,
"emitDeclarationOnly": true,
"declarationDir": "./dist",
"outDir": "./dist"
}
}

View file

@ -35,6 +35,9 @@ importers:
prettier: prettier:
specifier: ^3.4.2 specifier: ^3.4.2
version: 3.4.2 version: 3.4.2
typescript:
specifier: ^5.7.3
version: 5.7.3
vitest: vitest:
specifier: ^2.1.8 specifier: ^2.1.8
version: 2.1.8(@types/node@22.10.2)(@vitest/ui@2.1.8)(terser@5.37.0) version: 2.1.8(@types/node@22.10.2)(@vitest/ui@2.1.8)(terser@5.37.0)

15
tsconfig.base.json Normal file
View file

@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"strict": true,
"moduleResolution": "Node16",
"target": "ES2022",
"module": "Node16",
"esModuleInterop": true,
"skipLibCheck": true,
"verbatimModuleSyntax": true,
"stripInternal": true
}
}