Skip to content
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
2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ catalogs:
react-native-windows: ^0.81.0
react-test-renderer: 19.1.4

dynamicPackageExtensions: ./scripts/dynamic.extensions.mjs
dynamicPackageExtensions: ./scripts/dynamic.extensions.mts

enableGlobalCache: false

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
],
"scripts": {
"build": "lage build-all",
"clean-all": "node ./scripts/src/preinstall/clean-all.js",
"clean-all": "node ./scripts/src/preinstall/clean-all.ts",
"docs": "yarn workspace fluent-rn-website start",
"bundle:repo": "lage bundle",
"clean": "lage clean",
"change": "node .github/scripts/change.mts",
"changeset:version": "node .github/scripts/changeset-version-with-postbump.mts",
"change:check": "node .github/scripts/change.mts --check",
"check-publishing": "node ./scripts/src/cli.mjs check-publishing",
"check-publishing": "node ./scripts/src/cli.ts check-publishing",
"lint-fix": "cross-env FURN_FIX_MODE=true lage lint",
"lint-package-fix": "cross-env FURN_FIX_MODE=true lage lint-package",
"preinstall": "node ./scripts/src/preinstall/use-yarn-please.js",
"preinstall": "node ./scripts/src/preinstall/use-yarn-please.ts",
"format": "oxfmt",
"format:check": "oxfmt --check",
"lint-lockfile": "lint-lockfile",
Expand Down
36 changes: 13 additions & 23 deletions scripts/dynamic.extensions.mjs → scripts/dynamic.extensions.mts
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
// @ts-check

import fs from 'node:fs';
import path from 'node:path';
import { getToolVersion, hasJestConfig } from './src/preinstall/tool-versions.js';
import { getToolVersion, hasJestConfig } from './src/preinstall/tool-versions.ts';
import type { PackageManifest } from './src/utils/projectRoot.ts';

/**
* @typedef {() => boolean} ConditionalCheck
*/
type ConditionalCheck = () => boolean;

/**
* Conditionally add a dependency to the given dependencies object if it is not already present
* @param {string[]} depsToAdd
* @param {import('./src/utils/projectRoot.ts').PackageManifest} manifest
* @param {ConditionalCheck | boolean | undefined} condition
* @returns {Record<string, string>}
*/
function conditionallyAdd(depsToAdd, manifest, condition) {
/** @type {Record<string, string>} */
const newDeps = {};
function conditionallyAdd(
depsToAdd: string[],
manifest: PackageManifest,
condition: ConditionalCheck | boolean | undefined,
): Record<string, string> {
const newDeps: Record<string, string> = {};
if (!condition || (typeof condition === 'function' ? condition() : condition)) {
for (const dep of depsToAdd) {
if (!manifest.dependencies?.[dep] && !manifest.devDependencies?.[dep]) {
Expand All @@ -36,29 +32,23 @@ function conditionallyAdd(depsToAdd, manifest, condition) {
}

/**
* @param {import('./src/utils/projectRoot.ts').PackageManifest} manifest - The package manifest.
* @returns {boolean} true if oxfmt should be added based on the manifest's prettier scripts
* Returns true if oxfmt should be added based on the manifest's prettier scripts.
*/
function addOxfmt(manifest) {
function addOxfmt(manifest: PackageManifest): boolean {
return Boolean(manifest && manifest.scripts && (manifest.scripts.format || manifest.scripts['format:fix']));
}

/**
* Check if Jest is already in the manifest or if a Jest script is defined.
* @param {string} cwd - The current working directory.
* @param {import('./src/utils/projectRoot.ts').PackageManifest} manifest - The package manifest.
* @returns {boolean} - True if Jest should be added, false otherwise.
*/
function addJest(cwd, manifest) {
function addJest(cwd: string, manifest: PackageManifest): boolean {
return Boolean(manifest.scripts?.test && hasJestConfig(cwd));
}

/**
* Get the dynamic dependencies for the given package given the package root directory and its manifest.
* @param {{cwd: string, manifest: import('./src/utils/projectRoot.ts').PackageManifest}} param0
* @returns { { dependencies: Record<string, string> } }
*/
export default function ({ cwd, manifest }) {
export default function ({ cwd, manifest }: { cwd: string; manifest: PackageManifest }): { dependencies: Record<string, string> } {
const enableLinting = Boolean(manifest.scripts && manifest.scripts.lint);

return {
Expand Down
16 changes: 8 additions & 8 deletions scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
"directory": "scripts"
},
"bin": {
"fluentui-scripts": "./src/cli.mjs"
"fluentui-scripts": "./src/cli.ts"
},
"type": "module",
"main": "./src/index.js",
"main": "./src/index.ts",
"exports": {
".": {
"require": "./src/index.js",
"default": "./src/index.js"
"require": "./src/index.ts",
"default": "./src/index.ts"
},
"./babel-config": "./configs/jest/babel.config.cjs",
"./jest-config": "./configs/jest/jest.config.cjs",
Expand All @@ -29,10 +29,10 @@
"build": "tsgo",
"build-core": "tsgo",
"bundlesize": "bundlesize --debug",
"depcheck": "node ./src/cli.mjs depcheck",
"format": "node ./src/cli.mjs format",
"lint": "node ./src/cli.mjs lint",
"lint-package": "node ./src/cli.mjs lint-package"
"depcheck": "node ./src/cli.ts depcheck",
"format": "node ./src/cli.ts format",
"lint": "node ./src/cli.ts lint",
"lint-package": "node ./src/cli.ts lint-package"
},
"dependencies": {
"@babel/core": "catalog:",
Expand Down
11 changes: 5 additions & 6 deletions scripts/src/cli.mjs → scripts/src/cli.ts
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#!/usr/bin/env node
// @ts-check

import { Builtins, Cli } from 'clipanion';
import { BuildCommand } from './tasks/build.ts';
import { CleanCommand } from './tasks/clean.js';
import { FormatCommand } from './tasks/format.js';
import { LintCommand } from './tasks/lint.js';
import { CleanCommand } from './tasks/clean.ts';
import { FormatCommand } from './tasks/format.ts';
import { LintCommand } from './tasks/lint.ts';
import { LintPackageCommand } from './tasks/lintPackage.ts';
import { JestCommand } from './tasks/jest.js';
import { CheckPublishingCommand } from './tasks/checkPublishingTask.js';
import { JestCommand } from './tasks/jest.ts';
import { CheckPublishingCommand } from './tasks/checkPublishingTask.ts';
import { DepcheckCommand } from './tasks/depcheck.ts';

const cli = new Cli({
Expand Down
1 change: 0 additions & 1 deletion scripts/src/index.js → scripts/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
// @ts-check
export { isPnpmMode } from './utils/ispnpm.ts';
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
// @ts-check

const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
import child_process from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
// This script MUST NOT have any deps aside from Node built-ins, because it deletes all node_modules!

/**
* @param {string} question - The question to prompt the user with
* @returns {Promise<string>}
* */
function prompt(question) {
function prompt(question: string): Promise<string> {
return new Promise((resolve) => {
process.stdin.resume();
process.stdout.write(question);
Expand All @@ -22,10 +16,7 @@ function prompt(question) {
});
}

/**
* @param {string} itemPath - The path to the item to check
*/
function deleteIfSymlink(itemPath) {
function deleteIfSymlink(itemPath: string): void {
itemPath = path.resolve(itemPath);
try {
// Compare realpath since fs.statSync(itemPath).isSymbolicLink() doesn't work on Windows
Expand All @@ -40,10 +31,8 @@ function deleteIfSymlink(itemPath) {

/**
* Deletes symlinks in the specified node_modules directory.
* @param {string} nodeModulesPath - The path to the node_modules directory
* @returns {void}
*/
function deleteNodeModulesSymlinks(nodeModulesPath) {
function deleteNodeModulesSymlinks(nodeModulesPath: string): void {
if (!fs.existsSync(nodeModulesPath)) {
return;
}
Expand All @@ -62,10 +51,8 @@ function deleteNodeModulesSymlinks(nodeModulesPath) {

/**
* Deletes symlinks in the specified parent folder.
* @param {string} parentFolder - The path to the parent folder
* @returns {void}
*/
function deleteSymlinks(parentFolder) {
function deleteSymlinks(parentFolder: string): void {
const parentPath = path.join(process.cwd(), parentFolder);
if (!fs.existsSync(parentPath)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import type { PackageManifest } from '../utils/projectRoot.ts';

/**
* Get the package.json manifest for a given folder.
* @param {string} folder
* @returns {import('../utils/projectRoot.ts').PackageManifest}
*/
function getPackageManifest(folder) {
function getPackageManifest(folder: string): PackageManifest {
const manifestPath = path.join(folder, 'package.json');
return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
}
Expand All @@ -17,8 +17,7 @@ const scriptFolder = path.join(path.dirname(fileURLToPath(import.meta.url)), '..
const scriptManifest = getPackageManifest(scriptFolder);
const rootManifest = getPackageManifest(path.dirname(scriptFolder));

/** @type {Record<string, string>} */
const devToolVersions = {
const devToolVersions: Record<string, string> = {
'@eslint/js': '^9.0.0',
'@microsoft/eslint-plugin-sdl': '^1.1.0',
'@react-native-community/cli': '^13.6.4',
Expand Down Expand Up @@ -58,27 +57,21 @@ const devToolVersions = {
...rootManifest.devDependencies,
};

/** @type {Record<string, string>} */
const workspaceToolVersions = {
const workspaceToolVersions: Record<string, string> = {
'@fluentui-react-native/scripts': 'workspace:*',
};

/**
*
* @param {string} packageName
* @returns {string | null}
*/
export function getToolVersion(packageName) {
export function getToolVersion(packageName: string): string | null {
return devToolVersions[packageName] ?? workspaceToolVersions[packageName] ?? null;
}

const CONFIG_EXTENSIONS = ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts'];

/**
* @param {string} cwd - The current working directory.
* @returns {boolean} - True if a Jest config file exists in the cwd, false otherwise.
* @param cwd the current working directory.
* @returns true if a Jest config file exists in the cwd, false otherwise.
*/
export function hasJestConfig(cwd) {
export function hasJestConfig(cwd: string): boolean {
for (const ext of CONFIG_EXTENSIONS) {
if (fs.existsSync(path.join(cwd, `jest.config${ext}`))) {
return true;
Expand Down
4 changes: 1 addition & 3 deletions scripts/src/tasks/build.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// @ts-check

import { Command } from 'clipanion';
import { runYarn } from '../utils/runScript.js';
import { runYarn } from '../utils/runScript.ts';
import { getProjectRoot } from '../utils/projectRoot.ts';
import { getResolvedConfig } from '../utils/buildConfig.ts';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
// @ts-check

import { Command } from 'clipanion';
import { getPackageInfos, findGitRoot } from 'workspace-tools';

import { checkDependencies } from '../utils/checkDependencies.js';
import { checkDependencies } from '../utils/checkDependencies.ts';

/**
* @typedef {'dependencies' | 'devDependencies' | 'peerDependencies'} DependencyType
* @typedef {{ dependencyTypes?: DependencyType[] }} CheckPublishingOptions
*/
type DependencyType = 'dependencies' | 'devDependencies' | 'peerDependencies';

export class CheckPublishingCommand extends Command {
/** @override */
static paths = [['check-publishing']];
static override paths = [['check-publishing']];

/** @override */
static usage = Command.Usage({
static override usage = Command.Usage({
description: 'Check the matrix of packages for publishing errors',
details: 'This command checks for published packages that have a dependency on a private package.',
examples: [['Check for publishing errors', '$0 check-publishing']],
});

async execute() {
const dependencyTypes = ['dependencies'];
const dependencyTypes: DependencyType[] = ['dependencies'];
const packageInfos = getPackageInfos(findGitRoot(process.cwd()));
console.info('Starting scan for publishing errors');
try {
Expand Down
11 changes: 3 additions & 8 deletions scripts/src/tasks/clean.js → scripts/src/tasks/clean.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
// @ts-check

import { Command } from 'clipanion';
import fs from 'node:fs';
import path from 'node:path';

export class CleanCommand extends Command {
/** @override */
static paths = [['clean']];
static override paths = [['clean']];

/** @override */
static usage = Command.Usage({
static override usage = Command.Usage({
description: 'Cleans the current package',
details: 'This command removes all build artifacts from the current package.',
examples: [['Clean the current package', '$0 clean']],
Expand All @@ -22,9 +18,8 @@ export class CleanCommand extends Command {

/**
* Cleans the specified folder by removing certain directories and files.
* @param {string} [cwd=process.cwd()] - The target directory to clean.
*/
export function cleanFolder(cwd = process.cwd()) {
export function cleanFolder(cwd: string = process.cwd()): number {
const options = { force: true, maxRetries: 3, recursive: true };
[
'lib',
Expand Down
6 changes: 2 additions & 4 deletions scripts/src/tasks/depcheck.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// @ts-check

import { Command, Option } from 'clipanion';
import depcheck from 'depcheck';
import type { ProjectRoot } from '../utils/projectRoot.ts';
import { getProjectRoot } from '../utils/projectRoot.ts';
import getInjectedDeps from '../../dynamic.extensions.mjs';
import getInjectedDeps from '../../dynamic.extensions.mts';
import { getReporter } from '../utils/getReporter.ts';
import { getToolVersion } from '../preinstall/tool-versions.js';
import { getToolVersion } from '../preinstall/tool-versions.ts';
import micromatch from 'micromatch';
import { isFixMode } from '../utils/env.ts';

Expand Down
10 changes: 3 additions & 7 deletions scripts/src/tasks/format.js → scripts/src/tasks/format.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
// @ts-check

import { Command, Option } from 'clipanion';
import { runScript } from '../utils/runScript.js';
import { runScript } from '../utils/runScript.ts';
import { isFixMode } from '../utils/env.ts';

export class FormatCommand extends Command {
/** @override */
static paths = [['format']];
static override paths = [['format']];

/** @override */
static usage = Command.Usage({
static override usage = Command.Usage({
description: 'Formats the current package',
details: 'This command formats the current package using oxfmt.',
examples: [['Format the current package', '$0 format']],
Expand Down
11 changes: 4 additions & 7 deletions scripts/src/tasks/jest.js → scripts/src/tasks/jest.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
// @ts-check
import { Command, Option } from 'clipanion';
import { runScript } from '../utils/runScript.js';
import { hasJestConfig } from '../preinstall/tool-versions.js';
import { runScript } from '../utils/runScript.ts';
import { hasJestConfig } from '../preinstall/tool-versions.ts';

export class JestCommand extends Command {
/** @override */
static paths = [['jest']];
static override paths = [['jest']];

/** @override */
static usage = Command.Usage({
static override usage = Command.Usage({
description: 'Tests the current package using jest',
details: 'This command tests the current package.',
examples: [['Test the current package', '$0 jest']],
Expand Down
Loading
Loading