diff --git a/.changelogrc.js b/.changelogrc.js deleted file mode 100644 index b116ddc..0000000 --- a/.changelogrc.js +++ /dev/null @@ -1,215 +0,0 @@ -'use strict'; -// ? See https://github.com/conventional-changelog/conventional-changelog - -const debug = require('debug')( - `${require('./package.json').name}:conventional-changelog-config` -); - -const semver = require('semver'); -const execa = require('execa'); - -// ? Commit types that trigger releases by default (using angular configuration) -// ? See https://github.com/semantic-release/commit-analyzer/blob/master/lib/default-release-rules.js -const DEFAULT_RELEASED_TYPES = ['feat', 'fix', 'perf']; - -// ? Same options as commit-analyzer's releaseRules (see -// ? https://github.com/semantic-release/commit-analyzer#releaserules) with the -// ? addition of the `title` property to set the resulting section title -const ADDITIONAL_RELEASE_RULES = [ - { type: 'build', release: 'patch', title: 'Build System' } -]; - -const changelogTitle = - `# Changelog\n\n` + - `All notable changes to this project will be documented in this file.\n\n` + - `The format is based on [Conventional Commits](https://conventionalcommits.org),\n` + - `and this project adheres to [Semantic Versioning](https://semver.org).`; - -// ? Strings in commit messages that, when found, are skipped -// ! These also have to be updated in build-test-deploy.yml and cleanup.yml -const SKIP_COMMANDS = '[skip ci], [ci skip], [skip cd], [cd skip]'.split(', '); - -debug('SKIP_COMMANDS:', SKIP_COMMANDS); - -// ! XXX: dark magic to synchronously deal with this async package -// TODO: XXX: fork this package and offer a sync export instead of this dark magic -let wait; -try { - wait = execa.sync('node', [ - '-e', - 'require("conventional-changelog-angular").then(o => console.log(o.writerOpts.transform.toString()));' - ]).stdout; -} catch (e) { - throw new Error(`failed to acquire angular transformation: ${e}`); -} - -const transform = Function(`"use strict";return (${wait})`)(); -const sentenceCase = (s) => s.toString().charAt(0).toUpperCase() + s.toString().slice(1); - -const extraReleaseTriggerCommitTypes = ADDITIONAL_RELEASE_RULES.map((r) => r.type); -const allReleaseTriggerCommitTypes = [ - DEFAULT_RELEASED_TYPES, - extraReleaseTriggerCommitTypes -].flat(); - -debug('extra types that trigger releases: %O', extraReleaseTriggerCommitTypes); -debug('all types that trigger releases: %O', allReleaseTriggerCommitTypes); - -// ? Releases made before this repo adopted semantic-release. They will be -// ? collected together under a single header -const legacyReleases = []; -let shouldGenerate = true; - -module.exports = { - changelogTitle, - additionalReleaseRules: ADDITIONAL_RELEASE_RULES.map(({ title, ...r }) => r), - parserOpts: { - mergePattern: /^Merge pull request #(\d+) from (.*)$/, - mergeCorrespondence: ['id', 'source'], - noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'], - // eslint-disable-next-line no-console - warn: console.warn.bind(console) - }, - writerOpts: { - generateOn: (commit) => { - const decision = - shouldGenerate === 'always' || - (shouldGenerate && - !!semver.valid(commit.version) && - !semver.prerelease(commit.version)); - debug(`::generateOn shouldGenerate: ${shouldGenerate} [decision: ${decision}]`); - shouldGenerate = true; - return decision; - }, - transform: (commit, context) => { - const version = commit.version || null; - const firstRelease = version === context.gitSemverTags?.slice(-1)[0]?.slice(1); - - debug('::transform encountered commit: %O', commit); - debug(`::transform commit version: ${version}`); - debug(`::transform commit firstRelease: ${firstRelease}`); - - if (commit.revert) { - debug('::transform coercing to type "revert"'); - commit.type = 'revert'; - } else if (commit.type == 'revert') { - debug('::transform ignoring malformed revert commit'); - return null; - } - - commit.originalType = commit.type; - - if (!firstRelease || commit.type) { - // ? This commit does not have a type, but has a version. It must be a - // ? legacy release! - if (version && !commit.type) { - debug('::transform determined commit is legacy release'); - legacyReleases.push(commit); - commit = null; - shouldGenerate = false; - } else { - let fakeFix = false; - - if (extraReleaseTriggerCommitTypes.includes(commit.type)) { - debug(`::transform encountered custom commit type: ${commit.type}`); - commit.type = 'fix'; - fakeFix = true; - } - - commit = transform(commit, context); - - debug('::transform angular transformed commit: %O', commit); - - if (commit) { - if (fakeFix) { - commit.type = ADDITIONAL_RELEASE_RULES.find( - (r) => r.type == commit.originalType - )?.title; - debug('::transform debug: %O', ADDITIONAL_RELEASE_RULES); - debug(`::transform commit type set to custom title: ${commit.type}`); - } else commit.type = sentenceCase(commit.type); - - // ? Ignore any commits with skip commands in them - if (SKIP_COMMANDS.some((cmd) => commit.subject?.includes(cmd))) { - debug(`::transform saw skip command in commit message; commit skipped`); - return null; - } - - if (commit.subject) { - // ? Make scope-less commit subjects sentence case in the - // ? changelog per my tastes - if (!commit.scope) commit.subject = sentenceCase(commit.subject); - - // ? Italicize reverts per my tastes - if (commit.originalType == 'revert') commit.subject = `*${commit.subject}*`; - } - - // ? For breaking changes, make all scopes and subjects bold. - // ? Scope-less subjects are made sentence case. All per my - // ? tastes - commit.notes.forEach((note) => { - if (note.text) { - debug('::transform saw BC notes for this commit'); - const [firstLine, ...remainder] = note.text.trim().split('\n'); - note.text = - `**${!commit.scope ? sentenceCase(firstLine) : firstLine}**` + - remainder.reduce((result, line) => `${result}\n${line}`, ''); - } - }); - } - } - } - - // ? If this is the commit representing the earliest release (and there - // ? are legacy releases), use this commit to report collected legacy - // ? releases - else { - debug('::transform generating summary legacy release commit'); - shouldGenerate = 'always'; - - const getShortHash = (h) => h.substring(0, 7); - const shortHash = getShortHash(commit.hash); - const url = context.repository - ? `${context.host}/${context.owner}/${context.repository}` - : context.repoUrl; - - const subject = legacyReleases - .reverse() - .map(({ hash, version }) => ({ - url: `[${getShortHash(hash)}](${url}/commit/${hash})`, - version - })) - .reduce( - (subject, { url, version }) => `Version ${version} (${url})\n\n- ${subject}`, - `Version ${commit.version}` - ); - - commit = { - type: null, - scope: null, - subject, - id: null, - source: null, - merge: null, - header: null, - body: null, - footer: null, - notes: [], - references: [], - mentions: [], - revert: null, - hash: commit.hash, - shortHash, - gitTags: null, - committerDate: 'pre-CI/CD', - version: 'Archived Releases' - }; - } - - debug('::transform final commit: %O', commit); - return commit; - } - } -}; - -debug('exports: %O', module.exports); diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md index fe51f08..a94a69a 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -4,17 +4,14 @@ about: Alert us about an issue labels: bug --- -
Problematic behavior + + +
The problem
@@ -22,43 +19,59 @@ problem simply and in as few lines of code as possible!
Reproduction steps +🚩 Required (2 of 2): please replace this comment with a link to a repo +demonstrating your issue *using as few lines of code as possible*. If we can't +reproduce the problem on our side, how can we ever hope to fix it for you 🤷🏾? + +If your issue is simple enough that it doesn't warrant a demo repo, include +instead the simplest most basic possible steps to reproduce your problem; e.g.: + +1. Clone the dummy repo I made based on the docs example: https://github.com/... +2. Run `npm install` +3. Run `npx jest` +4. See error "xyz" at test 2, which shouldn't be happening + -->
+ + + +Optional: uncomment this block and replace this text with any additional +information that might help us figure out what's going on. This could be dense +runtime details, lengthy error logs, assets links, or what have you; e.g.: + +- OS: ubuntu 26.04 +- Node version: 20 +- Babel: yes, version 8.1.0 +- TypeScript: yes, version 5.2.0 +- Browser: firefox 171, chrome 190 +- List of installed packages: https://github.com/.../main/package.json + +Relevant log lines: +``` +(super long error log lines pasted here) +```
+--> diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md index 1bd3eb8..e699b28 100644 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -4,33 +4,23 @@ about: Tell us about your awesome idea labels: enhancement --- + + -### The solution - +
Alternatives and workarounds -### Alternatives considered - - - -
Additional context - - +For posterity, uncomment this block and replace this text with a clear and +concise description of any alternative solutions you've encountered or any +temporary workarounds you've come up with.
+--> diff --git a/.gitignore b/.gitignore index 15e71c5..970b82b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ *.ignore *.ignore.* ignore.* +/dist /build /.vscode /.vercel /.env /external-scripts/bin +/next-env.d.ts /node_modules /coverage diff --git a/.spellcheckignore b/.spellcheckignore new file mode 100644 index 0000000..e69de29 diff --git a/.vercelignore b/.vercelignore index 1570bfe..2cecbe8 100644 --- a/.vercelignore +++ b/.vercelignore @@ -11,12 +11,11 @@ !/types # Re-add root-level files -!/babel.config.js -!/.changelogrc.js !/.gitignore +!/babel.config.js !/next.config.js -!/package.json !/package-lock.json +!/package.json !/tsconfig.json # Custom adds diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a6b30b6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,191 @@ +# Contributing + +Hi there! First off, we're thrilled 🤩 you want contribute to this project! + +First time contributor to a GitHub project? If you could use some help getting +started, [take a look at this quick and easy guide][1]. 💜 + +## Briefly: Submitting a Pull Request (PR) + +> See also: [CODE_OF_CONDUCT.md][2] + +This repository uses a [fully automated][3] [continuous linting][4] (CL), +[integration testing][5] (CI), and [deployment][5] (CD) +[semantic-release][6]-based pipeline for integrating PRs and publishing +releases. The nice thing about a fully automated CL/CI/CD pipeline is that +anyone anywhere can make a contribution quickly and with minimal tedium all +around! + +This repository makes extensive use of [debug][7] (through [rejoinder][8]). +Should you wish to view all possible debugging output, [export `DEBUG='*'`][9]. +To get debugging output for just this project's components, [export +`DEBUG='next-test-api-route-handler:*'`][9]. + +The ideal contributor flow is as follows: + +1. [Fork][10] this repository and [clone it locally][11]. +2. Configure and install dependencies with `npm ci`. + - You use `npm ci` here instead of `npm install` to [prevent unnecessary + updates to `package.json` and `package-lock.json`][12], but if it makes + more sense to use `npm install` feel free to use that instead. + - If `.env.example` exists, consider copying it to `.env` and configuring + sensible defaults. + - If you're using `npm@<=6`, you'll need to install any [peer + dependencies][13] manually. If you're using `npm@>=7`, you may have to + [forcefully][14] allow peer deps to be satisfied by custom forks of + certain packages. +3. Before making any changes, ensure all unit tests are passing with + `npm run test`. +4. _(optional but recommended)_ Create a new branch, usually off `main`. + - Example: `git checkout -b contrib-feature-1` +5. Make your changes and commit. Thanks to CL, your work will be checked as you + commit it; any problems will abort the commit attempt + - Ensure any new tests still pass even when the `DEBUG` environment variable + is defined. + - Various [import aliases][24] are available in some projects. Check the + [tsconfig.json][25] `"paths"` key to see which if any aliases this project + supports. +6. Push your commits to your fork and, when you're ready, [_fearlessly_ submit + your PR][15]! Your changes will be tested in our CI pipeline. +7. Pat yourself on the back! Your hard work is well on its way to being + reviewed and, if everything looks good, merged and released 🚀 + +Additionally, there are a few things you can do to increase the likelihood your +PR passes review: + +- **Do** [open an issue][16] and discuss your proposed changes (to prevent + wasting your valuable time, e.g. _maybe we're already working on a fix!_), and + [search][17] to see if there are any existing issues related to your concerns +- **Do** practice [atomic committing][18] +- **Do not** reduce code coverage ([codecov][19] checks are performed during CI) +- **Do** [follow convention][20] when coming up with your commit messages +- **Do not** circumvent CL, i.e. automated pre-commit linting, formatting, and + unit testing +- **Do** ensure `README.md` and other documentation that isn't autogenerated is + kept consistent with your changes +- **Do not** create a PR to introduce [_purely_ cosmetic commits][21] + - Code de-duplication and other potential optimizations we **do not** consider + _purely_ cosmetic 🙂 +- **Do** ensure your tests still pass in the presence of the `DEBUG` environment + variable +- **Do** keep your PR as narrow and focused as possible + - If you ran `npm install` instead of `npm ci` and it updated `package.json` + or `package-lock.json` and those updates have nothing to do with your PR + (e.g. random nested deps were updated), **do not** stage changes to those + files + - If there are multiple related changes to be made but (1) they do not + immediately depend on one another or (2) one implements extended/alternative + functionality based on the other, consider submitting them as separate PRs + instead 👍🏿 + +> Be aware: all contributions to this project, regardless of committer, origin, +> or context and immediately upon push to this repository, are [released][22] in +> accordance with [this project's license][23]. + +At this point, you're ready to create your PR and ✨ contribute ✨! + +## NPM Scripts + +This repo ships with several [NPM scripts][49]. Use `npm run list-tasks` to see +which of the following scripts are available for this project. + +> Using these scripts requires a linux-like development environment. None of the +> scripts are likely to work on non-POSIX environments. If you're on Windows, +> use [WSL][50]. + +### Developing + +- `npm run dev` to start a development server or instance +- `npm run lint` to run a project-wide type check (handled by CL/CI) +- `npm run test` (or `npm test`, `npm run test-unit`) to run the unit tests + (handled by CL/CI) + - Also [gathers test coverage data][51] as HTML files (under `coverage/`) + - Can also run `npm run test-integration` to run all the integration tests +- `npm run test-integration-node` to run integration tests on the last three LTS + Node versions (handled by CI) +- `npm run test-integration-client` to run client (browser/cli/etc) integration + tests with [puppeteer][52] (handled by CI) +- `npm run test-integration-webpack` to run tests verifying the distributable + can be bundled with Webpack 5 (as both ESM and CJS) (handled by CI) +- `npm run test-integration-externals` to run tests on compiled external + executables (under `external-scripts/bin/`) (handled by CI) + +#### Other Development Scripts + +- `npm run test-repeat` to run the entire test suite 100 times + - Good for spotting bad async code and heisenbugs +- `npm run generate` to transpile config files (under `config/`) from scratch +- `npm run regenerate` to quickly re-transpile config files (under `config/`) +- `npm run postinstall` to (re-)install [Husky Git hooks][53] if not in a CI + environment (handled by NPM) + +### Building and Deploying + +- `npm run build` (alias: `npm run build-dist`) to compile `src/` into `dist/` + (or `build/`), which is what ships to production (handled by CI/CD) +- `npm run format` to run source formatting over the codebase (handled by + CL/CI/CD) +- `npm run start` to deploy a _local production mode_ instance +- `npm run deploy` to deploy to production (bring your own auth tokens) (handled + by CD) + +#### Other Build Scripts + +- `npm run clean` to delete all build process artifacts (except `node_modules/`) +- `npm run build-changelog` to re-build the changelog (handled by CI/CD) + - You can run this as `CHANGELOG_SKIP_TITLE=true npm run build-changelog` to + skip prepending the header +- `npm run build-docs` to re-build the documentation (handled by CI/CD) +- `npm run build-externals` to compile `external-scripts/` into + `external-scripts/bin/` +- `npm run build-stats` to gather statistics about Webpack (look for + `bundle-stats.ignore.json`) + +### NPX Scripts + +> These commands might be installed as a project dependency but are expected to +> be run using [`npx X`][54] instead of `npm run X` regardless. + +- `npx npm-force-resolutions` to forcefully patch security audit problems + (rarely necessary) +- `npx semantic-release -d` to run the CD pipeline locally (in [dry-run + mode][55]) + +[1]: https://www.dataschool.io/how-to-contribute-on-github +[2]: /.github/CODE_OF_CONDUCT.md +[3]: https://github.com/features/actions +[4]: https://github.com/Xunnamius/next-test-api-route-handler/tree/main/.husky +[5]: .github/workflows/build-test.yml +[6]: https://github.com/semantic-release/semantic-release#readme +[7]: https://www.npmjs.com/package/debug +[8]: https://www.npmjs.com/package/rejoinder +[9]: https://www.npmjs.com/package/debug#wildcards +[10]: https://github.com/Xunnamius/next-test-api-route-handler/fork +[11]: + https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/cloning-a-repository +[12]: https://docs.npmjs.com/cli/v6/commands/npm-ci +[13]: + https://docs.npmjs.com/cli/v6/configuring-npm/package-json#peerdependencies +[14]: + https://docs.npmjs.com/cli/v7/commands/npm-install#configuration-options-affecting-dependency-resolution-and-tree-design +[15]: https://github.com/Xunnamius/next-test-api-route-handler/compare +[16]: https://github.com/Xunnamius/next-test-api-route-handler/issues/new/choose +[17]: https://github.com/Xunnamius/next-test-api-route-handler/issues?q= +[18]: https://www.codewithjason.com/atomic-commits-testing/ +[19]: https://about.codecov.io/ +[20]: https://www.conventionalcommits.org/en/v1.0.0/#summary +[21]: https://github.com/rails/rails/pull/13771#issuecomment-32746700 +[22]: + https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license +[23]: LICENSE +[49]: https://docs.npmjs.com/cli/v6/commands/npm-run-script +[50]: https://docs.microsoft.com/en-us/windows/wsl/install-win10 +[51]: https://jestjs.io/docs/en/cli.html#--coverageboolean +[52]: https://github.com/puppeteer/puppeteer +[53]: https://github.com/typicode/husky +[54]: https://www.npmjs.com/package/npx +[55]: + https://semantic-release.gitbook.io/semantic-release/usage/configuration#dryrun +[24]: + https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping +[25]: tsconfig.json diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..04bfe3a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security ☠️ [![Known Vulnerabilities][2]][1] + +If the issue is related to a public alert from OWASP/GitHub/Dependabot/CVE/etc +and [does not already have an open issue][3], feel free to [open a new +issue][4]. Otherwise, please report any security vulnerability, other +security-related incident, or otherwise sensitive subject to us [via email][5]. + +Thank you for your contribution! + +[1]: https://snyk.io/test/github/Xunnamius/next-test-api-route-handler +[2]: https://snyk.io/test/github/Xunnamius/next-test-api-route-handler/badge.svg +[3]: https://github.com/Xunnamius/next-test-api-route-handler/issues?q= +[4]: https://github.com/Xunnamius/next-test-api-route-handler/issues/new/choose +[5]: + mailto:security@ergodark.com?subject=ALERT%3A%20SECURITY%20INCIDENT%3A%20%28five%20word%20summary%29 diff --git a/babel.config.js b/babel.config.js index 0d13419..f128074 100644 --- a/babel.config.js +++ b/babel.config.js @@ -45,7 +45,14 @@ module.exports = { plugins: [ '@babel/plugin-proposal-export-default-from', '@babel/plugin-proposal-function-bind', - '@babel/plugin-transform-typescript' + '@babel/plugin-transform-typescript', + // ? Interoperable named CJS imports for free + [ + 'transform-default-named-imports', + { + exclude: [/^next([/?#].+)?/, /^mongodb([/?#].+)?/] + } + ] ], // ? Sub-keys under the "env" config key will augment the above // ? configuration depending on the value of NODE_ENV and friends. Default @@ -85,7 +92,7 @@ module.exports = { presets: [ ['@babel/preset-env', { targets: { node: true } }], ['@babel/preset-typescript', { allowDeclareFields: true }] - // ? Webpack will handle minification + // ? Minification is handled by Webpack ] } } diff --git a/commitlint.config.js b/commitlint.config.js index 2877826..73f7aaf 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -10,14 +10,17 @@ module.exports = { 'always', [ 'feat', + 'feature', 'fix', + 'perf', + 'revert', + 'build', 'docs', 'style', 'refactor', 'test', - 'revert', - 'debug', - 'build', + 'ci', + 'cd', 'chore' ] ] diff --git a/conventional.config.js b/conventional.config.js new file mode 100644 index 0000000..eb01d6a --- /dev/null +++ b/conventional.config.js @@ -0,0 +1,4 @@ +'use strict'; +module.exports = require('@xunnamius/conventional-changelog-projector')({ + // * Your customizations here +}); diff --git a/jest.config.js b/jest.config.js index f86250c..90d6acd 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,7 +6,7 @@ module.exports = { testEnvironment: 'node', testRunner: 'jest-circus/runner', // ? 1 hour so MMS and other tools don't choke during debugging - testTimeout: 3600000, + testTimeout: 60000, verbose: false, testPathIgnorePatterns: ['/node_modules/'], // ! If changed, also update these aliases in tsconfig.json, diff --git a/package-lock.json b/package-lock.json index 100f553..69feb61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "babel-jest": "^27.0.6", "babel-loader": "^8.2.2", "babel-plugin-explicit-exports-references": "^1.0.1", + "babel-plugin-transform-default-named-imports": "^1.0.9", "clone-deep": "^4.0.1", "confusing-browser-globals": "^1.0.10", "conventional-changelog-cli": "^2.1.1", @@ -120,7 +121,7 @@ "webpack-node-externals": "^3.0.0" }, "engines": { - "node": ">=12.x" + "node": ">=12" } }, "node_modules/@babel/cli": { @@ -5392,6 +5393,20 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/babel-plugin-transform-default-named-imports": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-default-named-imports/-/babel-plugin-transform-default-named-imports-1.0.9.tgz", + "integrity": "sha512-1ck8vBMMo4o05zpNuOd67EHNeDgGKDsEHIbOc9dsGd1Ugo+LPZ7azZ7lQOJg/Nva6vzaJhs5aL5QEJIZU9CF4g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.13", + "@babel/types": "^7.12.13", + "webpack-node-module-types": "^1.0.6" + }, + "engines": { + "node": ">= 12.x" + } + }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -25083,6 +25098,15 @@ "node": ">=6" } }, + "node_modules/webpack-node-module-types": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/webpack-node-module-types/-/webpack-node-module-types-1.0.7.tgz", + "integrity": "sha512-Bii2Fi6mQ4IwBQg7VNaWFX8qWnTZ5YeEcj3pzxmfYDBz70T2qQvkQcT/yoOgnROkWmzD81R77e1BJfHit41jRQ==", + "dev": true, + "engines": { + "node": ">= 12.x" + } + }, "node_modules/webpack-sources": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.0.tgz", @@ -29419,6 +29443,17 @@ "@babel/helper-define-polyfill-provider": "^0.2.2" } }, + "babel-plugin-transform-default-named-imports": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-default-named-imports/-/babel-plugin-transform-default-named-imports-1.0.9.tgz", + "integrity": "sha512-1ck8vBMMo4o05zpNuOd67EHNeDgGKDsEHIbOc9dsGd1Ugo+LPZ7azZ7lQOJg/Nva6vzaJhs5aL5QEJIZU9CF4g==", + "dev": true, + "requires": { + "@babel/core": "^7.12.13", + "@babel/types": "^7.12.13", + "webpack-node-module-types": "^1.0.6" + } + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -44344,6 +44379,12 @@ "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", "dev": true }, + "webpack-node-module-types": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/webpack-node-module-types/-/webpack-node-module-types-1.0.7.tgz", + "integrity": "sha512-Bii2Fi6mQ4IwBQg7VNaWFX8qWnTZ5YeEcj3pzxmfYDBz70T2qQvkQcT/yoOgnROkWmzD81R77e1BJfHit41jRQ==", + "dev": true + }, "webpack-sources": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.0.tgz", diff --git a/package.json b/package.json index 1ebf094..2496585 100644 --- a/package.json +++ b/package.json @@ -12,21 +12,21 @@ "author": "Xunnamius", "type": "commonjs", "scripts": { + "dev": "next -p `npx -q acquire-port`", + "start": "next start", "__test-repeat-unit": "echo 'Repeating test suite [initializing]...'; (i=0; while [ \"$((( i += 1 ) <= 100 ))\" -ne 0 ]; do sleep 0.1 && echo \"\\r\\033[1A\\033[0KRepeating test suite [run $i/100]...\" && JEST_SILENT_REPORTER_SHOW_WARNINGS=true BABEL_ENV=test npx jest --reporters=jest-silent-reporter --testPathIgnorePatterns test/integration-*.test.ts dist || exit; done) && echo \"All tests passed! Congrats!\"", "__test-repeat-all": "echo 'Repeating test suite [initializing]...'; (i=0; while [ \"$((( i += 1 ) <= 100 ))\" -ne 0 ]; do sleep 0.1 && echo \"\\r\\033[1A\\033[0KRepeating test suite [run $i/100]...\" && JEST_SILENT_REPORTER_SHOW_WARNINGS=true BABEL_ENV=test npx jest --reporters=jest-silent-reporter || exit; done) && echo \"All tests passed! Congrats!\"", "build": "npm run build-dist --", - "build-changelog": "conventional-changelog --outfile CHANGELOG.md --preset angular --config .changelogrc.js --release-count 0 --skip-unstable && (if [ \"$CHANGELOG_SKIP_TITLE\" != 'true' ]; then { node -e 'console.log(require(\"./.changelogrc.js\").changelogTitle)'; cat CHANGELOG.md; } > CHANGELOG.md.ignore && mv CHANGELOG.md.ignore CHANGELOG.md; fi) && remark -o --use reference-links --use gfm --use frontmatter CHANGELOG.md && prettier --write CHANGELOG.md", + "build-changelog": "conventional-changelog --outfile CHANGELOG.md --config conventional.config.js --release-count 0 --skip-unstable && (if [ \"$CHANGELOG_SKIP_TITLE\" != 'true' ]; then { node -e 'console.log(require(\"./conventional.config.js\").changelogTitle)'; cat CHANGELOG.md; } > CHANGELOG.md.ignore && mv CHANGELOG.md.ignore CHANGELOG.md; fi) && remark -o --use reference-links --use gfm --use frontmatter CHANGELOG.md && prettier --write CHANGELOG.md", "build-dist": "if [ -r ./next.config.js ]; then next build; else NODE_ENV=production tsc --project tsconfig.types.json && NODE_ENV=production webpack --config-name lib && if [ -r ./src/cli.ts ]; then NODE_ENV=production webpack --config-name cli && chmod +x ./dist/cli.js; fi && NODE_ENV=esm babel src --extensions .ts --out-dir dist/esm --out-file-extension .mjs; fi", "build-docs": "if [ -r ./next.config.js ]; then typedoc --plugin typedoc-plugin-markdown --out docs --readme none lib src test types external-scripts --exclude '**/*.test.*' --exclude external-scripts/bin; else ENTRY=`node -e 'console.log((x => typeof x==\"string\"?x:x.default)(require(\"./package.json\").exports[\".\"]).replace(/\\.\\/dist\\/(.+)\\.[a-zA-Z0-9]+$/, \"./src/$1.ts\"))'` && echo 'Entry file:' \"$ENTRY\" && typedoc --plugin typedoc-plugin-markdown --out docs --readme none $ENTRY && find docs -name '*.md' -exec sed -i -e 's/Project: //g' {} + && sed -i -e 1,4d docs/README.md; fi && find docs -name '*.md' -exec sed -i -e 's/`__namedParameters`/`\\(destructured\\)`/g' {} + && find docs -name '*.md' -exec sed -i -E 's/`__namedParameters\\.([^`]+)`/`\\({ \\1 }\\)`/g' {} +", "build-externals": "NODE_ENV=external webpack --config-name externals", "build-stats": "NODE_ENV=production webpack --json > bundle-stats.ignore.json", - "clean": "rm -rf coverage external-scripts/bin bundle-stats.ignore.json && git ls-files --exclude-standard --ignored --others --directory dist | xargs rm -rf {} +", - "dev": "next -p `npx -q acquire-port`", + "clean": "rm -rf dist coverage external-scripts/bin bundle-stats.ignore.json && git ls-files --exclude-standard --ignored --others --directory dist | xargs rm -rf {} +", "format": "sort-package-json && remark -o --use reference-links --use gfm --use frontmatter '{{,.}*.md,!(node_modules)/**/{,.}*.md,.*/**/{,.}*.md}' && prettier --write '{{,.}*.md,!(node_modules)/**/{,.}*.md,.*/**/{,.}*.md}' && if [ -z \"$ALLOW_DISABLED_LINKS\" ] && grep -qR --exclude-dir=node_modules --include='*.md' '\\\\\\[[^\\]*\\]\\\\' .; then echo '---\nWARNING: disabled links were found in the following files:'; grep -R --color=always --exclude-dir=node_modules --include='*.md' '\\\\\\[[^\\]*\\]\\\\' .; echo '(to ignore this error, run this command again with ALLOW_DISABLED_LINKS=1)'; exit 1; fi", "lint": "stdbuf -i0 -o0 -e0 tsc --project tsconfig.lint.json; X=$?; stdbuf -i0 -o0 -e0 eslint --parser-options=project:tsconfig.lint.json src; Y=$?; remark --quiet --use gfm --use frontmatter --use lint-final-newline --use lint-no-auto-link-without-protocol --use lint-no-blockquote-without-marker --use lint-ordered-list-marker-style --use lint-hard-break-spaces --use lint-no-duplicate-definitions --use lint-no-heading-content-indent --use lint-no-inline-padding --use lint-no-undefined-references --use lint-no-unused-definitions --use validate-links '{{,.}*.md,!(node_modules)/**/{,.}*.md,.*/**/{,.}*.md}'; Z=$?; [ $X -eq 0 ] && [ $Y -eq 0 ] && [ $Z -eq 0 ]", "list-tasks": "node -e 'console.log(Object.keys(require(\"./package.json\").scripts).join(\"\\n\"))'", "prepare": "if [ -z \"$CI\" ] && [ \"$NODE_ENV\" = \"development\" ]; then npx --no husky install; else echo 'skipped installing husky git hooks'; fi", - "start": "next start", "test": "npm run test-unit --", "test-integration": "BABEL_ENV=test jest $JEST_CLI test/integration-*.test.ts* --testPathIgnorePatterns dist", "test-integration-client": "BABEL_ENV=test jest $JEST_CLI test/integration-client*.test.ts* --testPathIgnorePatterns dist", @@ -99,6 +99,7 @@ "babel-jest": "^27.0.6", "babel-loader": "^8.2.2", "babel-plugin-explicit-exports-references": "^1.0.1", + "babel-plugin-transform-default-named-imports": "^1.0.9", "clone-deep": "^4.0.1", "confusing-browser-globals": "^1.0.10", "conventional-changelog-cli": "^2.1.1", @@ -153,17 +154,6 @@ "webpack-node-externals": "^3.0.0" }, "engines": { - "node": ">=12.x" - }, - "expectedEnvVariables": [ - "NODE_ENV|BABEL_ENV|APP_ENV", - "MONGODB_URI", - "DISABLED_API_VERSIONS", - "RESULTS_PER_PAGE", - "IGNORE_RATE_LIMITS", - "LOCKOUT_ALL_KEYS", - "DISALLOWED_METHODS", - "REQUESTS_PER_CONTRIVED_ERROR", - "MAX_CONTENT_LENGTH_BYTES" - ] + "node": ">=12" + } } diff --git a/release.config.js b/release.config.js index e2bac4f..6b62b82 100644 --- a/release.config.js +++ b/release.config.js @@ -4,22 +4,18 @@ const debug = require('debug')( `${require('./package.json').name}:semantic-release-config` ); -const SHOULD_UPDATE_CHANGELOG = process.env.SHOULD_UPDATE_CHANGELOG === 'true'; -const SHOULD_DEPLOY = process.env.SHOULD_DEPLOY === 'true'; +// TODO: turn this into @xunnamius/semantic-release-projector-config -debug(`SHOULD_UPDATE_CHANGELOG:${SHOULD_UPDATE_CHANGELOG}`); -debug(`SHOULD_DEPLOY:${SHOULD_DEPLOY}`); +const updateChangelog = + process.env.UPDATE_CHANGELOG === 'true' || + // ? Legacy + process.env.SHOULD_UPDATE_CHANGELOG === 'true'; -const { - changelogTitle, - parserOpts, - writerOpts, - additionalReleaseRules -} = require('./.changelogrc.js'); +debug(`will update changelog: ${updateChangelog ? 'yes' : 'no'}`); + +const { changelogTitle, parserOpts, writerOpts } = require('./conventional.config.js'); -// ? See: https://semantic-release.gitbook.io/semantic-release/usage/configuration#options module.exports = { - // ? For branches, it's important that each entry only have higher version numbers than the last, which is why maintenance branches appear first. branches: [ '+([0-9])?(.{+([0-9]),x}).x', 'main', @@ -33,20 +29,28 @@ module.exports = { [ '@semantic-release/commit-analyzer', { - preset: 'angular', parserOpts, - releaseRules: additionalReleaseRules + releaseRules: [ + // ? releaseRules are checked first; if none match, defaults are + // ? checked next. + + // ! These two lines must always appear first and in order: + { breaking: true, release: 'major' }, + { revert: true, release: 'patch' }, + + // * Custom release rules, if any, may appear next: + { type: 'build', release: 'patch' } + ] } ], [ '@semantic-release/release-notes-generator', { - preset: 'angular', parserOpts, writerOpts } ], - ...(SHOULD_UPDATE_CHANGELOG + ...(updateChangelog ? [ [ '@semantic-release/exec', @@ -84,17 +88,7 @@ module.exports = { message: 'release: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' } ], - ['@semantic-release/github'], - ...(SHOULD_DEPLOY - ? [ - [ - '@semantic-release/exec', - { - successCmd: 'npm run deploy' - } - ] - ] - : []) + ['@semantic-release/github'] ] };