diff --git a/.eslintignore b/.eslintignore index 618e92150..e0f1fdcdb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -14,6 +14,8 @@ /packages/hbs-loader/**/*.d.ts /test-packages/support/**/*.js /test-packages/**/*.d.ts +/test-packages/release/src/*.js +/test-packages/release/src/*.d.ts /tests/scenarios/**/*.js /tests/scenarios/**/*.d.ts /packages/test-setup/**/*.js diff --git a/.prettierignore b/.prettierignore index 66b4f8041..3d79d5604 100644 --- a/.prettierignore +++ b/.prettierignore @@ -23,6 +23,8 @@ /packages/hbs-loader/**/*.d.ts /test-packages/support/**/*.js /test-packages/**/*.d.ts +/test-packages/release/src/*.js +/test-packages/release/src/*.d.ts /tests/scenarios/**/*.js /tests/scenarios/**/*.d.ts /packages/test-setup/**/*.js diff --git a/RELEASE.md b/RELEASE.md index 84d38abe7..8ad446b24 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,25 +1,26 @@ # Release Process -Release process is currently switching from release-it to https://github.com/changesets/changesets +1. You need a github token as `GITHUB_AUTH` environment variable. -## Notes +2. Run `pnpm embroider-release explain-plan`. If there are unlabeled PRs that need to be released it will complain and show you a list of them. Each PR needs to be labeled with one of: + - breaking + - enhancement + - bug + - documentation + - internal -Used `changesets` to do release-2022-10-6.0. Didn't go smoothly. +3. Once all the PRs are labeled, it will instead show you the release plain, explaining which packages are getting released, at which versions, and why. -1. Generated a changeset file describing everything since last release. +4. If you disagree with the plan, you can modify the list of changes before using it to `explain-plan` or `prepare` a release: - Scan for which packages were touched so nothing gets missed: + - `pnpm embroider-release gather-changes > /tmp/changelog` + - edit `/tmp/changelog` + - `pnpm embroider-release explain-plan --from-stdin < /tmp/changelog` - git diff --stat v1.8.3..HEAD + For example, this can be necessary if a PR that's labeled `breaking` touches multiple packages and only one of those packages is actually a breaking change. In that case you can take the other package names out of the description of the PR. - Find all PRs since previous release to summarize them +5. Once you're happy with the plan, run `pnpm embroider-release prepare`. This will edit CHANGELOG.md, bump the version numbers in package.json files, and create a file named `.release-plan.json`. Make a PR with these changes. - git log v1.8.3..HEAD +6. Once the PR is merged, in a clean local repo at the merge commit, run `pnpm embroider-release publish`. - And search for "Merge pull" - -2. Used `changeset version`, manually moved all readme content from changeset into our top-level readme (because the defaults in `changesets` want to create per-package ones). - -3. Tried using `changeset publish` but that started publishing lots of unintended packages. Followed up by manually releasing the others. - -4. Noticed that `changeset version` bumped a dependency version in `@embroider/util` but didn't bump `@embroider/util`'s version. Had to update and release it manually. + \ No newline at end of file diff --git a/package.json b/package.json index 4c5a835bc..375718355 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ } }, "devDependencies": { + "@embroider/release": "workspace:*", "@types/jest": "^29.2.0", "@typescript-eslint/eslint-plugin": "^5.59.5", "@typescript-eslint/parser": "^5.59.5", @@ -60,5 +61,16 @@ "node": "16.20.0", "pnpm": "8.4.0" }, - "version": "1.8.3" + "changelog": { + "__comment__": "Our release infrastructure relies on these exact labels. Be careful changing them.", + "labels": { + "breaking": ":boom: Breaking Change", + "enhancement": ":rocket: Enhancement", + "bug": ":bug: Bug Fix", + "documentation": ":memo: Documentation", + "internal": ":house: Internal", + "unlabeled": ":question: Unlabeled" + }, + "wildcardLabel": "unlabeled" + } } diff --git a/packages/router/package.json b/packages/router/package.json index 2d8cccae6..4c93e50ce 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -59,7 +59,7 @@ "typescript": "^4.9.0" }, "peerDependencies": { - "@embroider/core": "workspace:^" + "@embroider/core": "workspace:^2.0.0||^3.0.0" }, "peerDependenciesMeta": { "@embroider/core": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12a1e4ec6..c2543b260 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ importers: .: devDependencies: + '@embroider/release': + specifier: workspace:* + version: link:test-packages/release '@types/jest': specifier: ^29.2.0 version: 29.2.0 @@ -572,7 +575,7 @@ importers: specifier: workspace:^ version: link:../addon-shim '@embroider/core': - specifier: workspace:^ + specifier: workspace:^2.0.0||^3.0.0 version: link:../core devDependencies: '@babel/core': @@ -985,6 +988,54 @@ importers: specifier: ^5.38.1 version: 5.78.0 + test-packages/release: + dependencies: + '@ef4/lerna-changelog': + specifier: ^1.0.4 + version: 1.0.4 + '@octokit/rest': + specifier: ^19.0.8 + version: 19.0.8 + '@types/fs-extra': + specifier: ^9.0.12 + version: 9.0.12 + '@types/js-yaml': + specifier: ^4.0.5 + version: 4.0.5 + '@types/semver': + specifier: ^7.3.6 + version: 7.3.6 + '@types/yargs': + specifier: ^17.0.3 + version: 17.0.3 + assert-never: + specifier: ^1.2.1 + version: 1.2.1 + chalk: + specifier: ^4.1.1 + version: 4.1.1 + cli-highlight: + specifier: ^2.1.11 + version: 2.1.11 + execa: + specifier: ^4.0.3 + version: 4.0.3 + fs-extra: + specifier: ^10.0.0 + version: 10.0.0 + globby: + specifier: ^11.0.3 + version: 11.0.3 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + semver: + specifier: ^7.3.5 + version: 7.3.8 + yargs: + specifier: ^17.0.1 + version: 17.0.1 + test-packages/sample-transforms: dependencies: ember-cli-babel: @@ -3425,6 +3476,24 @@ packages: postcss-selector-parser: 6.0.13 dev: true + /@ef4/lerna-changelog@1.0.4: + resolution: {integrity: sha512-xG/w+aOAaBtZVrRQDN7Ina+yjhEEV1WENN119pue3SfFCcPOA00tYNgt5Hg2VMuO8G6+TOW8FQxA3jESTRLy4w==} + engines: {node: '>=6'} + hasBin: true + dependencies: + chalk: 2.4.2 + cli-highlight: 2.1.11 + execa: 0.10.0 + make-fetch-happen: 4.0.2 + normalize-git-url: 3.0.2 + p-map: 1.2.0 + progress: 2.0.3 + string.prototype.padend: 3.1.4 + yargs: 11.1.1 + transitivePeerDependencies: + - supports-color + dev: false + /@ember-data/adapter@3.28.0(@babel/core@7.19.6): resolution: {integrity: sha512-nt9DcoXBzDvBeAw411h3Nu7D90GTfzdCJYUVQVpc0MqQLv0pqC3h4UKrqzq9bDZD8LqKd6spWKo0iP8MaZJPSQ==} engines: {node: 12.* || >= 14.*} @@ -4208,7 +4277,7 @@ packages: resolution: {integrity: sha512-qZ2/xky9mWm5YC6noOa6AiAwgISEQ78YTZNv4SNu2PFgEK/H+Ha/3ddngzGSsnXkVnIHZyxIBzhxETonQYHY9g==} engines: {node: 12.* || 14.* || >= 16} dependencies: - babel-import-util: 1.1.0 + babel-import-util: 1.3.0 ember-rfc176-data: 0.3.17 fs-extra: 9.1.0 js-string-escape: 1.0.1 @@ -4658,7 +4727,7 @@ packages: '@jest/types': 29.5.0 '@types/node': 15.12.2 ansi-escapes: 4.3.2 - chalk: 4.1.1 + chalk: 4.1.2 ci-info: 3.8.0 exit: 0.1.2 graceful-fs: 4.2.11 @@ -4838,7 +4907,7 @@ packages: '@types/istanbul-reports': 3.0.1 '@types/node': 15.12.2 '@types/yargs': 17.0.24 - chalk: 4.1.1 + chalk: 4.1.2 /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} @@ -4927,6 +4996,122 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + /@octokit/auth-token@3.0.3: + resolution: {integrity: sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==} + engines: {node: '>= 14'} + dependencies: + '@octokit/types': 9.2.2 + dev: false + + /@octokit/core@4.2.0: + resolution: {integrity: sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==} + engines: {node: '>= 14'} + dependencies: + '@octokit/auth-token': 3.0.3 + '@octokit/graphql': 5.0.5 + '@octokit/request': 6.2.4 + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.2.2 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.0 + transitivePeerDependencies: + - encoding + dev: false + + /@octokit/endpoint@7.0.5: + resolution: {integrity: sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==} + engines: {node: '>= 14'} + dependencies: + '@octokit/types': 9.2.2 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.0 + dev: false + + /@octokit/graphql@5.0.5: + resolution: {integrity: sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==} + engines: {node: '>= 14'} + dependencies: + '@octokit/request': 6.2.4 + '@octokit/types': 9.2.2 + universal-user-agent: 6.0.0 + transitivePeerDependencies: + - encoding + dev: false + + /@octokit/openapi-types@17.2.0: + resolution: {integrity: sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==} + dev: false + + /@octokit/plugin-paginate-rest@6.1.0(@octokit/core@4.2.0): + resolution: {integrity: sha512-5T4iXjJdYCVA1rdWS1C+uZV9AvtZY9QgTG74kFiSFVj94dZXowyi/YK8f4SGjZaL69jZthGlBaDKRdCMCF9log==} + engines: {node: '>= 14'} + peerDependencies: + '@octokit/core': '>=4' + dependencies: + '@octokit/core': 4.2.0 + '@octokit/types': 9.2.2 + dev: false + + /@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.0): + resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} + peerDependencies: + '@octokit/core': '>=3' + dependencies: + '@octokit/core': 4.2.0 + dev: false + + /@octokit/plugin-rest-endpoint-methods@7.1.0(@octokit/core@4.2.0): + resolution: {integrity: sha512-SWwz/hc47GaKJR6BlJI4WIVRodbAFRvrR0QRPSoPMs7krb7anYPML3psg+ThEz/kcwOdSNh/oA8qThi/Wvs4Fw==} + engines: {node: '>= 14'} + peerDependencies: + '@octokit/core': '>=3' + dependencies: + '@octokit/core': 4.2.0 + '@octokit/types': 9.2.2 + deprecation: 2.3.1 + dev: false + + /@octokit/request-error@3.0.3: + resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==} + engines: {node: '>= 14'} + dependencies: + '@octokit/types': 9.2.2 + deprecation: 2.3.1 + once: 1.4.0 + dev: false + + /@octokit/request@6.2.4: + resolution: {integrity: sha512-at92SYQstwh7HH6+Kf3bFMnHrle7aIrC0r5rTP+Bb30118B6j1vI2/M4walh6qcQgfuLIKs8NUO5CytHTnUI3A==} + engines: {node: '>= 14'} + dependencies: + '@octokit/endpoint': 7.0.5 + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.2.2 + is-plain-object: 5.0.0 + node-fetch: 2.6.11 + universal-user-agent: 6.0.0 + transitivePeerDependencies: + - encoding + dev: false + + /@octokit/rest@19.0.8: + resolution: {integrity: sha512-/PKrzqn+zDzXKwBMwLI2IKrvk8yv8cedJOdcmxrjR3gmu6UIzURhP5oQj+4qkn7+uQi1gg7QqV4SqlaQ1HYW1Q==} + engines: {node: '>= 14'} + dependencies: + '@octokit/core': 4.2.0 + '@octokit/plugin-paginate-rest': 6.1.0(@octokit/core@4.2.0) + '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.0) + '@octokit/plugin-rest-endpoint-methods': 7.1.0(@octokit/core@4.2.0) + transitivePeerDependencies: + - encoding + dev: false + + /@octokit/types@9.2.2: + resolution: {integrity: sha512-9BjDxjgQIvCjNWZsbqyH5QC2Yni16oaE6xL+8SUBMzcYPF4TGQBXGA97Cl3KceK9mwiNMb1mOYCz6FbCCLEL+g==} + dependencies: + '@octokit/openapi-types': 17.2.0 + dev: false + /@popperjs/core@2.11.7: resolution: {integrity: sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==} dev: true @@ -5217,7 +5402,6 @@ packages: resolution: {integrity: sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==} dependencies: '@types/node': 15.12.2 - dev: true /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -5266,7 +5450,6 @@ packages: /@types/js-yaml@4.0.5: resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} - dev: true /@types/jsdom@16.2.11: resolution: {integrity: sha512-Dvtx0zFQOJqn06VgjRur7P5CeSNUOaQ5ivSSvdAdA3sBWzL3kl9OWApQRExKnS3XN39OaZdeCHpoYxVmX6FwCQ==} @@ -5391,7 +5574,6 @@ packages: /@types/semver@7.3.6: resolution: {integrity: sha512-0caWDWmpCp0uifxFh+FaqK3CuZ2SkRR/ZRxAV5+zNdC3QVUi6wyOJnefhPvtNt8NQWXB5OA93BUvZsXpWat2Xw==} - dev: true /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} @@ -5868,6 +6050,20 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /agent-base@4.2.1: + resolution: {integrity: sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==} + engines: {node: '>= 4.0.0'} + dependencies: + es6-promisify: 5.0.0 + dev: false + + /agent-base@4.3.0: + resolution: {integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==} + engines: {node: '>= 4.0.0'} + dependencies: + es6-promisify: 5.0.0 + dev: false + /agent-base@6.0.2(supports-color@8.1.0): resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -5876,6 +6072,13 @@ packages: transitivePeerDependencies: - supports-color + /agentkeepalive@3.5.2: + resolution: {integrity: sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==} + engines: {node: '>= 4.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -6015,6 +6218,10 @@ packages: /ansicolors@0.2.1: resolution: {integrity: sha512-tOIuy1/SK/dr94ZA0ckDohKXNeBNqZ4us6PjMVLs5h1w2GBB6uPtOknp2+VF4F/zcy9LI70W+Z+pE2Soajky1w==} + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: false + /anymatch@2.0.0: resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} dependencies: @@ -6037,6 +6244,10 @@ packages: jsesc: 2.5.2 dev: true + /aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + dev: false + /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} @@ -7010,6 +7221,10 @@ packages: dependencies: safe-buffer: 5.1.2 + /before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + dev: false + /big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -7405,7 +7620,7 @@ packages: fast-ordered-set: 1.0.3 fs-tree-diff: 0.5.9 heimdalljs: 0.2.6 - minimatch: 3.0.4 + minimatch: 3.1.2 mkdirp: 0.5.6 path-posix: 1.0.0 rimraf: 2.7.1 @@ -7923,6 +8138,25 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + /cacache@11.3.3: + resolution: {integrity: sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==} + dependencies: + bluebird: 3.7.2 + chownr: 1.1.4 + figgy-pudding: 3.5.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + lru-cache: 5.1.1 + mississippi: 3.0.0 + mkdirp: 0.5.6 + move-concurrently: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 2.7.1 + ssri: 6.0.2 + unique-filename: 1.1.1 + y18n: 4.0.3 + dev: false + /cache-base@1.0.1: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} engines: {node: '>=0.10.0'} @@ -7987,6 +8221,11 @@ packages: quick-lru: 4.0.1 dev: true + /camelcase@4.1.0: + resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} + engines: {node: '>=4'} + dev: false + /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -8082,6 +8321,10 @@ packages: dependencies: inherits: 2.0.4 + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: false + /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -8148,6 +8391,19 @@ packages: restore-cursor: 3.1.0 dev: true + /cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + dev: false + /cli-spinners@2.9.0: resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} engines: {node: '>=6'} @@ -8180,6 +8436,14 @@ packages: engines: {node: '>= 12'} dev: true + /cliui@4.1.0: + resolution: {integrity: sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==} + dependencies: + string-width: 2.1.1 + strip-ansi: 4.0.0 + wrap-ansi: 2.1.0 + dev: false + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -8258,6 +8522,11 @@ packages: transitivePeerDependencies: - supports-color + /code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + dev: false + /collect-v8-coverage@1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} dev: true @@ -8389,6 +8658,16 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + dev: false + /concurrently@7.2.1: resolution: {integrity: sha512-7cab/QyqipqghrVr9qZmoWbidu0nHsmxrpNqQ7r/67vfl1DWJElexehQnTH1p+87tDkihaAjM79xTZyBQh7HLw==} engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} @@ -8657,7 +8936,7 @@ packages: dev: true /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} /cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} @@ -8667,6 +8946,17 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + /copy-concurrently@1.0.5: + resolution: {integrity: sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==} + dependencies: + aproba: 1.2.0 + fs-write-stream-atomic: 1.0.10 + iferr: 0.1.5 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + dev: false + /copy-dereference@1.0.0: resolution: {integrity: sha512-40TSLuhhbiKeszZhK9LfNdazC67Ue4kq/gGwN5sdxEUWPXTIMmKmGmgD9mPfNKVAeecEW+NfEIpBaZoACCQLLw==} dev: true @@ -8862,6 +9152,10 @@ packages: dependencies: cssom: 0.3.8 + /cyclist@1.0.1: + resolution: {integrity: sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==} + dev: false + /dag-map@2.0.2: resolution: {integrity: sha512-xnsprIzYuDeiyu5zSKwilV/ajRHxnoMlAhEREfyfTgTSViMVY2fGP1ZcHJbtwup26oCkofySU/m6oKJ3HrkW7w==} @@ -8907,6 +9201,17 @@ packages: ms: 2.0.0 supports-color: 8.1.0 + /debug@3.1.0: + resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: false + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -8952,7 +9257,6 @@ packages: /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - dev: true /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -9071,6 +9375,10 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + /deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dev: false + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -9179,6 +9487,15 @@ packages: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} dev: true + /duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.1 + dev: false + /editions@1.3.4: resolution: {integrity: sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==} engines: {node: '>=0.8'} @@ -9233,7 +9550,7 @@ packages: broccoli-source: 3.0.1 css-loader: 5.2.6(webpack@5.78.0) debug: 4.3.2(supports-color@8.1.0) - fs-extra: 10.0.0 + fs-extra: 10.1.0 fs-tree-diff: 2.0.1 handlebars: 4.7.7 js-string-escape: 1.0.1 @@ -9262,7 +9579,7 @@ packages: broccoli-debug: 0.6.5 broccoli-funnel: 3.0.8 broccoli-merge-trees: 4.2.0 - chalk: 4.1.1 + chalk: 4.1.2 ember-auto-import: 2.6.3(webpack@5.78.0) ember-cli-babel: 7.26.11 ember-cli-build-config-editor: 0.5.1 @@ -9280,7 +9597,7 @@ packages: ember-render-helpers: 0.2.0 ember-style-modifier: 0.7.0(@babel/core@7.19.6) findup-sync: 5.0.0 - fs-extra: 10.0.0 + fs-extra: 10.1.0 resolve: 1.20.0 rsvp: 4.8.5 silent-error: 1.1.1 @@ -9846,7 +10163,7 @@ packages: broccoli-stew: 3.0.0 calculate-cache-key-for-tree: 2.0.0 capture-exit: 2.0.0 - chalk: 4.1.1 + chalk: 4.1.2 ci-info: 2.0.0 clean-base-url: 1.0.0 compression: 1.7.4 @@ -11232,7 +11549,7 @@ packages: broccoli-debug: 0.6.5 broccoli-funnel: 2.0.2 broccoli-merge-trees: 4.2.0 - chalk: 4.1.1 + chalk: 4.1.2 ember-cli-babel: 7.26.11 ember-cli-get-component-path-option: 1.0.0 ember-cli-is-package-missing: 1.0.0 @@ -11266,7 +11583,7 @@ packages: broccoli-debug: 0.6.5 broccoli-funnel: 2.0.2 broccoli-merge-trees: 4.2.0 - chalk: 4.1.1 + chalk: 4.1.2 ember-cli-babel: 7.26.11 ember-cli-get-component-path-option: 1.0.0 ember-cli-is-package-missing: 1.0.0 @@ -11300,7 +11617,7 @@ packages: broccoli-file-creator: 2.1.1 broccoli-funnel: 2.0.2 broccoli-merge-trees: 4.2.0 - chalk: 4.1.1 + chalk: 4.1.2 ember-cli-babel: 7.26.11 ember-cli-get-component-path-option: 1.0.0 ember-cli-is-package-missing: 1.0.0 @@ -11578,7 +11895,7 @@ packages: async-promise-queue: 1.0.5 colors: 1.4.0 commander: 6.2.1 - globby: 11.0.3 + globby: 11.1.0 ora: 5.4.1 slash: 3.0.0 tmp: 0.2.1 @@ -11598,7 +11915,7 @@ packages: async-promise-queue: 1.0.5 colors: 1.4.0 commander: 8.3.0 - globby: 11.0.3 + globby: 11.1.0 ora: 5.4.1 slash: 3.0.0 tmp: 0.2.1 @@ -11678,6 +11995,12 @@ packages: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + /encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + dependencies: + iconv-lite: 0.6.3 + dev: false + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: @@ -11742,6 +12065,10 @@ packages: engines: {node: '>=0.12'} dev: true + /err-code@1.1.2: + resolution: {integrity: sha512-CJAN+O0/yA1CKfRn9SXOGctSpEM7DCon/r/5r2eXFMY2zCCJBasFhcM5I+1kh3Ap11FsQCX+vGHceNPvpWKhoA==} + dev: false + /errlop@2.2.0: resolution: {integrity: sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw==} engines: {node: '>=0.8'} @@ -11839,6 +12166,16 @@ packages: is-date-object: 1.0.5 is-symbol: 1.0.4 + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -12441,6 +12778,19 @@ packages: /exec-sh@0.3.6: resolution: {integrity: sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==} + /execa@0.10.0: + resolution: {integrity: sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==} + engines: {node: '>=4'} + dependencies: + cross-spawn: 6.0.5 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + dev: false + /execa@1.0.0: resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} engines: {node: '>=6'} @@ -12764,6 +13114,10 @@ packages: dependencies: bser: 2.1.1 + /figgy-pudding@3.5.2: + resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} + dev: false + /figures@2.0.0: resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} engines: {node: '>=4'} @@ -13051,6 +13405,13 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true + /flush-write-stream@1.1.1: + resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + dev: false + /focus-trap@6.9.4: resolution: {integrity: sha512-v2NTsZe2FF59Y+sDykKY+XjqZ0cPfhq/hikWVL88BqLivnNiEffAsac6rP6H45ff9wG9LL5ToiDqrLEP9GX9mw==} dependencies: @@ -13103,7 +13464,7 @@ packages: map-cache: 0.2.2 /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} engines: {node: '>= 0.6'} /from2@2.3.0: @@ -13111,7 +13472,6 @@ packages: dependencies: inherits: 2.0.4 readable-stream: 2.3.8 - dev: true /fs-extra@0.24.0: resolution: {integrity: sha512-w1RvhdLZdU9V3vQdL+RooGlo6b9R9WVoBanOfoJvosWlqSKvrjFlci2oVhwvLwZXBtM7khyPvZ8r3fwsim3o0A==} @@ -13138,6 +13498,7 @@ packages: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 + dev: false /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -13146,7 +13507,6 @@ packages: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 - dev: true /fs-extra@11.1.1: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} @@ -13258,6 +13618,15 @@ packages: transitivePeerDependencies: - supports-color + /fs-write-stream-atomic@1.0.10: + resolution: {integrity: sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==} + dependencies: + graceful-fs: 4.2.11 + iferr: 0.1.5 + imurmurhash: 0.1.4 + readable-stream: 2.3.8 + dev: false + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -13309,6 +13678,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + /get-caller-file@1.0.3: + resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} + dev: false + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -13343,7 +13716,6 @@ packages: /get-stream@3.0.0: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} engines: {node: '>=4'} - dev: true /get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} @@ -13529,6 +13901,7 @@ packages: ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 + dev: false /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} @@ -13772,6 +14145,10 @@ packages: engines: {node: '>=10.0.0'} dev: true + /highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + dev: false + /home-or-tmp@2.0.0: resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} engines: {node: '>=0.10.0'} @@ -13834,7 +14211,6 @@ packages: /http-cache-semantics@3.8.1: resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} - dev: true /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -13862,6 +14238,16 @@ packages: /http-parser-js@0.5.8: resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + /http-proxy-agent@2.1.0: + resolution: {integrity: sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==} + engines: {node: '>= 4.5.0'} + dependencies: + agent-base: 4.3.0 + debug: 3.1.0 + transitivePeerDependencies: + - supports-color + dev: false + /http-proxy-agent@4.0.1(supports-color@8.1.0): resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} @@ -13893,6 +14279,16 @@ packages: transitivePeerDependencies: - debug + /https-proxy-agent@2.2.4: + resolution: {integrity: sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==} + engines: {node: '>= 4.5.0'} + dependencies: + agent-base: 4.3.0 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + dev: false + /https-proxy-agent@5.0.1(supports-color@8.1.0): resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -13918,6 +14314,12 @@ packages: engines: {node: '>=14.18.0'} dev: false + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -13942,6 +14344,10 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true + /iferr@0.1.5: + resolution: {integrity: sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==} + dev: false + /ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} @@ -14137,11 +14543,20 @@ packages: dependencies: loose-envify: 1.4.0 + /invert-kv@2.0.0: + resolution: {integrity: sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==} + engines: {node: '>=4'} + dev: false + /invert-kv@3.0.1: resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==} engines: {node: '>=8'} dev: true + /ip@1.1.5: + resolution: {integrity: sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA==} + dev: false + /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -14266,6 +14681,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + dependencies: + number-is-nan: 1.0.1 + dev: false + /is-fullwidth-code-point@2.0.0: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} engines: {node: '>=4'} @@ -14374,7 +14796,6 @@ packages: /is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - dev: true /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -14641,7 +15062,7 @@ packages: '@jest/core': 29.5.0 '@jest/test-result': 29.5.0 '@jest/types': 29.5.0 - chalk: 4.1.1 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.1.0 @@ -14972,7 +15393,7 @@ packages: dependencies: '@types/node': 15.12.2 merge-stream: 2.0.0 - supports-color: 8.1.0 + supports-color: 8.1.1 /jest-worker@29.5.0: resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} @@ -15275,6 +15696,13 @@ packages: language-subtag-registry: 0.3.22 dev: true + /lcid@2.0.0: + resolution: {integrity: sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==} + engines: {node: '>=6'} + dependencies: + invert-kv: 2.0.0 + dev: false + /lcid@3.1.1: resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==} engines: {node: '>=8'} @@ -15632,6 +16060,24 @@ packages: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: false + /make-fetch-happen@4.0.2: + resolution: {integrity: sha512-YMJrAjHSb/BordlsDEcVcPyTbiJKkzqMf48N8dAJZT9Zjctrkb6Yg4TY9Sq2AwSIQJFn5qBBKVTYt3vP5FMIHA==} + dependencies: + agentkeepalive: 3.5.2 + cacache: 11.3.3 + http-cache-semantics: 3.8.1 + http-proxy-agent: 2.1.0 + https-proxy-agent: 2.2.4 + lru-cache: 5.1.1 + mississippi: 3.0.0 + node-fetch-npm: 2.0.4 + promise-retry: 1.1.1 + socks-proxy-agent: 4.0.2 + ssri: 6.0.2 + transitivePeerDependencies: + - supports-color + dev: false + /makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} dependencies: @@ -15642,7 +16088,6 @@ packages: engines: {node: '>=6'} dependencies: p-defer: 1.0.0 - dev: true /map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} @@ -15772,6 +16217,15 @@ packages: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} + /mem@4.3.0: + resolution: {integrity: sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==} + engines: {node: '>=6'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 2.1.0 + p-is-promise: 2.1.0 + dev: false + /mem@5.1.1: resolution: {integrity: sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==} engines: {node: '>=8'} @@ -15810,7 +16264,7 @@ packages: dev: true /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -15984,6 +16438,22 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true + /mississippi@3.0.0: + resolution: {integrity: sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==} + engines: {node: '>=4.0.0'} + dependencies: + concat-stream: 1.6.2 + duplexify: 3.7.1 + end-of-stream: 1.4.4 + flush-write-stream: 1.1.1 + from2: 2.3.0 + parallel-transform: 1.2.0 + pump: 3.0.0 + pumpify: 1.5.1 + stream-each: 1.2.3 + through2: 2.0.5 + dev: false + /mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} engines: {node: '>=0.10.0'} @@ -16029,6 +16499,17 @@ packages: /mout@1.2.4: resolution: {integrity: sha512-mZb9uOruMWgn/fw28DG4/yE3Kehfk1zKCLhuDU2O3vlKdnBBr4XaOCqVTflJ5aODavGUPqFHZgrFX3NJVuxGhQ==} + /move-concurrently@1.0.1: + resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} + dependencies: + aproba: 1.2.0 + copy-concurrently: 1.0.5 + fs-write-stream-atomic: 1.0.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + dev: false + /mr-dep-walk@1.4.0: resolution: {integrity: sha512-UaDUqkLsd0ep3jAx2+A7BIpfw8wKxhthDj3yPNLBnevipK1CUFJJiz24jRVLw18q7R2aEiRq13WwUBlnwfbQqQ==} dependencies: @@ -16062,6 +16543,14 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: false + /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -16116,6 +16605,16 @@ packages: tslib: 2.5.0 dev: true + /node-fetch-npm@2.0.4: + resolution: {integrity: sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==} + engines: {node: '>=4'} + deprecated: This module is not used anymore, npm uses minipass-fetch for its fetch implementation now + dependencies: + encoding: 0.1.13 + json-parse-better-errors: 1.0.2 + safe-buffer: 5.2.1 + dev: false + /node-fetch@2.6.11: resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} @@ -16156,6 +16655,10 @@ packages: dependencies: abbrev: 1.1.1 + /normalize-git-url@3.0.2: + resolution: {integrity: sha512-UEmKT33ssKLLoLCsFJ4Si4fmNQsedNwivXpuNTR4V1I97jU9WZlicTV1xn5QAG5itE5B3Z9zhl8OItP6wIGkRA==} + dev: false + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -16292,6 +16795,11 @@ packages: boolbase: 1.0.0 dev: true + /number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + dev: false + /nwsapi@2.2.4: resolution: {integrity: sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==} @@ -16473,6 +16981,15 @@ packages: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} + /os-locale@3.1.0: + resolution: {integrity: sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==} + engines: {node: '>=6'} + dependencies: + execa: 1.0.0 + lcid: 2.0.0 + mem: 4.3.0 + dev: false + /os-locale@5.0.0: resolution: {integrity: sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==} engines: {node: '>=10'} @@ -16505,7 +17022,6 @@ packages: /p-defer@1.0.0: resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} engines: {node: '>=4'} - dev: true /p-defer@3.0.0: resolution: {integrity: sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==} @@ -16527,7 +17043,6 @@ packages: /p-is-promise@2.1.0: resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==} engines: {node: '>=6'} - dev: true /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} @@ -16585,6 +17100,11 @@ packages: p-limit: 4.0.0 dev: true + /p-map@1.2.0: + resolution: {integrity: sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==} + engines: {node: '>=4'} + dev: false + /p-map@3.0.0: resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} engines: {node: '>=8'} @@ -16617,6 +17137,14 @@ packages: semver: 6.3.0 dev: true + /parallel-transform@1.2.0: + resolution: {integrity: sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==} + dependencies: + cyclist: 1.0.1 + inherits: 2.0.4 + readable-stream: 2.3.8 + dev: false + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -16654,6 +17182,16 @@ packages: /parse-static-imports@1.1.0: resolution: {integrity: sha512-HlxrZcISCblEV0lzXmAHheH/8qEkKgmqkdxyHTPbSqsTUV8GzqmN1L+SSti+VbNPfbBO3bYLPHDiUs2avbAdbA==} + /parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + dependencies: + parse5: 6.0.1 + dev: false + + /parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + dev: false + /parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} @@ -16751,7 +17289,7 @@ packages: dev: true /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} /path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -16967,7 +17505,6 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true /process-relative-require@1.0.0: resolution: {integrity: sha512-r8G5WJPozMJAiv8sDdVWKgJ4In/zBXqwJdMCGAXQt2Kd3HdbAuJVzWYM4JW150hWoaI9DjhtbjcsCCHIMxm8RA==} @@ -16977,7 +17514,17 @@ packages: /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - dev: true + + /promise-inflight@1.0.1(bluebird@3.7.2): + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + dependencies: + bluebird: 3.7.2 + dev: false /promise-map-series@0.2.3: resolution: {integrity: sha512-wx9Chrutvqu1N/NHzTayZjE1BgIwt6SJykQoCOic4IZ9yUDjKyVYrpLa/4YCNsV61eRENfs29hrEquVuB13Zlw==} @@ -16988,6 +17535,14 @@ packages: resolution: {integrity: sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==} engines: {node: 10.* || >= 12.*} + /promise-retry@1.1.1: + resolution: {integrity: sha512-StEy2osPr28o17bIW776GtwO6+Q+M9zPiZkYfosciUUMYqjhU/ffwRAH0zN2+uvGyUsn8/YICIHRzLbPacpZGw==} + engines: {node: '>=0.12'} + dependencies: + err-code: 1.1.2 + retry: 0.10.1 + dev: false + /promise.hash.helper@1.0.8: resolution: {integrity: sha512-KYcnXctWUWyVD3W3Ye0ZDuA1N8Szrh85cVCxpG6xYrOk/0CttRtYCmU30nWsUch0NuExQQ63QXvzRE6FLimZmg==} engines: {node: 10.* || >= 12.*} @@ -17027,12 +17582,27 @@ packages: /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + /pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 + /pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + dev: false + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -17207,7 +17777,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -17405,6 +17974,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + /require-main-filename@1.0.1: + resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} + dev: false + /require-relative@0.8.7: resolution: {integrity: sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==} dev: true @@ -17535,6 +18108,10 @@ packages: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} + /retry@0.10.1: + resolution: {integrity: sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ==} + dev: false + /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -17701,6 +18278,12 @@ packages: dependencies: queue-microtask: 1.2.3 + /run-queue@1.0.3: + resolution: {integrity: sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==} + dependencies: + aproba: 1.2.0 + dev: false + /rx-lite-aggregates@4.0.8: resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} dependencies: @@ -18013,6 +18596,11 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: false + /snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} dependencies: @@ -18087,6 +18675,22 @@ packages: - supports-color - utf-8-validate + /socks-proxy-agent@4.0.2: + resolution: {integrity: sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==} + engines: {node: '>= 6'} + dependencies: + agent-base: 4.2.1 + socks: 2.3.3 + dev: false + + /socks@2.3.3: + resolution: {integrity: sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dependencies: + ip: 1.1.5 + smart-buffer: 4.2.0 + dev: false + /sort-keys@2.0.0: resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} engines: {node: '>=4'} @@ -18232,6 +18836,12 @@ packages: engines: {node: '>= 0.10.4'} dev: true + /ssri@6.0.2: + resolution: {integrity: sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==} + dependencies: + figgy-pudding: 3.5.2 + dev: false + /stable@0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' @@ -18273,6 +18883,17 @@ packages: internal-slot: 1.0.5 dev: true + /stream-each@1.2.3: + resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} + dependencies: + end-of-stream: 1.4.4 + stream-shift: 1.0.1 + dev: false + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: false + /strict-uri-encode@1.1.0: resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} engines: {node: '>=0.10.0'} @@ -18289,6 +18910,15 @@ packages: /string-template@0.2.1: resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==} + /string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + dev: false + /string-width@2.1.1: resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} engines: {node: '>=4'} @@ -18332,7 +18962,6 @@ packages: call-bind: 1.0.2 define-properties: 1.2.0 es-abstract: 1.21.2 - dev: true /string.prototype.trim@1.2.7: resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} @@ -18363,7 +18992,6 @@ packages: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 - dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -18563,7 +19191,6 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - dev: true /supports-hyperlinks@3.0.0: resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} @@ -18839,6 +19466,19 @@ packages: resolution: {integrity: sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==} engines: {node: '>=0.8'} + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: false + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: false + /thread-loader@3.0.4(webpack@5.78.0): resolution: {integrity: sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==} engines: {node: '>= 10.13.0'} @@ -18853,6 +19493,13 @@ packages: webpack: 5.78.0 dev: false + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: false + /through2@3.0.2: resolution: {integrity: sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==} dependencies: @@ -19184,6 +19831,10 @@ packages: dependencies: is-typedarray: 1.0.0 + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: false + /typescript-memoize@1.0.1: resolution: {integrity: sha512-oJNge1qUrOK37d5Y6Ly2txKeuelYVsFtNF6U9kXIN7juudcQaHJQg2MxLOy0CqtkW65rVDYuTCOjnSIVPd8z3w==} @@ -19251,12 +19902,28 @@ packages: is-extendable: 0.1.1 set-value: 2.0.1 + /unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + dependencies: + unique-slug: 2.0.2 + dev: false + + /unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + dependencies: + imurmurhash: 0.1.4 + dev: false + /unique-string@2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} dependencies: crypto-random-string: 2.0.0 + /universal-user-agent@6.0.0: + resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} + dev: false + /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -19671,6 +20338,10 @@ packages: is-weakset: 2.0.2 dev: true + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: false + /which-typed-array@1.1.9: resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} engines: {node: '>= 0.4'} @@ -19729,6 +20400,14 @@ packages: /workerpool@6.4.0: resolution: {integrity: sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A==} + /wrap-ansi@2.1.0: + resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} + engines: {node: '>=0.10.0'} + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + dev: false + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -19835,6 +20514,14 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + /y18n@3.2.2: + resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} + dev: false + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -19866,6 +20553,29 @@ packages: engines: {node: '>=12'} dev: true + /yargs-parser@9.0.2: + resolution: {integrity: sha512-CswCfdOgCr4MMsT1GzbEJ7Z2uYudWyrGX8Bgh/0eyCzj/DXWdKq6a/ADufkzI1WAOIW6jYaXJvRyLhDO0kfqBw==} + dependencies: + camelcase: 4.1.0 + dev: false + + /yargs@11.1.1: + resolution: {integrity: sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==} + dependencies: + cliui: 4.1.0 + decamelize: 1.2.0 + find-up: 2.1.0 + get-caller-file: 1.0.3 + os-locale: 3.1.0 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 2.1.1 + which-module: 2.0.1 + y18n: 3.2.2 + yargs-parser: 9.0.2 + dev: false + /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} diff --git a/test-packages/release/.gitignore b/test-packages/release/.gitignore new file mode 100644 index 000000000..2e2f15e2e --- /dev/null +++ b/test-packages/release/.gitignore @@ -0,0 +1,5 @@ +/node_modules +/src/**/*.js +/src/**/*.d.ts +/src/**/*.map + diff --git a/test-packages/release/package.json b/test-packages/release/package.json new file mode 100644 index 000000000..de36c8805 --- /dev/null +++ b/test-packages/release/package.json @@ -0,0 +1,28 @@ +{ + "name": "@embroider/release", + "version": "0.0.0", + "private": true, + "bin": { + "embroider-release": "./src/cli.js" + }, + "dependencies": { + "@ef4/lerna-changelog": "^1.0.4", + "@octokit/rest": "^19.0.8", + "@types/fs-extra": "^9.0.12", + "@types/js-yaml": "^4.0.5", + "@types/semver": "^7.3.6", + "@types/yargs": "^17.0.3", + "assert-never": "^1.2.1", + "chalk": "^4.1.1", + "cli-highlight": "^2.1.11", + "execa": "^4.0.3", + "fs-extra": "^10.0.0", + "globby": "^11.0.3", + "js-yaml": "^4.1.0", + "semver": "^7.3.5", + "yargs": "^17.0.1" + }, + "volta": { + "extends": "../../package.json" + } +} diff --git a/test-packages/release/src/change-parser.ts b/test-packages/release/src/change-parser.ts new file mode 100644 index 000000000..48e87c7e1 --- /dev/null +++ b/test-packages/release/src/change-parser.ts @@ -0,0 +1,123 @@ +export type Impact = 'major' | 'minor' | 'patch'; +export type UnlabeledSection = { unlabeled: true; summaryText: string }; +export type LabeledSection = { packages: string[]; impact: Impact; heading: string }; +export type Section = LabeledSection | UnlabeledSection; +export interface ParsedChangelog { + sections: Section[]; +} + +const knownSections: Record = { + ':boom: Breaking Change': { + impact: 'major', + }, + ':rocket: Enhancement': { + impact: 'minor', + }, + ':bug: Bug Fix': { + impact: 'patch', + }, + ':memo: Documentation': { + impact: 'patch', + }, + ':house: Internal': { + impact: 'patch', + }, + ':question: Unlabeled': { + unlabeled: true, + }, +}; + +const ignoredSections = [/Committers: \d+/]; + +function sectionHeading(line: string): string | undefined { + if (line.startsWith('#### ')) { + return line.slice(5); + } +} + +function stillWithinSection(lines: string[]): boolean { + return lines.length > 0 && !sectionHeading(lines[0]); +} + +function consumeSection(lines: string[]) { + let matchedLines = []; + while (stillWithinSection(lines)) { + matchedLines.push(lines.shift()); + } + return matchedLines; +} + +function parseSection(lines: string[]): Section | undefined { + let line = lines.shift(); + const heading = line ? sectionHeading(line) : undefined; + if (!heading) { + return; + } + + let sectionConfig = knownSections[heading]; + if (!sectionConfig) { + if (ignoredSections.some(pattern => pattern.test(heading))) { + consumeSection(lines); + return; + } + throw new Error(`unexpected section: ${heading}`); + } + + if ('unlabeled' in sectionConfig) { + return { unlabeled: true, summaryText: consumeSection(lines).join('\n') }; + } + + let packages = new Set(); + while (stillWithinSection(lines)) { + let packageList = parsePackageList(lines); + if (packageList) { + for (let pkg of packageList) { + packages.add(pkg); + } + } + } + return { + packages: [...packages], + impact: sectionConfig.impact, + heading, + }; +} + +function parsePackageList(lines: string[]): string[] | undefined { + let line = lines.shift(); + if (!line) { + return; + } + if (line === '* Other') { + return; + } + if (line.startsWith('* ')) { + let parts = line.slice(2).split(/,\s*/); + if (!parts.every(p => p.startsWith('`') && p.endsWith('`'))) { + throw new Error(`don't understanding this line: ${line}.`); + } + return parts.map(p => p.slice(1, -1)); + } +} + +export function parseChangeLog(src: string): ParsedChangelog { + let lines = src.split('\n'); + let sections = []; + while (lines.length > 0) { + let section = parseSection(lines); + if (section) { + sections.push(section); + } + } + return { sections }; +} + +export function parseChangeLogOrExit(src: string): ParsedChangelog { + try { + return parseChangeLog(src); + } catch (err) { + console.error(err); + console.error(`the full changelog that failed to parse was:\n${src}`); + process.exit(-1); + } +} diff --git a/test-packages/release/src/cli.ts b/test-packages/release/src/cli.ts new file mode 100644 index 000000000..433dd35bd --- /dev/null +++ b/test-packages/release/src/cli.ts @@ -0,0 +1,95 @@ +import yargs from 'yargs/yargs'; +import type { Argv } from 'yargs'; + +import { readFileSync } from 'fs'; +import { parseChangeLogOrExit } from './change-parser'; +import { publish } from './publish'; + +yargs(process.argv.slice(2)) + .usage( + `Most of the subcommands in here exist so you can easily test parts of the release process by themselves. To do an actual release, see RELEASE.md.` + ) + .scriptName('release') + .command( + 'prepare', + `Edits the package.json and changelog files to prepare for release.`, + yargs => fromStdin(yargs), + async function (opts) { + let { prepare } = await import('./prepare'); + let solution = await prepare(await newChangelogContent(opts)); + let { explain } = await import('./plan'); + process.stdout.write(explain(solution)); + process.stdout.write(`\nSuccessfully prepared released\n`); + } + ) + .command( + 'publish', + `Publishes an already-prepared released by tagging, pushing tags, creating GitHub release, and publishing to NPM.`, + yargs => + yargs.option('skipRepoSafetyCheck', { + type: 'boolean', + description: + 'Allows you to run "publish" even if there are uncommited changes in your repo. Useful only for developing "publish" itself.', + }), + async function (opts) { + await publish(opts); + } + ) + .command( + 'gather-changes', + `Uses lerna-changelog to build a description of all the PRs in the release.`, + yargs => yargs, + async function (/* opts */) { + let { gatherChanges } = await import('./gather-changes'); + process.stdout.write(await gatherChanges()); + } + ) + .command( + 'parse-changes', + `Parse the summary of changes into a structured format`, + yargs => fromStdin(yargs), + async function (opts) { + let { parseChangeLogOrExit } = await import('./change-parser'); + console.log(JSON.stringify(parseChangeLogOrExit(await newChangelogContent(opts)), null, 2)); + } + ) + .command( + 'discover-deps', + `Summarizes how all our published packages relate to each other`, + yargs => yargs, + async function (/* opts */) { + let { publishedInterPackageDeps } = await import('./interdep'); + console.log(publishedInterPackageDeps()); + } + ) + .command( + 'explain-plan', + `Explains which packages need to be released at what versions and why.`, + yargs => fromStdin(yargs), + async function (opts) { + let { planVersionBumps, explain } = await import('./plan'); + let solution = planVersionBumps(parseChangeLogOrExit(await newChangelogContent(opts))); + console.log(explain(solution)); + } + ) + .demandCommand() + .strictCommands() + .help().argv; + +function fromStdin(yargs: Argv) { + return yargs.option('fromStdin', { + type: 'boolean', + description: 'Read the summary of changes from stdin instead of building them from scratch.', + }); +} + +async function newChangelogContent(opts: { fromStdin: boolean | undefined }) { + let content: string; + if (opts.fromStdin) { + content = readFileSync(process.stdin.fd, 'utf8'); + } else { + let { gatherChanges } = await import('./gather-changes'); + content = await gatherChanges(); + } + return content; +} diff --git a/test-packages/release/src/gather-changes.ts b/test-packages/release/src/gather-changes.ts new file mode 100644 index 000000000..06c2d3f34 --- /dev/null +++ b/test-packages/release/src/gather-changes.ts @@ -0,0 +1,6 @@ +import execa from 'execa'; + +export async function gatherChanges() { + let result = await execa('pnpm', ['lerna-changelog', '--next-version', 'Release'], { cwd: __dirname }); + return result.stdout; +} diff --git a/test-packages/release/src/highlight.ts b/test-packages/release/src/highlight.ts new file mode 100644 index 000000000..957314907 --- /dev/null +++ b/test-packages/release/src/highlight.ts @@ -0,0 +1,13 @@ +import highlight from 'cli-highlight'; +import chalk from 'chalk'; + +export function highlightMarkdown(md: string): string { + return highlight(md, { + language: 'Markdown', + theme: { + section: chalk.blueBright, + string: chalk.hex('#0366d6'), + link: chalk.dim, + }, + }); +} diff --git a/test-packages/release/src/interdep.ts b/test-packages/release/src/interdep.ts new file mode 100644 index 000000000..bade2de48 --- /dev/null +++ b/test-packages/release/src/interdep.ts @@ -0,0 +1,58 @@ +import glob from 'globby'; +import { resolve } from 'path'; +import { readFileSync, readJSONSync } from 'fs-extra'; +import yaml from 'js-yaml'; + +export type Range = `workspace:${string}`; + +export interface PkgEntry { + version: string; + pkgJSONPath: string; + isDependencyOf: Map; + isPeerDependencyOf: Map; +} + +export function publishedInterPackageDeps(): Map { + let rootDir = resolve(__dirname, '..', '..', '..'); + let packages: Map = new Map(); + + let pkgJSONS: Map = new Map(); + + for (let pattern of (yaml.load(readFileSync(resolve(__dirname, '../../../pnpm-workspace.yaml'), 'utf8')) as any) + .packages) { + for (let dir of glob.sync(pattern, { cwd: rootDir, expandDirectories: false, onlyDirectories: true })) { + let pkgJSONPath = resolve(rootDir, dir, 'package.json'); + let pkg = readJSONSync(pkgJSONPath); + if (pkg.private) { + continue; + } + pkgJSONS.set(pkg.name, pkg); + packages.set(pkg.name, { + version: pkg.version, + pkgJSONPath, + isDependencyOf: new Map(), + isPeerDependencyOf: new Map(), + }); + } + } + + for (let [consumerName, consumerPkgJSON] of pkgJSONS) { + // no devDeps because changes to devDeps shouldn't ever force us to + // release + for (let section of ['dependencies', 'peerDependencies'] as const) { + if (consumerPkgJSON[section]) { + for (let [depName, depRange] of Object.entries(consumerPkgJSON[section] as Record)) { + if (depRange.startsWith('workspace:')) { + let dependency = packages.get(depName); + if (!dependency) { + throw new Error(`broken "workspace:" reference to ${depName} in ${consumerName}`); + } + let field = section === 'dependencies' ? ('isDependencyOf' as const) : ('isPeerDependencyOf' as const); + dependency[field].set(consumerName, depRange as Range); + } + } + } + } + } + return packages; +} diff --git a/test-packages/release/src/plan.ts b/test-packages/release/src/plan.ts new file mode 100644 index 000000000..7d10ee9db --- /dev/null +++ b/test-packages/release/src/plan.ts @@ -0,0 +1,241 @@ +import { Impact, ParsedChangelog } from './change-parser'; +import { publishedInterPackageDeps } from './interdep'; +import assertNever from 'assert-never'; +import { inc, satisfies } from 'semver'; +import { highlightMarkdown } from './highlight'; +import chalk from 'chalk'; +import { resolve } from 'path'; +import { existsSync, readJSONSync, writeJSONSync } from 'fs-extra'; + +export type Solution = Map< + string, + | { impact: undefined; oldVersion: string } + | { + impact: Impact; + oldVersion: string; + newVersion: string; + constraints: { impact: Impact; reason: string }[]; + pkgJSONPath: string; + } +>; + +class Plan { + #constraints: Map; + #pkgs: ReturnType; + + constructor() { + this.#pkgs = publishedInterPackageDeps(); + + // initialize constraints for every published package + let constraints = new Map(); + for (let pkg of this.#pkgs.keys()) { + constraints.set(pkg, []); + } + this.#constraints = constraints; + } + + addConstraint(packageName: string, impact: Impact, reason: string): void { + let pkgConstraints = this.#constraints.get(packageName); + if (!pkgConstraints) { + let err = new Error(`unknown package "${packageName}"`); + (err as any).unknownPackage = true; + throw err; + } + if (!pkgConstraints.some(existing => existing.impact === impact && existing.reason === reason)) { + pkgConstraints.push({ impact, reason }); + this.#propagate(packageName, impact); + } + } + + solve(): Solution { + let solution: Solution = new Map(); + for (let [pkgName, entry] of this.#pkgs) { + let constraints = this.#constraints.get(pkgName)!; + let impact = this.#sumImpact(constraints); + if (!impact) { + solution.set(pkgName, { impact: undefined, oldVersion: entry.version }); + } else { + let newVersion = inc(entry.version, impact)!; + solution.set(pkgName, { + impact, + oldVersion: entry.version, + newVersion, + constraints, + pkgJSONPath: entry.pkgJSONPath, + }); + } + } + return solution; + } + + #expandWorkspaceRange(range: `workspace:${string}`, availableVersion: string): string { + // this implements PNPM's rules for how workspace: protocol dependencies get + // expanded into proper semver ranges. + switch (range) { + case 'workspace:*': + return availableVersion; + case 'workspace:~': + return `~${availableVersion}`; + case 'workspace:^': + return `^${availableVersion}`; + default: + return range.slice(10); + } + } + + #propagate(packageName: string, impact: Impact) { + let entry = this.#pkgs.get(packageName)!; + let minNewVersion = inc(entry.version, impact)!; + for (let [consumerName, workspaceRange] of entry.isDependencyOf) { + this.#propagateDep(packageName, minNewVersion, 'dependencies', consumerName, workspaceRange); + } + for (let [consumerName, workspaceRange] of entry.isPeerDependencyOf) { + this.#propagateDep(packageName, minNewVersion, 'peerDependencies', consumerName, workspaceRange); + } + } + + #propagateDep( + packageName: string, + minNewVersion: string, + section: 'dependencies' | 'peerDependencies', + consumerName: string, + workspaceRange: `workspace:${string}` + ) { + let entry = this.#pkgs.get(packageName)!; + + let oldRange = this.#expandWorkspaceRange(workspaceRange, entry.version); + if (!satisfies(minNewVersion, oldRange)) { + switch (section) { + case 'dependencies': + this.addConstraint(consumerName, 'patch', `Has dependency ${'`'}${workspaceRange}${'`'} on ${packageName}`); + break; + case 'peerDependencies': + this.addConstraint( + consumerName, + 'major', + `Has peer dependency ${'`'}${workspaceRange}${'`'} on ${packageName}` + ); + break; + default: + throw assertNever(section); + } + } + } + + #sumImpact(impacts: { impact: Impact }[]): Impact | undefined { + if (impacts.some(i => i.impact === 'major')) { + return 'major'; + } + if (impacts.some(i => i.impact === 'minor')) { + return 'minor'; + } + if (impacts.some(i => i.impact === 'patch')) { + return 'patch'; + } + } +} + +function impactLabel(impact: Impact | undefined, text?: string) { + switch (impact) { + case undefined: + return chalk.gray(text); + case 'patch': + return chalk.blueBright(text); + case 'minor': + return chalk.greenBright(text); + case 'major': + return chalk.redBright(text); + } +} + +function capitalize(s: string): string { + return s[0].toUpperCase() + s.slice(1); +} + +export function explain(solution: Solution) { + let output: string[] = []; + + for (let priority of ['major', 'minor', 'patch'] as const) { + if ([...solution].some(entry => entry[1].impact === priority)) { + output.push(impactLabel(priority, capitalize(priority))); + output.push(''); + + for (let [pkgName, entry] of solution) { + if (entry.impact === priority) { + output.push(` ${impactLabel(entry.impact, pkgName)} from ${entry.oldVersion} to ${entry.newVersion}`); + for (let constraint of entry.constraints) { + if (constraint.impact === entry.impact) { + output.push(` - ${constraint.reason}`); + } + } + } + } + output.push(''); + } + } + + if ([...solution].some(entry => entry[1].impact === undefined)) { + output.push(impactLabel(undefined, 'Unreleased')); + output.push(''); + for (let [pkgName, entry] of solution) { + if (entry.impact === undefined) { + output.push(`## ${pkgName}`); + output.push(` ${impactLabel(entry.impact, pkgName)} unchanged`); + } + } + output.push(''); + } + + return output.join('\n'); +} + +export function planVersionBumps(changed: ParsedChangelog): Solution { + let plan = new Plan(); + for (let section of changed.sections) { + if ('unlabeled' in section) { + process.stderr.write( + highlightMarkdown( + `# Unlabeled Changes\n\n${section.summaryText}\n\n*Cannot plan release until the above changes are labeled*.\n` + ) + ); + process.exit(-1); + } + + for (let pkg of section.packages) { + plan.addConstraint(`@embroider/${pkg}`, section.impact, `Appears in changelog section ${section.heading}`); + } + } + + return plan.solve(); +} + +function solutionFile(): string { + return resolve(__dirname, '..', '..', '..', '.release-plan.json'); +} + +export function saveSolution(solution: Solution, description: string): void { + writeJSONSync(solutionFile(), { solution: Object.fromEntries(solution), description }, { spaces: 2 }); +} + +export function loadSolution(): { solution: Solution; description: string } { + try { + if (!existsSync(solutionFile())) { + let err = new Error(`No such file ${solutionFile()}`); + (err as any).code = 'ENOENT'; + throw err; + } + let json = readJSONSync(solutionFile()); + return { + solution: new Map(Object.entries(json.solution)), + description: json.description, + }; + } catch (err) { + process.stderr.write( + `Unable to load release plan file. You must run "embroider-release prepare" first to create the file.\n` + ); + if (err.code !== 'ENOENT') { + console.error(err); + } + process.exit(-1); + } +} diff --git a/test-packages/release/src/prepare.ts b/test-packages/release/src/prepare.ts new file mode 100644 index 000000000..6b4659054 --- /dev/null +++ b/test-packages/release/src/prepare.ts @@ -0,0 +1,53 @@ +import { parseChangeLogOrExit } from './change-parser'; +import { readFileSync, writeFileSync } from 'fs'; +import { resolve } from 'path'; +import { planVersionBumps, saveSolution, Solution } from './plan'; +import { readJSONSync, writeJSONSync } from 'fs-extra'; + +const changelogPreamble = `# Embroider Changelog +`; + +function updateChangelog(newChangelogContent: string, solution: Solution): string { + let targetChangelogFile = resolve(__dirname, '..', '..', '..', 'CHANGELOG.md'); + let oldChangelogContent = readFileSync(targetChangelogFile, 'utf8'); + if (!oldChangelogContent.startsWith(changelogPreamble)) { + process.stderr.write(`Cannot parse existing changelog. Expected it to start with:\n${changelogPreamble}`); + process.exit(-1); + } + oldChangelogContent = oldChangelogContent.slice(changelogPreamble.length); + + let [firstNewLine, ...restNewLines] = newChangelogContent.trim().split('\n'); + + let newOutput = firstNewLine + '\n\n' + versionSummary(solution) + '\n' + restNewLines.join('\n') + '\n'; + writeFileSync(targetChangelogFile, changelogPreamble + '\n' + newOutput + oldChangelogContent); + return newOutput; +} + +function versionSummary(solution: Solution): string { + let result: string[] = []; + for (let [pkgName, entry] of solution) { + if (entry.impact) { + result.push(`${pkgName} ${entry.newVersion} (${entry.impact})`); + } + } + return result.join('\n'); +} + +function updateVersions(solution: Solution) { + for (let entry of solution.values()) { + if (entry.impact) { + let pkg = readJSONSync(entry.pkgJSONPath); + pkg.version = entry.newVersion; + writeJSONSync(entry.pkgJSONPath, pkg, { spaces: 2 }); + } + } +} + +export async function prepare(newChangelogContent: string) { + let changes = parseChangeLogOrExit(newChangelogContent); + let solution = planVersionBumps(changes); + updateVersions(solution); + let description = updateChangelog(newChangelogContent, solution); + saveSolution(solution, description); + return solution; +} diff --git a/test-packages/release/src/publish.ts b/test-packages/release/src/publish.ts new file mode 100644 index 000000000..14d7a2f8d --- /dev/null +++ b/test-packages/release/src/publish.ts @@ -0,0 +1,130 @@ +import execa from 'execa'; +import { loadSolution, Solution } from './plan'; +import { dirname } from 'path'; +import { Octokit } from '@octokit/rest'; + +async function hasCleanRepo(): Promise { + let result = await execa('git', ['status', '--porcelain=v1'], { cwd: __dirname }); + return result.stdout.length === 0; +} + +function tagFor(pkgName: string, entry: { newVersion: string }): string { + return `v${entry.newVersion}-${pkgName.replace(/^@embroider\//, '')}`; +} + +class IssueReporter { + hadIssues = false; + reportFailure(message: string): void { + this.hadIssues = true; + process.stderr.write(message); + } +} + +async function makeTags(solution: Solution, reporter: IssueReporter): Promise { + for (let [pkgName, entry] of solution) { + if (!entry.impact) { + continue; + } + try { + await execa('git', ['tag', tagFor(pkgName, entry)], { + cwd: dirname(entry.pkgJSONPath), + stderr: 'inherit', + stdout: 'inherit', + }); + } catch (err) { + reporter.reportFailure(`Failed to create tag for ${pkgName}`); + } + } +} + +async function push(reporter: IssueReporter) { + try { + await execa('git', ['push', '--tags'], { cwd: __dirname }); + } catch (err) { + reporter.reportFailure(`Failed to git push`); + } +} + +function chooseRepresentativeTag(solution: Solution): string { + for (let [pkgName, entry] of solution) { + if (entry.impact) { + return tagFor(pkgName, entry); + } + } + process.stderr.write('Found no releaseable packages in the plan'); + process.exit(-1); +} + +async function createGithubRelease( + octokit: Octokit, + description: string, + tagName: string, + reporter: IssueReporter +): Promise { + try { + await octokit.repos.createRelease({ + owner: 'embroider-build', + repo: 'embroider', + tag_name: tagName, + body: description, + }); + } catch (err) { + console.error(err); + reporter.reportFailure(`Problem while creating GitHub release`); + } +} + +async function pnpmPublish(solution: Solution, reporter: IssueReporter): Promise { + for (let [pkgName, entry] of solution) { + if (!entry.impact) { + continue; + } + try { + await execa('pnpm', ['publish', '--access=public'], { + cwd: dirname(entry.pkgJSONPath), + stderr: 'inherit', + stdout: 'inherit', + }); + } catch (err) { + reporter.reportFailure(`Failed to pnpm publish ${pkgName}`); + } + } +} + +export async function publish(opts: { skipRepoSafetyCheck?: boolean }) { + if (!opts.skipRepoSafetyCheck) { + if (!(await hasCleanRepo())) { + process.stderr.write(`You have uncommitted changes. +To publish a release you should start from a clean repo. Run "embroider-release prepare", then commit the changes, then come back and run "embroider-release publish. +`); + process.exit(-1); + } + } + + let { solution, description } = loadSolution(); + + if (!process.env.GITHUB_AUTH) { + process.stderr.write(`You need to set GITHUB_AUTH.`); + process.exit(-1); + } + let octokit = new Octokit({ auth: process.env.GITHUB_AUTH }); + + let representativeTag = chooseRepresentativeTag(solution); + + // from this point forward we don't stop if something goes wrong, we just keep + // track of whether anything went wrong so we can use the right exit code at + // the end. + let reporter = new IssueReporter(); + + await makeTags(solution, reporter); + await push(reporter); + await createGithubRelease(octokit, description, representativeTag, reporter); + await pnpmPublish(solution, reporter); + + if (reporter.hadIssues) { + process.stderr.write(`\nSome parts of the release were unsuccessful.\n`); + process.exit(-1); + } else { + process.stdout.write(`\nSuccessfully published release\n`); + } +} diff --git a/tests/fixtures/package.json b/tests/fixtures/package.json index 3ebf291d2..807cb85d6 100644 --- a/tests/fixtures/package.json +++ b/tests/fixtures/package.json @@ -1,3 +1,4 @@ { - "name": "@embroider/test-fixtures" + "name": "@embroider/test-fixtures", + "private": true } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 0896d4e0b..3ef815899 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "./packages/*/src/**/*.ts", "./packages/*/tests/**/*.ts", "./test-packages/support/**/*.ts", + "./test-packages/release/src/**/*.ts", "./tests/scenarios/**/*.ts" ], "compilerOptions": { diff --git a/types/broccoli-file-creator/package.json b/types/broccoli-file-creator/package.json index e66dcf365..21e11207f 100644 --- a/types/broccoli-file-creator/package.json +++ b/types/broccoli-file-creator/package.json @@ -1,3 +1,4 @@ { - "name": "@types/broccoli-file-creator" + "name": "@types/broccoli-file-creator", + "private": true } \ No newline at end of file diff --git a/types/broccoli-merge-trees/package.json b/types/broccoli-merge-trees/package.json index fe8d49e09..d28f4d006 100644 --- a/types/broccoli-merge-trees/package.json +++ b/types/broccoli-merge-trees/package.json @@ -1,3 +1,4 @@ { - "name": "@types/broccoli-merge-trees" + "name": "@types/broccoli-merge-trees", + "private": true } \ No newline at end of file diff --git a/types/broccoli/package.json b/types/broccoli/package.json index e38612434..c5aac104c 100644 --- a/types/broccoli/package.json +++ b/types/broccoli/package.json @@ -1,3 +1,4 @@ { - "name": "@types/broccoli" + "name": "@types/broccoli", + "private": true } \ No newline at end of file diff --git a/types/console-ui/package.json b/types/console-ui/package.json index 9b9151fba..67b431156 100644 --- a/types/console-ui/package.json +++ b/types/console-ui/package.json @@ -1,3 +1,4 @@ { - "name": "@types/console-ui" + "name": "@types/console-ui", + "private": true } \ No newline at end of file diff --git a/types/ember-cli/package.json b/types/ember-cli/package.json index cf17ad920..42cdf8724 100644 --- a/types/ember-cli/package.json +++ b/types/ember-cli/package.json @@ -1,3 +1,4 @@ { - "name": "@types/ember-cli" + "name": "@types/ember-cli", + "private": true } \ No newline at end of file diff --git a/types/fast-sourcemap-concat/package.json b/types/fast-sourcemap-concat/package.json index 193f7bd51..03cbac1b7 100644 --- a/types/fast-sourcemap-concat/package.json +++ b/types/fast-sourcemap-concat/package.json @@ -1,3 +1,4 @@ { - "name": "@types/fast-sourcemap-concat" + "name": "@types/fast-sourcemap-concat", + "private": true } \ No newline at end of file diff --git a/types/source-map-url/package.json b/types/source-map-url/package.json index 03db6f81b..b8253e069 100644 --- a/types/source-map-url/package.json +++ b/types/source-map-url/package.json @@ -1,3 +1,4 @@ { - "name": "@types/source-map-url" + "name": "@types/source-map-url", + "private": true } \ No newline at end of file diff --git a/types/thread-loader/package.json b/types/thread-loader/package.json index 2dc756cf3..b87abeb23 100644 --- a/types/thread-loader/package.json +++ b/types/thread-loader/package.json @@ -1,3 +1,4 @@ { - "name": "@types/thread-loader" + "name": "@types/thread-loader", + "private": true } \ No newline at end of file