Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2eadd5c
common-utils: add .js extensions to relative imports
ChumpChief May 15, 2026
42d511e
common-utils: switch to Node16 ESM-first tsconfig layout
ChumpChief May 15, 2026
263809e
common-utils: align mocha tsconfig types order with client-utils
ChumpChief May 15, 2026
f6d007a
common-utils: rename jest configs to .cjs
ChumpChief May 15, 2026
18d2fb2
common-utils: delegate top-level build/lint scripts to fluid-build
ChumpChief May 15, 2026
cff5636
common-utils: bump build-tools to 0.65, fix exports surface
ChumpChief May 15, 2026
f66628d
common-utils: refresh devDependencies to align with client-utils
ChumpChief May 15, 2026
6728ad7
common-utils: drop deprecated @types/base64-js stub
ChumpChief May 15, 2026
3e82cb0
common-utils: add attw (check:are-the-types-wrong)
ChumpChief May 15, 2026
b2a5131
common-utils: chain check:are-the-types-wrong into lint
ChumpChief May 15, 2026
e089403
common-utils: simplify build:docs / ci:build:docs scripts
ChumpChief May 15, 2026
bd115aa
common-utils: adopt mocha-test-setup; switch to lodash.clonedeep
ChumpChief May 15, 2026
ea33410
common-utils: adopt @fluidframework/eslint-config-fluid recommended
ChumpChief May 15, 2026
029ab95
common-utils: bump @arethetypeswrong/cli to ^0.18.2
ChumpChief May 15, 2026
e550b03
common-utils: remove vestigial bump-version script
ChumpChief May 15, 2026
b181685
common-utils: switch RangeTracker cloneDeep to structuredClone
ChumpChief May 15, 2026
d5e2cc4
common-utils: lint exports per entrypoint
ChumpChief May 15, 2026
490458e
common-utils: stop pulling Node graph into browser builds
ChumpChief May 15, 2026
9e72168
common-utils: add @packageDocumentation with deprecation note
ChumpChief May 15, 2026
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
11 changes: 11 additions & 0 deletions common/lib/common-utils/.mocharc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

"use strict";

const getFluidTestMochaConfig = require("@fluid-internal/mocha-test-setup/mocharc-common");

const config = getFluidTestMochaConfig(__dirname);
module.exports = config;
5 changes: 0 additions & 5 deletions common/lib/common-utils/api-extractor-lint.json

This file was deleted.

2 changes: 1 addition & 1 deletion common/lib/common-utils/api-extractor.json
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the switch to node+browser, this should follow the client-utils pattern.
Perhaps better would be to just drop api-extractor model and report - all is deprecated and internal.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "../../build/build-common/api-extractor-base.cjs.no-legacy.json"
"extends": "../../build/build-common/api-extractor-base.esm.no-legacy.json"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-lint.json",
"mainEntryPointFilePath": "<projectFolder>/lib/indexBrowser.d.ts"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-lint.entrypoint.json",
"mainEntryPointFilePath": "<projectFolder>/dist/indexBrowser.d.ts"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-lint.entrypoint.json",
"mainEntryPointFilePath": "<projectFolder>/lib/indexBrowser.d.ts"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-lint.entrypoint.json",
"mainEntryPointFilePath": "<projectFolder>/dist/indexNode.d.ts"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-lint.entrypoint.json",
"mainEntryPointFilePath": "<projectFolder>/lib/indexNode.d.ts"
}
112 changes: 38 additions & 74 deletions common/lib/common-utils/eslint.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,55 @@
* Licensed under the MIT License.
*/

// TODO: AB#59243 Replace this standalone config with @fluidframework/eslint-config-fluid once a
// version is published that supports ESLint 9 flat config.
import type { Linter } from "eslint";
import { recommended } from "@fluidframework/eslint-config-fluid/flat.mts";

import eslint from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import rushstackPlugin from "@rushstack/eslint-plugin";
import importPlugin from "eslint-plugin-import";
import unicornPlugin from "eslint-plugin-unicorn";
import tseslint from "typescript-eslint";

