diff --git a/README.md b/README.md index 0eb20a87d..03011fe97 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,10 @@ Help and explanations docs Available commands -| Name | Description | -| ------ | ------------------------- | -| [docs] | Generate docs for the app | +| Name | Description | +| ------- | ------------------------- | +| [build] | Gasket build command | +| [docs] | Generate docs for the app | ## Actions @@ -83,6 +84,7 @@ Available actions | [getPublicGasketData] | Get the public Gasket data | | [getSWRegisterScript] | Get the service worker registration script | | [getWebpackConfig] | Get the webpack config | +| [startProxyServer] | Start the proxy server | | [startServer] | Start the server | ## Lifecycles @@ -92,6 +94,7 @@ Available lifecycles | Name | Description | | ----------------------- | ------------------------------------------------------------- | | [apmTransaction] | Modify the APM transaction | +| [build][1] | Gasket build lifecycle | | [commands] | Add custom commands to the CLI | | [composeServiceWorker] | Update the service worker script | | [createLogger] | Custom logger creation | @@ -101,10 +104,11 @@ Available lifecycles | [docsSetup] | Set up what docs are captured and how to transform them | | [docsView] | View the collated documentation | | [errorMiddleware] | Add Express style middleware for handling errors with Fastify | -| [errorMiddleware][1] | Add Express style middleware for handling errors | +| [errorMiddleware][2] | Add Express style middleware for handling errors | | [express] | Modify the Express instance to for adding endpoints | | [fastify] | Modify the Fastify instance to for adding endpoints | | [gasketData] | Adjust app level data after merged for the env | +| [httpsProxy] | Setup the httpsProxy options | | [initReduxState] | Initializes state of the Redux store | | [initReduxStore] | Plugin access to Redux store instance | | [initWebpack] | Create a webpack config | @@ -112,9 +116,9 @@ Available lifecycles | [manifest] | Modify the the web manifest for a request | | [metadata] | Allows plugins to adjust their metadata | | [middleware] | Add Express style middleware for Fastify | -| [middleware][2] | Add Express style middleware | +| [middleware][3] | Add Express style middleware | | [next] | Update the Next.js app instance before preparing for Express | -| [next][3] | Update the Next.js app instance before preparing for Fastify | +| [next][4] | Update the Next.js app instance before preparing for Fastify | | [nextConfig] | Setup the Next.js config | | [nextExpress] | Access the prepared Next.js app and Express instance | | [nextFastify] | Access the prepared Next.js app and Fastify instance | @@ -151,45 +155,47 @@ Available presets | Name | Version | Description | | ----------------------- | ------- | ------------------------------------ | -| [@gasket/preset-api] | 7.0.1 | Create Express-based API with Gasket | -| [@gasket/preset-nextjs] | 7.0.1 | Basic NextJS Framework | +| [@gasket/preset-api] | 7.0.14 | Create Express-based API with Gasket | +| [@gasket/preset-nextjs] | 7.0.14 | Basic NextJS Framework | ## Plugins Available plugins -| Name | Version | Description | -| ------------------------------- | ------- | ------------------------------------------------------------------------- | -| [@gasket/plugin-analyze] | 7.0.1 | Gasket Analyzer Plugin | -| [@gasket/plugin-command] | 7.0.1 | Plugin to enable other plugins to inject new gasket commands | -| [@gasket/plugin-cypress] | 7.0.1 | Integrates Cypress based testing into your Gasket application | -| [@gasket/plugin-data] | 7.0.1 | Supports application-specific settings and configurations | -| [@gasket/plugin-docs] | 7.0.1 | Centralize doc files from plugins and modules | -| [@gasket/plugin-docs-graphs] | 7.0.1 | Generate mermaid graphs of an applications gasket lifecycles | -| [@gasket/plugin-docusaurus] | 7.0.1 | Gasket plugin for docusaurus | -| [@gasket/plugin-elastic-apm] | 7.0.1 | Adds Elastic APM instrumentation to your application | -| [@gasket/plugin-express] | 7.0.1 | Adds express support to your application | -| [@gasket/plugin-fastify] | 7.0.1 | Adds fastify support to your application | -| [@gasket/plugin-git] | 7.0.1 | Adds git support to your application | -| [@gasket/plugin-happyfeet] | 7.0.1 | A gasket plugin to enable happyfeet healthchecks | -| [@gasket/plugin-https] | 7.0.1 | Create http/s servers with graceful termination | -| [@gasket/plugin-intl] | 7.0.1 | NodeJS script to build localization files. | -| [@gasket/plugin-jest] | 7.0.1 | Integrated jest into your application. | -| [@gasket/plugin-lint] | 7.0.1 | Adds GoDaddy standard linting to your application | -| [@gasket/plugin-logger] | 7.0.1 | Gasket plugin for logging | -| [@gasket/plugin-manifest] | 7.0.1 | The web app manifest for progressive Gasket applications | -| [@gasket/plugin-metadata] | 7.0.1 | Adds metadata to gasket lifecycles | -| [@gasket/plugin-middleware] | 7.0.1 | Handles common server engine setups for routing and executing lifecycles. | -| [@gasket/plugin-mocha] | 7.0.1 | Integrates mocha based testing in to your Gasket application | -| [@gasket/plugin-morgan] | 7.0.1 | Adds morgan request logger to your app | -| [@gasket/plugin-nextjs] | 7.0.1 | Adds Next support to your application | -| [@gasket/plugin-redux] | 7.0.1 | Gasket Redux Setup | -| [@gasket/plugin-service-worker] | 7.0.1 | Gasket Service Worker Plugin | -| [@gasket/plugin-swagger] | 7.0.1 | Generate and serve swagger docs | -| [@gasket/plugin-typescript] | 7.0.1 | Gasket plugin for TypeScript support | -| [@gasket/plugin-webpack] | 7.0.1 | Adds webpack support to your application | -| [@gasket/plugin-winston] | 7.0.1 | Gasket logger based on Winston | -| [@gasket/plugin-workbox] | 7.0.1 | Gasket Workbox Plugin | +| Name | Version | Description | +| -------------------------------- | -------------- | ------------------------------------------------------------------------- | +| [@gasket/plugin-analyze] | 7.0.9 | Gasket Analyzer Plugin | +| [@gasket/plugin-command] | 7.0.9 | Plugin to enable other plugins to inject new gasket commands | +| [@gasket/plugin-cypress] | 7.0.9 | Integrates Cypress based testing into your Gasket application | +| [@gasket/plugin-data] | 7.0.9 | Supports application-specific settings and configurations | +| [@gasket/plugin-docs] | 7.0.9 | Centralize doc files from plugins and modules | +| [@gasket/plugin-docs-graphs] | 7.0.1 | Generate mermaid graphs of an applications gasket lifecycles | +| [@gasket/plugin-docusaurus] | 7.0.9 | Gasket plugin for docusaurus | +| [@gasket/plugin-dynamic-plugins] | 0.0.0 | | +| [@gasket/plugin-elastic-apm] | 7.0.9 | Adds Elastic APM instrumentation to your application | +| [@gasket/plugin-express] | 7.0.14 | Adds express support to your application | +| [@gasket/plugin-fastify] | 7.0.13 | Adds fastify support to your application | +| [@gasket/plugin-git] | 7.0.9 | Adds git support to your application | +| [@gasket/plugin-happyfeet] | 7.0.4 | A gasket plugin to enable happyfeet healthchecks | +| [@gasket/plugin-https] | 7.0.9 | Create http/s servers with graceful termination | +| [@gasket/plugin-https-proxy] | 7.0.0-canary.0 | Adds support for running an https proxy | +| [@gasket/plugin-intl] | 7.0.14 | NodeJS script to build localization files. | +| [@gasket/plugin-jest] | 7.0.10 | Integrated jest into your application. | +| [@gasket/plugin-lint] | 7.0.3 | Adds GoDaddy standard linting to your application | +| [@gasket/plugin-logger] | 7.0.9 | Gasket plugin for logging | +| [@gasket/plugin-manifest] | 7.0.9 | The web app manifest for progressive Gasket applications | +| [@gasket/plugin-metadata] | 7.0.9 | Adds metadata to gasket lifecycles | +| [@gasket/plugin-middleware] | 7.0.1 | Handles common server engine setups for routing and executing lifecycles. | +| [@gasket/plugin-mocha] | 7.0.4 | Integrates mocha based testing in to your Gasket application | +| [@gasket/plugin-morgan] | 7.0.9 | Adds morgan request logger to your app | +| [@gasket/plugin-nextjs] | 7.0.9 | Adds Next support to your application | +| [@gasket/plugin-redux] | 7.0.14 | Gasket Redux Setup | +| [@gasket/plugin-service-worker] | 7.0.9 | Gasket Service Worker Plugin | +| [@gasket/plugin-swagger] | 7.0.9 | Generate and serve swagger docs | +| [@gasket/plugin-typescript] | 7.0.1 | Gasket plugin for TypeScript support | +| [@gasket/plugin-webpack] | 7.0.9 | Adds webpack support to your application | +| [@gasket/plugin-winston] | 7.0.9 | Gasket logger based on Winston | +| [@gasket/plugin-workbox] | 7.0.9 | Gasket Workbox Plugin | @@ -197,16 +203,17 @@ Available plugins Supporting modules -| Name | Version | Description | -| -------------------- | ------- | ------------------------------------------------------------------------ | -| [@gasket/assets] | 7.0.1 | Gasket assets | -| [@gasket/core] | 7.0.1 | Entry point to setting up Gasket instances | -| [@gasket/data] | 7.0.1 | Helper package for accessing embedded Gasket Data in the browser | -| [@gasket/intl] | 7.0.1 | Internationalization managers for translation files and locale handling. | -| [@gasket/nextjs] | 7.0.1 | Gasket integrations for Next.js apps | -| [@gasket/react-intl] | 7.0.1 | React component library to enable localization for gasket apps. | -| [@gasket/redux] | 7.0.1 | Gasket Redux Configuration | -| [@gasket/utils] | 7.0.1 | Reusable utilities for Gasket internals | +| Name | Version | Description | +| -------------------- | -------------- | ------------------------------------------------------------------------ | +| [@gasket/assets] | 7.0.1 | Gasket assets | +| [@gasket/core] | 7.0.9 | Entry point to setting up Gasket instances | +| [@gasket/data] | 7.0.1 | Helper package for accessing embedded Gasket Data in the browser | +| [@gasket/intl] | 7.0.1 | Internationalization managers for translation files and locale handling. | +| [@gasket/nextjs] | 7.0.1 | Gasket integrations for Next.js apps | +| [@gasket/react-intl] | 7.0.1 | React component library to enable localization for gasket apps. | +| [@gasket/redux] | 7.0.14 | Gasket Redux Configuration | +| [@gasket/request] | 7.0.0-canary.0 | Utilities for working with request objects in Gasket | +| [@gasket/utils] | 7.0.9 | Reusable utilities for Gasket internals | ## Configurations @@ -215,25 +222,27 @@ Available configuration options in the `gasket.js` | Name | Description | Type | Default | | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -------------------------------------- | ------------------------------ | | [bundleAnalyzerConfig] | Tune both browser and server Webpack analysis reports | object | | -| [docs][4] | Docs config object | object | | +| [docs][5] | Docs config object | object | | | [docs.outputDir] | Output directory for generated docs | string | .docs | | [docusaurus] | Docusaurus plugin config | object | | | [docusaurus.docsDir] | Sub-directory for the generated markdown from the docs plugin | string | docs | | [docusaurus.host] | Hostname to serve the docs from | string | localhost | | [docusaurus.port] | Port number to serve docs site | number | 3000 | | [docusaurus.rootDir] | Root Docusaurus directory | string | .docs | +| [dynamicPlugins] | Specify which plugins to load dynamically into gasket | array | | | [elasticAPM] | Configuration to provide additional setup helpers | object | | | [elasticAPM.sensitiveCookies] | List of sensitive cookies to filter | string[] | [] | -| [express][5] | Express plugin configuration | object | | +| [express][6] | Express plugin configuration | object | | | [express.compression] | Automatic compression | boolean | true | | [express.excludedRoutesRegex (deprecated)][express.excludedRoutesRegex (deprecated)] | Routes to be included for Gasket middleware, based on a regex | RegExp | | | [express.middlewareInclusionRegex] | Routes to be included for Gasket middleware, based on a regex | RegExp | | -| [fastify][6] | Fastify configuration object | object | | +| [fastify][7] | Fastify configuration object | object | | | [fastify.compression] | Automatic compression | boolean | true | | [fastify.excludedRoutesRegex] | Routes to be excluded based on a regex | RegExp | | | [http] | HTTP port or config object | number | object | | | [http2] | HTTP2 config object | object | | | [https] | HTTPS config object | object | | +| [httpsProxy][8] | http-proxy config object | object | | | [intl] | Intl config object | object | | | [intl.defaultLocale] | Locale to fallback to when loading files | string | en | | [intl.defaultLocaleFilePath] | Lookup path to locale files | string | locales | @@ -243,11 +252,11 @@ Available configuration options in the `gasket.js` | [intl.managerFilename] | Change the name of the IntlManager file | string | intl.js | | [intl.modules] | Enable locale files collation from node modules | boolean | object | | | [intl.nextRouting] | Enable Next.js Routing when used with @gasket/plugin-nextjs | boolean | true | -| [manifest][7] | Manifest plugin config | object | | +| [manifest][9] | Manifest plugin config | object | | | [morgan] | Morgan plugin configuration | object | | | [morgan.format] | Log format to print | string | tiny | | [morgan.options] | Morgan options | object | | -| [nextConfig][8] | Everything that can be configured in `next.config.js` can be added here. | object | | +| [nextConfig][10] | Everything that can be configured in `next.config.js` can be added here. | object | | | [redux] | Redux plugin config object | object | | | [redux.initState] | Initial state to include in the store | object | | | [redux.makeStore] | Relative path to a custom makeStore configuration | string | store.js | @@ -265,10 +274,10 @@ Available configuration options in the `gasket.js` | [swagger.definitionFile] | Target swagger spec file, either json or yaml | string | swagger.json | | [swagger.jsdoc] | If set, the definitionFile will be generated based on JSDocs in the configured files | object | | | [swagger.ui] | Optional custom UI options | object | | -| [terminus][9] | Terminus config object | object | | +| [terminus][11] | Terminus config object | object | | | [terminus.healthcheck] | Custom Terminus healthcheck endpoint names | string[] | /healthcheck,/healthcheck.html | | [winston] | Setup and customize winston logger | object | | -| [workbox][10] | Workbox config object | object | | +| [workbox][12] | Workbox config object | object | | | [workbox.basePath] | Change the default path to `/_workbox` endpoint by adding a path prefix here | string | | | [workbox.config] | Any initial workbox config options which will be merged with those from any `workbox` lifecycle hooks | object | | | [workbox.outputDir] | The path to the directory in which the Workbox libraries should be copied | string | ./build/workbox | @@ -283,6 +292,7 @@ Available configuration options in the `gasket.js` [Next.js Routing Guide]:/packages/gasket-plugin-nextjs/docs/routing.md [Next.js Deployment Guide]:/packages/gasket-plugin-nextjs/docs/deployment.md [Webpack Configuration Guide]:/packages/gasket-plugin-webpack/docs/webpack.md +[build]:/packages/gasket-plugin-command/README.md#build [docs]:/packages/gasket-plugin-docs/README.md#commands [getApmTransaction]:/packages/gasket-plugin-elastic-apm/README.md#getApmTransaction [getExpressApp]:/packages/gasket-plugin-express/README.md#getExpressApp @@ -298,8 +308,10 @@ Available configuration options in the `gasket.js` [getPublicGasketData]:/packages/gasket-plugin-data/README.md#getPublicGasketData [getSWRegisterScript]:/packages/gasket-plugin-service-worker/README.md#getSWRegisterScript [getWebpackConfig]:/packages/gasket-plugin-webpack/README.md#getWebpackConfig +[startProxyServer]:/packages/gasket-plugin-https-proxy/README.md#startProxyServer [startServer]:/packages/gasket-plugin-https/README.md#startServer [apmTransaction]:/packages/gasket-plugin-elastic-apm/README.md#apmtransaction +[1]:/packages/gasket-plugin-command/README.md#build [commands]:/packages/gasket-plugin-command/README.md#commands [composeServiceWorker]:/packages/gasket-plugin-service-worker/README.md#composeServiceWorker [createLogger]:/packages/gasket-plugin-logger/README.md#createLogger @@ -309,10 +321,11 @@ Available configuration options in the `gasket.js` [docsSetup]:/packages/gasket-plugin-docs/README.md#docsSetup [docsView]:/packages/gasket-plugin-docs/README.md#docsView [errorMiddleware]:/packages/gasket-plugin-fastify/README.md#errorMiddleware -[1]:/packages/gasket-plugin-express/README.md#errorMiddleware +[2]:/packages/gasket-plugin-express/README.md#errorMiddleware [express]:/packages/gasket-plugin-express/README.md#express [fastify]:/packages/gasket-plugin-fastify/README.md#express [gasketData]:/packages/gasket-plugin-data/README.md#gasketData +[httpsProxy]:/packages/gasket-plugin-https-proxy/README.md#httpsProxy [initReduxState]:/packages/gasket-plugin-redux/README.md#initReduxState [initReduxStore]:/packages/gasket-plugin-redux/README.md#initReduxStore [initWebpack]:/packages/gasket-plugin-webpack/README.md#initwebpack @@ -320,9 +333,9 @@ Available configuration options in the `gasket.js` [manifest]:/packages/gasket-plugin-manifest/README.md#manifest [metadata]:/packages/gasket-plugin-metadata/README.md#metadata [middleware]:/packages/gasket-plugin-fastify/README.md#middleware -[2]:/packages/gasket-plugin-express/README.md#middleware +[3]:/packages/gasket-plugin-express/README.md#middleware [next]:/packages/gasket-plugin-nextjs/README.md#next -[3]:/packages/gasket-plugin-nextjs/README.md#next +[4]:/packages/gasket-plugin-nextjs/README.md#next [nextConfig]:/packages/gasket-plugin-nextjs/README.md#nextConfig [nextExpress]:/packages/gasket-plugin-nextjs/README.md#nextExpress [nextFastify]:/packages/gasket-plugin-nextjs/README.md#nextFastify @@ -352,12 +365,14 @@ Available configuration options in the `gasket.js` [@gasket/plugin-docs]:/packages/gasket-plugin-docs/README.md [@gasket/plugin-docs-graphs]:/packages/gasket-plugin-docs-graphs/README.md [@gasket/plugin-docusaurus]:/packages/gasket-plugin-docusaurus/README.md +[@gasket/plugin-dynamic-plugins]:/packages/gasket-plugin-dynamic-plugins/README.md [@gasket/plugin-elastic-apm]:/packages/gasket-plugin-elastic-apm/README.md [@gasket/plugin-express]:/packages/gasket-plugin-express/README.md [@gasket/plugin-fastify]:/packages/gasket-plugin-fastify/README.md [@gasket/plugin-git]:/packages/gasket-plugin-git/README.md [@gasket/plugin-happyfeet]:/packages/gasket-plugin-happyfeet/README.md [@gasket/plugin-https]:/packages/gasket-plugin-https/README.md +[@gasket/plugin-https-proxy]:/packages/gasket-plugin-https-proxy/README.md [@gasket/plugin-intl]:/packages/gasket-plugin-intl/README.md [@gasket/plugin-jest]:/packages/gasket-plugin-jest/README.md [@gasket/plugin-lint]:/packages/gasket-plugin-lint/README.md @@ -382,27 +397,30 @@ Available configuration options in the `gasket.js` [@gasket/nextjs]:/packages/gasket-nextjs/README.md [@gasket/react-intl]:/packages/gasket-react-intl/README.md [@gasket/redux]:/packages/gasket-redux/README.md +[@gasket/request]:/packages/gasket-request/README.md [@gasket/utils]:/packages/gasket-utils/README.md [bundleAnalyzerConfig]:/packages/gasket-plugin-analyze/README.md#configuration -[4]:/packages/gasket-plugin-docs/README.md#configuration +[5]:/packages/gasket-plugin-docs/README.md#configuration [docs.outputDir]:/packages/gasket-plugin-docs/README.md#configuration [docusaurus]:/packages/gasket-plugin-docusaurus/README.md#configuration [docusaurus.docsDir]:/packages/gasket-plugin-docusaurus/README.md#configuration [docusaurus.host]:/packages/gasket-plugin-docusaurus/README.md#configuration [docusaurus.port]:/packages/gasket-plugin-docusaurus/README.md#configuration [docusaurus.rootDir]:/packages/gasket-plugin-docusaurus/README.md#configuration +[dynamicPlugins]:/packages/gasket-plugin-dynamic-plugins/README.md#configuration [elasticAPM]:/packages/gasket-plugin-elastic-apm/README.md#configuration [elasticAPM.sensitiveCookies]:/packages/gasket-plugin-elastic-apm/README.md#configuration -[5]:/packages/gasket-plugin-express/README.md#configuration +[6]:/packages/gasket-plugin-express/README.md#configuration [express.compression]:/packages/gasket-plugin-express/README.md#configuration [express.excludedRoutesRegex (deprecated)]:/packages/gasket-plugin-express/README.md#configuration [express.middlewareInclusionRegex]:/packages/gasket-plugin-express/README.md#configuration -[6]:/packages/gasket-plugin-fastify/README.md#configuration +[7]:/packages/gasket-plugin-fastify/README.md#configuration [fastify.compression]:/packages/gasket-plugin-fastify/README.md#configuration [fastify.excludedRoutesRegex]:/packages/gasket-plugin-fastify/README.md#configuration [http]:/packages/gasket-plugin-https/README.md#configuration [http2]:/packages/gasket-plugin-https/README.md#configuration [https]:/packages/gasket-plugin-https/README.md#configuration +[8]:/packages/gasket-plugin-https-proxy/README.md#configuration [intl]:/packages/gasket-plugin-intl/README.md#configuration [intl.defaultLocale]:/packages/gasket-plugin-intl/README.md#configuration [intl.defaultLocaleFilePath]:/packages/gasket-plugin-intl/README.md#configuration @@ -412,11 +430,11 @@ Available configuration options in the `gasket.js` [intl.managerFilename]:/packages/gasket-plugin-intl/README.md#configuration [intl.modules]:/packages/gasket-plugin-intl/README.md#configuration [intl.nextRouting]:/packages/gasket-plugin-intl/README.md#configuration -[7]:/packages/gasket-plugin-manifest/README.md#configuration +[9]:/packages/gasket-plugin-manifest/README.md#configuration [morgan]:/packages/gasket-plugin-morgan/README.md#configuration [morgan.format]:/packages/gasket-plugin-morgan/README.md#configuration [morgan.options]:/packages/gasket-plugin-morgan/README.md#configuration -[8]:/packages/gasket-plugin-nextjs/README.md#configuration +[10]:/packages/gasket-plugin-nextjs/README.md#configuration [redux]:/packages/gasket-plugin-redux/README.md#configuration [redux.initState]:/packages/gasket-plugin-redux/README.md#configuration [redux.makeStore]:/packages/gasket-plugin-redux/README.md#configuration @@ -434,10 +452,10 @@ Available configuration options in the `gasket.js` [swagger.definitionFile]:/packages/gasket-plugin-swagger/README.md#configuration [swagger.jsdoc]:/packages/gasket-plugin-swagger/README.md#configuration [swagger.ui]:/packages/gasket-plugin-swagger/README.md#configuration -[9]:/packages/gasket-plugin-https/README.md#configuration +[11]:/packages/gasket-plugin-https/README.md#configuration [terminus.healthcheck]:/packages/gasket-plugin-https/README.md#configuration [winston]:/packages/gasket-plugin-winston/README.md#configuration -[10]:/packages/gasket-plugin-workbox/README.md#configuration +[12]:/packages/gasket-plugin-workbox/README.md#configuration [workbox.basePath]:/packages/gasket-plugin-workbox/README.md#configuration [workbox.config]:/packages/gasket-plugin-workbox/README.md#configuration [workbox.outputDir]:/packages/gasket-plugin-workbox/README.md#configuration diff --git a/docs/authoring-presets.md b/docs/authoring-presets.md index 9089e8c51..5938dc717 100644 --- a/docs/authoring-presets.md +++ b/docs/authoring-presets.md @@ -186,5 +186,5 @@ You can also add configuration to the `context` object through the command line npx create-gasket-app --presets <@your/gasket-preset-example> --config "{\"my\": \"value\"}" ``` -[recommended naming conventions]: /docs/plugins.md#recommended-naming-convention -[plugin]: /docs/plugins.md +[recommended naming conventions]: /docs/authoring-plugins.md#recommended-naming-convention +[plugin]: /docs/authoring-plugins.md diff --git a/docs/generated-docs/lifecycle-graphs.md b/docs/generated-docs/lifecycle-graphs.md index 9976d1ae8..17c87c641 100644 --- a/docs/generated-docs/lifecycle-graphs.md +++ b/docs/generated-docs/lifecycle-graphs.md @@ -1,7 +1,8 @@ ```mermaid graph LR; middleware -- exec --> apmTransaction; -ready -- execSync --> commands; +commands -- exec --> build; +ready -- exec --> commands; express -- execWaterfall --> composeServiceWorker; init -- execSync --> createLogger; start -- execWaterfall --> createServers; @@ -14,6 +15,7 @@ createServers -- exec --> errorMiddleware; createServers -- exec --> express; createServers -- exec --> fastify; gasket/plugin-data -- execWaterfall --> gasketData; +gasket/plugin-https-proxy -- execWaterfall --> httpsProxy; middleware -- execWaterfall --> initReduxState; middleware -- exec --> initReduxStore; build-cmd(build) --> initWebpack; diff --git a/docs/package-management.md b/docs/package-management.md index 2dbeb26a5..c8b1c4c8e 100644 --- a/docs/package-management.md +++ b/docs/package-management.md @@ -69,4 +69,4 @@ dependency definitions. [npm install]: https://docs.npmjs.com/cli/install [yarn install]: https://yarnpkg.com/en/docs/cli/add#toc-yarn-add-dev-d -[one-off plugin]: plugins.md#one-off-plugins +[one-off plugin]: authoring-plugins.md#one-off-plugins diff --git a/docs/upgrade-to-6.md b/docs/upgrade-to-6.md index 6352e4644..9fd8ec02b 100644 --- a/docs/upgrade-to-6.md +++ b/docs/upgrade-to-6.md @@ -54,7 +54,7 @@ There are two ways to add data to the Gasket Data object: We have created the `public` property in the `app.config.js` file to allow the client to access app config properties. -The [@gasket/plugin-config] plugin will return these `public` config properties +The @gasket/plugin-config plugin will return these `public` config properties to the browser. The [@gasket/data] package will then access the properties and make them available on `.config`. @@ -373,7 +373,7 @@ to avoid unnecessarily committing those files to the git repo. ### Lifecycle name If you have a custom lifecycle hook to determine the locale, either in a plugin -or [lifecycle file], then you will need to update the name and the signature. +or lifecycle file, then you will need to update the name and the signature. ```diff // gasket-plugin-example.js @@ -660,17 +660,14 @@ _Impacted Plugins/Packages: `@gasket/resolve`, `@gasket/engine`_ -[intl]: #intl -[app config]: #public-config-property [next.js routing documentation]: https://nextjs.org/docs/routing/introduction [webpack website]: https://webpack.js.org/configuration/node/ [gasket data script tag]: /packages/gasket-data/README.md#usage [new utility HOC]: #inject-gasket-data -[@gasket/plugin-config]: /packages/gasket-plugin-response-data/README.md [@gasket/data]: /packages/gasket-data/README.md [@gasket/plugin-workbox]: /packages/gasket-data/README.md [@gasket/plugin-service-worker]: /packages/gasket-data/README.md -[naming convention]: /packages/gasket-resolve/README.md#plugins +[naming convention]: /docs/authoring-plugins.md#recommended-naming-convention @@ -684,7 +681,6 @@ _Impacted Plugins/Packages: `@gasket/resolve`, `@gasket/engine`_ [select locale message example]: /packages/gasket-plugin-intl/README.md#selectlocalemessage [@gasket/react-intl]: /packages/gasket-react-intl/README.md [@gasket/plugin-nextjs]: /packages/gasket-plugin-nextjs/README.md -[lifecycle file]: /packages/gasket-plugin-lifecycle/README.md#usage [@gasket/plugin-redux]: /packages/gasket-plugin-redux/README.md [Redux configuration]: /packages/gasket-plugin-redux/README.md#configuration [@gasket/plugin-webpack]: /packages/gasket-plugin-webpack/README.md @@ -697,4 +693,3 @@ _Impacted Plugins/Packages: `@gasket/resolve`, `@gasket/engine`_ [resolve.fallback]: https://webpack.js.org/configuration/resolve/#resolvefallback [Webpack 5 docs]: https://webpack.js.org/configuration/node/ [@godaddy/eslint-plugin-react-intl]: https://github.com/godaddy/eslint-plugin-react-intl - diff --git a/docs/upgrade-to-7.md b/docs/upgrade-to-7.md index 908e95033..2a64cde4f 100644 --- a/docs/upgrade-to-7.md +++ b/docs/upgrade-to-7.md @@ -4,29 +4,33 @@ This guide will take you through updating `@gasket/*` packages to `7.x`. ## Table of Contents -- [Update Dependency Versions](#update-dependency-versions) -- [Switch to makeGasket](#switch-to-makegasket) - - [Switch to ESM (Optional)](#switch-to-esm-optional) - - [Update Plugin Imports](#update-plugin-imports) - - [Update Command Scripts](#update-command-scripts) - - [Update Next.js Scripts](#update-nextjs-scripts) -- [Update Next.js](#update-nextjs) -- [Switch to GasketActions](#switch-to-gasketactions) -- [Update configurations](#update-configurations) -- [Switch to Docusaurus](#switch-to-docusaurus) -- [Update Lifecycles Contexts](#update-lifecycles-contexts) -- [Update ElasticAPM Start](#update-elasticapm-start) -- [Switch to GasketData](#switch-to-gasketdata) -- [Switch Redux to GasketData](#switch-redux-to-gasketdata) -- [Switch to @gasket/plugin-logger](#switch-to-gasketplugin-logger) -- [Update Intl](#update-intl) - - [Bring your Own Intl Provider](#bring-your-own-intl-provider) - - [Switch to Intl Manager](#switch-to-intl-manager) - - [Move locale files (Optional)](#move-locale-files-optional) -- [Update Custom Commands](#update-custom-commands) -- [Update App Plugins](#update-app-plugins) -- [Update App Lifecycles](#update-app-lifecycles) -- [Update Mocha Tests](#update-mocha-tests) +- [Upgrade to v7 (Active)](#upgrade-to-v7-active) + - [Table of Contents](#table-of-contents) + - [Update Dependency Versions](#update-dependency-versions) + - [Switch to makeGasket](#switch-to-makegasket) + - [Switch to ESM (Optional)](#switch-to-esm-optional) + - [Update Plugin Imports](#update-plugin-imports) + - [Update Command Scripts](#update-command-scripts) + - [Update Next.js Scripts](#update-nextjs-scripts) + - [Update Next.js](#update-nextjs) + - [Switch to GasketActions](#switch-to-gasketactions) + - [Motivation](#motivation) + - [Example](#example) + - [Update configurations](#update-configurations) + - [Switch to Docusaurus](#switch-to-docusaurus) + - [Update Lifecycles Contexts](#update-lifecycles-contexts) + - [Update ElasticAPM Start](#update-elasticapm-start) + - [Switch to GasketData](#switch-to-gasketdata) + - [Switch Redux to GasketData](#switch-redux-to-gasketdata) + - [Switch to @gasket/plugin-logger](#switch-to-gasketplugin-logger) + - [Update Intl](#update-intl) + - [Bring your Own Intl Provider](#bring-your-own-intl-provider) + - [Switch to Intl Manager](#switch-to-intl-manager) + - [Move locale files (Optional)](#move-locale-files-optional) + - [Update Custom Commands](#update-custom-commands) + - [Update App Plugins](#update-app-plugins) + - [Update App Lifecycles](#update-app-lifecycles) + - [Update Mocha Tests](#update-mocha-tests) ## Update Dependency Versions @@ -48,9 +52,9 @@ demonstrate what to look for: ## Switch to makeGasket -Gasket no longer comes with a CLI. -Instead, you can use the `makeGasket` function from `@gasket/core` to create a -Gasket instance which can be used throughout your app. +Gasket no longer comes with a CLI. Instead, you can use the `makeGasket` +function from `@gasket/core` to create a Gasket instance which can be used +throughout your app. ```diff "dependencies": { @@ -59,15 +63,15 @@ Gasket instance which can be used throughout your app. } ``` -Next you need to update your gasket.config.js file to use the `makeGasket` function. -We recommend renaming this file to `gasket.js` for clarity, since it's more than -just config. +Next you need to update your gasket.config.js file to use the `makeGasket` +function. We recommend renaming this file to `gasket.js` for clarity, since it's +more than just config. ### Switch to ESM (Optional) -Gasket works well with ESM if you're ready to make that move. -Most of the documentation will be in ESM format, but you can still choose to -use CommonJS, or TypeScript. +Gasket works well with ESM if you're ready to make that move. Most of the +documentation will be in ESM format, but you can still choose to use CommonJS, +or TypeScript. If you wish to make that move with this upgrade, you can set the `type` field in your `package.json` to `module`. @@ -78,14 +82,14 @@ your `package.json` to `module`. } ``` -This will treat all your `.js` files as ESM files. -If you are not ready, you can keep your files defaulted as CommonJS, and -switch individual files to ESM by using the `.mjs` extension (i.e. `gasket.mjs`) +This will treat all your `.js` files as ESM files. If you are not ready, you can +keep your files defaulted as CommonJS, and switch individual files to ESM by +using the `.mjs` extension (i.e. `gasket.mjs`) ### Update Plugin Imports -Before, plugins were configured by their names as strings. -Now, plugins should be imported and configured in the `makeGasket` function. +Before, plugins were configured by their names as strings. Now, plugins should +be imported and configured in the `makeGasket` function. ```diff // gasket.config.js @@ -156,9 +160,9 @@ Next, update your package.json scripts to use our new custom server entry: + "start": "node server.js", ``` -> You don't have to use nodemon, but it's a good choice for development. -> Also note that specifying `GASKET_DEV=1` will enable the development mode -> so you get HMR and other development features from Next.js. +> You don't have to use nodemon, but it's a good choice for development. Also +> note that specifying `GASKET_DEV=1` will enable the development mode so you +> get HMR and other development features from Next.js. If you were using CLI flags for setting the environment, since there is no CLI you can use environment variables instead. @@ -174,9 +178,9 @@ with the environment variable pattern if flags are currently being used. ## Update Next.js -Gasket now supports Next.js 14 and changes have been made to support its features. -While some older versions may work, we recommend updating to the latest version -of Next.js. +Gasket now supports Next.js 14 and changes have been made to support its +features. While some older versions may work, we recommend updating to the +latest version of Next.js. ```diff "dependencies": { @@ -185,8 +189,8 @@ of Next.js. } ``` -You can reference the [Next.js 14] and [Next.js 13] Upgrade Guides as needed -for more details. +You can reference the [Next.js 14] and [Next.js 13] Upgrade Guides as needed for +more details. In order for Next.js configurations from plugins or `nextConfig` in the `gasket.js` file to be picked up, you will need to create a `next.config.js` @@ -208,29 +212,29 @@ in favor of using the new GasketActions API introduced in v7. ### Motivation Middleware in Gasket apps runs for every request, regardless of whether it is -used or not. We added support for [middleware paths] to help reduce this, -but it is still not ideal and requires the developer to manage something that -should be optimized already by the plugin. +used or not. We added support for [middleware paths] to help reduce this, but it +is still not ideal and requires the developer to manage something that should be +optimized already by the plugin. As a caveat of the middleware pattern, when the `req` and `res` objects are decorated with various added properties, it is not always easy to know what is available and when. In addition to issues with middleware, we need to move away from reliance on -`req` and `res` objects to fully utilize Nextjs 14 features such as -[App Router] and [streaming]. +`req` and `res` objects to fully utilize Nextjs 14 features such as [App Router] +and [streaming]. The GasketActions API provides a more structured way to access and modify data -in Gasket applications. This API is designed to be more consistent and easier -to use than the previous pattern of adding attachments to `req` and `res` objects. +in Gasket applications. This API is designed to be more consistent and easier to +use than the previous pattern of adding attachments to `req` and `res` objects. The `req` object can be used as a GasketAction argument to give access to headers, cookies, queries, or to be used as a `WeakMap` key for repeated calls. ### Example -When retrieving a request-based variable called `myValue` in middleware, -you might have done something like this: +When retrieving a request-based variable called `myValue` in middleware, you +might have done something like this: ```js const myValue = res.locals.myValue; @@ -272,8 +276,8 @@ export default({ **[@gasket/plugin-intl]** -- Remove deprecated `languageMap`, `defaultLanguage`, and `assetPrefix`. - Use `localeMap`, `defaultLocale`, and `basePath` instead. +- Remove deprecated `languageMap`, `defaultLanguage`, and `assetPrefix`. Use + `localeMap`, `defaultLocale`, and `basePath` instead. **[@gasket/plugin-webpack]** @@ -335,9 +339,8 @@ If your app or plugins hooks these lifecycles you may need to adjust them. ## Update ElasticAPM Start With the Gasket CLI going away, we need to update how we start the ElasticAPM -agent. -We recommend using the `NODE_OPTIONS` environment variable to import -(or require) a setup script. +agent. We recommend using the `NODE_OPTIONS` environment variable to import (or +require) a setup script. ```diff "scripts": { @@ -350,16 +353,17 @@ See [@gasket/plugin-elastic-apm] for more details about the setup script. ## Switch to GasketData -We have had a lot of confusion around the config plugin and its purpose. -As such, we are renaming and refocusing what the plugin does, -which is to allow environment-specific data to be accessible for requests, -with public data available with responses. +We have had a lot of confusion around the config plugin and its purpose. As +such, we are renaming and refocusing what the plugin does, which is to allow +environment-specific data to be accessible for requests, with public data +available with responses. Instead of the generic 'config' name, we will term this 'gasketData' which pairs well with the `@gasket/data` package - which is what makes this data accessible in browser code. -Existing apps will need to update their Gasket config to use the new plugin name. +Existing apps will need to update their Gasket config to use the new plugin +name. ```js // gasket.js @@ -375,15 +379,16 @@ export default makeGasket({ }); ``` -If you have an `app.config.js` you will want to change the name to `gasket-data.js` +If you have an `app.config.js` you will want to change the name to +`gasket-data.js` ```diff - /app.config.js + /gasket-data.js ``` -Individual environment files are no longer supported out of the box. -You can still use this structure by importing environment-specific to the +Individual environment files are no longer supported out of the box. You can +still use this structure by importing environment-specific to the `gasket-data.js` file and exporting them as environment properties. ```js @@ -423,8 +428,8 @@ export default { } ``` -If you add lifecycle hooks for modifying the config data before, -you will need to update the hook name to `gasketData` and adjust the signature. +If you add lifecycle hooks for modifying the config data before, you will need +to update the hook name to `gasketData` and adjust the signature. - `appEnvConfig` -> `gasketData` - `appRequestConfig` -> `publicGasketData` @@ -433,18 +438,17 @@ See the [@gasket/plugin-data] docs for more details. ## Switch Redux to GasketData -If you are using the [@gasket/plugin-redux] to surface -config-like data to the browser, we recommend switch to GasketData, using the -[@gasket/plugin-data] plugin with [@gasket/data] instead. -The GasketData approach is leaner and works with the Next.js App Router and -Page Router using its built-in server. +If you are using the [@gasket/plugin-redux] to surface config-like data to the +browser, we recommend switch to GasketData, using the [@gasket/plugin-data] +plugin with [@gasket/data] instead. The GasketData approach is leaner and works +with the Next.js App Router and Page Router using its built-in server. -`@gasket/plugin-redux` is not supported for Next.js built-in server apps. +`@gasket/plugin-redux` is not supported for Next.js built-in server apps. -If you have other reasons to stick with Redux, you can still use it -Next.js Page Router using a custom server. However, -you will need to change the store property from `config` -> `gasketData`, -corresponding with the other guidance in the [Switch to GasketData] section. +If you have other reasons to stick with Redux, you can still use it Next.js Page +Router using a custom server. However, you will need to change the store +property from `config` -> `gasketData`, corresponding with the other guidance in +the [Switch to GasketData] section. ![alt text](images/redux-with-gasket-data.png) @@ -452,16 +456,18 @@ corresponding with the other guidance in the [Switch to GasketData] section. Gasket's logging infrastructure was comprised of two main parts: -1. `@gasket/plugin-log`: Manages lifecycle timing and executes the `logTransports` - hook for adding extra transports to the logger configuration. -2. `@gasket/log`: Implements logging using Diagnostics (Client-side) and Winston (Server-side). +1. `@gasket/plugin-log`: Manages lifecycle timing and executes the + `logTransports` hook for adding extra transports to the logger configuration. +2. `@gasket/log`: Implements logging using Diagnostics (Client-side) and Winston + (Server-side). While these components worked together to initialize `gasket.logger`, not all applications utilized them. Additionally, despite Winston's prevalence, we need -to be aware of the numerous logging libraries in the ecosystem when adopting Gasket. -The following updates aim to address these concerns: +to be aware of the numerous logging libraries in the ecosystem when adopting +Gasket. The following updates aim to address these concerns: Updates: + - Removed `@gasket/log` - Created new [@gasket/plugin-logger] to replace `@gasket/plugin-log` - Created new [@gasket/plugin-winston] to customize the default logger @@ -478,8 +484,8 @@ To upgrade your app, first adjust the dependencies in your `package.json`. + "@gasket/plugin-winston": "^7.0.0", ``` -Next, update your `gasket.js` file to use the new plugins. -This examples demonstrates how to migrate from an old `gasket.config.js`. +Next, update your `gasket.js` file to use the new plugins. This examples +demonstrates how to migrate from an old `gasket.config.js`. ```diff // gasket.config.js @@ -505,8 +511,8 @@ This examples demonstrates how to migrate from an old `gasket.config.js`. ``` Existing Gasket apps will need to make changes to how they handle logging. -Logging levels now follow `console` conventions. -Loggers at minimum support the following levels: +Logging levels now follow `console` conventions. Loggers at minimum support the +following levels: - `debug` - `error` @@ -523,7 +529,8 @@ Loggers at minimum support the following levels: + logger.info ``` -The lifecycle method formerly known as `logTransports` is now `winstonTransports`. +The lifecycle method formerly known as `logTransports` is now +`winstonTransports`. ```diff - // /lifecycles/log-transports.js @@ -535,12 +542,11 @@ See the [@gasket/plugin-logger] docs for more details, as well as the ## Update Intl -Previous versions of Gasket generated a `locale-manifest.json` file which was -loaded behind the scene. -In this version, Gasket generates a `intl.js` file which is explicitly imported. -This allows for better transparency and simplifies bundling as it exports a -`intlManager` which handles loading and resolving locale files and can be -bundled with Webpack. +Previous versions of Gasket generated a `locale-manifest.json` file which was +loaded behind the scene. In this version, Gasket generates a `intl.js` file +which is explicitly imported. This allows for better transparency and simplifies +bundling as it exports a `intlManager` which handles loading and resolving +locale files and can be bundled with Webpack. The next sections demonstrate how to use the `intl.js` import. @@ -550,8 +556,9 @@ The [@gasket/react-intl] package is convenience wrapper for connecting [@gasket/plugin-intl] features to a Next.js/React app, and which and had a hard dependency on the `react-intl` package. -In our new version, users have more flexibility to choose their own intl provider. -While `react-intl` is still a good choice, it is no longer a hard dependency. +In our new version, users have more flexibility to choose their own intl +provider. While `react-intl` is still a good choice, it is no longer a hard +dependency. ```diff // pages/_app.js @@ -588,9 +595,8 @@ is required to be passed to the `withMessagesProvider` HOC. This manager is responsible for loading and managing the translations for the app. Locale files that are registered as statics are loaded at app startup and are -available for SSR. -Other locale files can be loaded on-demand in the browser. -No longer is `getInitialProps` or other Next.js props methods required. +available for SSR. Other locale files can be loaded on-demand in the browser. No +longer is `getInitialProps` or other Next.js props methods required. As such, some of the component options have changed, and we adjusted some naming for clarification. @@ -612,20 +618,19 @@ The [@gasket/intl] package should be added as an app dependency. npm install @gasket/intl ``` -The new `intlManager` pattern enables locale files -to be bundled as Webpack chunks. -As such, it is no longer necessary to store these under the public directory of -a Next.js or serve then with an Express endpoint. -The locale files can exist anywhere, though a top-level `/locales` directory is -recommended as a convention. +The new `intlManager` pattern enables locale files to be bundled as Webpack +chunks. As such, it is no longer necessary to store these under the public +directory of a Next.js or serve then with an Express endpoint. The locale files +can exist anywhere, though a top-level `/locales` directory is recommended as a +convention. See [@gasket/plugin-intl] for more details and other changes. ### Move locale files (Optional) -Because the `intl.js` is imported and can be bundle with Webpack, -it is no longer necessary to serve locale files as static files. -As such, for Next.js, these can be moved out of the `./public` directory. +Because the `intl.js` is imported and can be bundle with Webpack, it is no +longer necessary to serve locale files as static files. As such, for Next.js, +these can be moved out of the `./public` directory. ```diff - /public/locales/en-US.json @@ -652,12 +657,12 @@ files: ## Update Custom Commands -Update custom commands to be plugin imports in `gasket.js`. -All commands need to be imported and used in the `makeGasket` function. +Update custom commands to be plugin imports in `gasket.js`. All commands need to +be imported and used in the `makeGasket` function. To create a custom command, you first need to install [@gasket/plugin-command]. -``` +```bash npm i @gasket/plugin-command ``` @@ -770,11 +775,12 @@ See the [@gasket/plugin-command] docs for more details. ## Update App Plugins Previously, custom plugins defined in the `/plugins` directory did not require -any additional configuration. -This is no longer supported in `v7`. -Instead, all plugins will need to be explicitly imported to `gasket.js`. +any additional configuration. This is no longer supported in `v7`. Instead, all +plugins will need to be explicitly imported to `gasket.js`. + +For example, if the plugins folder of your application looks something like the +following: -For example, if the plugins folder of your application looks something like the following: ``` /pages /plugins @@ -783,7 +789,8 @@ For example, if the plugins folder of your application looks something like the gasket.js ``` -The two plugins will be imported to `gasket.js` and added to the list of plugins in `makeGasket`. +The two plugins will be imported to `gasket.js` and added to the list of plugins +in `makeGasket`. ```diff // gasket.js @@ -802,10 +809,10 @@ export default makeGasket({ ## Update App Lifecycles -Support for lifecycle magic directories has also been removed in `v7`. -Now lifecycles need to be defined and hooked in a plugin. -One way of doing this is to create a new plugin, import the lifecycles as hooks, -and then import the plugin to `gasket.js`. +Support for lifecycle magic directories has also been removed in `v7`. Now +lifecycles need to be defined and hooked in a plugin. One way of doing this is +to create a new plugin, import the lifecycles as hooks, and then import the +plugin to `gasket.js`. ```js // /lifecycles/[lifecycle].js @@ -857,16 +864,29 @@ export default { ## Update Mocha Tests -Previously, the `@gasket/plugin-mocha` utilized [babel-register] to compile files on the fly when testing JSX. However, as we move towards ES modules as the default for Gasket apps, we've had to find another solution for transpiling JSX in mohca tests as babel-register does not support compiling ES modules on the fly. +Previously, the `@gasket/plugin-mocha` utilized [babel-register] to compile +files on the fly when testing JSX. However, as we move towards ES modules as the +default for Gasket apps, we've had to find another solution for transpiling JSX +in mohca tests as babel-register does not support compiling ES modules on the +fly. From the Babel docs: -> @babel/register does not support compiling native Node.js ES modules on the fly, since currently there is no stable API for intercepting ES modules loading. +> @babel/register does not support compiling native Node.js ES modules on the +> fly, since currently there is no stable API for intercepting ES modules +> loading. -To work around this, we added a node-loader (`@gasket/plugin-mocha/node-loader-babel`) that uses babel to transpile JSX to JS. This node-loader also gives you the ability to add other babel presets or plugins to a generated `.babelrc` in the test folder in newly created apps using v7. +To work around this, we added a node-loader +(`@gasket/plugin-mocha/node-loader-babel`) that uses babel to transpile JSX to +JS. This node-loader also gives you the ability to add other babel presets or +plugins to a generated `.babelrc` in the test folder in newly created apps using +v7. -To update your existing app to use the node-loader for transpiling JSX in mocha tests, you need to make the following changes after upgrading to the newest version of `@gasket/plugin-mocha`: +To update your existing app to use the node-loader for transpiling JSX in mocha +tests, you need to make the following changes after upgrading to the newest +version of `@gasket/plugin-mocha`: -1. Add `-r ./test/register-loader.js` to your `test:runner` script in your `package.json`: +1. Add `-r ./test/register-loader.js` to your `test:runner` script in your + `package.json`: ```diff - "test:runner": "mocha -r global-jsdom/register -r setup-env --recursive \"test/**/*.{test,spec}.{js,jsx}\"" @@ -893,9 +913,10 @@ import { pathToFileURL } from 'url'; register('@gasket/plugin-mocha/node-loader-babel', pathToFileURL('./test')); ``` -4. Optional: If you to have styles imported into your JSX, you can add our node-loader for handling styles to your `test/register-loader.js` file: +4. Optional: If you to have styles imported into your JSX, you can add our + node-loader for handling styles to your `test/register-loader.js` file: -```diff +```diff import { register } from 'module'; import { pathToFileURL } from 'url'; @@ -906,7 +927,6 @@ register('@gasket/plugin-mocha/node-loader-babel', pathToFileURL('./test')); + register('@gasket/plugin-mocha/node-loader-styles', pathToFileURL('./test')); ``` - [middleware paths]:https://github.com/godaddy/gasket/blob/main/packages/gasket-plugin-express/README.md#middleware-paths [streaming]: https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming @@ -921,14 +941,11 @@ register('@gasket/plugin-mocha/node-loader-babel', pathToFileURL('./test')); [@gasket/react-intl]: ../packages/gasket-react-intl/README.md [@gasket/plugin-data]: ../packages/gasket-plugin-data/README.md [@gasket/data]: ../packages/gasket-data/README.md -[@gasket/plugin-data]: ../packages/gasket-plugin-data/README.md [@gasket/plugin-docusaurus]: ../packages/gasket-plugin-docusaurus/README.md -[@gasket/plugin-data]: ../packages/gasket-plugin-data/README.md [@gasket/plugin-workbox]: ../packages/gasket-plugin-workbox/README.md [@gasket/plugin-nextjs]: ../packages/gasket-plugin-nextjs/README.md [@gasket/plugin-redux]: ../packages/gasket-plugin-redux/README.md [@gasket/plugin-logger]: ../packages/gasket-plugin-logger/README.md -[@gasket/plugin-intl]: ../packages/gasket-plugin-intl/README.md [@gasket/plugin-webpack]: ../packages/gasket-plugin-webpack/README.md [@gasket/plugin-elastic-apm]: ../packages/gasket-plugin-elastic-apm/README.md [@gasket/utils]: ../packages/gasket-utils/README.md diff --git a/package-lock.json b/package-lock.json index 2a5e63852..2a15a6ad6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8936,7 +8936,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -8954,7 +8953,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -8972,7 +8970,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -8990,7 +8987,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9008,7 +9004,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9026,7 +9021,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9044,7 +9038,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9062,7 +9055,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -9080,7 +9072,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -9098,7 +9089,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -17174,6 +17164,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -17184,6 +17175,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -34805,6 +34797,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.9.2" @@ -42276,7 +42269,7 @@ "mkdirp": "^1.0.4", "ora": "3.4.0", "pump": "^3.0.0", - "semver": "^7.5.4", + "semver": "^7.6.3", "tar-fs": "^2.0.0", "untildify": "^4.0.0" }, @@ -42293,7 +42286,8 @@ "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-unicorn": "^55.0.0", - "jest": "^29.7.0" + "jest": "^29.7.0", + "typescript": "^5.4.5" } }, "packages/create-gasket-app/node_modules/commander": { @@ -42693,6 +42687,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-godaddy": "^7.1.1", + "eslint-config-godaddy-typescript": "^4.0.3", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-unicorn": "^55.0.0", @@ -43035,7 +43030,7 @@ "fs-extra": "^10.0.0", "glob": "^8.1.0", "intl": "^1.2.5", - "semver": "^7.5.4" + "semver": "^7.6.3" }, "devDependencies": { "@gasket/core": "^7.0.9", @@ -44199,7 +44194,7 @@ "concat-stream": "^2.0.0", "deepmerge": "^4.3.1", "diagnostics": "^2.0.2", - "semver": "^7.5.4" + "semver": "^7.6.3" }, "devDependencies": { "@gasket/core": "^7.0.9", @@ -44209,6 +44204,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-godaddy": "^7.1.1", + "eslint-config-godaddy-typescript": "^4.0.3", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-unicorn": "^55.0.0", diff --git a/packages/create-gasket-app/README.md b/packages/create-gasket-app/README.md index 81636f9ba..c76410b83 100644 --- a/packages/create-gasket-app/README.md +++ b/packages/create-gasket-app/README.md @@ -81,7 +81,6 @@ Additional code style choices are prompted during the create command. Some predefined choices are provided from the [lint plugin], or you can specify your own config. - ## Lifecycles Lifecycles for apps are enabled by plugins, however the CLI has some built-in @@ -232,7 +231,6 @@ The hook is passed the following parameters: | `utils` | Functions that aid in post create hooks | | `utils.runScript` | run an `npm` script at the root of the generated `npm` package | - ## License [MIT](./LICENSE.md) @@ -245,7 +243,7 @@ The hook is passed the following parameters: [yarn env vars]:https://yarnpkg.com/en/docs/envvars#toc-npm-config [Jest plugin]:/packages/gasket-plugin-jest/README.md [Mocha plugin]:/packages/gasket-plugin-mocha/README.md -[execWaterfall]:/packages/gasket-engine/README.md#execwaterfallevent-value-args -[exec]:/packages/gasket-engine/README.md#execevent-args +[execWaterfall]:/packages/gasket-core/docs/gasket-engine.md#execwaterfallevent-value-args +[exec]:/packages/gasket-core/docs/gasket-engine.md#execevent-args [inquirer questions]:https://github.com/SBoudrias/Inquirer.js#question [lint plugin]:/packages/gasket-plugin-lint/README.md diff --git a/packages/create-gasket-app/package.json b/packages/create-gasket-app/package.json index 267362ac1..39a8c672a 100644 --- a/packages/create-gasket-app/package.json +++ b/packages/create-gasket-app/package.json @@ -17,9 +17,9 @@ "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict --experimental-vm-modules' jest", "test:watch": "npm run test -- --watch", "test:coverage": "jest --coverage", + "posttest": "npm run lint && npm run typecheck", "typecheck": "tsc", - "typecheck:watch": "tsc --watch", - "posttest": "npm run lint && npm run typecheck" + "typecheck:watch": "tsc --watch" }, "repository": { "type": "git", @@ -52,7 +52,7 @@ "mkdirp": "^1.0.4", "ora": "3.4.0", "pump": "^3.0.0", - "semver": "^7.5.4", + "semver": "^7.6.3", "tar-fs": "^2.0.0", "untildify": "^4.0.0" }, @@ -66,7 +66,8 @@ "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-unicorn": "^55.0.0", - "jest": "^29.7.0" + "jest": "^29.7.0", + "typescript": "^5.4.5" }, "eslintConfig": { "extends": [ diff --git a/packages/gasket-core/docs/gasket-engine.md b/packages/gasket-core/docs/gasket-engine.md index a2cec1234..ff2b36e36 100644 --- a/packages/gasket-core/docs/gasket-engine.md +++ b/packages/gasket-core/docs/gasket-engine.md @@ -121,11 +121,7 @@ and register their hooks. The Gasket Engine uses the [`debug`](https://www.npmjs.com/package/debug) package to trace the plugin lifecycle. If you set the `DEBUG` environment variable to `gasket:engine` you'll see additional output in `stderr` indicating when things are invoked. -## License - -[MIT](./LICENSE.md) - -[preset guide]: /docs/presets.md -[plugin guide]: /docs/plugins.md +[preset guide]: /docs/authoring-presets.md +[plugin guide]: /docs/authoring-plugins.md diff --git a/packages/gasket-core/package.json b/packages/gasket-core/package.json index f72010cda..efc381763 100644 --- a/packages/gasket-core/package.json +++ b/packages/gasket-core/package.json @@ -28,8 +28,8 @@ "typecheck:watch": "tsc --watch", "build": "swc lib -d cjs --delete-dir-on-start --strip-leading-paths", "build:watch": "npm run build -- --watch", - "postbuild": "node -e \"require('fs').writeFileSync('cjs/package.json', '{}')\"", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "postbuild": "node -e \"require('fs').writeFileSync('cjs/package.json', '{}')\"" }, "repository": { "type": "git", diff --git a/packages/gasket-data/package.json b/packages/gasket-data/package.json index c5f27224b..e64aca2b7 100644 --- a/packages/gasket-data/package.json +++ b/packages/gasket-data/package.json @@ -26,8 +26,8 @@ "typecheck": "tsc", "typecheck:watch": "tsc --watch", "build": "swc lib -d cjs --delete-dir-on-start --strip-leading-paths --out-file-extension cjs", - "postbuild": "node -e \"require('fs').writeFileSync('cjs/package.json', '{}')\"", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "postbuild": "node -e \"require('fs').writeFileSync('cjs/package.json', '{}')\"" }, "repository": { "type": "git", diff --git a/packages/gasket-intl/README.md b/packages/gasket-intl/README.md index d09d32846..2d577cca5 100644 --- a/packages/gasket-intl/README.md +++ b/packages/gasket-intl/README.md @@ -10,7 +10,6 @@ npm i @gasket/intl @gasket/plugin-intl See [@gasket/plugin-intl] for more information on how to configure the plugin. - ## Usage With a `intl.js` built by [@gasket/plugin-intl], you can use the manager to @@ -40,16 +39,12 @@ await localeHandler.load('locales/examples') localeHandler.getAllMessages(); ``` - ### _TODO: more examples coming_ - ## License [MIT](./LICENSE.md) - [@gasket/plugin-intl]: /packages/gasket-plugin-intl/README.md - diff --git a/packages/gasket-plugin-command/README.md b/packages/gasket-plugin-command/README.md index d1f017358..64eafcd9b 100644 --- a/packages/gasket-plugin-command/README.md +++ b/packages/gasket-plugin-command/README.md @@ -1,8 +1,9 @@ # @gasket/plugin-command -Enable plugins to inject new commands to be available for use with the Gasket -CLI. Executes the `commands` lifecycle in the `configure` hook of the -`@gasket/plugin-command` plugin. This plugin utilizes [Commander.js] and additional documentation can be found in the documentation. +This plugin enables other plugins to define and inject custom commands into the +Gasket CLI. It executes the `commands` lifecycle during the `configure` hook, +allowing you to extend the functionality of the Gasket CLI with custom commands. +The plugin utilizes [Commander.js] for command management. ## Installation @@ -10,7 +11,7 @@ CLI. Executes the `commands` lifecycle in the `configure` hook of the npm i @gasket/plugin-command ``` -Update your `gasket` file plugin configuration: +Update your Gasket configuration to include the plugin: ```diff import { makeGasket } from '@gasket/core'; @@ -24,212 +25,205 @@ export default makeGasket({ }); ``` +--- + ## Lifecycles -### Commands +### commands + +The `commands` lifecycle is executed during the `configure` hook if the `gasket` +CLI command is present in the `argv`. You can define commands that include +arguments, options, and custom parsing logic. + +#### Examples Basic Command -Executed in the `configure` hook of `@gasket/plugin-command` if the `gasket` command is present in the `argv`. The `gasket` command is the CLI execution of the `gasket.js` file. +Define a command with a description and an action: ```js export default { - name: 'test-plugin', + name: 'example-plugin', hooks: { commands(gasket) { return { - id: 'test-plugin-cmd', - description: 'Test plugin', + id: 'example-cmd', + description: 'Example command', action: async () => { - console.log('test-plugin'); + console.log('Hello from example command!'); } - } + }; } } }; ``` -Commands can be configured with options (flags), arguments, defaults, and parsing functions. +Execute the command: + +```bash +node ./gasket.js example-cmd +# Output: Hello from example command! +``` -#### Example with arguments +--- -Add arguments to the command by adding an `args` array in the command definition. +#### Example Command with Arguments + +Add arguments to your command using the `args` array: ```js export default { - name: 'test-plugin', + name: 'example-plugin', hooks: { commands(gasket) { return { - id: 'test-plugin-cmd', - description: 'Test plugin', + id: 'example-cmd', + description: 'Example command with arguments', args: [ { name: 'message', description: 'Message to display', - required: true // error if message argument is not provided - }, - { - name: 'optional-message', - description: 'Optional message to display' + required: true } ], - // Arguments are spread into the action function - action: async (message, optionalMessage) => { - console.log('test-plugin', message); - console.log('test-plugin:optional', optionalMessage); + action: async (message) => { + console.log('Message:', message); } - } + }; } } }; ``` -Execute the command with the `message` argument. +Run with arguments: ```bash -node ./gasket.js test-plugin-cmd "Hello, World!" -# result: test-plugin Hello, World! - -# Optional message -node ./gasket.js test-plugin-cmd "Hello, World!" "Optional message" -# result: test-plugin Hello, World! -# result: test-plugin:optional Optional message +node ./gasket.js example-cmd "Hello, World!" +# Output: Message: Hello, World! ``` -#### Example with options - -Add options to the command by adding an `options` array in the command definition. +#### Example Command with Options ```js export default { - name: 'test-plugin', + name: 'example-plugin', hooks: { commands(gasket) { return { - id: 'test-plugin-cmd', - description: 'Test plugin', + id: 'example-cmd', + description: 'Example command with options', options: [ { name: 'message', description: 'Message to display', - required: true, // error if --message option is not provided + required: true, short: 'm', type: 'string' - }, - { - name: 'optional-message', - description: 'Optional message to display', - short: 'op', - type: 'string' } - ] - // hyphenated options are camelCased - action: async ({ message, optionalMessage }) => { - console.log('test-plugin', message); - console.log('test-plugin:optional', optionalMessage); + ], + action: async ({ message }) => { + console.log('Message:', message); } - } + }; } } }; ``` -Execute the command with the `--message` option. +Run with options: ```bash -node ./gasket.js test-plugin-cmd --message "Hello, World!" -# result: test-plugin Hello, World! - -# Short option -node ./gasket.js test-plugin-cmd -m "Hello, World!" -# result: test-plugin Hello, World! - -# Optional message -node ./gasket.js test-plugin-cmd --message "Hello, World!" --optional-message "Optional message" -# result: test-plugin Hello, World! -# result: test-plugin:optional Optional message +node ./gasket.js example-cmd --message "Hello, World!" +# Output: Message: Hello, World! ``` -#### Example with parsing function +#### Example Command with Parsing -Add a `parse` function to the option to parse the value before it is passed to the action function. +Use a custom `parse` function to transform option values: ```js export default { - name: 'test-plugin', + name: 'example-plugin', hooks: { commands(gasket) { return { - id: 'test-plugin-cmd', - description: 'Test plugin', - args: [ - { - name: 'numberOfItems', - description: 'Retrieve a number of items from an array', - required: true // error if message argument is not provided - } - ], + id: 'example-cmd', + description: 'Example command with parsing', options: [ { - name: 'groceryList', - description: 'List of grocery items', + name: 'list', + description: 'Comma-separated list of items', required: true, type: 'string', - parse: (value) => value.split(',') // split string to an array + parse: (value) => value.split(',') } ], - // args are spread and options are passed as an object - action: async (numberOfItems, { groceryList }) => { - const items = groceryList.slice(0, numberOfItems); - console.log('test-plugin', items); + action: async ({ list }) => { + console.log('Parsed List:', list); } - } + }; + } + } +}; +``` + +Run with parsing: + +```bash +node ./gasket.js example-cmd --list "apple,banana,orange" +# Output: Parsed List: [ 'apple', 'banana', 'orange' ] +``` + +### build + +The `build` lifecycle allows plugins to hook into the application's build +process. This lifecycle is triggered by the `build` command in the Gasket CLI. + +#### Example + +Define a plugin that hooks into the `build` lifecycle: + +```js +export default { + name: 'example-plugin', + hooks: { + async build(gasket) { + console.log('Running custom build logic...'); } } }; ``` -Execute the command with the `--groceryList` option. +Run the `build` command: ```bash -node ./gasket.js test-plugin-cmd 3 --groceryList "apple,banana,orange,grape" -# result: test-plugin [ 'apple', 'banana', 'orange' ] +node ./gasket.js build +# Output: +# Running custom build logic... ``` #### Example with JSDoc Types -The `CommandsHook` type is available for type checking your hook's arguments and options. +For type safety, use the `CommandsHook` type: ```js export default { - name: 'test-plugin', + name: 'example-plugin', hooks: { - /* @type {import('@gasket/plugin-command').CommandsHook} */ + /** @type {import('@gasket/plugin-command').CommandsHook} */ commands(gasket) { return { - id: 'test-plugin-cmd', - description: 'Test plugin', + id: 'example-cmd', + description: 'Example command', args: [ { - name: 'numberOfItems', - description: 'Retrieve a number of items from an array', - required: true // error if message argument is not provided - } - ], - options: [ - { - name: 'groceryList', - description: 'List of grocery items', - required: true, - type: 'string', - parse: (value) => value.split(',') // split string to an array + name: 'message', + description: 'Message to display', + required: true } ], - // args are spread and options are passed as an object - action: async (numberOfItems, { groceryList }) => { - const items = groceryList.slice(0, numberOfItems); - console.log('test-plugin', items); + action: async (message) => { + console.log('Message:', message); } - } + }; } } }; diff --git a/packages/gasket-plugin-command/lib/cli.js b/packages/gasket-plugin-command/lib/cli.js index 63f46b5dc..084476ba3 100644 --- a/packages/gasket-plugin-command/lib/cli.js +++ b/packages/gasket-plugin-command/lib/cli.js @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { logo } from './utils/index.js'; +import { logo } from './utils/logo.js'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); const { version } = require('../package.json'); @@ -12,4 +12,4 @@ export const gasketBin = program .version(version) .addHelpText('beforeAll', logo); -export { processCommand } from './utils/index.js'; +export { processCommand } from './utils/process-command.js'; diff --git a/packages/gasket-plugin-command/lib/create.js b/packages/gasket-plugin-command/lib/create.js index 4ab64fd7c..f456475b5 100644 --- a/packages/gasket-plugin-command/lib/create.js +++ b/packages/gasket-plugin-command/lib/create.js @@ -1,3 +1,5 @@ +/// + import { createRequire } from 'module'; const require = createRequire(import.meta.url); const { name, version } = require('../package.json'); diff --git a/packages/gasket-plugin-command/lib/index.d.ts b/packages/gasket-plugin-command/lib/index.d.ts index 6b82028d6..5dc3b2947 100644 --- a/packages/gasket-plugin-command/lib/index.d.ts +++ b/packages/gasket-plugin-command/lib/index.d.ts @@ -1,6 +1,8 @@ -import type { MaybeAsync, GasketConfig, Hook } from '@gasket/core'; -import type { PluginData } from '@gasket/plugin-metadata'; -import type { Command, Option } from 'commander'; +import type { Plugin, MaybeAsync } from '@gasket/core'; +import type { + GasketArgDefinition, + GasketOptionDefinition +} from './internal.js'; export interface GasketCommandDefinition { /* Command id/name */ @@ -25,92 +27,16 @@ export interface GasketCommandDefinition { default?: boolean; } -export interface GasketCommand { - command: Command; - hidden: boolean; - isDefault: boolean; -} - -// Default cannot be used when required is true -export type GasketArgDefinition = { - /* Argument name */ - name: string; - - /* Argument description */ - description: string; - - /* Is the argument required */ - required?: true; - - /* Default value for the argument - never if required is true*/ - default?: never; -} | { - name: string; - description: string; - required?: false; - default?: any; -}; - -export type GasketCommandArg = Parameters - -export interface GasketOptionDefinition { - /* Long option name */ - name: string; - - /* Option description */ - description: string; - - /* Is the option required */ - required?: boolean; - - /* Short option name */ - short?: string; - - /* Function to parse the option value */ - parse?: (value: string) => any; - - /* Default is always string - boolean changes the format of the option */ - type?: 'string' | 'boolean'; - - /* list of option names that cannot be used together */ - conflicts?: Array; - - /* Hide from command help output */ - hidden?: boolean; - - /* Default option value */ - default?: any; -} - -/* Processed Option */ -export interface GasketCommandOption { - options: ConstructorParameters; - conflicts: Array; - hidden: boolean; - defaultValue: any | undefined; - parse: (value: string) => any | undefined; - required: boolean; -} - -export type CommandsHook = Hook<'commands'>; - -export function processCommand(command: GasketCommandDefinition): GasketCommand; - declare module '@gasket/core' { - - export interface GasketActions { - performCommand(): any; - } - - export interface HookExecTypes { - build(): any; + interface HookExecTypes { commands(): GasketCommandDefinition; + build(): void; } } -export default { +const plugin: Plugin = { name: '@gasket/plugin-command', - version: '', - description: '', hooks: {} }; + +export default plugin; diff --git a/packages/gasket-plugin-command/lib/index.js b/packages/gasket-plugin-command/lib/index.js index 61f510342..da44159b2 100644 --- a/packages/gasket-plugin-command/lib/index.js +++ b/packages/gasket-plugin-command/lib/index.js @@ -1,3 +1,5 @@ +/// + import create from './create.js'; import ready from './ready.js'; import commands from './commands.js'; @@ -17,13 +19,27 @@ export default { metadata(gasket, meta) { return { ...meta, + commands: [ + { + name: 'build', + description: 'Gasket build command', + link: 'README.md#build' + } + ], lifecycles: [ { name: 'commands', - method: 'execSync', + method: 'exec', description: 'Add custom commands to the CLI', link: 'README.md#commands', parent: 'ready' + }, + { + name: 'build', + method: 'exec', + description: 'Gasket build lifecycle', + link: 'README.md#build', + parent: 'commands' } ] }; diff --git a/packages/gasket-plugin-command/lib/internal.d.ts b/packages/gasket-plugin-command/lib/internal.d.ts new file mode 100644 index 000000000..ac37a0887 --- /dev/null +++ b/packages/gasket-plugin-command/lib/internal.d.ts @@ -0,0 +1,90 @@ +import type { Hook } from '@gasket/core'; +import type { Command, Option } from 'commander'; +import type { GasketCommandDefinition } from './index.d.ts'; + +/* Processed Option */ +interface GasketCommandOption { + options: ConstructorParameters; + conflicts: Array; + hidden: boolean; + defaultValue: any | undefined; + parse: (value: string) => any | undefined; + required: boolean; +} + +export function createOption(definition: GasketCommandOption): Option; + +// Default cannot be used when required is true +type GasketArgDefinition = + | { + /* Argument name */ + name: string; + + /* Argument description */ + description: string; + + /* Is the argument required */ + required?: true; + + /* Default value for the argument - never if required is true*/ + default?: never; + } + | { + name: string; + description: string; + required?: false; + default?: any; + }; + +export function isValidArg(arg: GasketArgDefinition): boolean; + +type GasketCommandArg = Parameters; + +export function processArgs(args: GasketArgDefinition[]): GasketCommandArg[]; + +export function isValidCommand(command: GasketCommandDefinition): boolean; + +interface GasketCommand { + command: Command; + hidden: boolean; + isDefault: boolean; +} + +interface GasketOptionDefinition { + /* Long option name */ + name: string; + + /* Option description */ + description: string; + + /* Is the option required */ + required?: boolean; + + /* Short option name */ + short?: string; + + /* Function to parse the option value */ + parse?: (value: string) => any; + + /* Default is always string - boolean changes the format of the option */ + type?: 'string' | 'boolean'; + + /* list of option names that cannot be used together */ + conflicts?: Array; + + /* Hide from command help output */ + hidden?: boolean; + + /* Default option value */ + default?: any; +} + +type CommandsHook = Hook<'commands'>; + +export function processCommand(command: GasketCommandDefinition): GasketCommand; + +export function isValidOption(option: GasketOptionDefinition): boolean; + +export function processOptions( + options: GasketOptionDefinition[] +): GasketCommandOption[]; diff --git a/packages/gasket-plugin-command/lib/utils/create-option.js b/packages/gasket-plugin-command/lib/utils/create-option.js index c80c7222e..676819930 100644 --- a/packages/gasket-plugin-command/lib/utils/create-option.js +++ b/packages/gasket-plugin-command/lib/utils/create-option.js @@ -1,9 +1,8 @@ import { Option } from 'commander'; /** - * createOption - Create a commander option - * @param {import('../index.d.ts').GasketCommandOption} definition - The option configuration - * @returns {import('commander').Option} option + * Create a commander option + * @type {import('../internal.d.ts').createOption} */ export function createOption(definition) { const option = new Option(...definition.options); diff --git a/packages/gasket-plugin-command/lib/utils/index.js b/packages/gasket-plugin-command/lib/utils/index.js deleted file mode 100644 index fd09d8a24..000000000 --- a/packages/gasket-plugin-command/lib/utils/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export { processCommand } from './process-command.js'; -export { processArgs } from './process-args.js'; -export { processOptions } from './process-options.js'; -export { createOption } from './create-option.js'; -export { logo } from './logo.js'; diff --git a/packages/gasket-plugin-command/lib/utils/process-args.js b/packages/gasket-plugin-command/lib/utils/process-args.js index eca8ef0c8..aa75f69ce 100644 --- a/packages/gasket-plugin-command/lib/utils/process-args.js +++ b/packages/gasket-plugin-command/lib/utils/process-args.js @@ -1,24 +1,22 @@ /** * isValidArg - Validates the argument configuration - * @param {import('../index.d.ts').GasketArgDefinition} arg The argument configuration - * @returns {boolean} True if valid, false otherwise + * @type {import('../internal.d.ts').isValidArg} */ function isValidArg(arg) { const keys = Object.keys(arg); if (arg.required && arg.default) return false; - const isValid = keys.length && - keys.length <= 4 && - arg.name && arg.description; + const isValid = + keys.length && keys.length <= 4 && arg.name && arg.description; return Boolean(isValid); } /** - * processArgs - Process the arguments configuration - * @param {import('../index.d.ts').GasketArgDefinition[]} args Array of argument configurations - * @returns {import('../index.d.ts').GasketCommandArg[]} Array of argument definitions + * Process the arguments configuration + * @type {import('../internal.d.ts').processArgs} */ export function processArgs(args) { - if (!Array.isArray(args) || !args.every(isValidArg)) throw new Error('Invalid argument(s) configuration'); + if (!Array.isArray(args) || !args.every(isValidArg)) + throw new Error('Invalid argument(s) configuration'); return args.reduce((acc, arg) => { const def = []; diff --git a/packages/gasket-plugin-command/lib/utils/process-command.js b/packages/gasket-plugin-command/lib/utils/process-command.js index a5b459455..5a49658ac 100644 --- a/packages/gasket-plugin-command/lib/utils/process-command.js +++ b/packages/gasket-plugin-command/lib/utils/process-command.js @@ -5,41 +5,48 @@ import { createOption } from './create-option.js'; const program = new Command(); /** - * isValidCommand - Validates the command configuration - * @param {import('../index.d.ts').GasketCommandDefinition} command The command configuration - * @returns {boolean} True if valid, false otherwise + * Validates the command configuration + * @type {import('../internal.d.ts').isValidCommand} */ function isValidCommand(command) { const keys = Object.keys(command); - return keys.length && + return ( + keys.length && keys.length <= 7 && command && command.id && command.description && command.action && - typeof command.action === 'function'; + typeof command.action === 'function' + ); } /** - * processCommand - Process the command configuration - * @type {import('../index.d.ts').processCommand} + * Process the command configuration + * @type {import('../internal.d.ts').processCommand} */ export function processCommand(command) { - if (!isValidCommand(command)) throw new Error('Invalid command configuration'); - const { id, description, action, args, options, hidden = false, default: isDefault = false } = command; - const cmd = program - .command(id) - .description(description) - .action(action); + if (!isValidCommand(command)) + throw new Error('Invalid command configuration'); + const { + id, + description, + action, + args, + options, + hidden = false, + default: isDefault = false + } = command; + const cmd = program.command(id).description(description).action(action); if (args) { const cmdArgs = processArgs(args); - cmdArgs.forEach(arg => cmd.argument(...arg)); + cmdArgs.forEach((arg) => cmd.argument(...arg)); } if (options) { const cmdOpts = processOptions(options); - cmdOpts.forEach(o => { + cmdOpts.forEach((o) => { const option = createOption(o); cmd.addOption(option); }); diff --git a/packages/gasket-plugin-command/lib/utils/process-options.js b/packages/gasket-plugin-command/lib/utils/process-options.js index 5f1d1b298..a1496a2a0 100644 --- a/packages/gasket-plugin-command/lib/utils/process-options.js +++ b/packages/gasket-plugin-command/lib/utils/process-options.js @@ -1,24 +1,21 @@ /** - * isValidOption - Validate the option - * @param {import('../index.d.ts').GasketOptionDefinition} option The option configuration - * @returns {boolean} True if valid, false otherwise + * Validate the option + * @type {import('../internal.d.ts').isValidOption} */ function isValidOption(option) { const keys = Object.keys(option); - const isValid = keys.length && - keys.length <= 5 && - option.name && - option.description; + const isValid = + keys.length && keys.length <= 5 && option.name && option.description; return Boolean(isValid); } /** - * processOptions - Process the options configuration - * @param {import('../index.d.ts').GasketOptionDefinition[]} options Array of option configurations - * @returns {import('../index.d.ts').GasketCommandOption[]} Processed option definitions + * Process the options configuration + * @type {import('../internal.d.ts').processOptions} */ export function processOptions(options) { - if (!Array.isArray(options) || !options.every(isValidOption)) throw new Error('Invalid option(s) configuration'); + if (!Array.isArray(options) || !options.every(isValidOption)) + throw new Error('Invalid option(s) configuration'); return options.reduce((acc, option) => { const def = []; @@ -38,7 +35,14 @@ export function processOptions(options) { const flags = short ? `-${short}, --${name}` : `--${name}`; def.push(`${flags}${type !== 'boolean' ? ` ${format}` : ''}`, description); - acc.push({ options: def, conflicts, hidden, defaultValue, parse, required }); + acc.push({ + options: def, + conflicts, + hidden, + defaultValue, + parse, + required + }); return acc; }, []); diff --git a/packages/gasket-plugin-command/package.json b/packages/gasket-plugin-command/package.json index bfdbdc378..9bffb6df7 100644 --- a/packages/gasket-plugin-command/package.json +++ b/packages/gasket-plugin-command/package.json @@ -8,9 +8,7 @@ "lib" ], "exports": { - ".": { - "import": "./lib/index.js" - }, + ".": "./lib/index.js", "./package.json": "./package.json" }, "scripts": { @@ -19,7 +17,9 @@ "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict --experimental-vm-modules' jest", "test:watch": "npm run test -- --watch", "test:coverage": "npm run test -- --coverage", - "posttest": "npm run lint" + "posttest": "npm run lint && npm run typecheck", + "typecheck": "tsc", + "typecheck:watch": "tsc --watch" }, "repository": { "type": "git", @@ -29,9 +29,9 @@ "access": "public" }, "keywords": [ + "command", "gasket", - "plugin", - "command" + "plugin" ], "author": "GoDaddy Operating Company, LLC", "license": "MIT", @@ -50,6 +50,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-godaddy": "^7.1.1", + "eslint-config-godaddy-typescript": "^4.0.3", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-unicorn": "^55.0.0", @@ -68,6 +69,19 @@ ], "rules": { "unicorn/filename-case": "error" - } + }, + "ignorePatterns": [ + "cjs/" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "extends": [ + "godaddy-typescript" + ] + } + ] } } diff --git a/packages/gasket-plugin-command/test/cli.test.js b/packages/gasket-plugin-command/test/cli.test.js index 95650cdde..8b9adf3bd 100644 --- a/packages/gasket-plugin-command/test/cli.test.js +++ b/packages/gasket-plugin-command/test/cli.test.js @@ -1,10 +1,11 @@ -import { gasketBin, processCommand } from '../lib/cli.js'; import { createRequire } from 'module'; +import { gasketBin } from '../lib/cli'; +import { processCommand } from '../lib/utils/process-command'; + const require = createRequire(import.meta.url); const { version } = require('../package.json'); describe('cli', () => { - it('should have a gasketBin property', () => { expect(gasketBin).toEqual(expect.any(Object)); }); diff --git a/packages/gasket-plugin-command/test/index.test.js b/packages/gasket-plugin-command/test/index.test.js index 610ba3c04..1de7443bb 100644 --- a/packages/gasket-plugin-command/test/index.test.js +++ b/packages/gasket-plugin-command/test/index.test.js @@ -1,10 +1,13 @@ import plugin from '../lib/index.js'; +import create from '../lib/create.js'; +import ready from '../lib/ready.js'; +import commands from '../lib/commands.js'; import { createRequire } from 'module'; + const require = createRequire(import.meta.url); const { name, version, description } = require('../package.json'); describe('@gasket/plugin-command', () => { - it('should export an object', () => { expect(plugin).toEqual(expect.any(Object)); }); @@ -16,12 +19,65 @@ describe('@gasket/plugin-command', () => { expect(plugin).toHaveProperty('hooks'); }); + it('should have a create hook', () => { + expect(plugin.hooks.create).toBe(create); + expect(plugin.hooks.create).toEqual(expect.any(Function)); + }); + it('should have a ready hook', () => { + expect(plugin.hooks.ready).toBe(ready); expect(plugin.hooks.ready).toEqual(expect.any(Function)); }); + it('should have a commands hook', () => { + expect(plugin.hooks.commands).toBe(commands); + expect(plugin.hooks.commands).toEqual(expect.any(Function)); + }); + + it('should include a metadata hook', () => { + expect(plugin.hooks.metadata).toEqual(expect.any(Function)); + }); + + it('should return metadata from the metadata hook', () => { + const gasket = {}; // Mock Gasket instance + const meta = { existing: 'value' }; + + const result = plugin.hooks.metadata(gasket, meta); + + expect(result).toEqual( + expect.objectContaining({ + existing: 'value', + commands: expect.arrayContaining([ + { + name: 'build', + description: 'Gasket build command', + link: 'README.md#build' + } + ]), + lifecycles: expect.arrayContaining([ + { + name: 'commands', + method: 'exec', + description: 'Add custom commands to the CLI', + link: 'README.md#commands', + parent: 'ready' + }, + { + name: 'build', + method: 'exec', + description: 'Gasket build lifecycle', + link: 'README.md#build', + parent: 'commands' + } + ]) + }) + ); + }); + it('should have expected hooks', () => { - const expected = ['ready']; - expect(Object.keys(plugin.hooks)).toEqual(expect.arrayContaining(expected)); + const expectedHooks = ['create', 'ready', 'commands', 'metadata']; + expect(Object.keys(plugin.hooks)).toEqual( + expect.arrayContaining(expectedHooks) + ); }); }); diff --git a/packages/gasket-plugin-command/test/utils/create-option.test.js b/packages/gasket-plugin-command/test/utils/create-option.test.js index 1479db919..059a2b3ca 100644 --- a/packages/gasket-plugin-command/test/utils/create-option.test.js +++ b/packages/gasket-plugin-command/test/utils/create-option.test.js @@ -1,4 +1,4 @@ -import { createOption } from '../../lib/utils/index.js'; +import { createOption } from '../../lib/utils/create-option.js'; describe('createOption', () => { diff --git a/packages/gasket-plugin-command/test/utils/process-args.test.js b/packages/gasket-plugin-command/test/utils/process-args.test.js index 216894f5c..6bad7fd2a 100644 --- a/packages/gasket-plugin-command/test/utils/process-args.test.js +++ b/packages/gasket-plugin-command/test/utils/process-args.test.js @@ -1,4 +1,4 @@ -import { processArgs } from '../../lib/utils/index.js'; +import { processArgs } from '../../lib/utils/process-args.js'; describe('processArgs', () => { let mockArgs; @@ -11,9 +11,10 @@ describe('processArgs', () => { }); describe('isValidArg', () => { - it('throws an error if args is not an array', () => { - expect(() => processArgs({})).toThrow('Invalid argument(s) configuration'); + expect(() => processArgs({})).toThrow( + 'Invalid argument(s) configuration' + ); }); it('throws an error if args is not an array of valid args', () => { @@ -22,22 +23,30 @@ describe('processArgs', () => { it('throws an error if an arg is not an object', () => { mockArgs.push('not an object'); - expect(() => processArgs(mockArgs)).toThrow('Invalid argument(s) configuration'); + expect(() => processArgs(mockArgs)).toThrow( + 'Invalid argument(s) configuration' + ); }); it('throws an error if an arg is missing a name', () => { delete mockArgs[0].name; - expect(() => processArgs(mockArgs)).toThrow('Invalid argument(s) configuration'); + expect(() => processArgs(mockArgs)).toThrow( + 'Invalid argument(s) configuration' + ); }); it('throws an error if an arg is missing a description', () => { delete mockArgs[0].description; - expect(() => processArgs(mockArgs)).toThrow('Invalid argument(s) configuration'); + expect(() => processArgs(mockArgs)).toThrow( + 'Invalid argument(s) configuration' + ); }); it('throws if required is true and default is provided', () => { mockArgs[0].default = 'default'; - expect(() => processArgs(mockArgs)).toThrow('Invalid argument(s) configuration'); + expect(() => processArgs(mockArgs)).toThrow( + 'Invalid argument(s) configuration' + ); }); }); diff --git a/packages/gasket-plugin-command/test/utils/process-command.test.js b/packages/gasket-plugin-command/test/utils/process-command.test.js index 3dc678f72..51f3e6b7c 100644 --- a/packages/gasket-plugin-command/test/utils/process-command.test.js +++ b/packages/gasket-plugin-command/test/utils/process-command.test.js @@ -1,24 +1,29 @@ import { jest } from '@jest/globals'; import { Command } from 'commander'; -import { processCommand } from '../../lib/utils/index.js'; +import { processCommand } from '../../lib/utils/process-command.js'; describe('process-command', () => { - describe('isValidCommand', () => { it('throws error for undefined command', () => { expect(() => processCommand({})).toThrow('Invalid command configuration'); }); it('throws error on missing id', () => { - expect(() => processCommand({ description: 'test', action: () => { } })).toThrow('Invalid command configuration'); + expect(() => + processCommand({ description: 'test', action: () => {} }) + ).toThrow('Invalid command configuration'); }); it('throws error on missing description', () => { - expect(() => processCommand({ id: 'test', action: () => { } })).toThrow('Invalid command configuration'); + expect(() => processCommand({ id: 'test', action: () => {} })).toThrow( + 'Invalid command configuration' + ); }); it('throws error on missing action', () => { - expect(() => processCommand({ id: 'test', description: 'test' })).toThrow('Invalid command configuration'); + expect(() => processCommand({ id: 'test', description: 'test' })).toThrow( + 'Invalid command configuration' + ); }); }); @@ -26,7 +31,7 @@ describe('process-command', () => { const cmd = { id: 'test1', description: 'test command', - action: () => { }, + action: () => {}, args: [{ name: 'arg', description: 'arg description' }], options: [{ name: 'option', description: 'option description' }] }; @@ -43,7 +48,7 @@ describe('process-command', () => { id: 'test2', description: 'test command', options: [{ name: 'option', description: 'option description' }], - action: () => { } + action: () => {} }; const { command } = processCommand(cmd); expect(command).toBeDefined(); @@ -58,7 +63,7 @@ describe('process-command', () => { id: 'test3', description: 'test command', args: [{ name: 'arg', description: 'arg description' }], - action: () => { } + action: () => {} }; const { command } = processCommand(cmd); expect(command).toBeDefined(); @@ -72,7 +77,7 @@ describe('process-command', () => { const cmd = { id: 'test4', description: 'test command', - action: () => { } + action: () => {} }; const { command } = processCommand(cmd); expect(command).toBeDefined(); @@ -89,29 +94,33 @@ describe('process-command', () => { program.name('process-command-test'); program.exitOverride(); program.configureOutput({ - writeErr: () => { }, - writeOut: (str) => { output = str; } + writeErr: () => {}, + writeOut: (str) => { + output = str; + } }); return program; })(); const hiddenCmd = { id: 'hidden-cmd', description: 'test command', - action: () => { }, + action: () => {}, hidden: true }; const visibleCmd = { id: 'visible-cmd', description: 'test command', - action: () => { } + action: () => {} }; const hiddenProcessed = processCommand(hiddenCmd); const visibleProcessed = processCommand(visibleCmd); bin.addCommand(hiddenProcessed.command, { hidden: hiddenProcessed.hidden }); - bin.addCommand(visibleProcessed.command, { hidden: visibleProcessed.hidden }); + bin.addCommand(visibleProcessed.command, { + hidden: visibleProcessed.hidden + }); try { await bin.parseAsync(['node', 'process-command-test', '--help']); @@ -133,26 +142,34 @@ describe('process-command', () => { return program; })(); - const spy = jest.spyOn(console, 'log').mockImplementation(() => { }); + const spy = jest.spyOn(console, 'log').mockImplementation(() => {}); const defaultCmd = { id: 'default-cmd', description: 'test command', // eslint-disable-next-line no-console - action: () => { console.log('default-cmd output greatness'); }, + action: () => { + console.log('default-cmd output greatness'); + }, default: true }; const nonDefaultCmd = { id: 'non-default-cmd', description: 'test command', - action: () => { } + action: () => {} }; const defaultProcessed = processCommand(defaultCmd); const nonDefaultProcessed = processCommand(nonDefaultCmd); - bin.addCommand(defaultProcessed.command, { hidden: defaultProcessed.hidden, isDefault: defaultProcessed.isDefault }); - bin.addCommand(nonDefaultProcessed.command, { hidden: nonDefaultProcessed.hidden, isDefault: nonDefaultProcessed.isDefault }); + bin.addCommand(defaultProcessed.command, { + hidden: defaultProcessed.hidden, + isDefault: defaultProcessed.isDefault + }); + bin.addCommand(nonDefaultProcessed.command, { + hidden: nonDefaultProcessed.hidden, + isDefault: nonDefaultProcessed.isDefault + }); try { await bin.parseAsync(['node', 'process-command-test']); diff --git a/packages/gasket-plugin-command/test/utils/process-options.test.js b/packages/gasket-plugin-command/test/utils/process-options.test.js index 775cf4a1c..52f92cad9 100644 --- a/packages/gasket-plugin-command/test/utils/process-options.test.js +++ b/packages/gasket-plugin-command/test/utils/process-options.test.js @@ -1,22 +1,25 @@ /* eslint-disable no-undefined */ import { jest } from '@jest/globals'; import { Command } from 'commander'; -import { processOptions, processCommand } from '../../lib/utils/index.js'; +import { processOptions } from '../../lib/utils/process-options.js'; +import { processCommand } from '../../lib/utils/process-command.js'; describe('processOptions', () => { - describe('isValidOption', () => { - it('throws on invalid option', () => { const mockOptions = [ { name: 'option1' }, { description: 'description2' } ]; - expect(() => processOptions(mockOptions)).toThrow('Invalid option(s) configuration'); + expect(() => processOptions(mockOptions)).toThrow( + 'Invalid option(s) configuration' + ); }); it('throws an error if options is not an array', () => { - expect(() => processOptions({})).toThrow('Invalid option(s) configuration'); + expect(() => processOptions({})).toThrow( + 'Invalid option(s) configuration' + ); }); it('throws an error if options is undefined', () => { @@ -26,8 +29,18 @@ describe('processOptions', () => { it('returns an array of option definitions', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o' }, - { name: 'option2', description: 'description2', required: false, short: 't' } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o' + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't' + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -52,8 +65,20 @@ describe('processOptions', () => { it('processes boolean options', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o', type: 'boolean' }, - { name: 'option2', description: 'description2', required: false, short: 't', type: 'boolean' } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o', + type: 'boolean' + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't', + type: 'boolean' + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -78,8 +103,20 @@ describe('processOptions', () => { it('processes default values', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o', default: 'default1' }, - { name: 'option2', description: 'description2', required: false, short: 't', default: 'default2' } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o', + default: 'default1' + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't', + default: 'default2' + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -104,8 +141,20 @@ describe('processOptions', () => { it('processes parse functions', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o', parse: () => { } }, - { name: 'option2', description: 'description2', required: false, short: 't', parse: () => { } } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o', + parse: () => {} + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't', + parse: () => {} + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -130,8 +179,20 @@ describe('processOptions', () => { it('processes conflicts', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o', conflicts: ['option2'] }, - { name: 'option2', description: 'description2', required: false, short: 't', conflicts: ['option1'] } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o', + conflicts: ['option2'] + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't', + conflicts: ['option1'] + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -156,8 +217,20 @@ describe('processOptions', () => { it('processes hidden options', () => { const mockOptions = [ - { name: 'option1', description: 'description1', required: true, short: 'o', hidden: true }, - { name: 'option2', description: 'description2', required: false, short: 't', hidden: true } + { + name: 'option1', + description: 'description1', + required: true, + short: 'o', + hidden: true + }, + { + name: 'option2', + description: 'description2', + required: false, + short: 't', + hidden: true + } ]; const result = processOptions(mockOptions); expect(result).toEqual([ @@ -193,13 +266,19 @@ describe('processOptions', () => { return program; })(); - const writeSpy = jest.spyOn(process.stderr, 'write').mockImplementation((err) => err); - const exitSpy = jest.spyOn(process, 'exit').mockImplementation((err) => err); + const writeSpy = jest + .spyOn(process.stderr, 'write') + .mockImplementation((err) => err); + const exitSpy = jest + .spyOn(process, 'exit') + .mockImplementation((err) => err); const mockCmd = { id: 'test', description: 'test command', - options: [{ name: 'option1', description: 'description1', required: true }], - action: () => { } + options: [ + { name: 'option1', description: 'description1', required: true } + ], + action: () => {} }; const { command } = processCommand(mockCmd); bin.addCommand(command); @@ -210,7 +289,9 @@ describe('processOptions', () => { // ignore } - expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('required option')); + expect(writeSpy).toHaveBeenCalledWith( + expect.stringContaining('required option') + ); expect(exitSpy).toHaveBeenCalledWith(1); }); }); diff --git a/packages/gasket-plugin-command/tsconfig.json b/packages/gasket-plugin-command/tsconfig.json index 5ec495d82..c824dbf32 100644 --- a/packages/gasket-plugin-command/tsconfig.json +++ b/packages/gasket-plugin-command/tsconfig.json @@ -4,6 +4,7 @@ "checkJs": true, "noEmit": true, "skipLibCheck": true, + "noImplicitAny": true, "resolveJsonModule": true, "esModuleInterop": true, "module": "nodenext", @@ -16,9 +17,7 @@ "@types/node" ] }, - "exclude": [ - "test", - "coverage", - "cjs" + "include": [ + "lib" ] } diff --git a/packages/gasket-plugin-docs/README.md b/packages/gasket-plugin-docs/README.md index 81fd66940..407cc28f1 100644 --- a/packages/gasket-plugin-docs/README.md +++ b/packages/gasket-plugin-docs/README.md @@ -5,7 +5,7 @@ app's plugins, presets, and supporting modules. ## Installation -``` +```bash npm i @gasket/plugin-docs ``` diff --git a/packages/gasket-plugin-docs/lib/utils/collate-files.js b/packages/gasket-plugin-docs/lib/utils/collate-files.js index fb4c36feb..a1573c86f 100644 --- a/packages/gasket-plugin-docs/lib/utils/collate-files.js +++ b/packages/gasket-plugin-docs/lib/utils/collate-files.js @@ -1,4 +1,4 @@ -const { readFile, writeFile, copyFile } = require('fs').promises; +const { readFile, writeFile, copyFile, stat } = require('fs').promises; const path = require('path'); const { promisify } = require('util'); const mkdirp = require('mkdirp'); @@ -6,13 +6,28 @@ const mkdirp = require('mkdirp'); // https://github.com/isaacs/rimraf/pull/229 const rimraf = promisify(require('rimraf')); +/** + * Checks if a path is a file. + * @param {string} filePath - The path to check. + * @returns {Promise} - True if it's a file, false otherwise. + */ +async function isFile(filePath) { + try { + const stats = await stat(filePath); + return stats.isFile(); + } catch (err) { + console.error(`Error checking file type for: ${filePath}`, err); + return false; + } +} + /** * Copies configured files for a module to the target output dir and applies any * transforms. * @param {import('../internal').ModuleDocsConfig} moduleDocsConfig - * @param {import('../internal').DocsConfigSet} docsConfigSet - Configurations for * collating docs - * @returns {Promise} promise + * @returns {Promise} promise * @private */ async function processModule(moduleDocsConfig, docsConfigSet) { @@ -25,10 +40,17 @@ async function processModule(moduleDocsConfig, docsConfigSet) { files.map(async (filename) => { const source = path.join(sourceRoot, filename); const target = path.join(targetRoot, filename); + + // Check if the source is a file + const isSourceFile = await isFile(source); + if (!isSourceFile) { + console.warn(`Skipping non-file: ${source}`); + return; + } + await mkdirp(path.dirname(target)); - // Process all files which meet transform any tests Currently on - // supports/expects utf8 text files + // Process all files which meet transform tests (expects UTF-8 text files) if (allTransforms.some((tx) => tx.test.test(source))) { let content = await readFile(source, 'utf8'); content = allTransforms.reduce((acc, tx) => { @@ -44,7 +66,7 @@ async function processModule(moduleDocsConfig, docsConfigSet) { return await writeFile(target, content); } - // If file does not need transformed we just copy it + // If file does not need transformation, just copy it await copyFile(source, target); }) ); @@ -54,18 +76,16 @@ async function processModule(moduleDocsConfig, docsConfigSet) { * Collect and combine doc files in proper order. * @param {import('../internal').DocsConfigSet} docsConfigSet - Configurations for * collating docs - * @returns {Promise} promise + * @returns {Promise} promise */ async function collateFiles(docsConfigSet) { const { docsRoot } = docsConfigSet; await mkdirp(docsRoot); await rimraf(path.join(docsRoot, '*')); - // flatten the moduleDocsConfigs then generate + // Flatten the moduleDocsConfigs then generate const flattened = ['plugins', 'presets', 'modules'].reduce( - (acc, type) => { - return acc.concat(docsConfigSet[type]); - }, + (acc, type) => acc.concat(docsConfigSet[type]), [docsConfigSet.app] ); diff --git a/packages/gasket-plugin-docs/test/utils/collate-files.test.js b/packages/gasket-plugin-docs/test/utils/collate-files.test.js index 96e264152..2f94d7548 100644 --- a/packages/gasket-plugin-docs/test/utils/collate-files.test.js +++ b/packages/gasket-plugin-docs/test/utils/collate-files.test.js @@ -6,6 +6,7 @@ const mockWriteFileStub = jest.fn(); const mockCopyFileStub = jest.fn(); const mockMkdirpStub = jest.fn(); const mockRimrafStub = jest.fn(); +const mockStatStub = jest.fn(); const collateFiles = require('../../lib/utils/collate-files'); @@ -13,7 +14,8 @@ jest.mock('fs', () => ({ promises: { readFile: mockReadFileStub, writeFile: mockWriteFileStub, - copyFile: mockCopyFileStub + copyFile: mockCopyFileStub, + stat: mockStatStub } })); jest.mock('mkdirp', () => mockMkdirpStub); @@ -96,6 +98,16 @@ describe('Utils - collateFiles', () => { beforeEach(() => { mockDocConfig = mockDocsConfigSet.plugins[0]; + + mockStatStub.mockImplementation((filePath) => { + if (filePath.includes('directory')) { + return Promise.resolve({ + isFile: () => false, + isDirectory: () => true + }); + } + return Promise.resolve({ isFile: () => true, isDirectory: () => false }); + }); }); it('makes output dir', async () => { @@ -121,7 +133,6 @@ describe('Utils - collateFiles', () => { }); describe('processModule', () => { - it('makes target dirs', async () => { await processModule(mockDocConfig, mockDocsConfigSet); expect(mockMkdirpStub).toHaveBeenCalledWith(mockDocConfig.targetRoot); @@ -129,6 +140,18 @@ describe('Utils - collateFiles', () => { expect(mockMkdirpStub).toHaveBeenCalledWith(path.join(mockDocConfig.targetRoot, 'deep', 'er')); }); + it('skips directories in files', async () => { + await processModule(mockDocConfig, mockDocsConfigSet); + expect(mockCopyFileStub).not.toHaveBeenCalledWith( + expect.stringContaining('directory'), + expect.any(String) + ); + expect(mockReadFileStub).not.toHaveBeenCalledWith( + expect.stringContaining('directory'), + 'utf8' + ); + }); + it('copies files that do not need transformed', async () => { await processModule(mockDocConfig, mockDocsConfigSet); const { files, sourceRoot, targetRoot } = mockDocConfig; diff --git a/packages/gasket-plugin-docs/tsconfig.json b/packages/gasket-plugin-docs/tsconfig.json index b1005f224..e06834ea0 100644 --- a/packages/gasket-plugin-docs/tsconfig.json +++ b/packages/gasket-plugin-docs/tsconfig.json @@ -15,8 +15,7 @@ "@types/node" ] }, - "exclude": [ - "test", - "coverage" + "include": [ + "lib" ] } diff --git a/packages/gasket-plugin-docusaurus/README.md b/packages/gasket-plugin-docusaurus/README.md index d293864a3..6c663e683 100644 --- a/packages/gasket-plugin-docusaurus/README.md +++ b/packages/gasket-plugin-docusaurus/README.md @@ -27,7 +27,6 @@ export default makeGasket({ Now, when you run `npx gasket docs` in your app, a nice Docusaurus website will be launched in your browser. - ## Configuration To be set under `docusaurus` in the `gasket.js`. @@ -38,6 +37,7 @@ To be set under `docusaurus` in the `gasket.js`. - `host` - (string) Hostname to serve the docs from. Default is `localhost`. #### Example + ```js // gasket.js @@ -58,6 +58,7 @@ gasket-app/ // app root ``` ### `docusaurus.config.js` + A required `docusaurus.config.js` will generated in the root directory if one is not present. Docusaurus allows for additional [configuration/customization](https://docusaurus.io/docs/api/docusaurus-config) options and you can define those directly in the `docusaurus.config.js`. ## License diff --git a/packages/gasket-plugin-elastic-apm/README.md b/packages/gasket-plugin-elastic-apm/README.md index 527455dbe..54c8f7a25 100644 --- a/packages/gasket-plugin-elastic-apm/README.md +++ b/packages/gasket-plugin-elastic-apm/README.md @@ -61,7 +61,6 @@ In particular, the APM server URL (`ELASTIC_APM_SERVER_URL`) and secret token (`ELASTIC_APM_SECRET_TOKEN`) are both required configuration. If either of these are not present, the APM agent will be disabled. - ### Plugin Configurations The Gasket plugin provides some additional setup helpers. These can be @@ -102,6 +101,7 @@ require('elastic-apm-node').start({ ``` The `sanitizeFieldNames` config option can be used for: + - request and response HTTP headers - HTTP request cookies - any form field captured during an `application/x-www-form-urlencoded` data request @@ -180,7 +180,6 @@ such as for sensitive cookies. -[preboot]:/packages/gasket-plugin-start/README.md#preboot [init]:packages/gasket-plugin-command/README.md#init [middleware]:/packages/gasket-plugin-express/README.md#middleware [configuration options documentation]:https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html diff --git a/packages/gasket-plugin-git/README.md b/packages/gasket-plugin-git/README.md index dc5e23274..bd18d57d7 100644 --- a/packages/gasket-plugin-git/README.md +++ b/packages/gasket-plugin-git/README.md @@ -109,4 +109,3 @@ See [plugin hook timings] for more information. [gasket create command]:/packages/gasket-cli/README.md#create-command [plugin hook timings]:/packages/gasket-engine/README.md -[Gitignore]: ./lib/gitignore.js diff --git a/packages/gasket-plugin-happyfeet/README.md b/packages/gasket-plugin-happyfeet/README.md index 51fc9803d..6081b5c05 100644 --- a/packages/gasket-plugin-happyfeet/README.md +++ b/packages/gasket-plugin-happyfeet/README.md @@ -48,9 +48,9 @@ export default makeGasket({ ### getHappyFeet -This action is used to configure and get a [Happy Feet](https://github.com/asilvas/happy-feet#usage) instance. -You can specify the various [happy-feet](https://github.com/asilvas/happy-feet#usage) config options in the gasketConfig -or pass the config object directly to the action. +This action is used to configure and get a [Happy Feet](https://github.com/asilvas/happy-feet#usage) instance. +You can specify the various [happy-feet](https://github.com/asilvas/happy-feet#usage) config options in the gasketConfig +or pass the config object directly to the action. #### gasketConfig example diff --git a/packages/gasket-plugin-https/README.md b/packages/gasket-plugin-https/README.md index 48fb835bf..a23b86ea4 100644 --- a/packages/gasket-plugin-https/README.md +++ b/packages/gasket-plugin-https/README.md @@ -333,4 +333,3 @@ export default { [create-servers]: https://github.com/http-party/create-servers#create-servers [terminus]: https://github.com/godaddy/terminus [ALPN negotiation]: https://nodejs.org/api/http2.html#http2_alpn_negotiation - diff --git a/packages/gasket-plugin-intl/README.md b/packages/gasket-plugin-intl/README.md index 85b9453d5..1f95e077a 100644 --- a/packages/gasket-plugin-intl/README.md +++ b/packages/gasket-plugin-intl/README.md @@ -234,6 +234,7 @@ entry. This action invokes the `intlLocale` lifecycle hook to determine the user's locale. parameters: + - `req` - (object) Request object ```js @@ -385,15 +386,8 @@ Once enabled, look for messages under the namespace `gasket:plugin:intl` and `ga [locales map]:#locales-map [locales manifest]:#locales-manifest [module locales]:#module-files -[Gasket data]:#gasket-data -[intlLocale lifecycle]:#intllocale [Next.js Routing]:#nextjs-routing [@gasket/intl]: /packages/gasket-intl/README.md -[@gasket/react-intl]: /packages/gasket-react-intl/README.md [@gasket/plugin-nextjs]: /packages/gasket-plugin-nextjs/README.md -[GasketData script tag]: /packages/gasket-data/README.md [Next.js Internationalized Routing]: https://nextjs.org/docs/advanced-features/i18n-routing - -[global window object]:https://developer.mozilla.org/en-US/docs/Glossary/Global_object - diff --git a/packages/gasket-plugin-intl/package.json b/packages/gasket-plugin-intl/package.json index dce8c1c46..dfb51f263 100644 --- a/packages/gasket-plugin-intl/package.json +++ b/packages/gasket-plugin-intl/package.json @@ -42,7 +42,7 @@ "fs-extra": "^10.0.0", "glob": "^8.1.0", "intl": "^1.2.5", - "semver": "^7.5.4" + "semver": "^7.6.3" }, "devDependencies": { "@gasket/core": "^7.0.9", diff --git a/packages/gasket-plugin-jest/README.md b/packages/gasket-plugin-jest/README.md index 2433e9fba..3e7df5c76 100644 --- a/packages/gasket-plugin-jest/README.md +++ b/packages/gasket-plugin-jest/README.md @@ -27,4 +27,3 @@ manipulate, and traverse your React Components. ## License [MIT](./LICENSE.md) - diff --git a/packages/gasket-plugin-lint/README.md b/packages/gasket-plugin-lint/README.md index 13090a392..c3bed9368 100644 --- a/packages/gasket-plugin-lint/README.md +++ b/packages/gasket-plugin-lint/README.md @@ -19,6 +19,7 @@ the linting configuration. **Which code style do you want configured?** Choices are: + - [GoDaddy] - [Standard] - [Airbnb] @@ -117,7 +118,7 @@ export default async function presetPrompt(gasket, context, { prompt }) { }; ``` -## Contribute! +## Contribute If there is an important and widely used code style that you feel would be a good addition to the default choices of [Code Styles], reach out or submit a PR @@ -133,7 +134,6 @@ with your suggestion. [GoDaddy]: #godaddy [Standard]: #standard [Airbnb]: #airbnb -[Presets]: #presets [ESLint]: https://eslint.org/ [stylelint]: https://stylelint.io/ diff --git a/packages/gasket-plugin-metadata/README.md b/packages/gasket-plugin-metadata/README.md index d34eae1d6..03c547c05 100644 --- a/packages/gasket-plugin-metadata/README.md +++ b/packages/gasket-plugin-metadata/README.md @@ -85,7 +85,6 @@ export default { Beside the lifecycles available to plugins, metadata can also be described for modules. - ### Modules Lastly, modules can describe metadata by defining a `gasket.metadata` property @@ -145,18 +144,8 @@ export default { -[metadata]: #metadata - [ModuleData]: docs/api.md#ModuleData -[PluginData]: docs/api.md#PluginData - -[PresetData]: docs/api.md#PresetData - -[DetailData]: docs/api.md#DetailData - [metadata object]: docs/api.md#DetailData [@gasket/plugin-docs]: /packages/gasket-plugin-docs/README.md - -[init lifecycle]: /packages/gasket-plugin-command/README.md#init diff --git a/packages/gasket-plugin-metadata/lib/index.d.ts b/packages/gasket-plugin-metadata/lib/index.d.ts index 824cd5057..443af732b 100644 --- a/packages/gasket-plugin-metadata/lib/index.d.ts +++ b/packages/gasket-plugin-metadata/lib/index.d.ts @@ -133,4 +133,4 @@ const plugin: Plugin = { hooks: {} }; -export = plugin; +export default plugin; diff --git a/packages/gasket-plugin-metadata/package.json b/packages/gasket-plugin-metadata/package.json index 66ecafe7d..e4f775c46 100644 --- a/packages/gasket-plugin-metadata/package.json +++ b/packages/gasket-plugin-metadata/package.json @@ -2,6 +2,7 @@ "name": "@gasket/plugin-metadata", "version": "7.0.9", "description": "Adds metadata to gasket lifecycles", + "type": "module", "main": "lib/index.js", "types": "lib/index.d.ts", "files": [ @@ -55,10 +56,12 @@ "eslintConfig": { "extends": [ "godaddy", - "plugin:jest/recommended" + "plugin:jest/recommended", + "plugin:jsdoc/recommended-typescript-flavor" ], "plugins": [ - "unicorn" + "unicorn", + "jsdoc" ], "rules": { "unicorn/filename-case": "error" diff --git a/packages/gasket-plugin-workbox/README.md b/packages/gasket-plugin-workbox/README.md index 78b26341c..8eab72de1 100644 --- a/packages/gasket-plugin-workbox/README.md +++ b/packages/gasket-plugin-workbox/README.md @@ -115,7 +115,5 @@ the app. These can be set up to edge cache by setting the `basePath` option. [composeServiceWorker]:/packages/gasket-plugin-service-worker/README.md#composeserviceworker [@gasket/plugin-service-worker]:/packages/gasket-plugin-service-worker/README.md [Workbox]:https://github.com/GoogleChrome/workbox -[Workbox precaching]:https://developers.google.com/web/tools/workbox/modules/workbox-precaching -[background sync]:https://developers.google.com/web/updates/2015/12/background-sync [workbox-build]:https://developers.google.com/web/tools/workbox/modules/workbox-build [generateSWString]:https://developers.google.com/web/tools/workbox/modules/workbox-build#generateswstring_mode diff --git a/packages/gasket-redux/README.md b/packages/gasket-redux/README.md index f32f4fd42..09811ef8d 100644 --- a/packages/gasket-redux/README.md +++ b/packages/gasket-redux/README.md @@ -34,7 +34,6 @@ Set up Redux store configuration and return a `makeStore` function - `optionsFn` - (function) function that returns the options object. - `postCreate` - (function) Executed after the store is create the resulting store as the argument -- **Return Value** @@ -103,7 +102,6 @@ const initialState = { custom: 'example' }; export default configureMakeStore({ initialState, reducers }); ``` - #### Example: adding middleware in a custom path (redux-saga) ```js diff --git a/packages/gasket-utils/README.md b/packages/gasket-utils/README.md index a99e018c0..0e62ecd76 100644 --- a/packages/gasket-utils/README.md +++ b/packages/gasket-utils/README.md @@ -8,10 +8,6 @@ Reusable utilities for Gasket internals npm i @gasket/utils ``` -## Usage - -See the [API docs](docs/api.md) for details on what is available. - ## License [MIT](./LICENSE.md) diff --git a/packages/gasket-utils/lib/config.d.ts b/packages/gasket-utils/lib/config.d.ts index 77b2a963d..eee64f3b8 100644 --- a/packages/gasket-utils/lib/config.d.ts +++ b/packages/gasket-utils/lib/config.d.ts @@ -5,16 +5,15 @@ interface ConfigContext { env: string; /** Name of command */ commandId?: string; - /** Project root; required if using localeFile */ } interface ConfigDefinition extends Record { - environments?: Record> - commands?: Record> - [key: string]: any + environments?: Record>; + commands?: Record>; + [key: string]: any; } -type ConfigOutput = Omit +type ConfigOutput = Omit; type ConfigPartial = Partial | undefined | void | unknown; export function getPotentialConfigs( @@ -22,38 +21,37 @@ export function getPotentialConfigs( configContext: ConfigContext ): Array; -function getCommandOverrides( +export function getCommandOverrides( commands: Record>, commandId: string ): Array; -function getSubEnvironmentOverrides( +export function getSubEnvironmentOverrides( env: string, environments: Record> ): Array; -function getDevOverrides( +export function getDevOverrides( isLocalEnv: boolean, environments: Record> ): Array; -async function getLatestVersion( +export async function getLatestVersion( pkgName: string, /** current time in milliseconds */ currentTime: number, cache: Record ): Promise; -function getLocalOverrides( +export function getLocalOverrides( isLocalEnv: boolean, root: string, localFile: string ): Generator; -/** - * Normalize the config by applying any overrides for environments, commands, or local-only config file. - */ -export function applyConfigOverrides( - config: Def, - configContext: ConfigContext -): Out; +// Normalize the config by applying any overrides for environments, commands, or +// local-only config file. +export function applyConfigOverrides< + Def extends ConfigDefinition, + Out extends ConfigOutput +>(config: Def, configContext: ConfigContext): Out; diff --git a/packages/gasket-utils/lib/index.d.ts b/packages/gasket-utils/lib/index.d.ts index 6be6020cb..f5c376ff3 100644 --- a/packages/gasket-utils/lib/index.d.ts +++ b/packages/gasket-utils/lib/index.d.ts @@ -1,4 +1,5 @@ import type { MaybeAsync } from '@gasket/core'; +import type { SpawnOpts } from 'node:child_process'; export { applyConfigOverrides } from './config'; @@ -23,7 +24,6 @@ export class PackageManager { /** * Executes npm in the application directory `this.dest`. This installation * can be run multiple times. - * * @param cmd The command that needs to be executed. * @param args Additional CLI arguments to pass to `npm`. */ @@ -31,7 +31,6 @@ export class PackageManager { /** * Executes npm link in the application directory `this.dest`. - * * @param packages Explicit `npm` packages to link locally. */ link(packages?: Array): Promise; @@ -39,7 +38,6 @@ export class PackageManager { /** * Executes npm install in the application directory `this.dest`. This * installation can be run multiple times. - * * @param args Additional CLI arguments to pass to `npm`. * @public */ @@ -47,7 +45,6 @@ export class PackageManager { /** * Executes yarn or npm info, and returns parsed JSON data results. - * * @param args Additional CLI arguments to pass to `npm`. * @returns stdout and data * @public @@ -74,7 +71,6 @@ export interface Signal { * async function helloWorld() { * await runShellCommand('echo', ['hello world']); * } - * * @example * // With timeout using AbortController * @@ -101,7 +97,7 @@ export function runShellCommand( /** Path to the target app (Default: cwd/appName) */ cwd?: string; }, - /** When present pipes std{out,err} to process.* */ + /** When present pipes std{out,err} to process.*/ debug?: boolean ): Promise<{ stdout: string }>; @@ -177,8 +173,14 @@ declare module '@gasket/utils' { /** Additional CLI arguments to pass to `npm`. */ args: string[] ): Promise<{ data: any; stdout: string }>; -} -export function warnIfOutdated(pkgName: string, currentVersion: string): MaybeAsync; + export function warnIfOutdated( + pkgName: string, + currentVersion: string + ): MaybeAsync; +} -export function getPackageLatestVersion(pkgName: string, options?: object): Promise; +export function getPackageLatestVersion( + pkgName: string, + options?: object +): Promise; diff --git a/packages/gasket-utils/package.json b/packages/gasket-utils/package.json index 8635e579f..558d8eaa1 100644 --- a/packages/gasket-utils/package.json +++ b/packages/gasket-utils/package.json @@ -5,16 +5,6 @@ "files": [ "lib" ], - "scripts": { - "lint": "eslint .", - "lint:fix": "npm run lint -- --fix", - "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' jest", - "test:watch": "jest --watch", - "test:coverage": "jest --coverage", - "posttest": "npm run lint && npm run typecheck", - "typecheck": "tsc", - "typecheck:watch": "tsc --watch" - }, "exports": { ".": { "types": "./lib/index.d.ts", @@ -26,6 +16,16 @@ }, "./package.json": "./package.json" }, + "scripts": { + "lint": "eslint .", + "lint:fix": "npm run lint -- --fix", + "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage", + "posttest": "npm run lint && npm run typecheck", + "typecheck": "tsc", + "typecheck:watch": "tsc --watch" + }, "repository": { "type": "git", "url": "git+ssh://git@github.com/godaddy/gasket.git" @@ -48,7 +48,7 @@ "concat-stream": "^2.0.0", "deepmerge": "^4.3.1", "diagnostics": "^2.0.2", - "semver": "^7.5.4" + "semver": "^7.6.3" }, "devDependencies": { "@gasket/core": "^7.0.9", @@ -58,6 +58,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-godaddy": "^7.1.1", + "eslint-config-godaddy-typescript": "^4.0.3", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-unicorn": "^55.0.0", @@ -87,6 +88,20 @@ "jsdoc/require-param-type": "off", "jsdoc/require-returns-description": "off" } + }, + { + "files": [ + "*.ts" + ], + "extends": [ + "godaddy-typescript" + ], + "rules": { + "jsdoc/require-jsdoc": "off", + "jsdoc/require-param-description": "off", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "off" + } } ] }, diff --git a/scripts/align-packages.js b/scripts/align-packages.js index 8ffa49dad..0784d43bb 100644 --- a/scripts/align-packages.js +++ b/scripts/align-packages.js @@ -324,20 +324,10 @@ function setupTypes(pkgJson) { const { name } = pkgJson; const packagesToSkip = [ - 'create-gasket-app', '@gasket/assets', - '@gasket/engine', - '@gasket/log', - '@gasket/plugin-command', - '@gasket/plugin-config', - '@gasket/plugin-docsify', - '@gasket/plugin-lifecycle', - '@gasket/plugin-log', - '@gasket/plugin-metadata', '@gasket/plugin-workbox', // Skip until v7 as workbox-build@4 has no types '@gasket/preset-api', '@gasket/preset-nextjs', - '@gasket/resolve', '@gasket/typescript-tests', '@gasket/repository' ]; diff --git a/site/README.md b/site/README.md index 0c6c2c27b..7c15e56b6 100644 --- a/site/README.md +++ b/site/README.md @@ -1,41 +1,45 @@ # Website -This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. +This website is built using [Docusaurus](https://docusaurus.io/), a modern +static website generator. -### Installation +## Installation -``` -$ yarn +```bash +yarn ``` -### Local Development +## Local Development -``` -$ yarn start +```bash +yarn start ``` -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. +This command starts a local development server and opens up a browser window. +Most changes are reflected live without having to restart the server. -### Build +## Build -``` -$ yarn build +```bash +yarn build ``` -This command generates static content into the `build` directory and can be served using any static contents hosting service. +This command generates static content into the `build` directory and can be +served using any static contents hosting service. -### Deployment +## Deployment Using SSH: -``` -$ USE_SSH=true yarn deploy +```bash +USE_SSH=true yarn deploy ``` Not using SSH: -``` -$ GIT_USER= yarn deploy +```bash +GIT_USER= yarn deploy ``` -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. +If you are using GitHub pages for hosting, this command is a convenient way to +build the website and push to the `gh-pages` branch. diff --git a/site/blog/2024-9-26-gasket-v7.md b/site/blog/2024-9-26-gasket-v7.md index 9ef474468..8450c05d9 100644 --- a/site/blog/2024-9-26-gasket-v7.md +++ b/site/blog/2024-9-26-gasket-v7.md @@ -13,12 +13,16 @@ hide_table_of_contents: false We are thrilled to announce the next major release of Gasket, packed with powerful new features, improvements, and optimizations that make building -applications with Gasket easier and more flexible than ever before. This release introduces a range of enhancements that help launch your development -experience to new heights. +applications with Gasket easier and more flexible than ever before. This release +introduces a range of enhancements that help launch your development experience +to new heights. + + ## Key Updates in Gasket v7 ### **Less Magic, More Transparency** + In Gasket v7, we’ve taken significant steps to reduce the magic and increase transparency, providing developers with a more intuitive and straightforward development experience. One of the key changes is the removal of "magic files" @@ -31,8 +35,8 @@ Gasket applications. Gasket v7 no longer relies on the Gasket CLI for core tasks. Instead, we now delegate responsibilities such as transpilation, bundling, and other optimizations to the primary framework in use. This shift allows the core -framework to handle crucial tasks, making your Gasket apps lighter, faster, -and better aligned with the ecosystem you’re already using. +framework to handle crucial tasks, making your Gasket apps lighter, faster, and +better aligned with the ecosystem you’re already using. ### **ESM-Ready** @@ -43,8 +47,8 @@ build systems. ### **Full TypeScript Support** -Whether you’re building Gasket apps or in-app plugins, Gasket v7 now offers -full support for TypeScript. This update improves both development speed and +Whether you’re building Gasket apps or in-app plugins, Gasket v7 now offers full +support for TypeScript. This update improves both development speed and reliability, with enhanced type checking, better tooling, and internal JSDoc typings for a smoother TypeScript experience across the board. @@ -56,17 +60,17 @@ needs. This unlocks using React Server Components and other potential future features of Next.js. While Gasket v7 unblocks App Router with React Server Components, using it to -meet our app requirements at GoDaddy is still ongoing. -If you want to get involved, chime in on the [github repo]. +meet our app requirements at GoDaddy is still ongoing. If you want to get +involved, chime in on the [github repo]. ### **Introducing Gasket Actions** A major new feature in v7 is **Gasket Actions** — a powerful new pattern for accessing and setting data on demand in Gasket applications. This feature -reduces the need to decorate `req`/`res` objects or rely on middleware, -offering a cleaner, more flexible method to manage application data. -Gasket Actions provide a reliable and intuitive way to work with dynamic data -without adding complexity to your app’s architecture. +reduces the need to decorate `req`/`res` objects or rely on middleware, offering +a cleaner, more flexible method to manage application data. Gasket Actions +provide a reliable and intuitive way to work with dynamic data without adding +complexity to your app’s architecture. ### **Increased Flexibility and Portability** @@ -80,10 +84,10 @@ Gasket with the frameworks and tools you already know and love. ### **Easier Contributions** We’ve aligned our testing framework with Jest, one of the most widely used -testing libraries in the JavaScript ecosystem. -We have refined our TypeScript types and connected them with the code using -JSDoc imports to assist in better code completion and type checking, -without sacrificing the debug ability of JavaScript. +testing libraries in the JavaScript ecosystem. We have refined our TypeScript +types and connected them with the code using JSDoc imports to assist in better +code completion and type checking, without sacrificing the debug ability of +JavaScript. ### What’s Next? diff --git a/site/docusaurus.config.js b/site/docusaurus.config.js index 82121ba20..4a97ccdd7 100644 --- a/site/docusaurus.config.js +++ b/site/docusaurus.config.js @@ -152,6 +152,11 @@ module.exports = { }, mermaid: { theme: { light: 'neutral', dark: 'dark' }, + }, + algolia: { + appId: 'OB26TYFNYK', + apiKey: '6ac9413965486a885b0d332087335ead', + indexName: 'gasket' } }), };