Skip to content

Commit

Permalink
Merge branch 'main' into 231208-typescript-module-resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
MajorLift committed Apr 30, 2024
2 parents ee7a935 + 109ebe0 commit 2d6710e
Show file tree
Hide file tree
Showing 410 changed files with 49,310 additions and 15,941 deletions.
24 changes: 24 additions & 0 deletions .depcheckrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
ignores:
# Ignore dependencies used by Yarn binaries in `.yarn`
- '@yarnpkg/*'
- 'clipanion'
- 'typanion'
# Ignore dependencies imported implicitly by TypeScript
- '@types/*'
# Ignore tools (packages which we use as executables and not libraries)
- '@lavamoat/allow-scripts'
- '@metamask/auto-changelog'
- '@metamask/create-release-branch'
- 'depcheck'
- 'eslint-interactive'
- 'simple-git-hooks'
- 'ts-node'
- 'typedoc'
# Ignore plugins implicitly imported by tools
- 'jest-silent-reporter'
- 'prettier-plugin-packagejson'
# Ignore plugins we explicitly use with tools
- 'babel-jest'
# Ignore dependencies which plug into the NPM lifecycle
- '@lavamoat/preinstall-always-fail'
10 changes: 7 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ module.exports = {
'!.eslintrc.js',
'!jest.config.js',
'node_modules',
'dist',
'docs',
'coverage',
'**/dist',
'**/docs',
'**/coverage',
'merged-packages',
'scripts/create-package/package-template',
],
overrides: [
{
Expand Down Expand Up @@ -41,6 +42,9 @@ module.exports = {
project: ['./tsconfig.packages.json'],
},
rules: {
// Enable rules that are disabled in `@metamask/eslint-config-typescript`
'@typescript-eslint/no-explicit-any': 'error',

// TODO: auto-fix breaks stuff
'@typescript-eslint/promise-function-async': 'off',

Expand Down
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.

* @MetaMask/devs
* @MetaMask/engineering

/packages/permission-controller @MetaMask/snaps-devs
/packages/notification-controller @MetaMask/snaps-devs
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/ensure-blocking-pr-labels-absent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'Check for PR labels that block merging'
on:
pull_request:
types:
- opened
- synchronize
- labeled
- unlabeled

jobs:
ensure-blocking-pr-labels-absent:
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
- name: Install dependencies
run: yarn --immutable
- name: Run command
uses: actions/github-script@v7
with:
script: |
if (context.payload.pull_request.labels.some((label) => label.name === 'DO-NOT-MERGE')) {
core.setFailed(
"PR cannot be merged because it contains the label 'DO-NOT-MERGE'."
);
}
3 changes: 2 additions & 1 deletion .github/workflows/lint-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Fetch workspace package names
id: workspace-package-names
run: |
echo "child-workspace-package-names=$(yarn child-workspace-package-names-as-json)" >> "$GITHUB_OUTPUT"
echo "child-workspace-package-names=$(yarn workspaces list --no-private --json | jq --slurp --raw-output 'map(.name) | @json')" >> "$GITHUB_OUTPUT"
shell: bash

lint:
Expand Down Expand Up @@ -115,6 +115,7 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: yarn
- run: yarn --immutable
- run: yarn test:scripts
- run: yarn workspace ${{ matrix.package-name }} run test
- name: Require clean working directory
shell: bash
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/security-code-scanner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: 'MetaMask Security Code Scanner'

on:
push:
branches: ['main']
pull_request:
branches: ['main']

jobs:
run-security-scan:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: MetaMask Security Code Scanner
uses: MetaMask/Security-Code-Scanner@main
with:
repo: ${{ github.repository }}
paths_ignored: |
'**/test*/'
docs/
'**/*.test.js'
'**/*.test.ts'
node_modules
merged-packages/
'**/jest.environment.js'
project_metrics_token: ${{secrets.SECURITY_SCAN_METRICS_TOKEN}}
slack_webhook: ${{ secrets.APPSEC_BOT_SLACK_WEBHOOK }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ preview-build-message.txt
packages/*/coverage
packages/*/dist
packages/*/docs
scripts/coverage

# yarn v3 (w/o zero-install)
# See: https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
Expand Down
7 changes: 5 additions & 2 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// All of these are defaults except singleQuote, but we specify them
// for explicitness
/**
* @type {import('prettier').Options}
*/
module.exports = {
// All of these are defaults except singleQuote, but we specify them
// for explicitness
quoteProps: 'as-needed',
singleQuote: true,
tabWidth: 2,
Expand Down
13 changes: 13 additions & 0 deletions .yarn/patches/tsup-npm-8.0.2-86e40f68a7.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/dist/index.js b/dist/index.js
index 4500c4e43c3bbd24aa60b7d4cf95aa3fee8eb185..9c442bc216f99b7cfadb5ac62cb98d3ae9ce2f56 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1813,6 +1813,8 @@ var cjsSplitting = () => {
}
const { transform: transform3 } = await Promise.resolve().then(() => require("sucrase"));
const result = transform3(code, {
+ // https://github.com/egoist/tsup/issues/1087
+ disableESTransforms: true,
filePath: info.path,
transforms: ["imports"],
sourceMapOptions: this.options.sourcemap ? {
9 changes: 9 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// We use Babel for our tests in scripts/.
module.exports = {
env: {
test: {
presets: ['@babel/preset-typescript'],
plugins: ['@babel/plugin-transform-modules-commonjs'],
},
},
};
133 changes: 99 additions & 34 deletions constraints.pro
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ repo_name(RepoUrl, RepoName) :-
RepoNameLength is End - Start,
sub_atom(RepoUrl, PrefixLength, RepoNameLength, SuffixLength, RepoName).

% True if DependencyIdent starts with '@metamask' and ends with '-controller'
% True if DependencyIdent starts with '@metamask' and ends with '-controller'.
is_controller(DependencyIdent) :-
Prefix = '@metamask/',
atom_length(Prefix, PrefixLength),
Expand Down Expand Up @@ -238,12 +238,33 @@ gen_enforced_field(WorkspaceCwd, 'main', null) :-
workspace_field(WorkspaceCwd, 'private', true).

% The type definitions entrypoint for all publishable packages must be the same.
gen_enforced_field(WorkspaceCwd, 'types', './dist/index.d.ts') :-
gen_enforced_field(WorkspaceCwd, 'types', './dist/types/index.d.ts') :-
\+ workspace_field(WorkspaceCwd, 'private', true).
% Non-published packages must not specify a type definitions entrypoint.
gen_enforced_field(WorkspaceCwd, 'types', null) :-
workspace_field(WorkspaceCwd, 'private', true).

% The exports for all published packages must be the same.
gen_enforced_field(WorkspaceCwd, 'exports["."].import', './dist/index.mjs') :-
\+ workspace_field(WorkspaceCwd, 'private', true).
gen_enforced_field(WorkspaceCwd, 'exports["."].require', './dist/index.js') :-
\+ workspace_field(WorkspaceCwd, 'private', true).
gen_enforced_field(WorkspaceCwd, 'exports["."].types', './dist/types/index.d.ts') :-
\+ workspace_field(WorkspaceCwd, 'private', true).
gen_enforced_field(WorkspaceCwd, 'exports["./package.json"]', './package.json') :-
\+ workspace_field(WorkspaceCwd, 'private', true).
% Non-published packages must not specify exports.
gen_enforced_field(WorkspaceCwd, 'exports', null) :-
workspace_field(WorkspaceCwd, 'private', true).

% Published packages must not have side effects.
gen_enforced_field(WorkspaceCwd, 'sideEffects', false) :-
\+ workspace_field(WorkspaceCwd, 'private', true),
WorkspaceCwd \= 'packages/base-controller'.
% Non-published packages must not specify side effects.
gen_enforced_field(WorkspaceCwd, 'sideEffects', null) :-
workspace_field(WorkspaceCwd, 'private', true).

% The list of files included in published packages must only include files
% generated during the build step.
gen_enforced_field(WorkspaceCwd, 'files', ['dist/']) :-
Expand All @@ -254,6 +275,10 @@ gen_enforced_field(WorkspaceCwd, 'files', ['dist/']) :-
gen_enforced_field(WorkspaceCwd, 'files', []) :-
WorkspaceCwd = '.'.

% All non-root packages must have the same "build" script.
gen_enforced_field(WorkspaceCwd, 'scripts.build', 'tsup --config ../../tsup.config.ts --tsconfig ./tsconfig.build.json --clean') :-
WorkspaceCwd \= '.'.

% All non-root packages must have the same "build:docs" script.
gen_enforced_field(WorkspaceCwd, 'scripts.build:docs', 'typedoc') :-
WorkspaceCwd \= '.'.
Expand All @@ -276,6 +301,16 @@ gen_enforced_field(WorkspaceCwd, 'scripts.changelog:validate', CorrectChangelogV
atom_concat('../../scripts/validate-changelog.sh ', WorkspacePackageName, ExpectedPrefix),
\+ atom_concat(ExpectedPrefix, _, ChangelogValidationCommand).

% The "changelog:update" script for each published package must run a common
% script with the name of the package as the first argument.
gen_enforced_field(WorkspaceCwd, 'scripts.changelog:update', CorrectChangelogUpdateCommand) :-
\+ workspace_field(WorkspaceCwd, 'private', true),
workspace_field(WorkspaceCwd, 'scripts.changelog:update', ChangelogUpdateCommand),
workspace_package_name(WorkspaceCwd, WorkspacePackageName),
atomic_list_concat(['../../scripts/update-changelog.sh ', WorkspacePackageName, ' [...]'], CorrectChangelogUpdateCommand),
atom_concat('../../scripts/update-changelog.sh ', WorkspacePackageName, ExpectedPrefix),
\+ atom_concat(ExpectedPrefix, _, ChangelogUpdateCommand).

% All non-root packages must have the same "test" script.
gen_enforced_field(WorkspaceCwd, 'scripts.test', 'jest --reporters=jest-silent-reporter') :-
WorkspaceCwd \= '.'.
Expand All @@ -298,43 +333,80 @@ gen_enforced_dependency(WorkspaceCwd, DependencyIdent, 'a range optionally start
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType),
\+ is_valid_version_range(DependencyRange).

% All references to a workspace package must be up to date with the current
% version of that package.
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, CorrectDependencyRange, DependencyType) :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType),
workspace_ident(OtherWorkspaceCwd, DependencyIdent),
workspace_version(OtherWorkspaceCwd, OtherWorkspaceVersion),
atomic_list_concat(['^', OtherWorkspaceVersion], CorrectDependencyRange).

% All dependency ranges for a package must be synchronized across the monorepo
% (the least version range wins), regardless of which "*dependencies" field
% where the package appears.
% All version ranges used to reference one workspace package in another
% workspace package's `dependencies` or `devDependencies` must be the same.
% Among all references to the same dependency across the monorepo, the one with
% the smallest version range will win. (We handle `peerDependencies` in another
% constraint, as it has slightly different logic.)
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, OtherDependencyRange, DependencyType) :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType),
workspace_has_dependency(OtherWorkspaceCwd, DependencyIdent, OtherDependencyRange, OtherDependencyType),
WorkspaceCwd \= OtherWorkspaceCwd,
DependencyRange \= OtherDependencyRange,
npm_version_range_out_of_sync(DependencyRange, OtherDependencyRange).
npm_version_range_out_of_sync(DependencyRange, OtherDependencyRange),
DependencyType \= 'peerDependencies',
OtherDependencyType \= 'peerDependencies'.

% If a dependency is listed under "dependencies", it should not be listed under
% "devDependencies". We match on the same dependency range so that if a
% dependency is listed under both lists, their versions are synchronized and
% then this constraint will apply and remove the "right" duplicate.
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, null, DependencyType) :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'dependencies'),
% All version ranges used to reference one workspace package in another
% workspace package's `dependencies` or `devDependencies` must match the current
% version of that package. (We handle `peerDependencies` in another rule.)
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, CorrectDependencyRange, DependencyType) :-
DependencyType \= 'peerDependencies',
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType),
DependencyType == 'devDependencies'.
workspace_ident(OtherWorkspaceCwd, DependencyIdent),
workspace_version(OtherWorkspaceCwd, OtherWorkspaceVersion),
atomic_list_concat(['^', OtherWorkspaceVersion], CorrectDependencyRange).

% If a controller dependency (other than `base-controller`, `eth-keyring-controller` and
% `polling-controller`) is listed under "dependencies", it should also be
% listed under "peerDependencies". Each controller is a singleton, so we need
% to ensure the versions used match expectations.
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'peerDependencies') :-
% If a workspace package is listed under another workspace package's
% `dependencies`, it should not also be listed under its `devDependencies`.
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, null, 'devDependencies') :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'dependencies').