export default tseslint.config(
{
ignores: ["dist/**", "lib/**", "node_modules/**", "**/*.d.ts"],
},
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
...tseslint.configs.stylisticTypeChecked,
eslintConfigPrettier,
const config: Linter.Config[] = [
...recommended,
{
plugins: {
"@rushstack": rushstackPlugin,
"import": importPlugin,
"unicorn": unicornPlugin,
},
// Override @typescript-eslint/parser to use explicit project list instead of projectService.
// This package has non-standard test directories (mocha/, jest/, types/) that
// typescript-eslint's projectService can't auto-discover.
files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
projectService: false,
project: [
"./tsconfig.json",
"./src/test/mocha/tsconfig.json",
"./src/test/jest/tsconfig.cjs.json",
"./src/test/types/tsconfig.json",
],
},
},
},
{
// This package has been deprecated in favor of @fluidframework/core-utils and
// @fluid-internal/client-utils. Existing violations are not being fixed here.
linterOptions: {
reportUnusedDisableDirectives: "off",
},
rules: {
// Rules from the shared config that are referenced by inline eslint-disable comments.
"@rushstack/no-new-null": "error",
"@typescript-eslint/no-non-null-assertion": "error",
"default-case": "error",
"import/no-internal-modules": "error",
"no-bitwise": "error",
"no-new-func": "error",
"no-restricted-syntax": [
"error",
{
selector: "ExportAllDeclaration",
message:
"Exporting * is not permitted. You should export only named items you intend to export.",
},
],
"unicorn/error-message": "error",
"unicorn/no-thenable": "error",

// This package is being deprecated, so it's okay to use deprecated APIs.
"@typescript-eslint/no-deprecated": "off",
"import/no-deprecated": "off",

// This package uses node's events APIs.
// This should probably be reconsidered, but until then we will leave an exception for it here.
"import/no-nodejs-modules": ["error", { allow: ["events"] }],

// This package has been deprecated. The following rules have a significant number of
// violations that will not be fixed here.
"@eslint-community/eslint-comments/require-description": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/prefer-promise-reject-errors": "off",
"@typescript-eslint/no-duplicate-type-constituents": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-redundant-type-constituents": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/prefer-nullish-coalescing": "off",
"unicorn/text-encoding-identifier-case": "off",
"unicorn/prefer-node-protocol": "off",
"@typescript-eslint/prefer-promise-reject-errors": "off",
"depend/ban-dependencies": "off",
"import-x/no-deprecated": "off",
"import-x/no-nodejs-modules": "off",
"unicorn/prefer-at": "off",
"unicorn/prefer-code-point": "off",
"unicorn/prefer-node-protocol": "off",
"unicorn/prefer-string-replace-all": "off",
"unicorn/text-encoding-identifier-case": "off",
},
},
{
files: ["src/test/**"],
rules: {
// It's fine for tests to use node.js modules.
"import/no-nodejs-modules": "off",
},
},
);
];

