From 61f723b8a8d5e6a609b52ca10b2ae7ba662e1f89 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Thu, 25 Jan 2024 09:28:26 -0600 Subject: [PATCH 01/14] chore(format): fix code formatting --- packages/next-drupal/src/client.ts | 15 ++++++--------- packages/next-drupal/src/utils.ts | 9 ++++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index 4cc4e4c9..97a3d4d2 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -215,7 +215,6 @@ export class DrupalClient { this.tokenExpiresOn = Date.now() + token.expires_in * 1000 } - /* eslint-disable @typescript-eslint/no-explicit-any */ async fetch(input: RequestInfo, init?: FetchOptions): Promise { init = { ...init, @@ -268,9 +267,8 @@ export class DrupalClient { init["headers"]["Authorization"] = `Bearer ${token.access_token}` } } else if (isAccessTokenAuth(this._auth)) { - init["headers"][ - "Authorization" - ] = `${this._auth.token_type} ${this._auth.access_token}` + init["headers"]["Authorization"] = + `${this._auth.token_type} ${this._auth.access_token}` } } } else if (typeof init.withAuth === "string") { @@ -297,9 +295,8 @@ export class DrupalClient { init["headers"]["Authorization"] = `Bearer ${token.access_token}` } } else if (isAccessTokenAuth(init.withAuth)) { - init["headers"][ - "Authorization" - ] = `${init.withAuth.token_type} ${init.withAuth.access_token}` + init["headers"]["Authorization"] = + `${init.withAuth.token_type} ${init.withAuth.access_token}` } } @@ -1419,8 +1416,8 @@ export class DrupalClient { } // Error handling. - // If throwErrors is enable, we show errors in the Next.js overlay. - // Otherwise we log the errors even if debugging is turned off. + // If throwErrors is enabled, we show errors in the Next.js overlay. + // Otherwise, we log the errors even if debugging is turned off. // In production, errors are always logged never thrown. private throwError(error: Error) { if (!this.throwJsonApiErrors) { diff --git a/packages/next-drupal/src/utils.ts b/packages/next-drupal/src/utils.ts index 996f94e6..dd8330ec 100644 --- a/packages/next-drupal/src/utils.ts +++ b/packages/next-drupal/src/utils.ts @@ -89,9 +89,8 @@ export async function buildHeaders({ // This reduces the number of OAuth call to the Drupal server. // Intentionally marked as unstable for now. if (process.env.UNSTABLE_DRUPAL_ACCESS_TOKEN) { - headers[ - "Authorization" - ] = `Bearer ${process.env.UNSTABLE_DRUPAL_ACCESS_TOKEN}` + headers["Authorization"] = + `Bearer ${process.env.UNSTABLE_DRUPAL_ACCESS_TOKEN}` return headers } @@ -122,8 +121,8 @@ export function getPathFromContext( return !slug ? process.env.DRUPAL_FRONT_PAGE : prefix - ? `${prefix}/${slug}` - : slug + ? `${prefix}/${slug}` + : slug } export function syncDrupalPreviewRoutes(path) { From e0fc4bd6697c11803539b5faef68a0e0e897d653 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Sun, 28 Jan 2024 14:15:42 -0600 Subject: [PATCH 02/14] feat(next-drupal)!: add public debug() method to DrupalClient Fixes #668 BREAKING CHANGE: DrupalClient previously had a debug property that indicated if debugging was enabled. This property has been removed and replaced with a debug() method that accepts a string and logs it as a debug message if debugging is enabled. --- packages/next-drupal/src/client.ts | 75 ++++++++++++----------- packages/next-drupal/src/logger.ts | 13 ++-- packages/next-drupal/tests/client.test.ts | 2 +- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index 97a3d4d2..f66ff9bc 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -77,10 +77,10 @@ function isClientIdSecretAuth( export class DrupalClient { baseUrl: BaseUrl - debug: DrupalClientOptions["debug"] - frontPage: DrupalClientOptions["frontPage"] + private isDebugEnabled: DrupalClientOptions["debug"] + private serializer: DrupalClientOptions["serializer"] private cache: DrupalClientOptions["cache"] @@ -148,7 +148,7 @@ export class DrupalClient { this.apiPrefix = apiPrefix this.serializer = serializer this.frontPage = frontPage - this.debug = debug + this.isDebugEnabled = !!debug this.useDefaultResourceTypeEntry = useDefaultResourceTypeEntry this.fetcher = fetcher this.auth = auth @@ -166,7 +166,7 @@ export class DrupalClient { this.throwJsonApiErrors = false } - this._debug("Debug mode is on.") + this.debug("Debug mode is on.") } set apiPrefix(apiPrefix: DrupalClientOptions["apiPrefix"]) { @@ -228,7 +228,7 @@ export class DrupalClient { // Using the auth set on the client. // TODO: Abstract this to a re-usable. if (init?.withAuth) { - this._debug(`Using authenticated request.`) + this.debug(`Using authenticated request.`) if (init.withAuth === true) { if (typeof this._auth === "undefined") { @@ -240,15 +240,15 @@ export class DrupalClient { // By default, if withAuth is set to true, we use the auth configured // in the client constructor. if (typeof this._auth === "function") { - this._debug(`Using custom auth callback.`) + this.debug(`Using custom auth callback.`) init["headers"]["Authorization"] = this._auth() } else if (typeof this._auth === "string") { - this._debug(`Using custom authorization header.`) + this.debug(`Using custom authorization header.`) init["headers"]["Authorization"] = this._auth } else if (typeof this._auth === "object") { - this._debug(`Using custom auth credentials.`) + this.debug(`Using custom auth credentials.`) if (isBasicAuth(this._auth)) { const basic = Buffer.from( @@ -258,7 +258,7 @@ export class DrupalClient { init["headers"]["Authorization"] = `Basic ${basic}` } else if (isClientIdSecretAuth(this._auth)) { // Use the built-in client_credentials grant. - this._debug(`Using default auth (client_credentials).`) + this.debug(`Using default auth (client_credentials).`) // Fetch an access token and add it to the request. // Access token can be fetched from cache or using a custom auth method. @@ -272,15 +272,15 @@ export class DrupalClient { } } } else if (typeof init.withAuth === "string") { - this._debug(`Using custom authorization header.`) + this.debug(`Using custom authorization header.`) init["headers"]["Authorization"] = init.withAuth } else if (typeof init.withAuth === "function") { - this._debug(`Using custom authorization callback.`) + this.debug(`Using custom authorization callback.`) init["headers"]["Authorization"] = init.withAuth() } else if (isBasicAuth(init.withAuth)) { - this._debug(`Using basic authorization header`) + this.debug(`Using basic authorization header.`) const basic = Buffer.from( `${init.withAuth.username}:${init.withAuth.password}` @@ -301,12 +301,12 @@ export class DrupalClient { } if (this.fetcher) { - this._debug(`Using custom fetcher.`) + this.debug(`Using custom fetcher, fetching: ${input}`) return await this.fetcher(input, init) } - this._debug(`Using default fetch (polyfilled by Next.js).`) + this.debug(`Using default fetch, fetching: ${input}`) return await fetch(input, init) } @@ -329,8 +329,7 @@ export class DrupalClient { const url = this.buildUrl(apiPath, options?.params) - this._debug(`Creating resource of type ${type}.`) - this._debug(url.toString()) + this.debug(`Creating resource of type ${type}.`) // Add type to body. body.data.type = type @@ -373,8 +372,7 @@ export class DrupalClient { options?.params ) - this._debug(`Creating file resource for media of type ${type}.`) - this._debug(url.toString()) + this.debug(`Creating file resource for media of type ${type}.`) const response = await this.fetch(url.toString(), { method: "POST", @@ -415,8 +413,7 @@ export class DrupalClient { const url = this.buildUrl(`${apiPath}/${uuid}`, options?.params) - this._debug(`Updating resource of type ${type} with id ${uuid}.`) - this._debug(url.toString()) + this.debug(`Updating resource of type ${type} with id ${uuid}.`) // Update body. body.data.type = type @@ -455,8 +452,7 @@ export class DrupalClient { const url = this.buildUrl(`${apiPath}/${uuid}`, options?.params) - this._debug(`Deleting resource of type ${type} with id ${uuid}.`) - this._debug(url.toString()) + this.debug(`Deleting resource of type ${type} with id ${uuid}.`) const response = await this.fetch(url.toString(), { method: "DELETE", @@ -489,7 +485,7 @@ export class DrupalClient { const cached = (await this.cache.get(options.cacheKey)) as string if (cached) { - this._debug(`Returning cached resource ${type} with id ${uuid}`) + this.debug(`Returning cached resource ${type} with id ${uuid}.`) const json = JSON.parse(cached) @@ -504,8 +500,7 @@ export class DrupalClient { const url = this.buildUrl(`${apiPath}/${uuid}`, options?.params) - this._debug(`Fetching resource ${type} with id ${uuid}.`) - this._debug(url.toString()) + this.debug(`Fetching resource ${type} with id ${uuid}.`) const response = await this.fetch(url.toString(), { withAuth: options.withAuth, @@ -687,6 +682,8 @@ export class DrupalClient { _format: "json", }) + this.debug(`Fetching resource by path, ${path}.`) + const response = await this.fetch(url.toString(), { method: "POST", credentials: "include", @@ -739,8 +736,7 @@ export class DrupalClient { ...options?.params, }) - this._debug(`Fetching resource collection of type ${type}`) - this._debug(url.toString()) + this.debug(`Fetching resource collection of type ${type}.`) const response = await this.fetch(url.toString(), { withAuth: options.withAuth, @@ -910,6 +906,8 @@ export class DrupalClient { path, }) + this.debug(`Fetching translated path, ${path}.`) + const response = await this.fetch(url.toString(), { withAuth: options.withAuth, }) @@ -990,6 +988,8 @@ export class DrupalClient { ) try { + this.debug(`Fetching JSON:API index.`) + const response = await this.fetch(url.toString(), { // As per https://www.drupal.org/node/2984034 /jsonapi is public. withAuth: false, @@ -1123,7 +1123,7 @@ export class DrupalClient { const cached = (await this.cache.get(options.cacheKey)) as string if (cached) { - this._debug(`Returning cached menu items for ${name}`) + this.debug(`Returning cached menu items for ${name}.`) return JSON.parse(cached) } } @@ -1138,8 +1138,7 @@ export class DrupalClient { options.params ) - this._debug(`Fetching menu items for ${name}.`) - this._debug(url.toString()) + this.debug(`Fetching menu items for ${name}.`) const response = await this.fetch(url.toString(), { withAuth: options.withAuth, @@ -1212,6 +1211,8 @@ export class DrupalClient { options.params ) + this.debug(`Fetching view, ${viewId}.${displayId}.`) + const response = await this.fetch(url.toString(), { withAuth: options.withAuth, }) @@ -1252,6 +1253,8 @@ export class DrupalClient { options.params ) + this.debug(`Fetching search index, ${name}.`) + const response = await this.fetch(url.toString(), { withAuth: options.withAuth, }) @@ -1330,11 +1333,11 @@ export class DrupalClient { this._token && Date.now() < this.tokenExpiresOn ) { - this._debug(`Using existing access token.`) + this.debug(`Using existing access token.`) return this._token } - this._debug(`Fetching new access token.`) + this.debug(`Fetching new access token.`) const basic = Buffer.from(`${clientId}:${clientSecret}`).toString("base64") @@ -1343,7 +1346,7 @@ export class DrupalClient { if (opts?.scope) { body = `${body}&scope=${opts.scope}` - this._debug(`Using scope: ${opts.scope}`) + this.debug(`Using scope: ${opts.scope}`) } const response = await this.fetch(url.toString(), { @@ -1362,8 +1365,6 @@ export class DrupalClient { const result: AccessToken = await response.json() - this._debug(result) - this.token = result this.accessTokenScope = opts?.scope @@ -1411,8 +1412,8 @@ export class DrupalClient { return message } - private _debug(message) { - !!this.debug && this.logger.debug(message) + debug(message) { + this.isDebugEnabled && this.logger.debug(message) } // Error handling. diff --git a/packages/next-drupal/src/logger.ts b/packages/next-drupal/src/logger.ts index e1b207e8..c8dc2edd 100644 --- a/packages/next-drupal/src/logger.ts +++ b/packages/next-drupal/src/logger.ts @@ -1,17 +1,22 @@ import type { Logger } from "./types" +export const LOG_MESSAGE_PREFIX = "[next-drupal][log]:" +export const DEBUG_MESSAGE_PREFIX = "[next-drupal][debug]:" +export const WARN_MESSAGE_PREFIX = "[next-drupal][warn]:" +export const ERROR_MESSAGE_PREFIX = "[next-drupal][error]:" + // Default logger. Uses console. export const logger: Logger = { log(message) { - console.log(`[next-drupal][log]:`, message) + console.log(LOG_MESSAGE_PREFIX, message) }, debug(message) { - console.debug(`[next-drupal][debug]:`, message) + console.debug(DEBUG_MESSAGE_PREFIX, message) }, warn(message) { - console.warn(`[next-drupal][debug]:`, message) + console.warn(WARN_MESSAGE_PREFIX, message) }, error(message) { - console.error(`[next-drupal][error]:`, message) + console.error(ERROR_MESSAGE_PREFIX, message) }, } diff --git a/packages/next-drupal/tests/client.test.ts b/packages/next-drupal/tests/client.test.ts index 3dc2b604..7e061fae 100644 --- a/packages/next-drupal/tests/client.test.ts +++ b/packages/next-drupal/tests/client.test.ts @@ -59,7 +59,7 @@ describe("DrupalClient", () => { "[next-drupal][debug]:", "Debug mode is on." ) - expect(client.debug).toBe(true) + expect(client.isDebugEnabled).toBe(true) }) }) From 11e108a10bbaa69ac34a26b4462acbf744512633 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Wed, 17 Jan 2024 09:36:40 -0600 Subject: [PATCH 03/14] feat(next): update Next.js settings to add draft mode Issue #502 --- modules/next/composer.json | 2 +- .../src/Plugin/Next/PreviewUrlGenerator/Jwt.php | 4 ++-- modules/next/next.info.yml | 2 +- .../src/Controller/NextSiteEntityController.php | 2 +- .../next/src/Form/NextEntityTypeConfigForm.php | 16 ++++++++-------- modules/next/src/Form/NextSettingsForm.php | 4 ++-- modules/next/src/Form/NextSiteForm.php | 16 ++++++++-------- .../Next/PreviewUrlGenerator/SimpleOauth.php | 4 ++-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/next/composer.json b/modules/next/composer.json index 05f49ac4..48cea01e 100644 --- a/modules/next/composer.json +++ b/modules/next/composer.json @@ -1,6 +1,6 @@ { "name": "drupal/next", - "description": "Next.js + Drupal for Incremental Static Regeneration and Preview mode.", + "description": "Next.js + Drupal for Incremental Static Regeneration and Draft mode.", "type": "drupal-module", "homepage": "http://drupal.org/project/next", "license": "GPL-2.0-or-later", diff --git a/modules/next/modules/next_jwt/src/Plugin/Next/PreviewUrlGenerator/Jwt.php b/modules/next/modules/next_jwt/src/Plugin/Next/PreviewUrlGenerator/Jwt.php index c5676e21..f09b2f59 100644 --- a/modules/next/modules/next_jwt/src/Plugin/Next/PreviewUrlGenerator/Jwt.php +++ b/modules/next/modules/next_jwt/src/Plugin/Next/PreviewUrlGenerator/Jwt.php @@ -103,8 +103,8 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form['secret_expiration'] = [ - '#title' => $this->t('Preview secret expiration time'), - '#description' => $this->t('The value, in seconds, to be used as expiration time for the preview secret. It is recommended to use short-lived secrets for increased security.'), + '#title' => $this->t('Secret expiration time'), + '#description' => $this->t('The value, in seconds, to be used as expiration time for the validation secret. It is recommended to use short-lived secrets for increased security.'), '#type' => 'number', '#required' => TRUE, '#default_value' => $this->configuration['secret_expiration'], diff --git a/modules/next/next.info.yml b/modules/next/next.info.yml index de7eaf0a..42872eb2 100644 --- a/modules/next/next.info.yml +++ b/modules/next/next.info.yml @@ -1,5 +1,5 @@ name: Next.js -description: Next.js + Drupal for Incremental Static Regeneration and Preview mode. +description: Next.js + Drupal for Incremental Static Regeneration and Draft mode. type: module core_version_requirement: ^9 || ^10 package: Web services diff --git a/modules/next/src/Controller/NextSiteEntityController.php b/modules/next/src/Controller/NextSiteEntityController.php index 07fab5a7..d6e280e8 100644 --- a/modules/next/src/Controller/NextSiteEntityController.php +++ b/modules/next/src/Controller/NextSiteEntityController.php @@ -64,7 +64,7 @@ public function environmentVariables(NextSiteInterface $next_site) { if ($secret = $next_site->getPreviewSecret()) { $variables += [ - 'preview_variables' => '# Required for Preview Mode', + 'preview_variables' => '# Required for Draft Mode', 'DRUPAL_PREVIEW_SECRET' => $secret, ]; } diff --git a/modules/next/src/Form/NextEntityTypeConfigForm.php b/modules/next/src/Form/NextEntityTypeConfigForm.php index feb56514..37d2e65b 100644 --- a/modules/next/src/Form/NextEntityTypeConfigForm.php +++ b/modules/next/src/Form/NextEntityTypeConfigForm.php @@ -119,16 +119,16 @@ public function form(array $form, FormStateInterface $form_state) { '#title' => $this->t('Settings'), ]; - $form['preview_mode'] = [ - '#title' => $this->t('Preview Mode'), - '#description' => $this->t('Configure preview mode the entity type.'), + $form['draft_mode'] = [ + '#title' => $this->t('Draft Mode'), + '#description' => $this->t('Configure draft mode for this entity type.'), '#type' => 'details', '#group' => 'settings', ]; - $form['preview_mode']['site_resolver'] = [ + $form['draft_mode']['site_resolver'] = [ '#title' => $this->t('Plugin'), - '#description' => $this->t('Select a plugin to use for resolving the preview site for this entity type.'), + '#description' => $this->t('Select a plugin to use when validating the draft url for this entity type.'), '#type' => 'select', '#options' => array_merge(['' => $this->t('None')], array_column($this->siteResolverManager->getDefinitions(), 'label', 'id')), '#default_value' => $entity->getSiteResolver() ? $entity->getSiteResolver()->getId() : NULL, @@ -142,7 +142,7 @@ public function form(array $form, FormStateInterface $form_state) { ], ]; - $form['preview_mode']['site_resolver_settings_container'] = [ + $form['draft_mode']['site_resolver_settings_container'] = [ '#type' => 'container', '#prefix' => '
', '#suffix' => '
', @@ -152,7 +152,7 @@ public function form(array $form, FormStateInterface $form_state) { if ($site_resolver instanceof ConfigurableSiteResolverInterface) { $form['configuration'] = []; $subform_state = SubformState::createForSubform($form['configuration'], $form, $form_state); - $form['preview_mode']['site_resolver_settings_container']['configuration'] = $site_resolver->buildConfigurationForm($form['configuration'], $subform_state); + $form['draft_mode']['site_resolver_settings_container']['configuration'] = $site_resolver->buildConfigurationForm($form['configuration'], $subform_state); } $form['revalidation'] = [ @@ -223,7 +223,7 @@ public function submitSiteResolver(array $form, FormStateInterface $form_state) * Handles switching the site resolver selector. */ public function ajaxReplaceSiteResolverSettingsForm($form, FormStateInterface $form_state) { - return $form['preview_mode']['site_resolver_settings_container']; + return $form['draft_mode']['site_resolver_settings_container']; } /** diff --git a/modules/next/src/Form/NextSettingsForm.php b/modules/next/src/Form/NextSettingsForm.php index ac938209..9d1b4181 100644 --- a/modules/next/src/Form/NextSettingsForm.php +++ b/modules/next/src/Form/NextSettingsForm.php @@ -87,14 +87,14 @@ public function buildForm(array $form, FormStateInterface $form_state) { ]; $form['preview_url_generator_container'] = [ - '#title' => $this->t('Preview URL'), + '#title' => $this->t('Draft Mode'), '#type' => 'details', '#group' => 'settings', ]; $form['preview_url_generator_container']['preview_url_generator'] = [ '#title' => $this->t('Plugin'), - '#description' => $this->t('Select a plugin to use for the preview URL generator.'), + '#description' => $this->t('Select a plugin to use for the draft validation generator.'), '#type' => 'select', '#options' => array_column($this->previewUrlGeneratorManager->getDefinitions(), 'label', 'id'), '#default_value' => $config->get('preview_url_generator'), diff --git a/modules/next/src/Form/NextSiteForm.php b/modules/next/src/Form/NextSiteForm.php index 94aa6683..9ccfd0d2 100644 --- a/modules/next/src/Form/NextSiteForm.php +++ b/modules/next/src/Form/NextSiteForm.php @@ -51,9 +51,9 @@ public function form(array $form, FormStateInterface $form_state) { ]; $form['preview'] = [ - '#title' => $this->t('Preview Mode'), - '#description' => $this->t('Preview mode allows editors to preview content on the site. You can read more on the Next.js documentation.', [ - ':uri' => 'https://nextjs.org/docs/advanced-features/preview-mode', + '#title' => $this->t('Draft Mode'), + '#description' => $this->t('Draft mode (or the deprecated Preview mode) allows editors to preview content on the site. You can read more on the Next.js documentation.', [ + ':uri' => 'https://nextjs.org/docs/app/building-your-application/configuring/draft-mode', ]), '#type' => 'details', '#group' => 'settings', @@ -61,22 +61,22 @@ public function form(array $form, FormStateInterface $form_state) { $form['preview']['preview_url'] = [ '#type' => 'url', - '#title' => $this->t('Preview URL'), - '#description' => $this->t('Enter the preview URL. Example: https://example.com/api/preview.'), + '#title' => $this->t('Draft URL (or Preview URL)'), + '#description' => $this->t('Enter the draft URL or preview URL. Example: https://example.com/api/draft or https://example.com/api/preview.'), '#default_value' => $entity->getPreviewUrl(), ]; $form['preview']['preview_secret'] = [ '#type' => 'textfield', - '#title' => $this->t('Preview secret'), - '#description' => $this->t('Enter a secret for the site preview. This is the same value used for DRUPAL_PREVIEW_SECRET.'), + '#title' => $this->t('Secret key'), + '#description' => $this->t('Enter a secret for the site draft/preview. This must be unique for each Next.js site'), '#default_value' => $entity->getPreviewSecret(), ]; $form['revalidation'] = [ '#title' => $this->t('On-demand Revalidation'), '#description' => $this->t('On-demand revalidation updates your pages when content is updated on your Drupal site. You can read more on the Next.js documentation.', [ - ':uri' => 'https://nextjs.org/docs/advanced-features/preview-mode', + ':uri' => 'https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data', ]), '#type' => 'details', '#group' => 'settings', diff --git a/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php b/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php index ec17960f..bb15e7bc 100644 --- a/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php +++ b/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php @@ -83,8 +83,8 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form['secret_expiration'] = [ - '#title' => $this->t('Preview secret expiration time'), - '#description' => $this->t('The value, in seconds, to be used as expiration time for the preview secret. It is recommended to use short-lived secrets for increased security.'), + '#title' => $this->t('Secret expiration time'), + '#description' => $this->t('The value, in seconds, to be used as expiration time for the validation secret. It is recommended to use short-lived secrets for increased security.'), '#type' => 'number', '#required' => TRUE, '#default_value' => $this->configuration['secret_expiration'], From 7a62a3921ca36291b5a5eeb7db942c006e0645e0 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Thu, 25 Jan 2024 09:26:00 -0600 Subject: [PATCH 04/14] feat(next-drupal): add draft mode for app router pages Issue #502 --- modules/next/next.post_update.php | 15 ++++++ modules/next/next.routing.yml | 9 ++++ packages/next-drupal/jest.config.cjs | 8 +-- packages/next-drupal/package.json | 12 ++++- packages/next-drupal/src/client.ts | 50 +++++++++++++++---- packages/next-drupal/src/draft.ts | 73 ++++++++++++++++++++++++++++ packages/next-drupal/tsup.config.ts | 2 +- 7 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 modules/next/next.post_update.php create mode 100644 packages/next-drupal/src/draft.ts diff --git a/modules/next/next.post_update.php b/modules/next/next.post_update.php new file mode 100644 index 00000000..b9fe007f --- /dev/null +++ b/modules/next/next.post_update.php @@ -0,0 +1,15 @@ + { + const slug = searchParams.get("slug") + + this.debug(`Fetching draft url validation for ${slug}.`) + + // Fetch the headless CMS to check if the provided `slug` exists + let response: Response + try { + // Validate the draft url. + const validateUrl = this.buildUrl("/next/draft-url").toString() + response = await this.fetch(validateUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(Object.fromEntries(searchParams.entries())), + }) + } catch (error) { + response = new Response(JSON.stringify({ message: error.message }), { + status: 401, + }) + } + + this.debug( + response.status !== 200 + ? `Could not validate slug, ${slug}` + : `Validated slug, ${slug}` + ) + + return response + } + async preview( - request?: NextApiRequest, - response?: NextApiResponse, + request: NextApiRequest, + response: NextApiResponse, options?: PreviewOptions ) { const { slug, resourceVersion, plugin } = request.query @@ -1056,14 +1091,9 @@ export class DrupalClient { response.clearPreviewData() // Validate the preview url. - const validateUrl = this.buildUrl("/next/preview-url") - const result = await this.fetch(validateUrl.toString(), { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(request.query), - }) + const result = await this.validateDraftUrl( + new URL(request.url).searchParams + ) if (!result.ok) { response.statusCode = result.status diff --git a/packages/next-drupal/src/draft.ts b/packages/next-drupal/src/draft.ts new file mode 100644 index 00000000..32f42cd0 --- /dev/null +++ b/packages/next-drupal/src/draft.ts @@ -0,0 +1,73 @@ +import { cookies, draftMode } from "next/headers" +import { redirect } from "next/navigation" +import { DRAFT_DATA_COOKIE_NAME, DRAFT_MODE_COOKIE_NAME } from "./client" +import type { NextRequest } from "next/server" +import type { DrupalClient } from "./client" + +export async function enableDraftMode( + request: NextRequest, + drupal: DrupalClient +): Promise { + // Validate the draft request. + const response = await drupal.validateDraftUrl(request.nextUrl.searchParams) + + // If validation fails, don't enable draft mode. + if (!response.ok) { + return response + } + + const searchParams = request.nextUrl.searchParams + const slug = searchParams.get("slug") + + // Enable Draft Mode by setting the cookie + draftMode().enable() + + // Override the default SameSite=lax. + // See https://github.com/vercel/next.js/issues/49927 + const draftModeCookie = cookies().get(DRAFT_MODE_COOKIE_NAME) + if (draftModeCookie) { + cookies().set({ + ...draftModeCookie, + sameSite: "none", + secure: true, + }) + } + + // Send Drupal's data to the draft-mode page. + const { secret, scope, plugin, ...draftData } = Object.fromEntries( + searchParams.entries() + ) + cookies().set({ + ...draftModeCookie, + name: DRAFT_DATA_COOKIE_NAME, + sameSite: "none", + secure: true, + value: JSON.stringify(draftData), + }) + + // Redirect to the path from the fetched post. We can safely redirect to the + // slug since this has been validated on the server. + redirect(slug) +} + +export function disableDraftMode() { + cookies().delete(DRAFT_DATA_COOKIE_NAME) + draftMode().disable() + + return new Response("Draft mode is disabled") +} + +export interface DraftData { + slug?: string + resourceVersion?: string +} + +export function getDraftData() { + let data: DraftData = {} + + if (draftMode().isEnabled && cookies().has(DRAFT_DATA_COOKIE_NAME)) { + data = JSON.parse(cookies().get(DRAFT_DATA_COOKIE_NAME)?.value || "{}") + } + + return data +} diff --git a/packages/next-drupal/tsup.config.ts b/packages/next-drupal/tsup.config.ts index 0690563c..b7692abe 100644 --- a/packages/next-drupal/tsup.config.ts +++ b/packages/next-drupal/tsup.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from "tsup" export const tsup = defineConfig({ - entry: ["src/index.ts", "src/navigation.ts"], + entry: ["src/index.ts", "src/draft.ts", "src/navigation.ts"], // Enable experimental code splitting support in CommonJS. // splitting: true, // Use Rollup for tree shaking. From 0b2f311431d5db4239ff7252441af5c8a7c46410 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Tue, 30 Jan 2024 15:17:21 -0600 Subject: [PATCH 05/14] moar: add draft mode for app router pages --- modules/next/next.routing.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/next/next.routing.yml b/modules/next/next.routing.yml index ef7da5a8..7594d18c 100644 --- a/modules/next/next.routing.yml +++ b/modules/next/next.routing.yml @@ -17,6 +17,7 @@ next.validate_draft_url: _access: 'TRUE' _format: 'json' +# TODO: This path is used by next-drupal 1.6.0; remove with next 3.x. next.validate_preview_url: path: '/next/preview-url' defaults: From a4f8d840038f2ab6f7a6e733b48240ecade55266 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Thu, 25 Jan 2024 12:00:53 -0600 Subject: [PATCH 06/14] feat(next-drupal)!: add draft mode to pages router Issue #502 BREAKING CHANGE: The options to the DrupalClient.preview() method were previously ignored. The options are now passed to the NextApiResponse.setDraftMode() method and their TypeScript definition have now changed to match the options parameter of the setDraftMode method. --- packages/next-drupal/src/client.ts | 74 +++++++++++++++++++++--------- packages/next-drupal/src/types.ts | 7 --- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index 9df7803a..e646d3a7 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -34,7 +34,6 @@ import type { Locale, PathAlias, PathPrefix, - PreviewOptions, } from "./types" const DEFAULT_API_PREFIX = "/jsonapi" @@ -1082,9 +1081,11 @@ export class DrupalClient { async preview( request: NextApiRequest, response: NextApiResponse, - options?: PreviewOptions + options?: Parameters[0] ) { - const { slug, resourceVersion, plugin } = request.query + const { slug, resourceVersion, plugin, secret, scope, ...draftData } = + request.query + const useDraftMode = options?.enable try { // Always clear preview data to handle different scopes. @@ -1092,46 +1093,75 @@ export class DrupalClient { // Validate the preview url. const result = await this.validateDraftUrl( - new URL(request.url).searchParams + new URL(request.url, `http://${request.headers.host}`).searchParams ) + const validationPayload = await result.json() + const previewData = { + resourceVersion, + plugin, + ...validationPayload, + } + if (!result.ok) { + this.debug(`Draft url validation error: ${validationPayload.message}`) response.statusCode = result.status - - return response.json(await result.json()) + return response.json(validationPayload) } - const validationPayload = await result.json() + // Optionally turn on draft mode. + if (useDraftMode) { + response.setDraftMode(options) + } - response.setPreviewData({ - resourceVersion, - plugin, - ...validationPayload, - }) + // Turns on preview mode and adds preview data to Next.js' static context. + response.setPreviewData(previewData) // Fix issue with cookie. // See https://github.com/vercel/next.js/discussions/32238. // See https://github.com/vercel/next.js/blob/d895a50abbc8f91726daa2d7ebc22c58f58aabbb/packages/next/server/api-utils/node.ts#L504. - if (this.forceIframeSameSiteCookie) { - const previous = response.getHeader("Set-Cookie") as string[] - previous.forEach((cookie, index) => { - previous[index] = cookie.replace( - "SameSite=Lax", - "SameSite=None;Secure" - ) - }) - response.setHeader(`Set-Cookie`, previous) + const cookies = (response.getHeader("Set-Cookie") as string[]).map( + (cookie) => cookie.replace("SameSite=Lax", "SameSite=None; Secure") + ) + if (useDraftMode) { + // Adds preview data for use in app router pages. + cookies.push( + `${DRAFT_DATA_COOKIE_NAME}=${encodeURIComponent( + JSON.stringify({ slug, resourceVersion, ...draftData }) + )}; Path=/; HttpOnly; SameSite=None; Secure` + ) } + response.setHeader("Set-Cookie", cookies) - // We can safely redirect to the slug since this has been validated on the server. + // We can safely redirect to the slug since this has been validated on the + // server. response.writeHead(307, { Location: slug }) + this.debug(`${useDraftMode ? "Draft" : "Preview"} mode enabled.`) + return response.end() } catch (error) { + this.debug(`Preview failed: ${error.message}`) return response.status(422).end() } } + async previewDisable(request: NextApiRequest, response: NextApiResponse) { + // Disable both preview and draft modes. + response.clearPreviewData() + response.setDraftMode({ enable: false }) + + // Delete the draft data cookie. + const cookies = response.getHeader("Set-Cookie") as string[] + cookies.push( + `${DRAFT_DATA_COOKIE_NAME}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=None; Secure` + ) + response.setHeader("Set-Cookie", cookies) + + response.writeHead(307, { Location: "/" }) + response.end() + } + async getMenu( name: string, options?: JsonApiWithLocaleOptions & diff --git a/packages/next-drupal/src/types.ts b/packages/next-drupal/src/types.ts index ebd5cb62..60c5c783 100644 --- a/packages/next-drupal/src/types.ts +++ b/packages/next-drupal/src/types.ts @@ -410,13 +410,6 @@ export interface JsonApiResourceWithPath extends JsonApiResource { path: PathAlias } -export interface PreviewOptions { - errorMessages?: { - secret?: string - slug?: string - } -} - export type GetResourcePreviewUrlOptions = JsonApiWithLocaleOptions & { isVersionable?: boolean } From 083cebbf33da9bdf40ede4e6f75bc510af9dfa65 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Thu, 25 Jan 2024 12:15:04 -0600 Subject: [PATCH 07/14] feat(next-drupal)!: drop forceIframeSameSiteCookie option BREAKING CHANGE: The forceIframeSameSiteCookie option to DrupalClient has been removed. The DrupalClient now automatically makes this change when the Next.js website is running in development mode (and the change is not needed for production sites). --- examples/example-graphql/lib/drupal.ts | 1 - packages/next-drupal/src/client.ts | 4 ---- packages/next-drupal/src/types.ts | 10 --------- www/content/docs/configuration.mdx | 28 -------------------------- 4 files changed, 43 deletions(-) diff --git a/examples/example-graphql/lib/drupal.ts b/examples/example-graphql/lib/drupal.ts index fdae367d..f1c78d5b 100644 --- a/examples/example-graphql/lib/drupal.ts +++ b/examples/example-graphql/lib/drupal.ts @@ -8,7 +8,6 @@ export const drupal = new DrupalClient( clientSecret: process.env.DRUPAL_CLIENT_SECRET, }, previewSecret: process.env.DRUPAL_PREVIEW_SECRET, - forceIframeSameSiteCookie: true, } ) diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index e646d3a7..7e22df04 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -113,8 +113,6 @@ export class DrupalClient { private previewSecret?: DrupalClientOptions["previewSecret"] - private forceIframeSameSiteCookie?: DrupalClientOptions["forceIframeSameSiteCookie"] - /** * Instantiates a new DrupalClient. * @@ -142,7 +140,6 @@ export class DrupalClient { auth, previewSecret, accessToken, - forceIframeSameSiteCookie = false, throwJsonApiErrors = true, } = options @@ -160,7 +157,6 @@ export class DrupalClient { this.previewSecret = previewSecret this.cache = cache this.accessToken = accessToken - this.forceIframeSameSiteCookie = forceIframeSameSiteCookie this.throwJsonApiErrors = throwJsonApiErrors // Do not throw errors in production. diff --git a/packages/next-drupal/src/types.ts b/packages/next-drupal/src/types.ts index 60c5c783..0e5c9730 100644 --- a/packages/next-drupal/src/types.ts +++ b/packages/next-drupal/src/types.ts @@ -139,16 +139,6 @@ export type DrupalClientOptions = { * The scope used for the current access token. */ accessTokenScope?: string - - /** - * If set to true, the preview cookie will be set with SameSite=None,Secure. - * - * * **Default value**: `false` - * * **Required**: *No* - * - * [Documentation](https://next-drupal.org/docs/client/configuration#forceiframesamesitecookie) - */ - forceIframeSameSiteCookie?: boolean } export type DrupalClientAuth = diff --git a/www/content/docs/configuration.mdx b/www/content/docs/configuration.mdx index 42d9f8ac..baaaec03 100644 --- a/www/content/docs/configuration.mdx +++ b/www/content/docs/configuration.mdx @@ -217,34 +217,6 @@ A long-lived access token you can set directly on the client. --- -### forceIframeSameSiteCookie - - - -Use `forceIframeSameSiteCookie` in development only. - - - -- **Default value**: `false` -- **Required**: No - -If you're running your site in development and the host address is different from the iframe preview, you might run into issues with `SameSite` cookies. - -You can use this option to force the cookie to be set to `SameSite=None,Secure` in **development**. - -```ts -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - forceIframeSameSiteCookie: process.env.NODE_ENV === "development", - } -) -``` - -For more info see: https://github.com/vercel/next.js/discussions/32238 - ---- - ### debug - **Default value**: `false` From 31958b5fbeebead708af072cbb1b55a08aa0fe56 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Sun, 28 Jan 2024 15:44:01 -0600 Subject: [PATCH 08/14] feat(next-drupal): add example-router-migration --- .../example-router-migration/.env.example | 12 + .../example-router-migration/.eslintrc.json | 4 + examples/example-router-migration/.gitignore | 40 ++++ examples/example-router-migration/.nvmrc | 1 + .../example-router-migration/.prettierignore | 18 ++ .../example-router-migration/.prettierrc.json | 4 + .../example-router-migration/CHANGELOG.md | 4 + examples/example-router-migration/README.md | 43 ++++ .../app/[...slug]/page.tsx | 115 ++++++++++ .../app/api/disable-draft/route.ts | 6 + .../app/api/draft/route.ts | 7 + .../app/api/revalidate/route.ts | 28 +++ .../example-router-migration/app/layout.tsx | 37 +++ .../example-router-migration/app/page.tsx | 51 +++++ .../components/drupal/Article.tsx | 46 ++++ .../components/drupal/ArticleTeaser.tsx | 54 +++++ .../components/drupal/BasicPage.tsx | 19 ++ .../components/misc/DraftAlert/Client.tsx | 38 ++++ .../components/misc/DraftAlert/index.tsx | 13 ++ .../components/navigation/HeaderNav.tsx | 21 ++ .../components/navigation/Link.tsx | 23 ++ .../components/pages-router/Layout.tsx | 15 ++ .../components/pages-router/PreviewAlert.tsx | 30 +++ .../example-router-migration/lib/drupal.ts | 13 ++ .../example-router-migration/lib/utils.ts | 12 + .../example-router-migration/next.config.js | 16 ++ .../example-router-migration/package.json | 34 +++ .../example-router-migration/pages/_app.tsx | 6 + .../pages/_document.tsx | 13 ++ .../pages/api/exit-preview.ts | 9 + .../pages/api/preview-only.ts | 9 + .../pages/api/preview.ts | 10 + .../pages/pages-router/[...slug].tsx | 92 ++++++++ .../pages/pages-router/index.tsx | 78 +++++++ .../postcss.config.js | 8 + .../public/favicon.ico | Bin 0 -> 15086 bytes .../public/robots.txt | 2 + .../styles/globals.css | 3 + .../tailwind.config.ts | 18 ++ .../example-router-migration/tsconfig.json | 28 +++ yarn.lock | 212 ++++++++++++++++-- 41 files changed, 1175 insertions(+), 17 deletions(-) create mode 100644 examples/example-router-migration/.env.example create mode 100644 examples/example-router-migration/.eslintrc.json create mode 100644 examples/example-router-migration/.gitignore create mode 100644 examples/example-router-migration/.nvmrc create mode 100644 examples/example-router-migration/.prettierignore create mode 100644 examples/example-router-migration/.prettierrc.json create mode 100644 examples/example-router-migration/CHANGELOG.md create mode 100644 examples/example-router-migration/README.md create mode 100644 examples/example-router-migration/app/[...slug]/page.tsx create mode 100644 examples/example-router-migration/app/api/disable-draft/route.ts create mode 100644 examples/example-router-migration/app/api/draft/route.ts create mode 100644 examples/example-router-migration/app/api/revalidate/route.ts create mode 100644 examples/example-router-migration/app/layout.tsx create mode 100644 examples/example-router-migration/app/page.tsx create mode 100644 examples/example-router-migration/components/drupal/Article.tsx create mode 100644 examples/example-router-migration/components/drupal/ArticleTeaser.tsx create mode 100644 examples/example-router-migration/components/drupal/BasicPage.tsx create mode 100644 examples/example-router-migration/components/misc/DraftAlert/Client.tsx create mode 100644 examples/example-router-migration/components/misc/DraftAlert/index.tsx create mode 100644 examples/example-router-migration/components/navigation/HeaderNav.tsx create mode 100644 examples/example-router-migration/components/navigation/Link.tsx create mode 100644 examples/example-router-migration/components/pages-router/Layout.tsx create mode 100644 examples/example-router-migration/components/pages-router/PreviewAlert.tsx create mode 100644 examples/example-router-migration/lib/drupal.ts create mode 100644 examples/example-router-migration/lib/utils.ts create mode 100644 examples/example-router-migration/next.config.js create mode 100644 examples/example-router-migration/package.json create mode 100644 examples/example-router-migration/pages/_app.tsx create mode 100644 examples/example-router-migration/pages/_document.tsx create mode 100644 examples/example-router-migration/pages/api/exit-preview.ts create mode 100644 examples/example-router-migration/pages/api/preview-only.ts create mode 100644 examples/example-router-migration/pages/api/preview.ts create mode 100644 examples/example-router-migration/pages/pages-router/[...slug].tsx create mode 100644 examples/example-router-migration/pages/pages-router/index.tsx create mode 100644 examples/example-router-migration/postcss.config.js create mode 100644 examples/example-router-migration/public/favicon.ico create mode 100644 examples/example-router-migration/public/robots.txt create mode 100644 examples/example-router-migration/styles/globals.css create mode 100644 examples/example-router-migration/tailwind.config.ts create mode 100644 examples/example-router-migration/tsconfig.json diff --git a/examples/example-router-migration/.env.example b/examples/example-router-migration/.env.example new file mode 100644 index 00000000..951ea909 --- /dev/null +++ b/examples/example-router-migration/.env.example @@ -0,0 +1,12 @@ +# See https://next-drupal.org/docs/environment-variables + +# Required +NEXT_PUBLIC_DRUPAL_BASE_URL=https://site.example.com +NEXT_IMAGE_DOMAIN=site.example.com + +# Authentication +DRUPAL_CLIENT_ID=Retrieve this from /admin/config/services/consumer +DRUPAL_CLIENT_SECRET=Retrieve this from /admin/config/services/consumer + +# Required for On-demand Revalidation +DRUPAL_REVALIDATE_SECRET=Retrieve this from /admin/config/services/next diff --git a/examples/example-router-migration/.eslintrc.json b/examples/example-router-migration/.eslintrc.json new file mode 100644 index 00000000..7c1a3add --- /dev/null +++ b/examples/example-router-migration/.eslintrc.json @@ -0,0 +1,4 @@ +{ + "extends": "next/core-web-vitals", + "root": true +} diff --git a/examples/example-router-migration/.gitignore b/examples/example-router-migration/.gitignore new file mode 100644 index 00000000..081b7c17 --- /dev/null +++ b/examples/example-router-migration/.gitignore @@ -0,0 +1,40 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# IDE files +/.idea +/.vscode + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/examples/example-router-migration/.nvmrc b/examples/example-router-migration/.nvmrc new file mode 100644 index 00000000..9a2a0e21 --- /dev/null +++ b/examples/example-router-migration/.nvmrc @@ -0,0 +1 @@ +v20 diff --git a/examples/example-router-migration/.prettierignore b/examples/example-router-migration/.prettierignore new file mode 100644 index 00000000..03c8a68b --- /dev/null +++ b/examples/example-router-migration/.prettierignore @@ -0,0 +1,18 @@ +# Ignore everything. +/* + +# Format most files in the root directory. +!/*.js +!/*.ts +!/*.md +!/*.json +# But ignore some. +/package.json +/package-lock.json +/CHANGELOG.md + +# Don't ignore these nested directories. +!/app +!/components +!/lib +!/pages diff --git a/examples/example-router-migration/.prettierrc.json b/examples/example-router-migration/.prettierrc.json new file mode 100644 index 00000000..3c60a7b5 --- /dev/null +++ b/examples/example-router-migration/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "semi": false, + "trailingComma": "es5" +} diff --git a/examples/example-router-migration/CHANGELOG.md b/examples/example-router-migration/CHANGELOG.md new file mode 100644 index 00000000..e4d87c4d --- /dev/null +++ b/examples/example-router-migration/CHANGELOG.md @@ -0,0 +1,4 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. diff --git a/examples/example-router-migration/README.md b/examples/example-router-migration/README.md new file mode 100644 index 00000000..c694ee20 --- /dev/null +++ b/examples/example-router-migration/README.md @@ -0,0 +1,43 @@ +# example-router-migration + +Next.js recommends using their new App Router over the legacy Pages Router. The [full router migration guide](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration) is available in the Next.js documentation. + +The new App Router is also designed to facilitate sites that need to migrate from the Pages Router in a piecemeal fashion rather than all at once. + +This codebase is an example of a `next-drupal` site that is in the middle of a Next.js Pages to App Router migration. + +## Piecemeal router migration steps + +### Initial migration + +1. Update the `next-drupal` package to the latest 2.x version. +2. Update the `next` module on your Drupal site to the latest 2.x version. + 1. The most recent version is available at https://www.drupal.org/project/next + 2. Run your Drupal site’s /update.php script. +3. Migrate from Preview Mode to Draft mode. Preview mode only works with the legacy Pages Router. Draft mode works with both routers. + 1. Update the `/pages/api/preview.ts` file to match the one in this Git repo. + 2. Update the `/pages/api/exit-preview.ts` file to match the one in this Git repo. + 3. Delete your `/pages/api/revalidate.ts` file. + 4. Create a `/app/api` directory and add all the files from this Git repo’s `/app/api` directory. + +### Piecemeal migration + +Follow [Next.js’ router migration guide](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration). + +Over time, you will be moving all the files from `/pages` to `/app`. However, these JavaScript files should remain in the `/pages` directory to prevent Preview/Draft Mode from breaking: + +- `/pages/api/exit-preview.ts` +- `/pages/api/preview.ts` + +### Final migration steps + +1. Turn off the legacy Preview Mode. + 1. Go to the Next.js site configuration on your Drupal site at `/admin/config/services/next`. + 2. For each Next.js configuration, change the end of the URL in the “Draft URL (or Preview URL)” setting from `preview` to `draft`, e.g. `https://example.com/api/preview` to `https://example.com/api/draft`. +2. Delete the last files in your `/pages` directory: + - `/pages/api/exit-preview.ts` + - `/pages/api/preview.ts` + +## License + +Licensed under the [MIT license](https://github.com/chapter-three/next-drupal/blob/master/LICENSE). diff --git a/examples/example-router-migration/app/[...slug]/page.tsx b/examples/example-router-migration/app/[...slug]/page.tsx new file mode 100644 index 00000000..2a76ee5e --- /dev/null +++ b/examples/example-router-migration/app/[...slug]/page.tsx @@ -0,0 +1,115 @@ +import { draftMode } from "next/headers" +import { notFound } from "next/navigation" +import { getDraftData } from "next-drupal/draft" +import { Article } from "@/components/drupal/Article" +import { BasicPage } from "@/components/drupal/BasicPage" +import { drupal } from "@/lib/drupal" +import type { Metadata, ResolvingMetadata } from "next" +import type { DrupalNode, JsonApiParams } from "next-drupal" + +async function getNode(slug: string[]) { + const path = slug.join("/") + + const params: JsonApiParams = {} + + const draftData = getDraftData() + + if (draftData.slug === `/${path}`) { + params.resourceVersion = draftData.resourceVersion + } + + // Translating the path also allows us to discover the entity type. + const translatedPath = await drupal.translatePath(path) + + if (!translatedPath) { + throw new Error("Resource not found", { cause: "NotFound" }) + } + + const type = translatedPath.jsonapi?.resourceName! + const uuid = translatedPath.entity.uuid + + if (type === "node--article") { + params.include = "field_image,uid" + } + + const resource = await drupal.getResource(type, uuid, { + params, + }) + + if (!resource) { + throw new Error( + `Failed to fetch resource: ${translatedPath?.jsonapi?.individual}`, + { + cause: "DrupalError", + } + ) + } + + return resource +} + +type NodePageParams = { + slug: string[] +} +type NodePageProps = { + params: NodePageParams + searchParams: { [key: string]: string | string[] | undefined } +} + +export async function generateMetadata( + { params: { slug } }: NodePageProps, + parent: ResolvingMetadata +): Promise { + let node + try { + node = await getNode(slug) + } catch (e) { + // If we fail to fetch the node, don't return any metadata. + return {} + } + + return { + title: node.title, + } +} + +const RESOURCE_TYPES = ["node--page", "node--article"] + +export async function generateStaticParams(): Promise { + // TODO: Replace getStaticPathsFromContext() usage since there is no context. + const paths = await drupal.getStaticPathsFromContext(RESOURCE_TYPES, {}) + // console.log( + // "generateStaticParams", + // paths.map(({ params }) => params) + // ) + return paths.map((path: string | { params: NodePageParams }) => + typeof path === "string" ? { slug: [] } : path?.params + ) +} + +export default async function NodePage({ + params: { slug }, + searchParams, +}: NodePageProps) { + const isDraftMode = draftMode().isEnabled + + let node + try { + node = await getNode(slug) + } catch (error) { + // If getNode throws an error, tell Next.js the path is 404. + notFound() + } + + // If we're not in draft mode and the resource is not published, return a 404. + if (!isDraftMode && node?.status === false) { + notFound() + } + + return ( + <> + {node.type === "node--page" && } + {node.type === "node--article" &&
} + + ) +} diff --git a/examples/example-router-migration/app/api/disable-draft/route.ts b/examples/example-router-migration/app/api/disable-draft/route.ts new file mode 100644 index 00000000..81900948 --- /dev/null +++ b/examples/example-router-migration/app/api/disable-draft/route.ts @@ -0,0 +1,6 @@ +import { disableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest) { + return disableDraftMode() +} diff --git a/examples/example-router-migration/app/api/draft/route.ts b/examples/example-router-migration/app/api/draft/route.ts new file mode 100644 index 00000000..b8757e2a --- /dev/null +++ b/examples/example-router-migration/app/api/draft/route.ts @@ -0,0 +1,7 @@ +import { drupal } from "@/lib/drupal" +import { enableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest): Promise { + return enableDraftMode(request, drupal) +} diff --git a/examples/example-router-migration/app/api/revalidate/route.ts b/examples/example-router-migration/app/api/revalidate/route.ts new file mode 100644 index 00000000..d3722f7b --- /dev/null +++ b/examples/example-router-migration/app/api/revalidate/route.ts @@ -0,0 +1,28 @@ +import { revalidatePath } from "next/cache" +import type { NextRequest } from "next/server" + +async function handler(request: NextRequest) { + const searchParams = request.nextUrl.searchParams + const slug = searchParams.get("slug") + const secret = searchParams.get("secret") + + // Validate secret. + if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) { + return new Response("Invalid secret.", { status: 401 }) + } + + // Validate slug. + if (!slug) { + return new Response("Invalid slug.", { status: 400 }) + } + + try { + revalidatePath(slug) + + return new Response("Revalidated.") + } catch (error) { + return new Response((error as Error).message, { status: 500 }) + } +} + +export { handler as GET, handler as POST } diff --git a/examples/example-router-migration/app/layout.tsx b/examples/example-router-migration/app/layout.tsx new file mode 100644 index 00000000..3b3c9652 --- /dev/null +++ b/examples/example-router-migration/app/layout.tsx @@ -0,0 +1,37 @@ +import { DraftAlert } from "@/components/misc/DraftAlert" +import { HeaderNav } from "@/components/navigation/HeaderNav" +import type { Metadata } from "next" +import type { ReactNode } from "react" + +import "@/styles/globals.css" + +export const metadata: Metadata = { + title: { + default: "Next.js for Drupal", + template: "%s | Next.js for Drupal", + }, + description: "A Next.js site powered by a Drupal backend.", + icons: { + icon: "/favicon.ico", + }, +} + +export default function RootLayout({ + // Layouts must accept a children prop. + // This will be populated with nested layouts or pages + children, +}: { + children: ReactNode +}) { + return ( + + + +
+ +
{children}
+
+ + + ) +} diff --git a/examples/example-router-migration/app/page.tsx b/examples/example-router-migration/app/page.tsx new file mode 100644 index 00000000..a7f1ec4d --- /dev/null +++ b/examples/example-router-migration/app/page.tsx @@ -0,0 +1,51 @@ +import { ArticleTeaser } from "@/components/drupal/ArticleTeaser" +import { Link } from "@/components/navigation/Link" +import { drupal } from "@/lib/drupal" +import type { Metadata } from "next" +import type { DrupalNode } from "next-drupal" + +export const metadata: Metadata = { + description: "A Next.js site powered by a Drupal backend.", +} + +export default async function Home() { + const nodes = await drupal.getResourceCollection( + "node--article", + { + params: { + "filter[status]": 1, + "fields[node--article]": "title,path,field_image,uid,created", + include: "field_image,uid", + sort: "-created", + }, + } + ) + + return ( + <> +

+ Latest Articles. +
+ + Using the App Router + +

+

+ Switch to{" "} + + Pages Router + +

+ {nodes?.length ? ( + nodes.map((node) => ( +
+ +
+
+ )) + ) : ( +

No nodes found

+ )} + + ) +} diff --git a/examples/example-router-migration/components/drupal/Article.tsx b/examples/example-router-migration/components/drupal/Article.tsx new file mode 100644 index 00000000..b4d3d234 --- /dev/null +++ b/examples/example-router-migration/components/drupal/Article.tsx @@ -0,0 +1,46 @@ +import Image from "next/image" +import { absoluteUrl, formatDate } from "@/lib/utils" +import type { DrupalNode } from "next-drupal" + +interface ArticleProps { + node: DrupalNode +} + +export function Article({ node, ...props }: ArticleProps) { + return ( +
+

{node.title}

+
+ {node.uid?.display_name ? ( + + Posted by{" "} + {node.uid?.display_name} + + ) : null} + - {formatDate(node.created)} +
+ {node.field_image && ( +
+ {node.field_image.resourceIdObjMeta.alt + {node.field_image.resourceIdObjMeta.title && ( +
+ {node.field_image.resourceIdObjMeta.title} +
+ )} +
+ )} + {node.body?.processed && ( +
+ )} +
+ ) +} diff --git a/examples/example-router-migration/components/drupal/ArticleTeaser.tsx b/examples/example-router-migration/components/drupal/ArticleTeaser.tsx new file mode 100644 index 00000000..8efeac62 --- /dev/null +++ b/examples/example-router-migration/components/drupal/ArticleTeaser.tsx @@ -0,0 +1,54 @@ +import Image from "next/image" +import { Link } from "@/components/navigation/Link" +import { absoluteUrl, formatDate } from "@/lib/utils" +import type { DrupalNode } from "next-drupal" + +interface ArticleTeaserProps { + node: DrupalNode +} + +export function ArticleTeaser({ node, ...props }: ArticleTeaserProps) { + return ( +
+ +

{node.title}

+ +
+ {node.uid?.display_name ? ( + + Posted by{" "} + {node.uid?.display_name} + + ) : null} + - {formatDate(node.created)} +
+ {node.field_image && ( +
+ {node.field_image.resourceIdObjMeta.alt} +
+ )} + + Read article + + + + +
+ ) +} diff --git a/examples/example-router-migration/components/drupal/BasicPage.tsx b/examples/example-router-migration/components/drupal/BasicPage.tsx new file mode 100644 index 00000000..88d7f00b --- /dev/null +++ b/examples/example-router-migration/components/drupal/BasicPage.tsx @@ -0,0 +1,19 @@ +import type { DrupalNode } from "next-drupal" + +interface BasicPageProps { + node: DrupalNode +} + +export function BasicPage({ node, ...props }: BasicPageProps) { + return ( +
+

{node.title}

+ {node.body?.processed && ( +
+ )} +
+ ) +} diff --git a/examples/example-router-migration/components/misc/DraftAlert/Client.tsx b/examples/example-router-migration/components/misc/DraftAlert/Client.tsx new file mode 100644 index 00000000..00932ae4 --- /dev/null +++ b/examples/example-router-migration/components/misc/DraftAlert/Client.tsx @@ -0,0 +1,38 @@ +"use client" + +import { useEffect, useState } from "react" + +export function DraftAlertClient({ + isDraftEnabled, +}: { + isDraftEnabled: boolean +}) { + const [showDraftAlert, setShowDraftAlert] = useState(false) + + useEffect(() => { + setShowDraftAlert(isDraftEnabled && window.top === window.self) + }, [isDraftEnabled]) + + if (!showDraftAlert) { + return null + } + + function buttonHandler() { + void fetch("/api/disable-draft") + setShowDraftAlert(false) + } + + return ( +
+

+ This page is a draft. + +

+
+ ) +} diff --git a/examples/example-router-migration/components/misc/DraftAlert/index.tsx b/examples/example-router-migration/components/misc/DraftAlert/index.tsx new file mode 100644 index 00000000..a07f0d67 --- /dev/null +++ b/examples/example-router-migration/components/misc/DraftAlert/index.tsx @@ -0,0 +1,13 @@ +import { Suspense } from "react" +import { draftMode } from "next/headers" +import { DraftAlertClient } from "./Client" + +export function DraftAlert() { + const isDraftEnabled = draftMode().isEnabled + + return ( + + + + ) +} diff --git a/examples/example-router-migration/components/navigation/HeaderNav.tsx b/examples/example-router-migration/components/navigation/HeaderNav.tsx new file mode 100644 index 00000000..bccb4e4c --- /dev/null +++ b/examples/example-router-migration/components/navigation/HeaderNav.tsx @@ -0,0 +1,21 @@ +import { Link } from "@/components/navigation/Link" + +export function HeaderNav() { + return ( +
+
+ + Next.js for Drupal + + + Read the docs + +
+
+ ) +} diff --git a/examples/example-router-migration/components/navigation/Link.tsx b/examples/example-router-migration/components/navigation/Link.tsx new file mode 100644 index 00000000..23dbc4c0 --- /dev/null +++ b/examples/example-router-migration/components/navigation/Link.tsx @@ -0,0 +1,23 @@ +import { forwardRef } from "react" +import NextLink from "next/link" +import type { AnchorHTMLAttributes, ReactNode } from "react" +import type { LinkProps as NextLinkProps } from "next/link" + +type LinkProps = NextLinkProps & + Omit, keyof NextLinkProps> & { + children?: ReactNode + } + +export const Link = forwardRef( + function LinkWithRef( + { + // Turn next/link prefetching off by default. + // @see https://github.com/vercel/next.js/discussions/24009 + prefetch = false, + ...rest + }, + ref + ) { + return + } +) diff --git a/examples/example-router-migration/components/pages-router/Layout.tsx b/examples/example-router-migration/components/pages-router/Layout.tsx new file mode 100644 index 00000000..16e08744 --- /dev/null +++ b/examples/example-router-migration/components/pages-router/Layout.tsx @@ -0,0 +1,15 @@ +import { HeaderNav } from "@/components/navigation/HeaderNav" +import { PreviewAlert } from "@/components/pages-router/PreviewAlert" +import type { ReactNode } from "react" + +export function Layout({ children }: { children: ReactNode }) { + return ( + <> + +
+ +
{children}
+
+ + ) +} diff --git a/examples/example-router-migration/components/pages-router/PreviewAlert.tsx b/examples/example-router-migration/components/pages-router/PreviewAlert.tsx new file mode 100644 index 00000000..abca6a68 --- /dev/null +++ b/examples/example-router-migration/components/pages-router/PreviewAlert.tsx @@ -0,0 +1,30 @@ +import { useEffect, useState } from "react" +import { useRouter } from "next/router" + +export function PreviewAlert() { + const router = useRouter() + const isPreview = router.isPreview + const [showPreviewAlert, setShowPreviewAlert] = useState(false) + + useEffect(() => { + setShowPreviewAlert(isPreview && window.top === window.self) + }, [isPreview]) + + if (!showPreviewAlert) { + return null + } + + return ( +
+

+ This page is a preview.{" "} + +

+
+ ) +} diff --git a/examples/example-router-migration/lib/drupal.ts b/examples/example-router-migration/lib/drupal.ts new file mode 100644 index 00000000..e390f347 --- /dev/null +++ b/examples/example-router-migration/lib/drupal.ts @@ -0,0 +1,13 @@ +import { DrupalClient } from "next-drupal" + +const baseUrl: string = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL || "" +const clientId = process.env.DRUPAL_CLIENT_ID || "" +const clientSecret = process.env.DRUPAL_CLIENT_SECRET || "" + +export const drupal = new DrupalClient(baseUrl, { + auth: { + clientId, + clientSecret, + }, + debug: true, +}) diff --git a/examples/example-router-migration/lib/utils.ts b/examples/example-router-migration/lib/utils.ts new file mode 100644 index 00000000..d83a0d73 --- /dev/null +++ b/examples/example-router-migration/lib/utils.ts @@ -0,0 +1,12 @@ +export function formatDate(input: string): string { + const date = new Date(input) + return date.toLocaleDateString("en-US", { + month: "long", + day: "numeric", + year: "numeric", + }) +} + +export function absoluteUrl(input: string) { + return `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${input}` +} diff --git a/examples/example-router-migration/next.config.js b/examples/example-router-migration/next.config.js new file mode 100644 index 00000000..0a7fabac --- /dev/null +++ b/examples/example-router-migration/next.config.js @@ -0,0 +1,16 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + images: { + remotePatterns: [ + { + // protocol: 'https', + hostname: process.env.NEXT_IMAGE_DOMAIN, + // port: '', + // pathname: '/sites/default/files/**', + }, + ], + }, +} + +module.exports = nextConfig diff --git a/examples/example-router-migration/package.json b/examples/example-router-migration/package.json new file mode 100644 index 00000000..2783e4c6 --- /dev/null +++ b/examples/example-router-migration/package.json @@ -0,0 +1,34 @@ +{ + "name": "example-router-migration", + "version": "1.8.0", + "private": true, + "license": "MIT", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "preview": "next build && next start", + "lint": "next lint", + "format": "prettier --write .", + "format:check": "prettier --check ." + }, + "dependencies": { + "next": "^14", + "next-drupal": "^2.0.0-alpha.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@tailwindcss/typography": "^0.5.10", + "@types/node": "^20.10.0", + "@types/react": "^18.2.39", + "@types/react-dom": "^18.2.17", + "autoprefixer": "^10.4.16", + "eslint": "^8.54.0", + "eslint-config-next": "^14.0.3", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "tailwindcss": "^3.3.5", + "typescript": "^5.3.2" + } +} diff --git a/examples/example-router-migration/pages/_app.tsx b/examples/example-router-migration/pages/_app.tsx new file mode 100644 index 00000000..70739e9b --- /dev/null +++ b/examples/example-router-migration/pages/_app.tsx @@ -0,0 +1,6 @@ +import "@/styles/globals.css" +import type { AppProps } from "next/app" + +export default function App({ Component, pageProps }: AppProps) { + return +} diff --git a/examples/example-router-migration/pages/_document.tsx b/examples/example-router-migration/pages/_document.tsx new file mode 100644 index 00000000..097cb7ff --- /dev/null +++ b/examples/example-router-migration/pages/_document.tsx @@ -0,0 +1,13 @@ +import { Html, Head, Main, NextScript } from "next/document" + +export default function Document() { + return ( + + + +
+ + + + ) +} diff --git a/examples/example-router-migration/pages/api/exit-preview.ts b/examples/example-router-migration/pages/api/exit-preview.ts new file mode 100644 index 00000000..f8847b39 --- /dev/null +++ b/examples/example-router-migration/pages/api/exit-preview.ts @@ -0,0 +1,9 @@ +import { drupal } from "@/lib/drupal" +import type { NextApiRequest, NextApiResponse } from "next" + +export default async function exit( + request: NextApiRequest, + response: NextApiResponse +) { + await drupal.previewDisable(request, response) +} diff --git a/examples/example-router-migration/pages/api/preview-only.ts b/examples/example-router-migration/pages/api/preview-only.ts new file mode 100644 index 00000000..26c04ffc --- /dev/null +++ b/examples/example-router-migration/pages/api/preview-only.ts @@ -0,0 +1,9 @@ +import { drupal } from "@/lib/drupal" +import type { NextApiRequest, NextApiResponse } from "next" + +export default async function preview( + request: NextApiRequest, + response: NextApiResponse +) { + await drupal.preview(request, response) +} diff --git a/examples/example-router-migration/pages/api/preview.ts b/examples/example-router-migration/pages/api/preview.ts new file mode 100644 index 00000000..a0733440 --- /dev/null +++ b/examples/example-router-migration/pages/api/preview.ts @@ -0,0 +1,10 @@ +import { drupal } from "@/lib/drupal" +import type { NextApiRequest, NextApiResponse } from "next" + +export default async function draft( + request: NextApiRequest, + response: NextApiResponse +) { + // Enables Preview mode and Draft mode. + await drupal.preview(request, response, { enable: true }) +} diff --git a/examples/example-router-migration/pages/pages-router/[...slug].tsx b/examples/example-router-migration/pages/pages-router/[...slug].tsx new file mode 100644 index 00000000..02ad87be --- /dev/null +++ b/examples/example-router-migration/pages/pages-router/[...slug].tsx @@ -0,0 +1,92 @@ +import Head from "next/head" +import { Article } from "@/components/drupal/Article" +import { BasicPage } from "@/components/drupal/BasicPage" +import { Layout } from "@/components/pages-router/Layout" +import { drupal } from "@/lib/drupal" +import type { + GetStaticPaths, + GetStaticProps, + InferGetStaticPropsType, +} from "next" +import type { DrupalNode } from "next-drupal" + +const RESOURCE_TYPES = ["node--page", "node--article"] + +export const getStaticPaths = (async (context) => { + return { + paths: await drupal.getStaticPathsFromContext(RESOURCE_TYPES, context), + fallback: "blocking", + } +}) satisfies GetStaticPaths + +export const getStaticProps = (async (context) => { + const path = await drupal.translatePathFromContext(context) + + if (!path) { + return { + notFound: true, + } + } + + const type = path?.jsonapi?.resourceName + + let params = {} + if (type === "node--article") { + params = { + include: "field_image,uid", + } + } + + const resource = await drupal.getResourceFromContext( + path, + context, + { + params, + } + ) + + // At this point, we know the path exists and it points to a resource. + // If we receive an error, it means something went wrong on Drupal. + // We throw an error to tell revalidation to skip this for now. + // Revalidation can try again on next request. + if (!resource) { + throw new Error(`Failed to fetch resource: ${path?.jsonapi?.individual}`) + } + + // If we're not in preview mode and the resource is not published, + // Return page not found. + if (!context.preview && resource?.status === false) { + return { + notFound: true, + } + } + + return { + props: { + resource, + }, + } +}) satisfies GetStaticProps<{ + resource: DrupalNode +}> + +export default function NodePage({ + resource, +}: InferGetStaticPropsType) { + if (!resource) return null + + return ( + + + {resource.title} + + + {resource.type === "node--page" && } + {resource.type === "node--article" &&
} + + ) +} diff --git a/examples/example-router-migration/pages/pages-router/index.tsx b/examples/example-router-migration/pages/pages-router/index.tsx new file mode 100644 index 00000000..5015df32 --- /dev/null +++ b/examples/example-router-migration/pages/pages-router/index.tsx @@ -0,0 +1,78 @@ +import Head from "next/head" +import { ArticleTeaser } from "@/components/drupal/ArticleTeaser" +import { Link } from "@/components/navigation/Link" +import { Layout } from "@/components/pages-router/Layout" +import { drupal } from "@/lib/drupal" +import type { InferGetStaticPropsType, GetStaticProps } from "next" +import type { DrupalNode } from "next-drupal" + +export const getStaticProps = (async (context) => { + const nodes = await drupal.getResourceCollectionFromContext( + "node--article", + context, + { + params: { + "filter[status]": 1, + "fields[node--article]": "title,path,field_image,uid,created", + include: "field_image,uid", + sort: "-created", + }, + } + ) + + return { + props: { + nodes, + }, + } +}) satisfies GetStaticProps<{ + nodes: DrupalNode[] +}> + +export default function Home({ + nodes, +}: InferGetStaticPropsType) { + return ( + + + Next.js for Drupal + + +

+ Latest Articles. +
+ + Using the Pages Router + +

+

+ Switch to{" "} + + App Router + +

+ {nodes?.length ? ( + nodes.map((node) => ( +
+ +
+
+ )) + ) : ( +

No nodes found

+ )} +
+ ) +} diff --git a/examples/example-router-migration/postcss.config.js b/examples/example-router-migration/postcss.config.js new file mode 100644 index 00000000..3fa0a951 --- /dev/null +++ b/examples/example-router-migration/postcss.config.js @@ -0,0 +1,8 @@ +// If you want to use other PostCSS plugins, see the following: +// https://tailwindcss.com/docs/using-with-preprocessors +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/examples/example-router-migration/public/favicon.ico b/examples/example-router-migration/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ea2f437d9db6552726693be6cc2943a32dc5a964 GIT binary patch literal 15086 zcmdU$X^c%<7ROI1lv$Z)$~+GtJY$|F!80Yq2f; >NSTKFL46_E}iL5mO)AEZS| zhz??kp>#q_Pa+X9S9!)q#7v>f>h;_1zJ2P{J?EY~6zP?$I_K=Y*ZTkWKIiUX?Ol$O z;bc0!dO3Q{aq`JLhPRsE;xZ>o<~Kd63*DEFk1M;XdugYEZ_Oa-Nh{-%0D^{MKAR3)TR78`8wfiHZP zw^UGo?y4J9e^;e_!*cd3hmYSYR;;*T(V|5?L_wL<$ z@a);MWqJ=*I%S|bJEdBpnlwj0+s2I>%gK``wdqCHu3cM_nVAU|n5l~P2F}l_<kDo{eQU1fr(;a=<7HsJ2X}tEcJ1Wh!-s|o-vjk==X>vm4I3s;pFTC^uUxqj`ki_GM4sUaXDiGB z1M$82Uj9v*H1V}>)TogZ6ciZlZ{NNZe!tdVl`2)FLWK&^XPX}43TK2l_;J;Qe7O1F zym?dn_`_}G%9Zlv%NN6c>(;H3m6c_%YSyeNGiT0}YSpSGgdO1uXSn~M`bQ)!w4bp2 zM~)mR&!0ax+^=4}D(&01k7CT8JzEYQJSbJGR*j}5zyr>3|BGrOYY&6v=6~zfEos`c zX&DZrojG&HaA%G)b?Ve;nGPK~n0}ObC*M#4ylq)H!=3ekwl>EI7{*43fg-In$8Z`Q0?)JKaJE#$(53x?l^4Y2;5_qa=u@U!I#kb9lRMnmBQyS&P7(aji?2E@j## zjr`%B)O^j$pT4G5t5(9C3@I)y7W&6n^-m*zxbqHT;sm98`L}J`RyJ+gWVrKZ=gytJ z<5C*=!#yp(Uya>F=k$yR-MV%2ZId+ew=q3mEWdZ)Zhz*&j~_oaZBM^4ckbLke`(}T z|C#dm75!-RX7}#hQoVZhZ^a+(DbF7)|GRhZO3$7>1G)1))71WU{=gh4rTH8DS;x$u zKR+(_H1fCeH|C(sMMGiRa`ZP39z3v3FMIdy73RY>Kj@mK_J=dvk%ZST+1c5qkGy{U zx|}+7D%5wQIHrEXhYy$c@86rcA3l6Ix*o9kA+L7*qQ%WxETQ!y82nC&L)EHPD^$B% zUiIqLGizbiz|8Y(dIDGP`Y}Uo6I#C~fRzltcsAbkyV5Z+iO}(r@5nz^`~?0;xyP>* zBVOAEPQS}LezcU8u3`m?0g{%YrLZ+zejpZEr&yd_fs z{vXe8#A+Aj;Qds;%lR3RqAbz38P#IPX~naS80-j1fer>-^K`?8s}ki8FWvd|Yv9`X z(Q(vF4ZjY0PVN6)i%8FMoC2=;*1Xp|(slOhy^@?x$-`L;oC4Bg@G2r*c{6aj>tpN5 z;+1;ab`YNRPqdv1BJF0|(Y7mPjDBr*KH?nJp{mhyTG{%LoX}TyR$ZXFSM{dq8& zlzY<1qYP!!(ZBP1WF5anwNUl5s@5`4DMQ&UBSwt)K^KF`@@T3))~IqGD;{QjQmLp-B2x4r?6?WX3a8t6!YfI zbNj$2zJrAR>bk1iE}{Frefx4=OZM#9BQ=Vj99`uI<4xp3H{u#VMAfx2z+gK zKRYnI-veXY>Qu1VpU^X2X8&Ztf(3rqHXST5t@PKMKU8ggsVn=C?59qfHqCc$e#(?7 z=DgFsefz@1o4^7S;WxfnwG^iNnX?$gw1_{)+7Is3sgn>dx_|$^aCXUU8*mRM*j-c$ z1In2_{YQ@;32{vKeik;g4SPYHUs$+sp~0?SzrJrfxp2S)oBlGeU*jBzAO39J3n50y z`48ev#E|mx@}y3kI`P^8OxvFami5E$-o3l9N6C4Ke*O9xABz_+ma}KihK+qOUc~Kd zzz3tSurRuxMT{*!Ki};CvqzzR%pN+wJTYo7$Z9lxVKtS|S~UH`6KyPCe0AnTGP zOG?=#i66TCsWW{X?SAy=QQ_Q^n`aXEV2Aqt=zrKl;+)KrCr@PX;K8M^;gJMB*!%{{ z_;RPw{`74K{mjy(ONDb&?lRmbfp6z)ar+;O&-h0F=EY6|-}XOo`(MUY&UCT|JY>j_ znAqSm_Os_l{}W=*qfl+YjywL)*7T?JtwCp^_{}p$>bx_s99&iH_@lRGEc6|JBjtVT zokYHS`~^Sd`A32rR!1q{@cJ12bJ@bbRw$%5zwP#FJo@PuU zjc3-pqeqX9`j3>w2HRbcXOqu4fzzi?NB=)!#flZOYSk*~+_`hCu@l?-ZhPh=*mJ&& z@s9JVy?ghTEnBw4Ix~%JsW}GroIPg#df>nT88c>#Ig^G@&Lz9CBDQ7hIfKf%80LhG z(X2-T>`U=)-MY0|r=L4_PB@ncUVuHerP_~m;IU)JWc>K?QLdb+mU@4D zAIvA*|69Yi$NbuzrgrxImHB==7+y^KY`-5ZZocQh@7Lp#viAGM9^o0EF@Har4la3= q@!D#Vku3e|`}>XLQ6?(ItsJLFQwlOQrkn9qqnVx?n@?G6u>CIsZs3vt literal 0 HcmV?d00001 diff --git a/examples/example-router-migration/public/robots.txt b/examples/example-router-migration/public/robots.txt new file mode 100644 index 00000000..14267e90 --- /dev/null +++ b/examples/example-router-migration/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / \ No newline at end of file diff --git a/examples/example-router-migration/styles/globals.css b/examples/example-router-migration/styles/globals.css new file mode 100644 index 00000000..b5c61c95 --- /dev/null +++ b/examples/example-router-migration/styles/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/examples/example-router-migration/tailwind.config.ts b/examples/example-router-migration/tailwind.config.ts new file mode 100644 index 00000000..c7f5c8a1 --- /dev/null +++ b/examples/example-router-migration/tailwind.config.ts @@ -0,0 +1,18 @@ +import type { Config } from "tailwindcss" + +const config: Config = { + content: [ + "./pages/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", + "./app/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: {}, + }, + variants: { + extend: {}, + }, + plugins: [require("@tailwindcss/typography")], +} + +export default config diff --git a/examples/example-router-migration/tsconfig.json b/examples/example-router-migration/tsconfig.json new file mode 100644 index 00000000..23ba4fd5 --- /dev/null +++ b/examples/example-router-migration/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index 527040b8..80d79bc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2045,11 +2045,21 @@ resolved "https://registry.yarnpkg.com/@next/env/-/env-12.3.4.tgz#c787837d36fcad75d72ff8df6b57482027d64a47" integrity sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A== +"@next/env@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.6.tgz#c1148e2e1aa166614f05161ee8f77ded467062bc" + integrity sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw== + "@next/env@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/env/-/env-14.0.4.tgz#d5cda0c4a862d70ae760e58c0cd96a8899a2e49a" integrity sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ== +"@next/env@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.1.0.tgz#43d92ebb53bc0ae43dcc64fb4d418f8f17d7a341" + integrity sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw== + "@next/eslint-plugin-next@12.3.4", "@next/eslint-plugin-next@^12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-12.3.4.tgz#e7dc00e2e89ed361f111d687b8534483ec15518b" @@ -2079,21 +2089,41 @@ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.4.tgz#14ac8357010c95e67327f47082af9c9d75d5be79" integrity sha512-DqsSTd3FRjQUR6ao0E1e2OlOcrF5br+uegcEGPVonKYJpcr0MJrtYmPxd4v5T6UCJZ+XzydF7eQo5wdGvSZAyA== +"@next/swc-darwin-arm64@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.6.tgz#b15d139d8971360fca29be3bdd703c108c9a45fb" + integrity sha512-5nvXMzKtZfvcu4BhtV0KH1oGv4XEW+B+jOfmBdpFI3C7FrB/MfujRpWYSBBO64+qbW8pkZiSyQv9eiwnn5VIQA== + "@next/swc-darwin-arm64@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.4.tgz#27b1854c2cd04eb1d5e75081a1a792ad91526618" integrity sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg== +"@next/swc-darwin-arm64@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz#70a57c87ab1ae5aa963a3ba0f4e59e18f4ecea39" + integrity sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ== + "@next/swc-darwin-x64@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.4.tgz#e7dc63cd2ac26d15fb84d4d2997207fb9ba7da0f" integrity sha512-PPF7tbWD4k0dJ2EcUSnOsaOJ5rhT3rlEt/3LhZUGiYNL8KvoqczFrETlUx0cUYaXe11dRA3F80Hpt727QIwByQ== +"@next/swc-darwin-x64@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.6.tgz#9c72ee31cc356cb65ce6860b658d807ff39f1578" + integrity sha512-6cgBfxg98oOCSr4BckWjLLgiVwlL3vlLj8hXg2b+nDgm4bC/qVXXLfpLB9FHdoDu4057hzywbxKvmYGmi7yUzA== + "@next/swc-darwin-x64@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz#9940c449e757d0ee50bb9e792d2600cc08a3eb3b" integrity sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw== +"@next/swc-darwin-x64@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz#0863a22feae1540e83c249384b539069fef054e9" + integrity sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g== + "@next/swc-freebsd-x64@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.4.tgz#fe7ceec58746fdf03f1fcb37ec1331c28e76af93" @@ -2109,71 +2139,141 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.4.tgz#43a7bc409b03487bff5beb99479cacdc7bd29af5" integrity sha512-kiX0vgJGMZVv+oo1QuObaYulXNvdH/IINmvdZnVzMO/jic/B8EEIGlZ8Bgvw8LCjH3zNVPO3mGrdMvnEEPEhKA== +"@next/swc-linux-arm64-gnu@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.6.tgz#59f5f66155e85380ffa26ee3d95b687a770cfeab" + integrity sha512-txagBbj1e1w47YQjcKgSU4rRVQ7uF29YpnlHV5xuVUsgCUf2FmyfJ3CPjZUvpIeXCJAoMCFAoGnbtX86BK7+sg== + "@next/swc-linux-arm64-gnu@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz#0eafd27c8587f68ace7b4fa80695711a8434de21" integrity sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w== +"@next/swc-linux-arm64-gnu@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz#893da533d3fce4aec7116fe772d4f9b95232423c" + integrity sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ== + "@next/swc-linux-arm64-musl@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.4.tgz#4d1db6de6dc982b974cd1c52937111e3e4a34bd3" integrity sha512-EETZPa1juczrKLWk5okoW2hv7D7WvonU+Cf2CgsSoxgsYbUCZ1voOpL4JZTOb6IbKMDo6ja+SbY0vzXZBUMvkQ== +"@next/swc-linux-arm64-musl@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.6.tgz#f012518228017052736a87d69bae73e587c76ce2" + integrity sha512-cGd+H8amifT86ZldVJtAKDxUqeFyLWW+v2NlBULnLAdWsiuuN8TuhVBt8ZNpCqcAuoruoSWynvMWixTFcroq+Q== + "@next/swc-linux-arm64-musl@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz#2b0072adb213f36dada5394ea67d6e82069ae7dd" integrity sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ== +"@next/swc-linux-arm64-musl@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz#d81ddcf95916310b8b0e4ad32b637406564244c0" + integrity sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g== + "@next/swc-linux-x64-gnu@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.4.tgz#c3b414d77bab08b35f7dd8943d5586f0adb15e38" integrity sha512-4csPbRbfZbuWOk3ATyWcvVFdD9/Rsdq5YHKvRuEni68OCLkfy4f+4I9OBpyK1SKJ00Cih16NJbHE+k+ljPPpag== +"@next/swc-linux-x64-gnu@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.6.tgz#339b867a7e9e7ee727a700b496b269033d820df4" + integrity sha512-Mc2b4xiIWKXIhBy2NBTwOxGD3nHLmq4keFk+d4/WL5fMsB8XdJRdtUlL87SqVCTSaf1BRuQQf1HvXZcy+rq3Nw== + "@next/swc-linux-x64-gnu@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz#68c67d20ebc8e3f6ced6ff23a4ba2a679dbcec32" integrity sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A== +"@next/swc-linux-x64-gnu@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz#18967f100ec19938354332dcb0268393cbacf581" + integrity sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ== + "@next/swc-linux-x64-musl@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.4.tgz#187a883ec09eb2442a5ebf126826e19037313c61" integrity sha512-YeBmI+63Ro75SUiL/QXEVXQ19T++58aI/IINOyhpsRL1LKdyfK/35iilraZEFz9bLQrwy1LYAR5lK200A9Gjbg== +"@next/swc-linux-x64-musl@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.6.tgz#ae0ae84d058df758675830bcf70ca1846f1028f2" + integrity sha512-CFHvP9Qz98NruJiUnCe61O6GveKKHpJLloXbDSWRhqhkJdZD2zU5hG+gtVJR//tyW897izuHpM6Gtf6+sNgJPQ== + "@next/swc-linux-x64-musl@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz#67cd81b42fb2caf313f7992fcf6d978af55a1247" integrity sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw== +"@next/swc-linux-x64-musl@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz#77077cd4ba8dda8f349dc7ceb6230e68ee3293cf" + integrity sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg== + "@next/swc-win32-arm64-msvc@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.4.tgz#89befa84e453ed2ef9a888f375eba565a0fde80b" integrity sha512-Sd0qFUJv8Tj0PukAYbCCDbmXcMkbIuhnTeHm9m4ZGjCf6kt7E/RMs55Pd3R5ePjOkN7dJEuxYBehawTR/aPDSQ== +"@next/swc-win32-arm64-msvc@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.6.tgz#a5cc0c16920485a929a17495064671374fdbc661" + integrity sha512-aFv1ejfkbS7PUa1qVPwzDHjQWQtknzAZWGTKYIAaS4NMtBlk3VyA6AYn593pqNanlicewqyl2jUhQAaFV/qXsg== + "@next/swc-win32-arm64-msvc@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz#be06585906b195d755ceda28f33c633e1443f1a3" integrity sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w== +"@next/swc-win32-arm64-msvc@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz#5f0b8cf955644104621e6d7cc923cad3a4c5365a" + integrity sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ== + "@next/swc-win32-ia32-msvc@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.4.tgz#cb50c08f0e40ead63642a7f269f0c8254261f17c" integrity sha512-rt/vv/vg/ZGGkrkKcuJ0LyliRdbskQU+91bje+PgoYmxTZf/tYs6IfbmgudBJk6gH3QnjHWbkphDdRQrseRefQ== +"@next/swc-win32-ia32-msvc@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.6.tgz#6a2409b84a2cbf34bf92fe714896455efb4191e4" + integrity sha512-XqqpHgEIlBHvzwG8sp/JXMFkLAfGLqkbVsyN+/Ih1mR8INb6YCc2x/Mbwi6hsAgUnqQztz8cvEbHJUbSl7RHDg== + "@next/swc-win32-ia32-msvc@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz#e76cabefa9f2d891599c3d85928475bd8d3f6600" integrity sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg== +"@next/swc-win32-ia32-msvc@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz#21f4de1293ac5e5a168a412b139db5d3420a89d0" + integrity sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw== + "@next/swc-win32-x64-msvc@12.3.4": version "12.3.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.4.tgz#d28ea15a72cdcf96201c60a43e9630cd7fda168f" integrity sha512-DQ20JEfTBZAgF8QCjYfJhv2/279M6onxFjdG/+5B0Cyj00/EdBxiWb2eGGFgQhrBbNv/lsvzFbbi0Ptf8Vw/bg== +"@next/swc-win32-x64-msvc@13.5.6": + version "13.5.6" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.6.tgz#4a3e2a206251abc729339ba85f60bc0433c2865d" + integrity sha512-Cqfe1YmOS7k+5mGu92nl5ULkzpKuxJrP3+4AEuPmrpFZ3BHxTY3TnHmU1On3bFmFFs6FbTcdF58CCUProGpIGQ== + "@next/swc-win32-x64-msvc@14.0.4": version "14.0.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz#e74892f1a9ccf41d3bf5979ad6d3d77c07b9cba1" integrity sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A== +"@next/swc-win32-x64-msvc@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz#e561fb330466d41807123d932b365cf3d33ceba2" + integrity sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg== + "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" @@ -4060,6 +4160,11 @@ caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.300015 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz#b4e5c1fa786f733ab78fc70f592df6b3f23244ca" integrity sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw== +caniuse-lite@^1.0.30001579: + version "1.0.30001580" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz#e3c76bc6fe020d9007647044278954ff8cd17d1e" + integrity sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA== + capture-stack-trace@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz#1c43f6b059d4249e7f3f8724f15f048b927d3a8a" @@ -5154,7 +5259,7 @@ drupal-jsonapi-params@^1.2.2: dependencies: qs "^6.10.0" -drupal-jsonapi-params@^2.0.0, drupal-jsonapi-params@^2.3.1: +drupal-jsonapi-params@^2.0.0, drupal-jsonapi-params@^2.1.0, drupal-jsonapi-params@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/drupal-jsonapi-params/-/drupal-jsonapi-params-2.3.1.tgz#7e91f9d7aa6b2b0793cf6b51fe19a5ffb9591278" integrity sha512-Isx6dudrFhORCl87OWHHO2LpQIAha5d6n7+/fwngsgcQs4PYeZcmTAA3pKUmvfyyFgCJ0N4fLAJQHyf4jtgiDA== @@ -8352,7 +8457,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -jsona@^1.12.1: +jsona@^1.12.1, jsona@^1.9.7: version "1.12.1" resolved "https://registry.yarnpkg.com/jsona/-/jsona-1.12.1.tgz#213f8c55a3460d94179824ac83d1dfdbfa265238" integrity sha512-44WL4ZdsKx//mCDPUFQtbK7mnVdHXcVzbBy7Pzy0LAgXyfpN5+q8Hum7cLUX4wTnRsClHb4eId1hePZYchwczg== @@ -9479,6 +9584,28 @@ next-auth@^4.22.1: preact-render-to-string "^5.1.19" uuid "^8.3.2" +next-drupal-query@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/next-drupal-query/-/next-drupal-query-0.4.0.tgz#26def174b3449fd5365670c83f23f942cab8d845" + integrity sha512-05kDHr/I0OiwaXLQxhBHEZ1q6xIWYNSnli2TsiAgEtfmDo4K2mqGEnjPDUXzkXvtH/XfJ7y5hG83qydLKghiAA== + dependencies: + deepmerge "^4.2.2" + drupal-jsonapi-params "^2.1.0" + next "^12.2.3 || ^13" + type-fest "^2.17.0" + +next-drupal@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/next-drupal/-/next-drupal-1.6.0.tgz#4bc14f73a5dc55763e461da696fc938da2bb6b67" + integrity sha512-IRHgcpidXj45jicVl2wEp2WhyaV384rfubxxWopgbmo4YKYvIrg0GtPj3EQNuuX5/EJxyZcULHmmhSXFSidlpg== + dependencies: + jsona "^1.9.7" + next "^12.2.0 || ^13" + node-cache "^5.1.2" + qs "^6.10.3" + react "^17.0.2 || ^18" + react-dom "^17.0.2 || ^18" + next-i18next@^13.1.5: version "13.3.0" resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-13.3.0.tgz#81575b0e17a94efa97319c1e697af893a4cea174" @@ -9529,29 +9656,28 @@ next-seo@^4.23.0: resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.29.0.tgz#d281e95ba47914117cc99e9e468599f0547d9b9b" integrity sha512-xmwzcz4uHaYJ8glbuhs6FSBQ7z3irmdPYdJJ5saWm72Uy3o+mPKGaPCXQetTCE6/xxVnpoDV4yFtFlEjUcljSg== -"next@^12.2.0 || ^13 || ^14", "next@^12.2.3 || ^13 || ^14", next@^14: - version "14.0.4" - resolved "https://registry.yarnpkg.com/next/-/next-14.0.4.tgz#bf00b6f835b20d10a5057838fa2dfced1d0d84dc" - integrity sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA== +"next@^12.2.0 || ^13", "next@^12.2.3 || ^13": + version "13.5.6" + resolved "https://registry.yarnpkg.com/next/-/next-13.5.6.tgz#e964b5853272236c37ce0dd2c68302973cf010b1" + integrity sha512-Y2wTcTbO4WwEsVb4A8VSnOsG1I9ok+h74q0ZdxkwM3EODqrs4pasq7O0iUxbcS9VtWMicG7f3+HAj0r1+NtKSw== dependencies: - "@next/env" "14.0.4" + "@next/env" "13.5.6" "@swc/helpers" "0.5.2" busboy "1.6.0" caniuse-lite "^1.0.30001406" - graceful-fs "^4.2.11" postcss "8.4.31" styled-jsx "5.1.1" watchpack "2.4.0" optionalDependencies: - "@next/swc-darwin-arm64" "14.0.4" - "@next/swc-darwin-x64" "14.0.4" - "@next/swc-linux-arm64-gnu" "14.0.4" - "@next/swc-linux-arm64-musl" "14.0.4" - "@next/swc-linux-x64-gnu" "14.0.4" - "@next/swc-linux-x64-musl" "14.0.4" - "@next/swc-win32-arm64-msvc" "14.0.4" - "@next/swc-win32-ia32-msvc" "14.0.4" - "@next/swc-win32-x64-msvc" "14.0.4" + "@next/swc-darwin-arm64" "13.5.6" + "@next/swc-darwin-x64" "13.5.6" + "@next/swc-linux-arm64-gnu" "13.5.6" + "@next/swc-linux-arm64-musl" "13.5.6" + "@next/swc-linux-x64-gnu" "13.5.6" + "@next/swc-linux-x64-musl" "13.5.6" + "@next/swc-win32-arm64-msvc" "13.5.6" + "@next/swc-win32-ia32-msvc" "13.5.6" + "@next/swc-win32-x64-msvc" "13.5.6" next@^12.2.3: version "12.3.4" @@ -9579,6 +9705,53 @@ next@^12.2.3: "@next/swc-win32-ia32-msvc" "12.3.4" "@next/swc-win32-x64-msvc" "12.3.4" +"next@^12.2.3 || ^13 || ^14", next@^14: + version "14.0.4" + resolved "https://registry.yarnpkg.com/next/-/next-14.0.4.tgz#bf00b6f835b20d10a5057838fa2dfced1d0d84dc" + integrity sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA== + dependencies: + "@next/env" "14.0.4" + "@swc/helpers" "0.5.2" + busboy "1.6.0" + caniuse-lite "^1.0.30001406" + graceful-fs "^4.2.11" + postcss "8.4.31" + styled-jsx "5.1.1" + watchpack "2.4.0" + optionalDependencies: + "@next/swc-darwin-arm64" "14.0.4" + "@next/swc-darwin-x64" "14.0.4" + "@next/swc-linux-arm64-gnu" "14.0.4" + "@next/swc-linux-arm64-musl" "14.0.4" + "@next/swc-linux-x64-gnu" "14.0.4" + "@next/swc-linux-x64-musl" "14.0.4" + "@next/swc-win32-arm64-msvc" "14.0.4" + "@next/swc-win32-ia32-msvc" "14.0.4" + "@next/swc-win32-x64-msvc" "14.0.4" + +"next@^13.4 || ^14": + version "14.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-14.1.0.tgz#b31c0261ff9caa6b4a17c5af019ed77387174b69" + integrity sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q== + dependencies: + "@next/env" "14.1.0" + "@swc/helpers" "0.5.2" + busboy "1.6.0" + caniuse-lite "^1.0.30001579" + graceful-fs "^4.2.11" + postcss "8.4.31" + styled-jsx "5.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "14.1.0" + "@next/swc-darwin-x64" "14.1.0" + "@next/swc-linux-arm64-gnu" "14.1.0" + "@next/swc-linux-arm64-musl" "14.1.0" + "@next/swc-linux-x64-gnu" "14.1.0" + "@next/swc-linux-x64-musl" "14.1.0" + "@next/swc-win32-arm64-msvc" "14.1.0" + "@next/swc-win32-ia32-msvc" "14.1.0" + "@next/swc-win32-x64-msvc" "14.1.0" + node-abi@^3.3.0: version "3.52.0" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.52.0.tgz#ffba0a85f54e552547e5849015f40f9514d5ba7c" @@ -12743,6 +12916,11 @@ type-fest@^0.8.0, type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^2.17.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-fest@^3.0.0: version "3.13.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" From 601cccb1f1841cbd1aebb8cca2e62b257a308dbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 22:08:14 +0000 Subject: [PATCH 09/14] build(deps-dev): bump @commitlint/cli from 17.8.1 to 18.6.0 Bumps [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) from 17.8.1 to 18.6.0. - [Release notes](https://github.com/conventional-changelog/commitlint/releases) - [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md) - [Commits](https://github.com/conventional-changelog/commitlint/commits/v18.6.0/@commitlint/cli) --- updated-dependencies: - dependency-name: "@commitlint/cli" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 264 +++++++++++++++++++++++++++------------------------ 2 files changed, 142 insertions(+), 124 deletions(-) diff --git a/package.json b/package.json index 2d00f8a7..5635bc68 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@babel/plugin-transform-runtime": "^7.23.2", "@babel/preset-env": "^7.23.2", "@babel/preset-react": "^7.22.15", - "@commitlint/cli": "^17.8.0", + "@commitlint/cli": "^18.6.0", "@commitlint/config-conventional": "^17.8.0", "@next/eslint-plugin-next": "^12.3.4", "@testing-library/cypress": "^8.0.7", diff --git a/yarn.lock b/yarn.lock index 80d79bc2..a311e26c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1261,16 +1261,16 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@commitlint/cli@^17.8.0": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-17.8.1.tgz#10492114a022c91dcfb1d84dac773abb3db76d33" - integrity sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg== - dependencies: - "@commitlint/format" "^17.8.1" - "@commitlint/lint" "^17.8.1" - "@commitlint/load" "^17.8.1" - "@commitlint/read" "^17.8.1" - "@commitlint/types" "^17.8.1" +"@commitlint/cli@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-18.6.0.tgz#f065e0514f3870b6dc9a3c608a78820806b46527" + integrity sha512-FiH23cr9QG8VdfbmvJJZmdfHGVMCouOOAzoXZ3Cd7czGC52RbycwNt8YCI7SA69pAl+t30vh8LMaO/N+kcel6w== + dependencies: + "@commitlint/format" "^18.6.0" + "@commitlint/lint" "^18.6.0" + "@commitlint/load" "^18.6.0" + "@commitlint/read" "^18.6.0" + "@commitlint/types" "^18.6.0" execa "^5.0.0" lodash.isfunction "^3.0.9" resolve-from "5.0.0" @@ -1284,141 +1284,137 @@ dependencies: conventional-changelog-conventionalcommits "^6.1.0" -"@commitlint/config-validator@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.8.1.tgz#5cc93b6b49d5524c9cc345a60e5bf74bcca2b7f9" - integrity sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA== +"@commitlint/config-validator@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-18.6.0.tgz#ea1e04e92829dd7b90cea444f245b0bdefa0a586" + integrity sha512-Ptfa865arNozlkjxrYG3qt6wT9AlhNUHeuDyKEZiTL/l0ftncFhK/KN0t/EAMV2tec+0Mwxo0FmhbESj/bI+1g== dependencies: - "@commitlint/types" "^17.8.1" + "@commitlint/types" "^18.6.0" ajv "^8.11.0" -"@commitlint/ensure@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-17.8.1.tgz#59183557844999dbb6aab6d03629a3d104d01a8d" - integrity sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow== +"@commitlint/ensure@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-18.6.0.tgz#3f3dc09d99016eaab0da9423123effd820d11931" + integrity sha512-xY07NmOBJ7JuhX3tic021PaeLepZARIQyqpAQoNQZoml1keBFfB6MbA7XlWZv0ebbarUFE4yhKxOPw+WFv7/qw== dependencies: - "@commitlint/types" "^17.8.1" + "@commitlint/types" "^18.6.0" lodash.camelcase "^4.3.0" lodash.kebabcase "^4.1.1" lodash.snakecase "^4.1.1" lodash.startcase "^4.4.0" lodash.upperfirst "^4.3.1" -"@commitlint/execute-rule@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz#504ed69eb61044eeb84fdfd10cc18f0dab14f34c" - integrity sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ== +"@commitlint/execute-rule@^18.4.4": + version "18.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-18.4.4.tgz#ade986742c1944c8162a54288747e54a8c6146b5" + integrity sha512-a37Nd3bDQydtg9PCLLWM9ZC+GO7X5i4zJvrggJv5jBhaHsXeQ9ZWdO6ODYR+f0LxBXXNYK3geYXJrCWUCP8JEg== -"@commitlint/format@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-17.8.1.tgz#6108bb6b4408e711006680649927e1b559bdc5f8" - integrity sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg== +"@commitlint/format@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-18.6.0.tgz#e13ef8419cd8eb37be5825a2e84e73cabbfb56ad" + integrity sha512-8UNWfs2slPPSQiiVpLGJTnPHv7Jkd5KYxfbNXbmLL583bjom4RrylvyrCVnmZReA8nNad7pPXq6mDH4FNVj6xg== dependencies: - "@commitlint/types" "^17.8.1" + "@commitlint/types" "^18.6.0" chalk "^4.1.0" -"@commitlint/is-ignored@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz#cf25bcd8409c79684b63f8bdeb35df48edda244e" - integrity sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g== +"@commitlint/is-ignored@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-18.6.0.tgz#d15ab04f547f7554cc3377d50f8e19178502b8af" + integrity sha512-Xjx/ZyyJ4FdLuz0FcOvqiqSFgiO2yYj3QN9XlvyrxqbXTxPVC7QFEXJYBVPulUSN/gR7WXH1Udw+HYYfD17xog== dependencies: - "@commitlint/types" "^17.8.1" + "@commitlint/types" "^18.6.0" semver "7.5.4" -"@commitlint/lint@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-17.8.1.tgz#bfc21215f6b18d41d4d43e2aa3cb79a5d7726cd8" - integrity sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA== - dependencies: - "@commitlint/is-ignored" "^17.8.1" - "@commitlint/parse" "^17.8.1" - "@commitlint/rules" "^17.8.1" - "@commitlint/types" "^17.8.1" - -"@commitlint/load@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.8.1.tgz#fa061e7bfa53281eb03ca8517ca26d66a189030c" - integrity sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA== - dependencies: - "@commitlint/config-validator" "^17.8.1" - "@commitlint/execute-rule" "^17.8.1" - "@commitlint/resolve-extends" "^17.8.1" - "@commitlint/types" "^17.8.1" - "@types/node" "20.5.1" +"@commitlint/lint@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-18.6.0.tgz#f54c856840a6238e0c2972588c2dc986317f1b7b" + integrity sha512-ycbuDWfyykPmslgiHzhz8dL6F0BJYltXLVfc+M49z0c+FNITM0v+r0Vd2+Tdtq06VTc894p2+YSmZhulY8Jn3Q== + dependencies: + "@commitlint/is-ignored" "^18.6.0" + "@commitlint/parse" "^18.6.0" + "@commitlint/rules" "^18.6.0" + "@commitlint/types" "^18.6.0" + +"@commitlint/load@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-18.6.0.tgz#98108294b9383aa2905781b192215df4718babb7" + integrity sha512-RRssj7TmzT0bowoEKlgwg8uQ7ORXWkw7lYLsZZBMi9aInsJuGNLNWcMxJxRZbwxG3jkCidGUg85WmqJvRjsaDA== + dependencies: + "@commitlint/config-validator" "^18.6.0" + "@commitlint/execute-rule" "^18.4.4" + "@commitlint/resolve-extends" "^18.6.0" + "@commitlint/types" "^18.6.0" chalk "^4.1.0" - cosmiconfig "^8.0.0" - cosmiconfig-typescript-loader "^4.0.0" + cosmiconfig "^8.3.6" + cosmiconfig-typescript-loader "^5.0.0" lodash.isplainobject "^4.0.6" lodash.merge "^4.6.2" lodash.uniq "^4.5.0" resolve-from "^5.0.0" - ts-node "^10.8.1" - typescript "^4.6.4 || ^5.2.2" -"@commitlint/message@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-17.8.1.tgz#a5cd226c419be20ee03c3d237db6ac37b95958b3" - integrity sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA== +"@commitlint/message@^18.4.4": + version "18.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-18.4.4.tgz#811682a0d147a24e5c467acdb52071434df2b9f5" + integrity sha512-lHF95mMDYgAI1LBXveJUyg4eLaMXyOqJccCK3v55ZOEUsMPrDi8upqDjd/NmzWmESYihaOMBTAnxm+6oD1WoDQ== -"@commitlint/parse@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-17.8.1.tgz#6e00b8f50ebd63562d25dcf4230da2c9f984e626" - integrity sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw== +"@commitlint/parse@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-18.6.0.tgz#ae19ff8ceb0c8ffab131158829b06b505b9921fd" + integrity sha512-Y/G++GJpATFw54O0jikc/h2ibyGHgghtPnwsOk3O/aU092ydJ5XEHYcd7xGNQYuLweLzQis2uEwRNk9AVIPbQQ== dependencies: - "@commitlint/types" "^17.8.1" - conventional-changelog-angular "^6.0.0" - conventional-commits-parser "^4.0.0" + "@commitlint/types" "^18.6.0" + conventional-changelog-angular "^7.0.0" + conventional-commits-parser "^5.0.0" -"@commitlint/read@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-17.8.1.tgz#b3f28777607c756078356cc133368b0e8c08092f" - integrity sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w== +"@commitlint/read@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-18.6.0.tgz#324ea1fa625f88427780df23fffe4a92d383d665" + integrity sha512-w39ji8VfWhPKRquPhRHB3Yd8XIHwaNHgOh28YI1QEmZ59qVpuVUQo6h/NsVb+uoC6LbXZiofTZv2iFR084jKEA== dependencies: - "@commitlint/top-level" "^17.8.1" - "@commitlint/types" "^17.8.1" - fs-extra "^11.0.0" + "@commitlint/top-level" "^18.4.4" + "@commitlint/types" "^18.6.0" git-raw-commits "^2.0.11" minimist "^1.2.6" -"@commitlint/resolve-extends@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz#9af01432bf2fd9ce3dd5a00d266cce14e4c977e7" - integrity sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q== +"@commitlint/resolve-extends@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-18.6.0.tgz#db55be2b32e12593bc98dc44c6d9a9d90941bab4" + integrity sha512-k2Xp+Fxeggki2i90vGrbiLDMefPius3zGSTFFlRAPKce/SWLbZtI+uqE9Mne23mHO5lmcSV8z5m6ziiJwGpOcg== dependencies: - "@commitlint/config-validator" "^17.8.1" - "@commitlint/types" "^17.8.1" + "@commitlint/config-validator" "^18.6.0" + "@commitlint/types" "^18.6.0" import-fresh "^3.0.0" lodash.mergewith "^4.6.2" resolve-from "^5.0.0" resolve-global "^1.0.0" -"@commitlint/rules@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-17.8.1.tgz#da49cab1b7ebaf90d108de9f58f684dc4ccb65a0" - integrity sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA== +"@commitlint/rules@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-18.6.0.tgz#6d933e2de5639b75b4946120b3880e72e66a6051" + integrity sha512-pTalvCEvuCWrBWZA/YqO/3B3nZnY3Ncc+TmQsRajBdC1tkQIm5Iovdo4Ec7f2Dw1tVvpYMUUNAgcWqsY0WckWg== dependencies: - "@commitlint/ensure" "^17.8.1" - "@commitlint/message" "^17.8.1" - "@commitlint/to-lines" "^17.8.1" - "@commitlint/types" "^17.8.1" + "@commitlint/ensure" "^18.6.0" + "@commitlint/message" "^18.4.4" + "@commitlint/to-lines" "^18.4.4" + "@commitlint/types" "^18.6.0" execa "^5.0.0" -"@commitlint/to-lines@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-17.8.1.tgz#a5c4a7cf7dff3dbdd69289fc0eb19b66f3cfe017" - integrity sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA== +"@commitlint/to-lines@^18.4.4": + version "18.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-18.4.4.tgz#546cf8d985459f3526359b6a63d7a5b421e1ed60" + integrity sha512-mwe2Roa59NCz/krniAdCygFabg7+fQCkIhXqBHw00XQ8Y7lw4poZLLxeGI3p3bLpcEOXdqIDrEGLwHmG5lBdwQ== -"@commitlint/top-level@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-17.8.1.tgz#206d37d6782f33c9572e44fbe3758392fdeea7bc" - integrity sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA== +"@commitlint/top-level@^18.4.4": + version "18.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-18.4.4.tgz#df69ffa49fdc4541d1f05e814352d575fb0f3b0d" + integrity sha512-PBwW1drgeavl9CadB7IPRUk6rkUP/O8jEkxjlC+ofuh3pw0bzJdAT+Kw7M1Yc9KtTb9xTaqUB8uvRtaybHa/tQ== dependencies: find-up "^5.0.0" -"@commitlint/types@^17.8.1": - version "17.8.1" - resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-17.8.1.tgz#883a0ad35c5206d5fef7bc6ce1bbe648118af44e" - integrity sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ== +"@commitlint/types@^18.6.0": + version "18.6.0" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-18.6.0.tgz#3d3493cb5910f60f3749a8eb56aca47dc2e1b662" + integrity sha512-oavoKLML/eJa2rJeyYSbyGAYzTxQ6voG5oeX3OrxpfrkRWhJfm4ACnhoRf5tgiybx2MZ+EVFqC1Lw3W8/uwpZA== dependencies: chalk "^4.1.0" @@ -3005,11 +3001,6 @@ dependencies: undici-types "~5.26.4" -"@types/node@20.5.1": - version "20.5.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" - integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg== - "@types/node@^14.14.31": version "14.18.63" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b" @@ -4623,20 +4614,13 @@ console-control-strings@^1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -conventional-changelog-angular@7.0.0: +conventional-changelog-angular@7.0.0, conventional-changelog-angular@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== dependencies: compare-func "^2.0.0" -conventional-changelog-angular@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz#a9a9494c28b7165889144fd5b91573c4aa9ca541" - integrity sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg== - dependencies: - compare-func "^2.0.0" - conventional-changelog-conventionalcommits@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz#3bad05f4eea64e423d3d90fc50c17d2c8cf17652" @@ -4697,6 +4681,16 @@ conventional-commits-parser@^4.0.0: meow "^8.1.2" split2 "^3.2.2" +conventional-commits-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz#57f3594b81ad54d40c1b4280f04554df28627d9a" + integrity sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA== + dependencies: + JSONStream "^1.3.5" + is-text-path "^2.0.0" + meow "^12.0.1" + split2 "^4.0.0" + conventional-recommended-bump@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424" @@ -4754,12 +4748,14 @@ core-util-is@^1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig-typescript-loader@^4.0.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz#f3feae459ea090f131df5474ce4b1222912319f9" - integrity sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw== +cosmiconfig-typescript-loader@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz#0d3becfe022a871f7275ceb2397d692e06045dc8" + integrity sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA== + dependencies: + jiti "^1.19.1" -cosmiconfig@^8.0.0, cosmiconfig@^8.2.0: +cosmiconfig@^8.2.0, cosmiconfig@^8.3.6: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== @@ -6250,7 +6246,7 @@ fs-exists-sync@^0.1.0: resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" integrity sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg== -fs-extra@^11.0.0, fs-extra@^11.1.0, fs-extra@^11.1.1: +fs-extra@^11.1.0, fs-extra@^11.1.1: version "11.2.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== @@ -7707,6 +7703,13 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" +is-text-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-2.0.0.tgz#b2484e2b720a633feb2e85b67dc193ff72c75636" + integrity sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw== + dependencies: + text-extensions "^2.0.0" + is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" @@ -9205,6 +9208,11 @@ memoize-one@^4.0.0: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.1.0.tgz#a2387c58c03fff27ca390c31b764a79addf3f906" integrity sha512-2GApq0yI/b22J2j9rhbrAlsHb0Qcz+7yWxeLG8h+95sl1XPUgeLimQSOdur4Vw7cUhrBHwaUZxWFZueojqNRzA== +meow@^12.0.1: + version "12.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" + integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== + meow@^8.0.0, meow@^8.1.2: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -12017,6 +12025,11 @@ split2@^3.0.0, split2@^3.2.2: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + split@0.3: version "0.3.3" resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" @@ -12539,6 +12552,11 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== +text-extensions@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-2.4.0.tgz#a1cfcc50cf34da41bfd047cc744f804d1680ea34" + integrity sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -12722,7 +12740,7 @@ ts-jest@^27.1.5: semver "7.x" yargs-parser "20.x" -ts-node@^10.8.1, ts-node@^10.9.1: +ts-node@^10.9.1: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -12982,7 +13000,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -"typescript@>=3 < 6", "typescript@^4.6.4 || ^5.2.2", typescript@^5.2.2, typescript@^5.3.2: +"typescript@>=3 < 6", typescript@^5.2.2, typescript@^5.3.2: version "5.3.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== From f73c064bb9b29e02d630ce19c3506084004fe933 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:14:09 +0000 Subject: [PATCH 10/14] build(deps-dev): bump prettier from 3.1.1 to 3.2.4 Bumps [prettier](https://github.com/prettier/prettier) from 3.1.1 to 3.2.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.1.1...3.2.4) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index a311e26c..cd6eca1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10793,9 +10793,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^3.0.3, prettier@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" - integrity sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw== + version "3.2.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.4.tgz#4723cadeac2ce7c9227de758e5ff9b14e075f283" + integrity sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ== pretty-bytes@^5.6.0: version "5.6.0" From dde673d1952da918e2fb5a2e05a49ddb2408356b Mon Sep 17 00:00:00 2001 From: Bojan Bogdanovic Date: Wed, 14 Feb 2024 17:36:10 +0100 Subject: [PATCH 11/14] feat(next): remove scope from preview URL generation and validation process Fixes #635 Co-authored-by: Bojan Bogdanovic --- .../Next/PreviewUrlGenerator/SimpleOauth.php | 75 ++++--------------- .../NextPreviewUrlControllerTest.php | 5 +- .../SimpleOauthPreviewUrlGeneratorTest.php | 72 ++++-------------- packages/next-drupal/tests/client.test.ts | 2 + 4 files changed, 33 insertions(+), 121 deletions(-) diff --git a/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php b/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php index bb15e7bc..27144c53 100644 --- a/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php +++ b/modules/next/src/Plugin/Next/PreviewUrlGenerator/SimpleOauth.php @@ -66,7 +66,16 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static($configuration, $plugin_id, $plugin_definition, $container->get('current_user'), $container->get('datetime.time'), $container->get('next.preview_secret_generator'), $container->get('entity_type.manager'), $container->get('module_handler')); + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('current_user'), + $container->get('datetime.time'), + $container->get('next.preview_secret_generator'), + $container->get('entity_type.manager'), + $container->get('module_handler') + ); } /** @@ -119,18 +128,9 @@ public function generate(NextSiteInterface $next_site, EntityInterface $entity, $query = []; $query['slug'] = $slug = $entity->toUrl()->toString(); - // Send the current user roles as scope. - $scopes = $this->getScopesForCurrentUser(); - - if (!count($scopes)) { - return NULL; - } - - $query['scope'] = $scope = implode(' ', $scopes); - // Create a secret based on the timestamp, slug, scope and resource version. $query['timestamp'] = $timestamp = $this->time->getRequestTime(); - $query['secret'] = $this->previewSecretGenerator->generate($timestamp . $slug . $scope . $resource_version); + $query['secret'] = $this->previewSecretGenerator->generate($timestamp . $slug . $resource_version); return Url::fromUri($next_site->getPreviewUrl(), [ 'query' => $query, @@ -159,66 +159,19 @@ public function validate(Request $request) { throw new InvalidPreviewUrlRequest("The provided secret has expired."); } - if (empty($body['scope'])) { - throw new InvalidPreviewUrlRequest("Field 'scope' is missing"); - } - // Validate the secret. if (empty($body['secret'])) { throw new InvalidPreviewUrlRequest("Field 'secret' is missing"); } - if ($body['secret'] !== $this->previewSecretGenerator->generate($body['timestamp'] . $body['slug'] . $body['scope'] . $body['resourceVersion'])) { + if ($body['secret'] !== $this->previewSecretGenerator->generate($body['timestamp'] . $body['slug'] . $body['resourceVersion'])) { throw new InvalidPreviewUrlRequest("The provided secret is invalid."); } return [ - 'scope' => $body['scope'], + 'path' => $body['slug'], + 'maxAge' => (int) $this->configuration['secret_expiration'], ]; } - /** - * Returns scope for the current user. - * - * @return array|mixed - * An array of roles as scopes. - * - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException - */ - protected function getScopesForCurrentUser(): array { - $roles = $this->currentUser->getRoles(TRUE); - $admin_role = $this->getAdminRole(); - - // Return the admin role for administrators. - if ((int) $this->currentUser->id() === 1 || in_array($admin_role, $roles)) { - return [$admin_role]; - } - - return $roles; - } - - /** - * Returns an array of admin roles. - * - * @return string|null - * The admin role. - * - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException - */ - protected function getAdminRole(): ?string { - $admin_roles = $this->entityTypeManager->getStorage('user_role') - ->getQuery() - ->accessCheck(FALSE) - ->condition('is_admin', TRUE) - ->execute(); - - if (!$admin_roles) { - return NULL; - } - - return reset($admin_roles); - } - } diff --git a/modules/next/tests/src/Kernel/Controller/NextPreviewUrlControllerTest.php b/modules/next/tests/src/Kernel/Controller/NextPreviewUrlControllerTest.php index da752d85..46d71ad3 100644 --- a/modules/next/tests/src/Kernel/Controller/NextPreviewUrlControllerTest.php +++ b/modules/next/tests/src/Kernel/Controller/NextPreviewUrlControllerTest.php @@ -71,7 +71,10 @@ public function testValidate() { $controller = NextPreviewUrlController::create($this->container); $response = $controller->validate($request); - $this->assertSame(['scope' => $user->getRoles(TRUE)[0]], Json::decode($response->getContent())); + $this->assertSame([ + 'path' => $page->toUrl()->toString(), + 'maxAge' => $this->config('next.settings')->get('preview_url_generator_configuration.secret_expiration'), + ], Json::decode($response->getContent())); } } diff --git a/modules/next/tests/src/Kernel/Plugin/SimpleOauthPreviewUrlGeneratorTest.php b/modules/next/tests/src/Kernel/Plugin/SimpleOauthPreviewUrlGeneratorTest.php index d5867f83..3ae17ad7 100644 --- a/modules/next/tests/src/Kernel/Plugin/SimpleOauthPreviewUrlGeneratorTest.php +++ b/modules/next/tests/src/Kernel/Plugin/SimpleOauthPreviewUrlGeneratorTest.php @@ -34,6 +34,13 @@ class SimpleOauthPreviewUrlGeneratorTest extends KernelTestBase { */ protected $nextSite; + /** + * The next settings manager. + * + * @var \Drupal\next\NextSettingsManagerInterface + */ + protected $nextSettingsManager; + /** * {@inheritdoc} */ @@ -46,6 +53,8 @@ protected function setUp(): void { $this->installSchema('system', ['sequences']); $this->installSchema('node', ['node_access']); + $this->nextSettingsManager = $this->container->get('next.settings.manager'); + // Create NextSite entities. $this->nextSite = NextSite::create([ 'label' => 'Blog', @@ -91,44 +100,11 @@ public function testGenerate() { $this->assertNotEmpty($query['timestamp']); $this->assertNotEmpty($query['secret']); $this->assertSame($query['plugin'], 'simple_oauth'); - $this->assertContains($query['scope'], $user->getRoles()); // Test the secret. /** @var \Drupal\next\PreviewSecretGeneratorInterface $secret_generator */ $secret_generator = \Drupal::service('next.preview_secret_generator'); - $this->assertSame($query['secret'], $secret_generator->generate($query['timestamp'] . $query['slug'] . $query['scope'] . $query['resourceVersion'])); - } - - /** - * @covers ::getScopesForCurrentUser - * @covers ::getAdminRole - */ - public function testCurrentUserScopes() { - /** @var \Drupal\next\NextSettingsManagerInterface $next_settings_manager */ - $next_settings_manager = $this->container->get('next.settings.manager'); - /** @var \Drupal\next\Plugin\Next\PreviewUrlGenerator\SimpleOauth $preview_url_generator */ - $preview_url_generator = $next_settings_manager->getPreviewUrlGenerator(); - - $page = $this->createNode(['type' => 'page']); - - // Log in as anonymous user. - $this->setCurrentUser(User::load(0)); - $url = $preview_url_generator->generate($this->nextSite, $page); - $this->assertNull($url); - - // Log in as user 1. - $admin_role = $this->createAdminRole(); - $this->setCurrentUser(User::load(1)); - $url = $preview_url_generator->generate($this->nextSite, $page); - $query = $url->getOption('query'); - $this->assertSame($query['scope'], $admin_role); - - // Log in as admin user. - $admin_user = $this->createUser([], NULL, TRUE); - $this->setCurrentUser($admin_user); - $url = $preview_url_generator->generate($this->nextSite, $page); - $query = $url->getOption('query'); - $this->assertSame($query['scope'], $admin_user->getRoles(TRUE)[0]); + $this->assertSame($query['secret'], $secret_generator->generate($query['timestamp'] . $query['slug'] . $query['resourceVersion'])); } /** @@ -137,10 +113,7 @@ public function testCurrentUserScopes() { */ public function testValidateForInvalidBody($body, $message, $is_valid = FALSE) { $request = Request::create('/', 'POST', [], [], [], [], Json::encode($body)); - - /** @var \Drupal\next\NextSettingsManagerInterface $next_settings_manager */ - $next_settings_manager = $this->container->get('next.settings.manager'); - $preview_url_generator = $next_settings_manager->getPreviewUrlGenerator(); + $preview_url_generator = $this->nextSettingsManager->getPreviewUrlGenerator(); if (!$is_valid) { $this->expectExceptionMessage($message); @@ -159,15 +132,9 @@ public function testValidateSecret() { $query = $preview_url->getOption('query'); $request = Request::create('/', 'POST', [], [], [], [], Json::encode($query)); + $preview_url_generator = $this->nextSettingsManager->getPreviewUrlGenerator(); - /** @var \Drupal\next\NextSettingsManagerInterface $next_settings_manager */ - $next_settings_manager = $this->container->get('next.settings.manager'); - $preview_url_generator = $next_settings_manager->getPreviewUrlGenerator(); - - $response = $preview_url_generator->validate($request); - $role = $user->getRoles(TRUE)[0]; - $this->assertSame(['scope' => $role], $response); - + $preview_url_generator->validate($request); $this->expectExceptionMessage('The provided secret is invalid.'); $query = $preview_url->getOption('query'); $query['timestamp'] = strtotime('+60seconds'); @@ -185,12 +152,6 @@ public function testValidateSecret() { $query['resourceVersion'] = 'rel:23'; $request = Request::create('/', 'POST', [], [], [], [], Json::encode($query)); $preview_url_generator->validate($request); - - $this->expectExceptionMessage('The provided secret is invalid.'); - $query = $preview_url->getOption('query'); - $query['scope'] = 'editor'; - $request = Request::create('/', 'POST', [], [], [], [], Json::encode($query)); - $preview_url_generator->validate($request); } /** @@ -203,15 +164,10 @@ public function providerValidateForInvalidBody() { return [ [[], "Field 'slug' is missing"], [['slug' => '/node/1'], "Field 'timestamp' is missing"], - [ - ['slug' => '/node/1', 'timestamp' => strtotime('now')], - "Field 'scope' is missing", - ], [ [ 'slug' => '/node/1', 'timestamp' => strtotime('now'), - 'scope' => 'llama', ], "Field 'secret' is missing", ], @@ -219,7 +175,6 @@ public function providerValidateForInvalidBody() { [ 'slug' => '/node/1', 'timestamp' => strtotime('-60 seconds'), - 'scope' => 'llama', 'secret' => 'secret', ], "The provided secret has expired.", @@ -228,7 +183,6 @@ public function providerValidateForInvalidBody() { [ 'slug' => '/node/1', 'timestamp' => strtotime('60 seconds'), - 'scope' => 'llama', 'secret' => 'secret', ], "", diff --git a/packages/next-drupal/tests/client.test.ts b/packages/next-drupal/tests/client.test.ts index 7e061fae..9df7849a 100644 --- a/packages/next-drupal/tests/client.test.ts +++ b/packages/next-drupal/tests/client.test.ts @@ -10,6 +10,8 @@ import type { } from "../src/types" import { BASE_URL } from "./utils" +jest.setTimeout(10000) + afterEach(() => { jest.restoreAllMocks() }) From e4fd11f29dacf2d4133a82c2c38a32304008d28d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:38:38 +0000 Subject: [PATCH 12/14] build(deps-dev): bump eslint-plugin-prettier from 5.1.0 to 5.1.3 Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.0 to 5.1.3. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.0...v5.1.3) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 133 ++++++------------------------------------------------ 1 file changed, 15 insertions(+), 118 deletions(-) diff --git a/yarn.lock b/yarn.lock index cd6eca1c..df42995b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2565,17 +2565,10 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@pkgr/utils@^2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" - integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.3.0" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.6.0" +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== "@rollup/rollup-android-arm-eabi@4.9.1": version "4.9.1" @@ -3874,11 +3867,6 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== -big-integer@^1.6.44: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -3930,13 +3918,6 @@ boxen@^4.2.0: type-fest "^0.8.1" widest-line "^3.1.0" -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -4018,13 +3999,6 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - bundle-require@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-4.0.2.tgz#65fc74ff14eabbba36d26c9a6161bd78fff6b29e" @@ -5013,24 +4987,6 @@ deepmerge@^4.2.2, deepmerge@^4.3.1: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - defaults@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" @@ -5057,11 +5013,6 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -5694,12 +5645,12 @@ eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-jsx-a11y@^6.7.1: object.fromentries "^2.0.7" eslint-plugin-prettier@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.0.tgz#f14bb2b18756ad54f1ad3dc4c989cb73dfa326a3" - integrity sha512-hQc+2zbnMeXcIkg+pKZtVa+3Yqx4WY7SMkn1PLZ4VbBEU7jJIpVn9347P8BBhTbz6ne85aXvQf30kvexcqBeWw== + version "5.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" + integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== dependencies: prettier-linter-helpers "^1.0.0" - synckit "^0.8.5" + synckit "^0.8.6" eslint-plugin-react-hooks@^4.5.0, "eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": version "4.6.0" @@ -5942,21 +5893,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -6401,7 +6337,7 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0, get-stream@^6.0.1: +get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -7078,11 +7014,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - human-signals@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" @@ -7435,11 +7366,6 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -7503,13 +7429,6 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -10229,16 +10148,6 @@ open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -open@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - openid-client@^5.4.0: version "5.6.1" resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.6.1.tgz#8f7526a50c290a5e28a7fe21b3ece3107511bc73" @@ -11574,13 +11483,6 @@ rollup@^4.0.2: "@rollup/rollup-win32-x64-msvc" "4.9.1" fsevents "~2.3.2" -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -12427,12 +12329,12 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -synckit@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.6.tgz#b69b7fbce3917c2673cbdc0d87fb324db4a5b409" - integrity sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA== +synckit@^0.8.6: + version "0.8.8" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== dependencies: - "@pkgr/utils" "^2.4.2" + "@pkgr/core" "^0.1.0" tslib "^2.6.2" tailwindcss@^3.0.15, tailwindcss@^3.0.23, tailwindcss@^3.0.24, tailwindcss@^3.3.5: @@ -12611,11 +12513,6 @@ timed-out@^4.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -12783,7 +12680,7 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.6.0, tslib@^2.6.2: +tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== From ac704e366273734d354095bdc65c3ee5da92fab8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:44:34 +0000 Subject: [PATCH 13/14] build(deps-dev): bump tailwindcss from 3.4.0 to 3.4.1 Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/master/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.0...v3.4.1) --- updated-dependencies: - dependency-name: tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index df42995b..66c52e3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12338,9 +12338,9 @@ synckit@^0.8.6: tslib "^2.6.2" tailwindcss@^3.0.15, tailwindcss@^3.0.23, tailwindcss@^3.0.24, tailwindcss@^3.3.5: - version "3.4.0" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.0.tgz#045a9c474e6885ebd0436354e611a76af1c76839" - integrity sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA== + version "3.4.1" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.1.tgz#f512ca5d1dd4c9503c7d3d28a968f1ad8f5c839d" + integrity sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA== dependencies: "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" From 9f6ae5816da2339e374b91fa7cc026b3ff0d4709 Mon Sep 17 00:00:00 2001 From: shadcn Date: Wed, 14 Feb 2024 21:13:03 +0400 Subject: [PATCH 14/14] fix(next-drupal): update TypeScript definition for translatePath and translatePathFromContext Fixes #359 --- packages/next-drupal/src/client.ts | 4 ++-- packages/next-drupal/tests/client.test.ts | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index 7e22df04..bd0cebe9 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -894,7 +894,7 @@ export class DrupalClient { async translatePath( path: string, options?: JsonApiWithAuthOptions - ): Promise { + ): Promise { options = { withAuth: this.withAuth, ...options, @@ -927,7 +927,7 @@ export class DrupalClient { options?: { pathPrefix?: PathPrefix } & JsonApiWithAuthOptions - ): Promise { + ): Promise { options = { pathPrefix: "/", ...options, diff --git a/packages/next-drupal/tests/client.test.ts b/packages/next-drupal/tests/client.test.ts index 9df7849a..aeacea93 100644 --- a/packages/next-drupal/tests/client.test.ts +++ b/packages/next-drupal/tests/client.test.ts @@ -1445,13 +1445,15 @@ describe("getResourceFromContext", () => { }, } - const recipe = await client.getResourceFromContext(path, context, { - params: { - "fields[node--recipe]": "title,path,status", - }, - }) + if (path) { + const recipe = await client.getResourceFromContext(path, context, { + params: { + "fields[node--recipe]": "title,path,status", + }, + }) - await expect(recipe).toMatchSnapshot() + await expect(recipe).toMatchSnapshot() + } }) })