% Each controller is a singleton, so we need to ensure the versions
% used match expectations. To accomplish this, if a controller (other than
% `base-controller`, `eth-keyring-controller` and `polling-controller`) is
% listed under a workspace package's `dependencies`, it should also be listed
% under its `peerDependencies`, and the major version of the peer dependency
% should match the major part of the current version dependency, with the minor
% and patch parts set to 0. If it is already listed there, then the major
% version should match the current version of the package and the minor and
% patch parts should be <= the corresponding parts.
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, CorrectPeerDependencyRange, 'peerDependencies') :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'dependencies'),
\+ workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, 'peerDependencies'),
is_controller(DependencyIdent),
DependencyIdent \= '@metamask/base-controller',
DependencyIdent \= '@metamask/eth-keyring-controller',
DependencyIdent \= '@metamask/polling-controller',
workspace_ident(DependencyWorkspaceCwd, DependencyIdent),
workspace_version(DependencyWorkspaceCwd, CurrentDependencyWorkspaceVersion),
parse_version_range(CurrentDependencyWorkspaceVersion, _, CurrentDependencyVersionMajor, _, _),
atomic_list_concat([CurrentDependencyVersionMajor, 0, 0], '.', CorrectPeerDependencyVersion),
atom_concat('^', CorrectPeerDependencyVersion, CorrectPeerDependencyRange).
gen_enforced_dependency(WorkspaceCwd, DependencyIdent, CorrectPeerDependencyRange, 'peerDependencies') :-
workspace_has_dependency(WorkspaceCwd, DependencyIdent, SpecifiedPeerDependencyRange, 'peerDependencies'),
is_controller(DependencyIdent),
DependencyIdent \= '@metamask/base-controller',
DependencyIdent \= '@metamask/eth-keyring-controller',
DependencyIdent \= '@metamask/polling-controller',
is_controller(DependencyIdent).
workspace_ident(DependencyWorkspaceCwd, DependencyIdent),
workspace_version(DependencyWorkspaceCwd, CurrentDependencyVersion),
parse_version_range(CurrentDependencyVersion, _, CurrentDependencyVersionMajor, CurrentDependencyVersionMinor, CurrentDependencyVersionPatch),
parse_version_range(SpecifiedPeerDependencyRange, _, SpecifiedPeerDependencyVersionMajor, SpecifiedPeerDependencyVersionMinor, SpecifiedPeerDependencyVersionPatch),
(
(
SpecifiedPeerDependencyVersionMajor == CurrentDependencyVersionMajor,
(
SpecifiedPeerDependencyVersionMinor @< CurrentDependencyVersionMinor ;
(
SpecifiedPeerDependencyVersionMinor == CurrentDependencyVersionMinor,
SpecifiedPeerDependencyVersionPatch @=< CurrentDependencyVersionPatch
)
)
) ->
CorrectPeerDependencyRange = SpecifiedPeerDependencyRange ;
atom_concat('^', CurrentDependencyVersion, CorrectPeerDependencyRange)
).

% All packages must specify a minimum Node version of 16.
gen_enforced_field(WorkspaceCwd, 'engines.node', '>=16.0.0').
Expand All @@ -349,10 +421,3 @@ gen_enforced_field(WorkspaceCwd, 'publishConfig.registry', 'https://registry.npm
% whatsoever.
gen_enforced_field(WorkspaceCwd, 'publishConfig', null) :-
workspace_field(WorkspaceCwd, 'private', true).

% eth-method-registry has an unlisted dependency on babel-runtime (via `ethjs->ethjs-query`), so
% that package needs to be present if eth-method-registry is present.
gen_enforced_dependency(WorkspaceCwd, 'babel-runtime', '^6.26.0', 'peerDependencies') :-
workspace_has_dependency(WorkspaceCwd, 'eth-method-registry', _, 'dependencies').
gen_enforced_dependency(WorkspaceCwd, 'babel-runtime', '^6.26.0', 'devDependencies') :-
workspace_has_dependency(WorkspaceCwd, 'eth-method-registry', _, 'dependencies').
Loading

0 comments on commit 2d6710e

Please sign in to comment.