export default config;
114 changes: 70 additions & 44 deletions common/lib/common-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,71 @@
"license": "MIT",
"author": "Microsoft and contributors",
"sideEffects": false,
"main": "dist/index.js",
"module": "lib/index.js",
"browser": {
"./dist/indexNode.js": "./dist/indexBrowser.js",
"./lib/indexNode.js": "./lib/indexBrowser.js"
"type": "module",
"exports": {
".": {
"node": {
"import": {
"types": "./lib/indexNode.d.ts",
"default": "./lib/indexNode.js"
},
"require": {
"types": "./dist/indexNode.d.ts",
"default": "./dist/indexNode.js"
}
},
"default": {
"import": {
"types": "./lib/indexBrowser.d.ts",
"default": "./lib/indexBrowser.js"
},
"require": {
"types": "./dist/indexBrowser.d.ts",
"default": "./dist/indexBrowser.js"
}
}
Comment on lines +17 to +36
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless a package is playing with export types like most client packages do for /beta, /internal, etc. The preference is to leave "types" out. Just specify the .js properties and let compiler do the sibling lookup. (There are cases where it does that anyway; so, just safer in general to not rely on "types" entries.)

}
},
"types": "dist/index.d.ts",
"main": "lib/indexBrowser.js",
"types": "lib/indexBrowser.d.ts",
Comment on lines +39 to +40
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not switch this around now since it is deprecated but keep with the same to reduce any risk.
In fact, if the ESM build was invalid which I have commonly found recently for packages that weren't dealt with in the large client migration, then it feels safe to drop the ESM build.
Node16 cleanup is good but leave out ESM.
"Restore" "type": "commonjs" (that was implicit before).
If there is a need for valid ESM build, then make ESM secondary using fluid-tsc module.

"scripts": {
"build": "npm run build:compile && concurrently npm:lint npm:build:docs",
"build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
"build:compile": "concurrently npm:build:commonjs npm:build:esnext",
"build:docs": "api-extractor run --local --typescript-compiler-folder ./node_modules/typescript && copyfiles -u 1 \"./_api-extractor-temp/doc-models/*\" ../../../_api-extractor-temp/",
"build:esnext": "tsc --project ./tsconfig.esnext.json",
"build": "fluid-build . --task build",
"build:commonjs": "fluid-build . --task commonjs",
"build:compile": "fluid-build . --task compile",
"build:docs": "api-extractor run --local",
"build:esnext": "tsc --project ./tsconfig.json",
"build:test": "concurrently npm:build:test:mocha npm:build:test:jest npm:build:test:types",
"build:test:jest": "tsc --project ./src/test/jest/tsconfig.json",
"build:test:mocha": "tsc --project ./src/test/mocha/tsconfig.json",
"build:test:jest": "fluid-tsc commonjs --project ./src/test/jest/tsconfig.cjs.json",
"build:test:mocha": "concurrently npm:build:test:mocha:esm npm:build:test:mocha:cjs",
"build:test:mocha:cjs": "fluid-tsc commonjs --project ./src/test/mocha/tsconfig.cjs.json",
"build:test:mocha:esm": "tsc --project ./src/test/mocha/tsconfig.json",
"build:test:types": "tsc --project ./src/test/types/tsconfig.json",
"bump-version": "npm version minor --no-push --no-git-tag-version",
"check:release-tags": "api-extractor run --config ./api-extractor-lint.json",
"check:are-the-types-wrong": "attw --pack .",
"check:exports": "concurrently \"npm:check:exports:*\"",
"check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
"check:exports:cjs:indexBrowser": "api-extractor run --config api-extractor/api-extractor-lint-indexBrowser.cjs.json",
"check:exports:cjs:indexNode": "api-extractor run --config api-extractor/api-extractor-lint-indexNode.cjs.json",
"check:exports:esm:indexBrowser": "api-extractor run --config api-extractor/api-extractor-lint-indexBrowser.esm.json",
"check:exports:esm:indexNode": "api-extractor run --config api-extractor/api-extractor-lint-indexNode.esm.json",
"ci:build": "fluid-build . --task ci:build",
"ci:build:docs": "api-extractor run --typescript-compiler-folder ./node_modules/typescript && copyfiles -u 1 \"./_api-extractor-temp/doc-models/*\" ../../../_api-extractor-temp/",
"ci:test": "npm run test:report",
"ci:build:docs": "api-extractor run",
"ci:test": "npm test",
"ci:test:coverage": "npm run test:coverage",
"clean": "rimraf --glob _api-extractor-temp dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" nyc",
"eslint": "eslint --format stylish src",
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
"format": "npm run prettier:fix",
"lint": "npm run prettier && npm run check:release-tags && npm run eslint",
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
"lint": "fluid-build . --task lint --task check:are-the-types-wrong",
"lint:fix": "fluid-build . --task lint:fix",
"prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
"prettier:fix": "prettier --write . --cache --ignore-path ../../../.prettierignore",
"test": "npm run test:mocha && npm run test:jest",
"test:coverage": "c8 npm run test:report",
"test:coverage": "c8 npm test",
"test:jest": "jest --ci",
"test:jest:report": "npm run test:jest -- --coverage",
"test:mocha": "mocha --unhandled-rejections=strict --recursive \"dist/test/mocha/**/*.spec.*js\"",
"test:mocha:multireport": "cross-env FLUID_TEST_MULTIREPORT=1 npm run test:mocha",
"test:mocha:report": "npm run test:mocha -- -- --reporter xunit --reporter-option output=nyc/mocha-junit-report.xml",
"test:report": "npm run test:mocha:report && npm run test:jest:report",
"tsc": "tsc",
"test:mocha": "npm run test:mocha:esm && npm run test:mocha:cjs",
"test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS \"MOCHA_SPEC=dist/test/mocha/**/*.spec.*js\" mocha",
"test:mocha:esm": "cross-env \"MOCHA_SPEC=lib/test/mocha/**/*.spec.*js\" mocha",
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package.json copied here is not likely correct since this has complicated export block. Better to just support CJS if the prior ESM was invalid anyway.

"typetests:gen": "flub generate typetests --dir . -v"
},
"c8": {
Expand Down Expand Up @@ -78,18 +103,17 @@
"base64-js": "^1.5.1",
"buffer": "^6.0.3",
"events": "^3.1.0",
"lodash": "^4.18.1",
"sha.js": "^2.4.12"
},
"devDependencies": {
"@eslint/js": "^9.39.0",
"@fluid-tools/build-cli": "^0.63.0",
"@arethetypeswrong/cli": "^0.18.2",
"@fluid-internal/mocha-test-setup": "~2.83.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite an old version, right? Why not more recent?
And why not ^ dep?

"@fluid-tools/build-cli": "^0.65.0",
"@fluidframework/build-common": "^2.0.3",
"@fluidframework/build-tools": "^0.63.0",
"@fluidframework/build-tools": "^0.65.0",
"@fluidframework/common-utils-previous": "npm:@fluidframework/common-utils@1.0.0",
"@fluidframework/eslint-config-fluid": "^10.0.0",
"@microsoft/api-extractor": "7.58.1",
"@rushstack/eslint-plugin": "~0.22.1",
"@types/base64-js": "^1.3.0",
"@types/jest": "29.5.3",
"@types/jest-environment-puppeteer": "2.2.0",
"@types/mocha": "^10.0.10",
Expand All @@ -98,26 +122,23 @@
"c8": "^10.1.3",
"concurrently": "^9.2.1",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"cross-env": "^10.1.0",
"eslint": "~9.39.1",
"eslint-config-prettier": "~10.1.8",
"eslint-plugin-import": "~2.32.0",
"eslint-plugin-unicorn": "~62.0.0",
"jest": "^29.6.2",
"jest-junit": "^10.0.0",
"jest-junit": "^16.0.0",
"jest-puppeteer": "^10.1.3",
"jiti": "^2.6.1",
"mocha": "^10.8.2",
"mocha": "^11.7.5",
"mocha-multi-reporters": "^1.5.1",
"prettier": "~3.0.3",
"puppeteer": "^23.6.0",
"rewire": "^5.0.0",
"rewire": "^9.0.1",
"rimraf": "^6.1.3",
"sinon": "^18.0.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "~5.4.5",
"typescript-eslint": "~8.55.0"
"ts-node": "^10.9.2",
"typescript": "~5.4.5"
},
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
"fluidBuild": {
Expand All @@ -128,18 +149,23 @@
"tasks": {
"eslint": [
"tsc",
"build:test:mocha",
"build:esnext",
"build:test:mocha:esm",
"build:test:mocha:cjs",
"build:test:jest",
"build:test:types"
],
Comment on lines 129 to 157
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect this can be removed. The standard definition should work. The only real dependency is on the production build. eslint does not require that the tests builds have been done. (The production build is needed because the tests depend on it and eslint checks the tests.)

"build:test:jest": [
"tsc"
],
"build:test:mocha": [
"build:test:mocha:cjs": [
"tsc"
],
"build:test:mocha:esm": [
"build:esnext"
],
"build:test:types": [
"tsc"
"build:esnext"
]
}
},
Expand Down
Loading
Loading