From cc6cc4148aa98d0e7b8f83c6466f81412b4c103d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20M=2E?= Date: Thu, 18 Jun 2026 23:55:07 +0100 Subject: [PATCH] feat(v8): foundation for the major 8.0 release (#5128) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(release): adopt Lerna 5 with GitHub Releases and add v8 breaking-change docs - Bump root lerna devDependency 3.13.3 -> 5.6.2 (matches ionic-framework) - publish:ci passes --create-release github so Lerna creates a GitHub Release per published tag; cd.yml provides GH_TOKEN (built-in token, contents: write) - Add BREAKING.md (+ BREAKING_ARCHIVE/ convention) seeding the v8 removed-command log - Add .github/RELEASING.md major-release runbook * fix(cli): make build, lint, and tests run on Windows and macOS Pre-existing cross-platform issues surfaced while validating the Lerna 5 upgrade; none are caused by the release tooling: - discover: pin netmask 2.0.2 and @types/netmask 2.0.5 — the untracked dependency tree had drifted to netmask 2.1.x, whose bundled types declare 'broadcast: string | undefined' and broke the build (TS2322) - replace the Unix-only 'lint': 'true' no-op with cross-platform 'exit 0' in all packages ('true' is not a cmd.exe builtin, so npm run lint failed on Windows) - angular/cordova tests: normalize path separators in assertions and return the floating expect().resolves promises (fixes Windows path failures and the resulting jest-worker 'Call retries were exceeded' crash) * docs(release): correct publish:testing guidance in runbook publish:testing is NOT a dry run — lerna publish runs npm publish (testing dist-tag); --no-push only suppresses git. It also only runs from 'stable' due to the allowBranch guard. Replace the §4 'dry run' step with a safe, non-publishing 'lerna version --no-push --no-git-tag-version --allow-branch' smoke test, and document the bump-from-commits behavior. * ci: pin actions to commit SHAs and bump to latest Security-harden workflows by pinning actions to immutable commit SHAs (version in trailing comment), and update from v3: - actions/checkout v3 -> v6.0.3 - actions/setup-node v3 -> v6.4.0 - actions/cache v3 -> v5.0.5 (v3 cache backend was retired by GitHub) * chore(deps): upgrade to TypeScript 5.9.3 and jest 29 Upgrade the TypeScript toolchain across all packages: - typescript ~4.8.0 -> ~5.9.3 - ts-jest ~26.3.0 -> ^29.4.11 - jest/jest-cli ^26.x -> ^29.7.0 (stays on 29 to keep Node 16 support) - @types/jest ^26.x -> ^29.5.14 - @types/node ~16.0.0 -> ^16.18.126 (16.0.3 conflicted with TS 5.9 libs) - tslib ^2.0.1 -> ^2.8.1 Required code/config changes: - jest.config.base.js: migrate ts-jest globals -> transform API, tsConfig -> tsconfig, explicit testEnvironment: node - utils-array reduce(): annotate accumulator T|U + cast awaited result (TS 5.9 Awaited/NonNullable inference) - tests: drop async from async-done callbacks (utils-fs), convert to async()+expect.assertions (utils-subprocess), spyOn().and.callFake -> jest.spyOn().mockImplementation (utils-network), legacyFakeTimers for timer-mock assertions (cli-framework-output) Validated: build + lint + full test suite green. * docs(release): make the runbook smoke-test command cross-shell The step-4 lerna version command used a bash-only backslash continuation and $(git branch --show-current), which fail in PowerShell/cmd. Use a single-line command with --allow-branch "*" (quoted so bash doesn't glob-expand it) so it runs identically in PowerShell, cmd, bash, and zsh. Also scope the cleanup to 'git checkout -- packages' so it only discards lerna's version writes. * Update .github/RELEASING.md Co-authored-by: Shane * fix(discover): let netmask float and handle nullable broadcast netmask was pinned to an exact 2.0.2 to dodge a TS2322 build break. The break originates from netmask >= 2.1, which ships its own bundled type declarations (broadcast: string | undefined) that shadow @types/netmask entirely — so pinning @types/netmask alone does not fix it. Instead, restore the caret (^2.0.2) so the runtime can receive 2.x patches, drop the now-shadowed @types/netmask dev dependency, and handle the nullable broadcast in computeBroadcastAddress (broadcast is absent for /31 and /32 blocks; fall back to the network address). Validated: discover build + tests green with netmask 2.1.1. * docs(release): refresh Node guidance for the jest 29 toolchain The pre-publish validation note referenced a "bundled jest 26 worker" caveat that is stale on this branch (it ships jest 29). jest 29 supports newer Node than 26 did, so drop the caveat and state the validated matrix: Node 18 to match CI, with the suite also green on Node 16 and 24. * ci: block publishing BREAKING.md with unfilled * Update .github/RELEASING.md Co-authored-by: Maria Hutt * feat!: require Node >= 18 Enforce the supported runtime through package.json rather than leaving it to documentation. Set engines.node to ">=18.0.0" across the monorepo: the root workspace, every published @ionic/* package, and the previously unset @ionic/discover and cli-scripts manifests. Align the rest of the toolchain with the new baseline — drop Node 16.x from the CI matrix (now 18.x and 20.x) and update the release runbook so the recommended and minimum Node versions no longer disagree. BREAKING CHANGE: Node 16 is no longer supported. The Ionic CLI and its @ionic/* packages now require Node 18 or newer. * docs(release): correct the discover drift-guard note The step-3 drift guard still described the old netmask@2.0.2 + @types/netmask@2.0.5 pins. That approach was replaced: netmask floats at ^2.0.2 (resolving to 2.1.x) using its own bundled types, @types/netmask was dropped, and computeBroadcastAddress handles the nullable broadcast. Update the note to match. * docs(release): point to source files for Node versions Stop hardcoding specific Node versions in the runbook. Reference the authoritative sources instead — `engines.node` in package.json for the minimum and the `node:` matrix in ci.yml (plus `node-version` in cd.yml) for the versions CI exercises — so the doc stays correct when CI's Node versions change without a separate edit. --------- Co-authored-by: Shane Co-authored-by: Maria Hutt --- .github/PULL_REQUEST_TEMPLATE.md | 34 ++++ .github/RELEASING.md | 164 ++++++++++++++++++ .github/workflows/cd.yml | 16 +- .github/workflows/ci.yml | 8 +- .github/workflows/docker-image.yml | 4 +- BREAKING.md | 128 ++++++++++++++ BREAKING_ARCHIVE/README.md | 12 ++ jest.config.base.js | 21 ++- package.json | 9 +- .../@ionic/cli-framework-output/package.json | 18 +- .../src/__tests__/tasks.ts | 2 +- .../@ionic/cli-framework-prompts/package.json | 18 +- packages/@ionic/cli-framework/package.json | 18 +- packages/@ionic/cli/package.json | 18 +- .../integrations/cordova/__tests__/project.ts | 6 +- .../lib/project/angular/__tests__/index.ts | 4 +- packages/@ionic/discover/package.json | 20 ++- packages/@ionic/discover/src/publisher.ts | 4 +- packages/@ionic/utils-array/package.json | 18 +- packages/@ionic/utils-array/src/index.ts | 4 +- packages/@ionic/utils-fs/package.json | 18 +- .../@ionic/utils-fs/src/__tests__/index.ts | 8 +- packages/@ionic/utils-network/package.json | 18 +- .../utils-network/src/__tests__/index.ts | 6 +- packages/@ionic/utils-object/package.json | 18 +- packages/@ionic/utils-process/package.json | 18 +- packages/@ionic/utils-stream/package.json | 18 +- packages/@ionic/utils-subprocess/package.json | 18 +- .../utils-subprocess/src/__tests__/index.ts | 8 +- packages/@ionic/utils-terminal/package.json | 18 +- packages/cli-scripts/package.json | 19 +- 31 files changed, 528 insertions(+), 165 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/RELEASING.md create mode 100644 BREAKING.md create mode 100644 BREAKING_ARCHIVE/README.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..fdb0e9339a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,34 @@ +Issue number: resolves # + +--------- + + + + + +## What is the current behavior? + + +## What is the new behavior? + + +- +- +- + +## Does this introduce a breaking change? + +- [ ] Yes +- [ ] No + + + + +## Other information + + diff --git a/.github/RELEASING.md b/.github/RELEASING.md new file mode 100644 index 0000000000..61d96a2d18 --- /dev/null +++ b/.github/RELEASING.md @@ -0,0 +1,164 @@ +# Releasing the Ionic CLI + +This runbook describes how the Ionic CLI is published and, specifically, **how +to cut a major release** (e.g. `8.0.0`). It reflects the repository as of the +`major-x` branch. + +## 1. How publishing works today + +The CLI is a **Lerna monorepo** with `independent` versioning +([`lerna.json`](../lerna.json) → `"version": "independent"`). +Each `@ionic/*` +package is versioned on its own based on the commits that touched it. + +Release is **conventional-commit driven and automatic**: + +- [`.github/workflows/cd.yml`](workflows/cd.yml) runs **only on push to the + `stable` branch**. +- It runs `npm run publish:ci`, defined in [`package.json`](../package.json): + + - `lerna version --conventional-commits` computes each package's next version + **from commit messages**, tags, and pushes the release commit. + - `--create-release github` makes Lerna create the **GitHub Release** for each + tag (see **3** — requires Lerna 5 and a `GH_TOKEN`). + - `lerna exec ... npm publish --provenance` publishes the changed packages to + npm. +- `lerna.json` pins `"allowBranch": "stable"`, so `lerna version` refuses to run + from any other branch. +- After publishing, `cd.yml` builds and pushes a Docker image to GHCR (GitHub Container Registry). + +> **Key consequence:** the version bump is derived from commit messages, **not** +> from `BREAKING.md`. `BREAKING.md` is human documentation only. To land +> `@ionic/cli` on `8.0.0`, the branch history must contain **breaking-change +> commits** — a `feat!:` / `fix!:` subject or a `BREAKING CHANGE:` footer — for +> the `@ionic/cli` package. + +## 2. Cutting the v8 major + +### 2a. Make sure the major bump will be computed + +Because versioning is conventional-commit driven: + +- The command-removal PRs (tracked separately) **must** use breaking-change + commit syntax so Lerna computes a major bump for the affected package(s): + + ```bash + feat(commands)!: remove deprecated Appflow/Enterprise/Cordova commands + + BREAKING CHANGE: The config, cordova, enterprise, git, init, link, + live-update, login, logout, repair, signup, and ssh commands have been + removed. See BREAKING.md. + ``` + +- `independent` versioning means **only the packages whose commits include the + breaking change get the major bump**. Confirm the removals live in the package + that owns the command surface (typically `@ionic/cli`) so `@ionic/cli` is the + one that reaches `8.0.0`. Utility `@ionic/*` packages bump independently based + on their own commits. + +### 2b. Path to publish from `major-8.0` + +`cd.yml` only publishes from `stable`. The `major-8.0` work branch is **not** +auto-published. Recommended path: + +1. Land all removal PRs (with breaking-change commits) onto `major-8.0`. +2. Normal merge / rebase `major-8.0` → `develop`. +3. Follow the normal `develop` → `stable` promotion. The push to `stable` + triggers `cd.yml`, which computes the major bump, tags, publishes to npm, and + creates the GitHub Releases. + +### 2c. Optional: ship a v8 release candidate first + +Use a prerelease on a `next` dist-tag before GA so consumers can test: + +```bash +# A real prerelease under the `testing` dist-tag (publishes to npm, no git push): +npm run publish:testing # publishes a `testing` prerelease with --no-push + +# A real RC under the `next` tag (run from an allowed branch): +lerna publish premajor --preid rc --dist-tag next --conventional-commits +``` + +> To cut an RC directly from `major-8.0`, temporarily relax `allowBranch` in +> `lerna.json` (e.g. `["stable", "major-8.0"]`) or run the prerelease from +> `stable`. Decide this deliberately — don't leave `major-8.0` permanently +> publishable. + +## 3. GitHub Release creation (Lerna 5) + +The CLI was upgraded from Lerna **3.13.3 → 5.x** so that releases are created on +GitHub natively. This is wired via +`--create-release github` in `publish:ci` (**1**). + +Requirements for `--create-release github` to work in CI: + +- It must run together with `--conventional-commits` (it is). +- A **`GH_TOKEN`** must be present in the environment of the `lerna version` + step. [`cd.yml`](workflows/cd.yml) provides it as `${{ github.token }}` — the + built-in workflow token, which is sufficient because the workflow already + grants `contents: write`. **No dedicated secret is required.** + +## 4. Pre-publish validation (always, but especially after the Lerna upgrade) + +These steps are **cross-platform** — every command is `npm`/`npx`-based and runs +identically in PowerShell, `cmd`, bash, and zsh (Windows and macOS). For the Node +version, don't rely on a number hardcoded here: the minimum is enforced by +`engines.node` in each `package.json`, and the versions CI exercises are the +`node:` matrix in [`ci.yml`](workflows/ci.yml) (the publish job pins its own under +`node-version` in [`cd.yml`](workflows/cd.yml)). Use a version that satisfies both +— checking those files keeps this runbook correct as the supported versions change. + +> **Order matters.** This is a `lerna bootstrap` monorepo: per-package +> devDependencies (including `@types/node`) are installed and hoisted by +> `npm run bootstrap`, **not** by `npm install`. You must run steps 0→1 before +> any `build`/`lint`/`test`. Running `npm run build` on a freshly-cleaned tree +> fails with `TS2688: Cannot find type definition file for 'node'` — that means +> bootstrap was skipped, not a real code error. + +```bash +# 0. (optional) Pristine tree — npx rimraf is cross-platform, unlike rm -rf +npx rimraf node_modules "packages/@ionic/*/node_modules" "packages/cli-scripts/node_modules" + +# 1. Install + bootstrap — REQUIRED before build/lint/test. +# `npm install` only installs root devDeps (lerna, typescript); +# `npm run bootstrap` installs+hoists every package's deps, then builds. +npm install +npm run bootstrap + +# 2. Confirm the Lerna upgrade — expect 5.x, and `--create-release` in the help +npx lerna --version +npx lerna version --help # look for: --create-release ... [choices: "gitlab","github"] + +# 3. Lint / test (bootstrap already built; re-run build explicitly if you like) +npm run lint +npm run test +# Drift guard: a green build of @ionic/discover (no publisher.ts "broadcast" +# TS2322) confirms netmask (^2.0.2, currently 2.1.x) resolved with its +# bundled types and computeBroadcastAddress handles the nullable broadcast. + +# 4. Non-publishing version smoke test — exercises the Lerna 5 version path +# WITHOUT publishing to npm or touching git. --allow-branch "*" overrides the +# lerna.json `allowBranch: stable` guard for this one local run. +# Single line + quoted "*" so it runs the same in PowerShell, cmd, bash, zsh. +npx lerna version --conventional-commits --no-push --no-git-tag-version --allow-branch "*" --yes +git checkout -- packages # discard the version/CHANGELOG file writes lerna just made +``` + +> **`npm run publish:testing` is NOT a dry run — it publishes to npm.** +> `lerna publish` runs an `npm publish` (the `@ionic/*` packages under the +> `testing` dist-tag); `--no-push`/`--no-git-tag-version` only suppress *git* +> actions, not the registry publish. It also only runs from `stable` (the +> `allowBranch` guard). Use step 4 above for a safe local check. Run +> `publish:testing` only when you actually intend to push a `testing` prerelease +> to npm, with valid npm credentials. + +The step-4 smoke test also reveals the **computed version bump** from the +branch's conventional commits. Note it will show a `patch`/`minor` bump until +the branch carries breaking-change commits (`feat!:` / `BREAKING CHANGE:`) — +those, not `BREAKING.md`, are what make `@ionic/cli` land on `8.0.0` (see §1). + +> **Known platform note (pre-existing, unrelated to the release tooling):** on +> **Windows**, one test in `integrations/cordova` asserts POSIX (`/`) path +> separators and fails because `path.relative` returns `\` on Windows. It passes +> on macOS/Linux (and therefore in CI). It is not introduced by these changes, +> and the Cordova integration is slated for removal in v8. diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 7d82e66baf..e6172def35 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -16,10 +16,18 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - - uses: actions/setup-node@v3 + - name: Guard against unfilled BREAKING.md placeholders + # The removal PRs fill in each command's entry. Block a stable publish + # if any Older majors are archived under [`BREAKING_ARCHIVE/`](BREAKING_ARCHIVE) (e.g. +> `BREAKING_ARCHIVE/v7.md`). When the next major begins, move the section below +> into `BREAKING_ARCHIVE/v8.md` and start a fresh `Version 9.x` section here. + +## Version 8.x + +In version 8, the Ionic CLI is focused on the **Framework and Capacitor** +workflows. The Appflow, Enterprise, and Cordova commands have been removed. + +- [Removed Commands](#removed-commands) + +### Removed Commands + +The following commands have been removed. Each entry records **what was +removed**, **why**, and the **migration path / alternative**. + +> **Note:** The removal PRs are authored and coordinated separately. The entries +> below are seeded placeholders — each removal PR should fill in the specifics +> (the exact `diff`, the reason, and the migration link) for the command it +> removes. + +#### `config` + +- **What:** The `config` command (and its `config get` / `config set` / + `config unset` subcommands) has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `cordova` + +- **What:** The `cordova` command group has been removed. __ +- **Why:** __ +- **Migration:** Migrate to Capacitor. __ + +#### `enterprise` + +- **What:** The `enterprise` command group has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `git` + +- **What:** The `git` command group has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `init` + +- **What:** The `init` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `integrations` (Enterprise portion only) + +- **What:** The **Enterprise portion** of the `integrations` command has been + removed. **The Capacitor integration is kept.** __ +- **Why:** __ +- **Migration:** Continue using `ionic integrations enable capacitor`. __ + +#### `link` + +- **What:** The `link` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `live-update` + +- **What:** The `live-update` command group has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `login` + +- **What:** The `login` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `logout` + +- **What:** The `logout` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `repair` + +- **What:** The `repair` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `signup` + +- **What:** The `signup` command has been removed. __ +- **Why:** __ +- **Migration:** __ + +#### `ssh` + +- **What:** The `ssh` command group (and its subcommands) has been removed. + __ +- **Why:** __ +- **Migration:** __ diff --git a/BREAKING_ARCHIVE/README.md b/BREAKING_ARCHIVE/README.md new file mode 100644 index 0000000000..ed190cad06 --- /dev/null +++ b/BREAKING_ARCHIVE/README.md @@ -0,0 +1,12 @@ +# Breaking Changes Archive + +This directory archives the breaking-changes sections for **past** major +versions of the Ionic CLI, one file per major (`v7.md`, `v8.md`, ...). + +The **current / in-progress** major is always documented inline at the top of +[`../BREAKING.md`](../BREAKING.md). When a new major cycle begins: + +1. Move the finished major's section out of `../BREAKING.md` into + `BREAKING_ARCHIVE/vN.md` here. +2. Add a link to it from the **Versions** index in `../BREAKING.md`. +3. Start a fresh `Version (N+1).x` section at the top of `../BREAKING.md`. diff --git a/jest.config.base.js b/jest.config.base.js index a51134bb8a..95b0a964a6 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -1,16 +1,15 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - diagnostics: { - // warnOnly: true, + testEnvironment: 'node', + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + diagnostics: {}, + tsconfig: { + types: ['node', 'jest'], + }, }, - tsConfig: { - types: [ - "node", - "jest", - ], - }, - }, + ], }, }; diff --git a/package.json b/package.json index 1e5a033907..732cb7dec1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,9 @@ { "name": "ionic-cli", "private": true, + "engines": { + "node": ">=18.0.0" + }, "scripts": { "bootstrap": "lerna bootstrap && npm run build", "clean": "lerna run clean", @@ -14,13 +17,13 @@ "docs": "node packages/cli-scripts/bin/ionic-cli-scripts docs", "docs:watch": "chokidar 'packages/cli-scripts/dist/docs/**/*.js' -c 'npm run docs'", "publish:testing": "lerna publish prerelease --preid=testing --exact --no-git-tag-version --no-push --dist-tag=testing", - "publish:ci": "lerna version -m 'chore(release): publish [skip ci]' --exact --conventional-commits --yes && lerna exec --no-private --since HEAD~ -- npm publish --provenance" + "publish:ci": "lerna version -m 'chore(release): publish [skip ci]' --exact --conventional-commits --create-release github --yes && lerna exec --no-private --since HEAD~ -- npm publish --provenance" }, "devDependencies": { "chokidar-cli": "^2.0.0", "husky": "^4.2.0", - "lerna": "^3.13.3", - "typescript": "~4.8.0" + "lerna": "^5.6.2", + "typescript": "~5.9.3" }, "husky": { "hooks": { diff --git a/packages/@ionic/cli-framework-output/package.json b/packages/@ionic/cli-framework-output/package.json index 76bab15ccb..ef87b7f004 100644 --- a/packages/@ionic/cli-framework-output/package.json +++ b/packages/@ionic/cli-framework-output/package.json @@ -7,7 +7,7 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -23,7 +23,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -33,18 +33,18 @@ "dependencies": { "@ionic/utils-terminal": "2.3.5", "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@ionic/utils-stream": "3.1.7", "@types/debug": "^4.1.1", "@types/inquirer": "0.0.43", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/cli-framework-output/src/__tests__/tasks.ts b/packages/@ionic/cli-framework-output/src/__tests__/tasks.ts index ed29a211c3..1aa8b3d10d 100644 --- a/packages/@ionic/cli-framework-output/src/__tests__/tasks.ts +++ b/packages/@ionic/cli-framework-output/src/__tests__/tasks.ts @@ -16,7 +16,7 @@ describe('@ionic/cli-framework-output', () => { }; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers({ legacyFakeTimers: true }); task = new Task({ msg: '' }); handlers = { success: jest.fn(), diff --git a/packages/@ionic/cli-framework-prompts/package.json b/packages/@ionic/cli-framework-prompts/package.json index ce4aacfe5b..077571644e 100644 --- a/packages/@ionic/cli-framework-prompts/package.json +++ b/packages/@ionic/cli-framework-prompts/package.json @@ -7,7 +7,7 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -23,7 +23,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -34,17 +34,17 @@ "@ionic/utils-terminal": "2.3.5", "debug": "^4.0.0", "inquirer": "^7.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", "@types/inquirer": "0.0.43", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/cli-framework/package.json b/packages/@ionic/cli-framework/package.json index d3b7b99dfe..4f32a815b7 100644 --- a/packages/@ionic/cli-framework/package.json +++ b/packages/@ionic/cli-framework/package.json @@ -7,7 +7,7 @@ "main": "./index.js", "types": "./index.d.ts", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "scripts": { "clean": "rimraf index.* definitions.* errors.* guards.* lib utils", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -39,20 +39,20 @@ "lodash": "^4.17.5", "minimist": "^1.2.0", "rimraf": "^3.0.0", - "tslib": "^2.0.1", + "tslib": "^2.8.1", "write-file-atomic": "^3.0.0" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", + "@types/jest": "^29.5.14", "@types/lodash": "^4.14.104", "@types/minimist": "^1.2.0", - "@types/node": "~16.0.0", + "@types/node": "^16.18.126", "@types/write-file-atomic": "^3.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/cli/package.json b/packages/@ionic/cli/package.json index d6fa27f6e8..fdc9553bab 100644 --- a/packages/@ionic/cli/package.json +++ b/packages/@ionic/cli/package.json @@ -8,13 +8,13 @@ "ionic": "./bin/ionic" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "main": "./index.js", "types": "./index.d.ts", "scripts": { "clean": "rimraf index.* bootstrap.* constants.* definitions.* guards.* lib commands", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -65,25 +65,25 @@ "stream-combiner2": "^1.1.1", "superagent": "^9.0.2", "tar": "^6.0.1", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", "@types/diff": "^4.0.0", "@types/elementtree": "^0.1.0", - "@types/jest": "^26.0.10", + "@types/jest": "^29.5.14", "@types/lodash": "^4.14.104", - "@types/node": "~16.0.0", + "@types/node": "^16.18.126", "@types/semver": "^7.1.0", "@types/split2": "^2.1.6", "@types/superagent": "4.1.3", "@types/tar": "^6.1.2", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", "source-map": "^0.7.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/cli/src/lib/integrations/cordova/__tests__/project.ts b/packages/@ionic/cli/src/lib/integrations/cordova/__tests__/project.ts index 34c1a8f211..31b6e851a2 100644 --- a/packages/@ionic/cli/src/lib/integrations/cordova/__tests__/project.ts +++ b/packages/@ionic/cli/src/lib/integrations/cordova/__tests__/project.ts @@ -1,3 +1,5 @@ +import * as path from 'path'; + import fsExtraSpy from 'fs-extra'; import * as fsSafeSpy from '@ionic/utils-fs/dist/safe'; import * as project from '../project'; @@ -97,7 +99,7 @@ describe('@ionic/cli', () => { jest.spyOn(fsExtraSpy, 'readJson').mockImplementation(async () => file); const p = project.getAndroidPackageFilePath('/path/to/proj', { release: false }); - expect(p).resolves.toEqual('platforms/android/app/build/outputs/apk/debug/foo-debug.apk'); + return expect(p).resolves.toEqual(path.normalize('platforms/android/app/build/outputs/apk/debug/foo-debug.apk')); }); it('should get file path from output.json', () => { @@ -115,7 +117,7 @@ describe('@ionic/cli', () => { jest.spyOn(fsExtraSpy, 'readJson').mockImplementation(async () => file); const p = project.getAndroidPackageFilePath('/path/to/proj', { release: false }); - expect(p).resolves.toEqual('platforms/android/app/build/outputs/apk/debug/bar-debug.apk'); + return expect(p).resolves.toEqual(path.normalize('platforms/android/app/build/outputs/apk/debug/bar-debug.apk')); }); }); diff --git a/packages/@ionic/cli/src/lib/project/angular/__tests__/index.ts b/packages/@ionic/cli/src/lib/project/angular/__tests__/index.ts index 3157342c9a..d1d877323f 100644 --- a/packages/@ionic/cli/src/lib/project/angular/__tests__/index.ts +++ b/packages/@ionic/cli/src/lib/project/angular/__tests__/index.ts @@ -15,7 +15,9 @@ describe('@ionic/cli', () => { }); it('should set directory attribute', async () => { - expect(p.directory).toEqual(path.resolve('/path/to/proj')); + // `directory` returns the (unresolved) dirname of configPath; compare + // against the same so the assertion holds on Windows and POSIX alike. + expect(p.directory).toEqual(path.dirname('/path/to/proj/file')); }); describe('getSourceDir', () => { diff --git a/packages/@ionic/discover/package.json b/packages/@ionic/discover/package.json index fc684c5114..e2ef4093c6 100644 --- a/packages/@ionic/discover/package.json +++ b/packages/@ionic/discover/package.json @@ -7,6 +7,9 @@ "homepage": "https://ionicframework.com/", "author": "Ionic Team (https://ionic.io)", "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, "files": [ "dist/", "LICENSE", @@ -21,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -30,20 +33,19 @@ "dependencies": { "debug": "^4.0.0", "netmask": "^2.0.2", - "tslib": "^2.0.1", + "tslib": "^2.8.1", "ws": "^7.0.0" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/netmask": "^2.0.5", - "@types/node": "~16.0.0", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", "@types/ws": "^7.2.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/discover/src/publisher.ts b/packages/@ionic/discover/src/publisher.ts index d36f2b112d..e23567da86 100644 --- a/packages/@ionic/discover/src/publisher.ts +++ b/packages/@ionic/discover/src/publisher.ts @@ -195,5 +195,7 @@ export function computeBroadcastAddress(address: string, netmask: string): strin const ip = address + '/' + netmask; const block = new Netmask(ip); - return block.broadcast; + // netmask >= 2.1 types `broadcast` as `string | undefined` (it is absent for + // /31 and /32 blocks); fall back to the network address in that case. + return block.broadcast ?? block.base; } diff --git a/packages/@ionic/utils-array/package.json b/packages/@ionic/utils-array/package.json index a7e8552d04..bcee072ffb 100644 --- a/packages/@ionic/utils-array/package.json +++ b/packages/@ionic/utils-array/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -32,17 +32,17 @@ }, "dependencies": { "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-array/src/index.ts b/packages/@ionic/utils-array/src/index.ts index 47a4173e49..de58df2ed7 100644 --- a/packages/@ionic/utils-array/src/index.ts +++ b/packages/@ionic/utils-array/src/index.ts @@ -67,11 +67,11 @@ export async function reduce(array: T[] | readonly T[], callback: (accumul initialValue = array[0]; } - let value = initialValue; + let value: T | U = initialValue; for (let i = startingIndex; i < array.length; i++) { const v = await callback(value, array[i], i, array); - value = v; + value = v as T | U; } return value; diff --git a/packages/@ionic/utils-fs/package.json b/packages/@ionic/utils-fs/package.json index 1ae20fc91f..8aff868a66 100644 --- a/packages/@ionic/utils-fs/package.json +++ b/packages/@ionic/utils-fs/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -34,17 +34,17 @@ "@types/fs-extra": "^8.0.0", "debug": "^4.0.0", "fs-extra": "^9.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-fs/src/__tests__/index.ts b/packages/@ionic/utils-fs/src/__tests__/index.ts index d2b20f2c0c..f974e2e304 100644 --- a/packages/@ionic/utils-fs/src/__tests__/index.ts +++ b/packages/@ionic/utils-fs/src/__tests__/index.ts @@ -170,7 +170,7 @@ describe('@ionic/cli-framework', () => { readdirSpy.mockReset(); }); - it('should emit data once with path for single file', async done => { + it('should emit data once with path for single file', done => { lstatSpy.mockImplementation((p: string, cb: any) => { cb(null, { isDirectory: () => false }); }); const dataSpy = jest.fn(); const walker = new fslib.Walker('root'); @@ -183,7 +183,7 @@ describe('@ionic/cli-framework', () => { }); }); - it('should emit data for each child', async done => { + it('should emit data for each child', done => { const root = 'root'; const children = ['a', 'b', 'c']; lstatSpy.mockImplementation((p: string, cb: any) => { cb(null, { isDirectory: () => p === root }); }); @@ -203,7 +203,7 @@ describe('@ionic/cli-framework', () => { }); }); - it('should emit data for each child recursively', async done => { + it('should emit data for each child recursively', done => { const root = 'root'; // directory const children = ['foo', 'bar']; // directories const fooChildren = ['a', 'b', 'c']; // directories @@ -231,7 +231,7 @@ describe('@ionic/cli-framework', () => { }); }); - it('should emit data for each child except for filtered paths', async done => { + it('should emit data for each child except for filtered paths', done => { const root = 'root'; const children = ['a', 'b', 'c']; lstatSpy.mockImplementation((p: string, cb: any) => { cb(null, { isDirectory: () => p === root }); }); diff --git a/packages/@ionic/utils-network/package.json b/packages/@ionic/utils-network/package.json index e417450863..b282f8dae3 100644 --- a/packages/@ionic/utils-network/package.json +++ b/packages/@ionic/utils-network/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -32,17 +32,17 @@ }, "dependencies": { "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-network/src/__tests__/index.ts b/packages/@ionic/utils-network/src/__tests__/index.ts index 4fed64770f..0885d2fc7f 100644 --- a/packages/@ionic/utils-network/src/__tests__/index.ts +++ b/packages/@ionic/utils-network/src/__tests__/index.ts @@ -27,19 +27,19 @@ describe('@ionic/utils-network', () => { }; it('should return empty array if no network interfaces', () => { - spyOn(osSpy, 'networkInterfaces').and.callFake(() => networkInterfaces1); + jest.spyOn(osSpy, 'networkInterfaces').mockImplementation(() => networkInterfaces1 as any); const result = getExternalIPv4Interfaces(); expect(result).toEqual([]); }); it('should return empty array if unsuitable network interfaces found', () => { - spyOn(osSpy, 'networkInterfaces').and.callFake(() => networkInterfaces2); + jest.spyOn(osSpy, 'networkInterfaces').mockImplementation(() => networkInterfaces2 as any); const result = getExternalIPv4Interfaces(); expect(result).toEqual([]); }); it('should find the suitable network interface', () => { - spyOn(osSpy, 'networkInterfaces').and.callFake(() => networkInterfaces3); + jest.spyOn(osSpy, 'networkInterfaces').mockImplementation(() => networkInterfaces3 as any); const result = getExternalIPv4Interfaces(); expect(result.length).toEqual(1); expect(result[0].device).toEqual('eth0'); diff --git a/packages/@ionic/utils-object/package.json b/packages/@ionic/utils-object/package.json index 433ce322f5..529f7a2919 100644 --- a/packages/@ionic/utils-object/package.json +++ b/packages/@ionic/utils-object/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -32,17 +32,17 @@ }, "dependencies": { "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-process/package.json b/packages/@ionic/utils-process/package.json index 872f9af426..24677e13b2 100644 --- a/packages/@ionic/utils-process/package.json +++ b/packages/@ionic/utils-process/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -36,18 +36,18 @@ "debug": "^4.0.0", "signal-exit": "^3.0.3", "tree-kill": "^1.2.2", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", "@types/signal-exit": "^3.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-stream/package.json b/packages/@ionic/utils-stream/package.json index 14b1fa2f46..984960ecd7 100644 --- a/packages/@ionic/utils-stream/package.json +++ b/packages/@ionic/utils-stream/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -32,18 +32,18 @@ }, "dependencies": { "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", "stream-combiner2": "^1.1.1", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-subprocess/package.json b/packages/@ionic/utils-subprocess/package.json index 90d51bf519..7450428131 100644 --- a/packages/@ionic/utils-subprocess/package.json +++ b/packages/@ionic/utils-subprocess/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -38,18 +38,18 @@ "@ionic/utils-terminal": "2.3.5", "cross-spawn": "^7.0.3", "debug": "^4.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/cross-spawn": "^6.0.0", "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/@ionic/utils-subprocess/src/__tests__/index.ts b/packages/@ionic/utils-subprocess/src/__tests__/index.ts index 411d301573..b5b61239d9 100644 --- a/packages/@ionic/utils-subprocess/src/__tests__/index.ts +++ b/packages/@ionic/utils-subprocess/src/__tests__/index.ts @@ -312,7 +312,8 @@ describe('@ionic/utils-subprocess', () => { expect(result.split('').filter((l: string) => l !== errletter).join('')).toEqual(outinput); }); - it('should error with combined output for output()', async done => { + it('should error with combined output for output()', async () => { + expect.assertions(3); const cmd = new Subprocess('cmd', []); const mockSpawnStdout = new ReadableStreamBuffer(); const mockSpawnStderr = new ReadableStreamBuffer(); @@ -343,11 +344,11 @@ describe('@ionic/utils-subprocess', () => { expect(e.output.length).toEqual(outinput.length + errinput.length); expect(e.output.split('').filter((l: string) => l !== outletter).join('')).toEqual(errinput); expect(e.output.split('').filter((l: string) => l !== errletter).join('')).toEqual(outinput); - done(); } }); - it('should error with combined output for combinedOutput()', async done => { + it('should error with combined output for combinedOutput()', async () => { + expect.assertions(3); const cmd = new Subprocess('cmd', []); const mockSpawnStdout = new ReadableStreamBuffer(); const mockSpawnStderr = new ReadableStreamBuffer(); @@ -378,7 +379,6 @@ describe('@ionic/utils-subprocess', () => { expect(e.output.length).toEqual(outinput.length + errinput.length); expect(e.output.split('').filter((l: string) => l !== outletter).join('')).toEqual(errinput); expect(e.output.split('').filter((l: string) => l !== errletter).join('')).toEqual(outinput); - done(); } }); diff --git a/packages/@ionic/utils-terminal/package.json b/packages/@ionic/utils-terminal/package.json index d4e3e53fff..c8fc3ec9ec 100644 --- a/packages/@ionic/utils-terminal/package.json +++ b/packages/@ionic/utils-terminal/package.json @@ -8,7 +8,7 @@ "author": "Ionic Team (https://ionic.io)", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "files": [ "dist/", @@ -24,7 +24,7 @@ }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -37,21 +37,21 @@ "slice-ansi": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", - "tslib": "^2.0.1", + "tslib": "^2.8.1", "untildify": "^4.0.0", "wrap-ansi": "^7.0.0" }, "devDependencies": { "@types/debug": "^4.1.1", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", "@types/signal-exit": "^3.0.0", "@types/wrap-ansi": "^3.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } } diff --git a/packages/cli-scripts/package.json b/packages/cli-scripts/package.json index c472ef2ba0..5ba8281ae5 100644 --- a/packages/cli-scripts/package.json +++ b/packages/cli-scripts/package.json @@ -2,12 +2,15 @@ "private": true, "name": "cli-scripts", "version": "2.1.75", + "engines": { + "node": ">=18.0.0" + }, "bin": { "ionic-cli-scripts": "./bin/ionic-cli-scripts" }, "scripts": { "clean": "rimraf dist", - "lint": "true", + "lint": "exit 0", "build": "npm run clean && tsc", "watch": "tsc -w --preserveWatchOutput", "test": "jest --maxWorkers=4", @@ -23,17 +26,17 @@ "chalk": "^4.0.0", "escape-string-regexp": "^4.0.0", "strip-ansi": "^6.0.0", - "tslib": "^2.0.1" + "tslib": "^2.8.1" }, "devDependencies": { "@types/ansi-styles": "^3.2.0", - "@types/jest": "^26.0.10", - "@types/node": "~16.0.0", - "jest": "^26.4.2", - "jest-cli": "^26.0.1", + "@types/jest": "^29.5.14", + "@types/node": "^16.18.126", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "lint-staged": "^10.0.2", "rimraf": "^3.0.0", - "ts-jest": "~26.3.0", - "typescript": "~4.8.0" + "ts-jest": "^29.4.11", + "typescript": "~5.9.3" } }