modules op de juiste plek pls make it stop aaaaaaaaaaaaaaaa

This commit is contained in:
2025-07-02 20:49:12 +02:00
parent 389b6db432
commit 9263d88cee
9177 changed files with 110 additions and 1554322 deletions
+107
View File
@@ -5,6 +5,7 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"@next/font": "^14.2.15",
"next": "^15.3.3", "next": "^15.3.3",
"oidc-client-ts": "^3.3.0", "oidc-client-ts": "^3.3.0",
"react": "^19.1.0", "react": "^19.1.0",
@@ -16,6 +17,8 @@
"@types/node": "24.0.3", "@types/node": "24.0.3",
"@types/react": "19.1.8", "@types/react": "19.1.8",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "^0.6.13",
"tailwindcss": "^4.1.10", "tailwindcss": "^4.1.10",
"typescript": "5.8.3" "typescript": "5.8.3"
} }
@@ -525,6 +528,15 @@
"integrity": "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==", "integrity": "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@next/font": {
"version": "14.2.15",
"resolved": "https://registry.npmjs.org/@next/font/-/font-14.2.15.tgz",
"integrity": "sha512-QopYhBmCDDrNDynbi+ZD1hDZXmQXVFo7TmAFp4DQgO/kogz1OLbQ92hPigJbj572eZ3GaaVxNIyYVn3/eAsehg==",
"license": "MIT",
"peerDependencies": {
"next": "*"
}
},
"node_modules/@next/swc-darwin-arm64": { "node_modules/@next/swc-darwin-arm64": {
"version": "15.3.3", "version": "15.3.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.3.tgz", "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.3.tgz",
@@ -1555,6 +1567,101 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-plugin-tailwindcss": {
"version": "0.6.13",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.13.tgz",
"integrity": "sha512-uQ0asli1+ic8xrrSmIOaElDu0FacR4x69GynTh2oZjFY10JUt6EEumTQl5tB4fMeD6I1naKd+4rXQQ7esT2i1g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.21.3"
},
"peerDependencies": {
"@ianvs/prettier-plugin-sort-imports": "*",
"@prettier/plugin-pug": "*",
"@shopify/prettier-plugin-liquid": "*",
"@trivago/prettier-plugin-sort-imports": "*",
"@zackad/prettier-plugin-twig": "*",
"prettier": "^3.0",
"prettier-plugin-astro": "*",
"prettier-plugin-css-order": "*",
"prettier-plugin-import-sort": "*",
"prettier-plugin-jsdoc": "*",
"prettier-plugin-marko": "*",
"prettier-plugin-multiline-arrays": "*",
"prettier-plugin-organize-attributes": "*",
"prettier-plugin-organize-imports": "*",
"prettier-plugin-sort-imports": "*",
"prettier-plugin-style-order": "*",
"prettier-plugin-svelte": "*"
},
"peerDependenciesMeta": {
"@ianvs/prettier-plugin-sort-imports": {
"optional": true
},
"@prettier/plugin-pug": {
"optional": true
},
"@shopify/prettier-plugin-liquid": {
"optional": true
},
"@trivago/prettier-plugin-sort-imports": {
"optional": true
},
"@zackad/prettier-plugin-twig": {
"optional": true
},
"prettier-plugin-astro": {
"optional": true
},
"prettier-plugin-css-order": {
"optional": true
},
"prettier-plugin-import-sort": {
"optional": true
},
"prettier-plugin-jsdoc": {
"optional": true
},
"prettier-plugin-marko": {
"optional": true
},
"prettier-plugin-multiline-arrays": {
"optional": true
},
"prettier-plugin-organize-attributes": {
"optional": true
},
"prettier-plugin-organize-imports": {
"optional": true
},
"prettier-plugin-sort-imports": {
"optional": true
},
"prettier-plugin-style-order": {
"optional": true
},
"prettier-plugin-svelte": {
"optional": true
}
}
},
"node_modules/react": { "node_modules/react": {
"version": "19.1.0", "version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+3
View File
@@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"@next/font": "^14.2.15",
"next": "^15.3.3", "next": "^15.3.3",
"oidc-client-ts": "^3.3.0", "oidc-client-ts": "^3.3.0",
"react": "^19.1.0", "react": "^19.1.0",
@@ -17,6 +18,8 @@
"@types/node": "24.0.3", "@types/node": "24.0.3",
"@types/react": "19.1.8", "@types/react": "19.1.8",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "^0.6.13",
"tailwindcss": "^4.1.10", "tailwindcss": "^4.1.10",
"typescript": "5.8.3" "typescript": "5.8.3"
} }
Generated Vendored
-1
View File
@@ -1 +0,0 @@
../nanoid/bin/nanoid.cjs
Generated Vendored
-1
View File
@@ -1 +0,0 @@
../next/dist/bin/next
Generated Vendored
-1
View File
@@ -1 +0,0 @@
../prettier/bin/prettier.cjs
Generated Vendored
-1
View File
@@ -1 +0,0 @@
../semver/bin/semver.js
-1092
View File
File diff suppressed because it is too large Load Diff
-46
View File
@@ -1,46 +0,0 @@
# `@img/sharp-libvips-linux-x64`
Prebuilt libvips and dependencies for use with sharp on Linux (glibc) x64.
## Licensing
This software contains third-party libraries
used under the terms of the following licences:
| Library | Used under the terms of |
|---------------|-----------------------------------------------------------------------------------------------------------|
| aom | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/) |
| cairo | Mozilla Public License 2.0 |
| cgif | MIT Licence |
| expat | MIT Licence |
| fontconfig | [fontconfig Licence](https://gitlab.freedesktop.org/fontconfig/fontconfig/blob/main/COPYING) (BSD-like) |
| freetype | [freetype Licence](https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT) (BSD-like) |
| fribidi | LGPLv3 |
| glib | LGPLv3 |
| harfbuzz | MIT Licence |
| highway | Apache-2.0 License, BSD 3-Clause |
| lcms | MIT Licence |
| libarchive | BSD 2-Clause |
| libexif | LGPLv3 |
| libffi | MIT Licence |
| libheif | LGPLv3 |
| libimagequant | [BSD 2-Clause](https://github.com/lovell/libimagequant/blob/main/COPYRIGHT) |
| libnsgif | MIT Licence |
| libpng | [libpng License](https://github.com/pnggroup/libpng/blob/master/LICENSE) |
| librsvg | LGPLv3 |
| libspng | [BSD 2-Clause, libpng License](https://github.com/randy408/libspng/blob/master/LICENSE) |
| libtiff | [libtiff License](https://gitlab.com/libtiff/libtiff/blob/master/LICENSE.md) (BSD-like) |
| libvips | LGPLv3 |
| libwebp | New BSD License |
| libxml2 | MIT Licence |
| mozjpeg | [zlib License, IJG License, BSD-3-Clause](https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md) |
| pango | LGPLv3 |
| pixman | MIT Licence |
| proxy-libintl | LGPLv3 |
| zlib-ng | [zlib Licence](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md) |
Use of libraries under the terms of the LGPLv3 is via the
"any later version" clause of the LGPLv2 or LGPLv2.1.
Please report any errors or omissions via
https://github.com/lovell/sharp-libvips/issues/new
@@ -1,221 +0,0 @@
/* glibconfig.h
*
* This is a generated file. Please modify 'glibconfig.h.in'
*/
#ifndef __GLIBCONFIG_H__
#define __GLIBCONFIG_H__
#include <glib/gmacros.h>
#include <limits.h>
#include <float.h>
#define GLIB_HAVE_ALLOCA_H
#define GLIB_STATIC_COMPILATION 1
#define GOBJECT_STATIC_COMPILATION 1
#define GIO_STATIC_COMPILATION 1
#define GMODULE_STATIC_COMPILATION 1
#define GI_STATIC_COMPILATION 1
#define G_INTL_STATIC_COMPILATION 1
#define FFI_STATIC_BUILD 1
/* Specifies that GLib's g_print*() functions wrap the
* system printf functions. This is useful to know, for example,
* when using glibc's register_printf_function().
*/
#define GLIB_USING_SYSTEM_PRINTF
G_BEGIN_DECLS
#define G_MINFLOAT FLT_MIN
#define G_MAXFLOAT FLT_MAX
#define G_MINDOUBLE DBL_MIN
#define G_MAXDOUBLE DBL_MAX
#define G_MINSHORT SHRT_MIN
#define G_MAXSHORT SHRT_MAX
#define G_MAXUSHORT USHRT_MAX
#define G_MININT INT_MIN
#define G_MAXINT INT_MAX
#define G_MAXUINT UINT_MAX
#define G_MINLONG LONG_MIN
#define G_MAXLONG LONG_MAX
#define G_MAXULONG ULONG_MAX
typedef signed char gint8;
typedef unsigned char guint8;
typedef signed short gint16;
typedef unsigned short guint16;
#define G_GINT16_MODIFIER "h"
#define G_GINT16_FORMAT "hi"
#define G_GUINT16_FORMAT "hu"
typedef signed int gint32;
typedef unsigned int guint32;
#define G_GINT32_MODIFIER ""
#define G_GINT32_FORMAT "i"
#define G_GUINT32_FORMAT "u"
#define G_HAVE_GINT64 1 /* deprecated, always true */
typedef signed long gint64;
typedef unsigned long guint64;
#define G_GINT64_CONSTANT(val) (val##L)
#define G_GUINT64_CONSTANT(val) (val##UL)
#define G_GINT64_MODIFIER "l"
#define G_GINT64_FORMAT "li"
#define G_GUINT64_FORMAT "lu"
#define GLIB_SIZEOF_VOID_P 8
#define GLIB_SIZEOF_LONG 8
#define GLIB_SIZEOF_SIZE_T 8
#define GLIB_SIZEOF_SSIZE_T 8
typedef signed long gssize;
typedef unsigned long gsize;
#define G_GSIZE_MODIFIER "l"
#define G_GSSIZE_MODIFIER "l"
#define G_GSIZE_FORMAT "lu"
#define G_GSSIZE_FORMAT "li"
#define G_MAXSIZE G_MAXULONG
#define G_MINSSIZE G_MINLONG
#define G_MAXSSIZE G_MAXLONG
typedef gint64 goffset;
#define G_MINOFFSET G_MININT64
#define G_MAXOFFSET G_MAXINT64
#define G_GOFFSET_MODIFIER G_GINT64_MODIFIER
#define G_GOFFSET_FORMAT G_GINT64_FORMAT
#define G_GOFFSET_CONSTANT(val) G_GINT64_CONSTANT(val)
#define G_POLLFD_FORMAT "%d"
#define GPOINTER_TO_INT(p) ((gint) (glong) (p))
#define GPOINTER_TO_UINT(p) ((guint) (gulong) (p))
#define GINT_TO_POINTER(i) ((gpointer) (glong) (i))
#define GUINT_TO_POINTER(u) ((gpointer) (gulong) (u))
typedef signed long gintptr;
typedef unsigned long guintptr;
#define G_GINTPTR_MODIFIER "l"
#define G_GINTPTR_FORMAT "li"
#define G_GUINTPTR_FORMAT "lu"
#define GLIB_MAJOR_VERSION 2
#define GLIB_MINOR_VERSION 84
#define GLIB_MICRO_VERSION 1
#define G_OS_UNIX
#define G_VA_COPY va_copy
#define G_VA_COPY_AS_ARRAY 1
#define G_HAVE_ISO_VARARGS 1
/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi
* is passed ISO vararg support is turned off, and there is no work
* around to turn it on, so we unconditionally turn it off.
*/
#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
# undef G_HAVE_ISO_VARARGS
#endif
#define G_HAVE_GROWING_STACK 0
#ifndef _MSC_VER
# define G_HAVE_GNUC_VARARGS 1
#endif
#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
#define G_GNUC_INTERNAL __attribute__((visibility("hidden")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
#define G_GNUC_INTERNAL __hidden
#elif defined (__GNUC__) && defined (G_HAVE_GNUC_VISIBILITY)
#define G_GNUC_INTERNAL __attribute__((visibility("hidden")))
#else
#define G_GNUC_INTERNAL
#endif
#define G_THREADS_ENABLED
#define G_THREADS_IMPL_POSIX
#define G_ATOMIC_LOCK_FREE
#define GINT16_TO_LE(val) ((gint16) (val))
#define GUINT16_TO_LE(val) ((guint16) (val))
#define GINT16_TO_BE(val) ((gint16) GUINT16_SWAP_LE_BE (val))
#define GUINT16_TO_BE(val) (GUINT16_SWAP_LE_BE (val))
#define GINT32_TO_LE(val) ((gint32) (val))
#define GUINT32_TO_LE(val) ((guint32) (val))
#define GINT32_TO_BE(val) ((gint32) GUINT32_SWAP_LE_BE (val))
#define GUINT32_TO_BE(val) (GUINT32_SWAP_LE_BE (val))
#define GINT64_TO_LE(val) ((gint64) (val))
#define GUINT64_TO_LE(val) ((guint64) (val))
#define GINT64_TO_BE(val) ((gint64) GUINT64_SWAP_LE_BE (val))
#define GUINT64_TO_BE(val) (GUINT64_SWAP_LE_BE (val))
#define GLONG_TO_LE(val) ((glong) GINT64_TO_LE (val))
#define GULONG_TO_LE(val) ((gulong) GUINT64_TO_LE (val))
#define GLONG_TO_BE(val) ((glong) GINT64_TO_BE (val))
#define GULONG_TO_BE(val) ((gulong) GUINT64_TO_BE (val))
#define GINT_TO_LE(val) ((gint) GINT32_TO_LE (val))
#define GUINT_TO_LE(val) ((guint) GUINT32_TO_LE (val))
#define GINT_TO_BE(val) ((gint) GINT32_TO_BE (val))
#define GUINT_TO_BE(val) ((guint) GUINT32_TO_BE (val))
#define GSIZE_TO_LE(val) ((gsize) GUINT64_TO_LE (val))
#define GSSIZE_TO_LE(val) ((gssize) GINT64_TO_LE (val))
#define GSIZE_TO_BE(val) ((gsize) GUINT64_TO_BE (val))
#define GSSIZE_TO_BE(val) ((gssize) GINT64_TO_BE (val))
#define G_BYTE_ORDER G_LITTLE_ENDIAN
#define GLIB_SYSDEF_POLLIN =1
#define GLIB_SYSDEF_POLLOUT =4
#define GLIB_SYSDEF_POLLPRI =2
#define GLIB_SYSDEF_POLLHUP =16
#define GLIB_SYSDEF_POLLERR =8
#define GLIB_SYSDEF_POLLNVAL =32
/* No way to disable deprecation warnings for macros, so only emit deprecation
* warnings on platforms where usage of this macro is broken */
#if defined(__APPLE__) || defined(_MSC_VER) || defined(__CYGWIN__)
#define G_MODULE_SUFFIX "so" GLIB_DEPRECATED_MACRO_IN_2_76
#else
#define G_MODULE_SUFFIX "so"
#endif
typedef int GPid;
#define G_PID_FORMAT "i"
#define GLIB_SYSDEF_AF_UNIX 1
#define GLIB_SYSDEF_AF_INET 2
#define GLIB_SYSDEF_AF_INET6 10
#define GLIB_SYSDEF_MSG_OOB 1
#define GLIB_SYSDEF_MSG_PEEK 2
#define GLIB_SYSDEF_MSG_DONTROUTE 4
#define G_DIR_SEPARATOR '/'
#define G_DIR_SEPARATOR_S "/"
#define G_SEARCHPATH_SEPARATOR ':'
#define G_SEARCHPATH_SEPARATOR_S ":"
#undef G_HAVE_FREE_SIZED
G_END_DECLS
#endif /* __GLIBCONFIG_H__ */
-1
View File
@@ -1 +0,0 @@
module.exports = __dirname;
Binary file not shown.
-42
View File
@@ -1,42 +0,0 @@
{
"name": "@img/sharp-libvips-linux-x64",
"version": "1.1.0",
"description": "Prebuilt libvips and dependencies for use with sharp on Linux (glibc) x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
"repository": {
"type": "git",
"url": "git+https://github.com/lovell/sharp-libvips.git",
"directory": "npm/linux-x64"
},
"license": "LGPL-3.0-or-later",
"funding": {
"url": "https://opencollective.com/libvips"
},
"preferUnplugged": true,
"publishConfig": {
"access": "public"
},
"files": [
"lib",
"versions.json"
],
"type": "commonjs",
"exports": {
"./lib": "./lib/index.js",
"./package": "./package.json",
"./versions": "./versions.json"
},
"config": {
"glibc": ">=2.26"
},
"os": [
"linux"
],
"libc": [
"glibc"
],
"cpu": [
"x64"
]
}
-30
View File
@@ -1,30 +0,0 @@
{
"aom": "3.12.0",
"archive": "3.7.9",
"cairo": "1.18.4",
"cgif": "0.5.0",
"exif": "0.6.25",
"expat": "2.7.1",
"ffi": "3.4.7",
"fontconfig": "2.16.1",
"freetype": "2.13.3",
"fribidi": "1.0.16",
"glib": "2.84.1",
"harfbuzz": "11.0.0",
"heif": "1.19.7",
"highway": "1.2.0",
"imagequant": "2.4.1",
"lcms": "2.17",
"mozjpeg": "4.1.5",
"pango": "1.56.3",
"pixman": "0.44.2",
"png": "1.6.47",
"proxy-libintl": "0.4",
"rsvg": "2.60.0",
"spng": "0.7.4",
"tiff": "4.7.0",
"vips": "8.16.1",
"webp": "1.5.0",
"xml": "2.14.1",
"zlib-ng": "2.2.4"
}
-191
View File
@@ -1,191 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-18
View File
@@ -1,18 +0,0 @@
# `@img/sharp-linux-x64`
Prebuilt sharp for use with Linux (glibc) x64.
## Licensing
Copyright 2013 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Binary file not shown.
-46
View File
@@ -1,46 +0,0 @@
{
"name": "@img/sharp-linux-x64",
"version": "0.34.2",
"description": "Prebuilt sharp for use with Linux (glibc) x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
"repository": {
"type": "git",
"url": "git+https://github.com/lovell/sharp.git",
"directory": "npm/linux-x64"
},
"license": "Apache-2.0",
"funding": {
"url": "https://opencollective.com/libvips"
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.1.0"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"type": "commonjs",
"exports": {
"./sharp.node": "./lib/sharp-linux-x64.node",
"./package": "./package.json"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"config": {
"glibc": ">=2.26"
},
"os": [
"linux"
],
"libc": [
"glibc"
],
"cpu": [
"x64"
]
}
-3
View File
@@ -1,3 +0,0 @@
# `@next/env`
Next.js' util for loading dotenv files in with the proper priorities
-22
View File
@@ -1,22 +0,0 @@
export type Env = {
[key: string]: string | undefined;
};
export type LoadedEnvFiles = Array<{
path: string;
contents: string;
env: Env;
}>;
export declare let initialEnv: Env | undefined;
export declare function updateInitialEnv(newEnv: Env): void;
type Log = {
info: (...args: any[]) => void;
error: (...args: any[]) => void;
};
export declare function processEnv(loadedEnvFiles: LoadedEnvFiles, dir?: string, log?: Log, forceReload?: boolean, onReload?: (envFilePath: string) => void): Env[];
export declare function resetEnv(): void;
export declare function loadEnvConfig(dir: string, dev?: boolean, log?: Log, forceReload?: boolean, onReload?: (envFilePath: string) => void): {
combinedEnv: Env;
parsedEnv: Env | undefined;
loadedEnvFiles: LoadedEnvFiles;
};
export {};
-1
View File
File diff suppressed because one or more lines are too long
-36
View File
@@ -1,36 +0,0 @@
{
"name": "@next/env",
"version": "15.3.4",
"keywords": [
"react",
"next",
"next.js",
"dotenv"
],
"description": "Next.js dotenv file loading",
"repository": {
"type": "git",
"url": "https://github.com/vercel/next.js",
"directory": "packages/next-env"
},
"author": "Next.js Team <support@vercel.com>",
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"dev": "ncc build ./index.ts -w -o dist/",
"prerelease": "node ../../scripts/rm.mjs dist",
"types": "tsc --declaration --emitDeclarationOnly --declarationDir dist",
"release": "ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register",
"build": "pnpm release && pnpm types",
"prepublishOnly": "cd ../../ && turbo run build"
},
"devDependencies": {
"@vercel/ncc": "0.34.0",
"dotenv": "16.3.1",
"dotenv-expand": "10.0.0"
}
}
-7
View File
@@ -1,7 +0,0 @@
# `@next/font`
`@next/font` includes built-in automatic self-hosting for any font file. This means you can optimally load web fonts with zero layout shift, thanks to the underlying CSS size-adjust property used.
This new font system also allows you to conveniently use all Google Fonts with performance and privacy in mind. CSS and font files are downloaded at build time and self-hosted with the rest of your static assets. No requests are sent to Google by the browser.
[Read more](https://nextjs.org/docs/app/building-your-application/optimizing/fonts)
-1
View File
@@ -1 +0,0 @@
export declare const allowedDisplayValues: string[];
-10
View File
@@ -1,10 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.allowedDisplayValues = void 0;
exports.allowedDisplayValues = [
'auto',
'block',
'swap',
'fallback',
'optional',
];
File diff suppressed because one or more lines are too long
-5
View File
@@ -1,5 +0,0 @@
/**
* Formats an array of values into a string that can be used error messages.
* ["a", "b", "c"] => "`a`, `b`, `c`"
*/
export declare const formatAvailableValues: (values: string[]) => string;
-9
View File
@@ -1,9 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatAvailableValues = void 0;
/**
* Formats an array of values into a string that can be used error messages.
* ["a", "b", "c"] => "`a`, `b`, `c`"
*/
const formatAvailableValues = (values) => values.map((val) => `\`${val}\``).join(', ');
exports.formatAvailableValues = formatAvailableValues;
-8
View File
@@ -1,8 +0,0 @@
/**
* Fetches the CSS containing the @font-face declarations from Google Fonts.
* The fetch has a user agent header with a modern browser to ensure we'll get .woff2 files.
*
* The env variable NEXT_FONT_GOOGLE_MOCKED_RESPONSES may be set containing a path to mocked data.
* It's used to define mocked data to avoid hitting the Google Fonts API during tests.
*/
export declare function fetchCSSFromGoogleFonts(url: string, fontFamily: string, isDev: boolean): Promise<string>;
-65
View File
@@ -1,65 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchCSSFromGoogleFonts = void 0;
// @ts-ignore
const node_fetch_1 = __importDefault(require("next/dist/compiled/node-fetch"));
const next_font_error_1 = require("../next-font-error");
const get_proxy_agent_1 = require("./get-proxy-agent");
const retry_1 = require("./retry");
/**
* Fetches the CSS containing the @font-face declarations from Google Fonts.
* The fetch has a user agent header with a modern browser to ensure we'll get .woff2 files.
*
* The env variable NEXT_FONT_GOOGLE_MOCKED_RESPONSES may be set containing a path to mocked data.
* It's used to define mocked data to avoid hitting the Google Fonts API during tests.
*/
async function fetchCSSFromGoogleFonts(url, fontFamily, isDev) {
// Check if mocked responses are defined, if so use them instead of fetching from Google Fonts
let mockedResponse;
if (process.env.NEXT_FONT_GOOGLE_MOCKED_RESPONSES) {
const mockFile = require(process.env.NEXT_FONT_GOOGLE_MOCKED_RESPONSES);
mockedResponse = mockFile[url];
if (!mockedResponse) {
(0, next_font_error_1.nextFontError)('Missing mocked response for URL: ' + url);
}
}
let cssResponse;
if (mockedResponse) {
// Just use the mocked CSS if it's set
cssResponse = mockedResponse;
}
else {
// Retry the fetch a few times in case of network issues as some font files
// are quite large:
// https://github.com/vercel/next.js/issues/45080
cssResponse = await (0, retry_1.retry)(async () => {
const controller = isDev && typeof AbortController !== 'undefined'
? new AbortController()
: undefined;
const signal = controller === null || controller === void 0 ? void 0 : controller.signal;
const timeoutId = controller
? setTimeout(() => controller.abort(), 3000)
: undefined;
const res = await (0, node_fetch_1.default)(url, {
agent: (0, get_proxy_agent_1.getProxyAgent)(),
// Add a timeout in dev
signal,
headers: {
// The file format is based off of the user agent, make sure woff2 files are fetched
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
},
}).finally(() => {
timeoutId && clearTimeout(timeoutId);
});
if (!res.ok) {
(0, next_font_error_1.nextFontError)(`Failed to fetch font \`${fontFamily}\`.\nURL: ${url}\n\nPlease check if the network is available.`);
}
return res.text();
}, 3);
}
return cssResponse;
}
exports.fetchCSSFromGoogleFonts = fetchCSSFromGoogleFonts;
-4
View File
@@ -1,4 +0,0 @@
/**
* Fetch the url and return a buffer with the font file.
*/
export declare function fetchFontFile(url: string, isDev: boolean): Promise<any>;
-39
View File
@@ -1,39 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchFontFile = void 0;
// @ts-ignore
const node_fetch_1 = __importDefault(require("next/dist/compiled/node-fetch"));
const get_proxy_agent_1 = require("./get-proxy-agent");
const retry_1 = require("./retry");
/**
* Fetch the url and return a buffer with the font file.
*/
async function fetchFontFile(url, isDev) {
// Check if we're using mocked data
if (process.env.NEXT_FONT_GOOGLE_MOCKED_RESPONSES) {
// If it's an absolute path, read the file from the filesystem
if (url.startsWith('/')) {
return require('fs').readFileSync(url);
}
// Otherwise just return a unique buffer
return Buffer.from(url);
}
return await (0, retry_1.retry)(async () => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);
const arrayBuffer = await (0, node_fetch_1.default)(url, {
agent: (0, get_proxy_agent_1.getProxyAgent)(),
// Add a timeout in dev
signal: isDev ? controller.signal : undefined,
})
.then((r) => r.arrayBuffer())
.finally(() => {
clearTimeout(timeoutId);
});
return Buffer.from(arrayBuffer);
}, 3);
}
exports.fetchFontFile = fetchFontFile;
-9
View File
@@ -1,9 +0,0 @@
/**
* Find all font files in the CSS response and determine which files should be preloaded.
* In Google Fonts responses, the @font-face's subset is above it in a comment.
* Walk through the CSS from top to bottom, keeping track of the current subset.
*/
export declare function findFontFilesInCss(css: string, subsetsToPreload?: string[]): {
googleFontFileUrl: string;
preloadFontFile: boolean;
}[];
-35
View File
@@ -1,35 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findFontFilesInCss = void 0;
/**
* Find all font files in the CSS response and determine which files should be preloaded.
* In Google Fonts responses, the @font-face's subset is above it in a comment.
* Walk through the CSS from top to bottom, keeping track of the current subset.
*/
function findFontFilesInCss(css, subsetsToPreload) {
var _a, _b;
// Find font files to download
const fontFiles = [];
// Keep track of the current subset
let currentSubset = '';
for (const line of css.split('\n')) {
const newSubset = (_a = /\/\* (.+?) \*\//.exec(line)) === null || _a === void 0 ? void 0 : _a[1];
if (newSubset) {
// Found new subset in a comment above the next @font-face declaration
currentSubset = newSubset;
}
else {
const googleFontFileUrl = (_b = /src: url\((.+?)\)/.exec(line)) === null || _b === void 0 ? void 0 : _b[1];
if (googleFontFileUrl &&
!fontFiles.some((foundFile) => foundFile.googleFontFileUrl === googleFontFileUrl)) {
// Found the font file in the @font-face declaration.
fontFiles.push({
googleFontFileUrl,
preloadFontFile: !!(subsetsToPreload === null || subsetsToPreload === void 0 ? void 0 : subsetsToPreload.includes(currentSubset)),
});
}
}
}
return fontFiles;
}
exports.findFontFilesInCss = findFontFilesInCss;
-1
View File
@@ -1 +0,0 @@
export {};
-90
View File
@@ -1,90 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const find_font_files_in_css_1 = require("./find-font-files-in-css");
describe('findFontFilesInCss', () => {
it('should find all font files and preload requested subsets', () => {
const css = `/* latin */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 300;
src: url(latin1.woff2) format('woff2');
}
/* greek */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 300;
src: url(greek1.woff2) format('woff2');
}
/* latin */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 400;
src: url(latin2.woff2) format('woff2');
}
/* greek */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 400;
src: url(greek2.woff2) format('woff2');
}
/* cyrilic */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 400;
src: url(cyrilic.woff2) format('woff2');
}
`;
expect((0, find_font_files_in_css_1.findFontFilesInCss)(css, ['latin', 'cyrilic'])).toEqual([
{ googleFontFileUrl: 'latin1.woff2', preloadFontFile: true },
{ googleFontFileUrl: 'greek1.woff2', preloadFontFile: false },
{ googleFontFileUrl: 'latin2.woff2', preloadFontFile: true },
{ googleFontFileUrl: 'greek2.woff2', preloadFontFile: false },
{ googleFontFileUrl: 'cyrilic.woff2', preloadFontFile: true },
]);
});
it('should not return duplicate font files when several variants use the same font file', () => {
const css = `/* latin */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 100;
font-display: swap;
src: url(https://fonts.gstatic.com/s/fraunces/v24/6NUu8FyLNQOQZAnv9bYEvDiIdE9Ea92uemAk_WBq8U_9v0c2Wa0K7iN7hzFUPJH58nib14c7qv8oRcTn.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/fraunces/v24/6NUu8FyLNQOQZAnv9bYEvDiIdE9Ea92uemAk_WBq8U_9v0c2Wa0K7iN7hzFUPJH58nib14c7qv8oRcTn.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Fraunces';
font-style: normal;
font-weight: 900;
font-display: swap;
src: url(https://fonts.gstatic.com/s/fraunces/v24/6NUu8FyLNQOQZAnv9bYEvDiIdE9Ea92uemAk_WBq8U_9v0c2Wa0K7iN7hzFUPJH58nib14c7qv8oRcTn.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
`;
expect((0, find_font_files_in_css_1.findFontFilesInCss)(css)).toEqual([
{
googleFontFileUrl: 'https://fonts.gstatic.com/s/fraunces/v24/6NUu8FyLNQOQZAnv9bYEvDiIdE9Ea92uemAk_WBq8U_9v0c2Wa0K7iN7hzFUPJH58nib14c7qv8oRcTn.woff2',
preloadFontFile: false,
},
]);
});
});
-14483
View File
File diff suppressed because it is too large Load Diff
@@ -1,14 +0,0 @@
/**
* Get precalculated fallback font metrics for the Google Fonts family.
*
* TODO:
* We might want to calculate these values with fontkit instead (like in next/font/local).
* That way we don't have to update the precalculated values every time a new font is added to Google Fonts.
*/
export declare function getFallbackFontOverrideMetrics(fontFamily: string): {
fallbackFont: any;
ascentOverride: string;
descentOverride: string;
lineGapOverride: string;
sizeAdjust: string;
} | undefined;
@@ -1,53 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFallbackFontOverrideMetrics = void 0;
// @ts-ignore
const font_utils_1 = require("next/dist/server/font-utils");
// @ts-ignore
const Log = __importStar(require("next/dist/build/output/log"));
/**
* Get precalculated fallback font metrics for the Google Fonts family.
*
* TODO:
* We might want to calculate these values with fontkit instead (like in next/font/local).
* That way we don't have to update the precalculated values every time a new font is added to Google Fonts.
*/
function getFallbackFontOverrideMetrics(fontFamily) {
try {
const { ascent, descent, lineGap, fallbackFont, sizeAdjust } = (0, font_utils_1.calculateSizeAdjustValues)(fontFamily);
return {
fallbackFont,
ascentOverride: `${ascent}%`,
descentOverride: `${descent}%`,
lineGapOverride: `${lineGap}%`,
sizeAdjust: `${sizeAdjust}%`,
};
}
catch {
Log.error(`Failed to find font override values for font \`${fontFamily}\``);
}
}
exports.getFallbackFontOverrideMetrics = getFallbackFontOverrideMetrics;
-8
View File
@@ -1,8 +0,0 @@
/**
* Validates and gets the data for each font axis required to generate the Google Fonts URL.
*/
export declare function getFontAxes(fontFamily: string, weights: string[], styles: string[], selectedVariableAxes?: string[]): {
wght?: string[];
ital?: string[];
variableAxes?: [string, string][];
};
-67
View File
@@ -1,67 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFontAxes = void 0;
const format_available_values_1 = require("../format-available-values");
const next_font_error_1 = require("../next-font-error");
const google_fonts_metadata_1 = require("./google-fonts-metadata");
/**
* Validates and gets the data for each font axis required to generate the Google Fonts URL.
*/
function getFontAxes(fontFamily, weights, styles, selectedVariableAxes) {
const hasItalic = styles.includes('italic');
const hasNormal = styles.includes('normal');
// Make sure the order is correct, otherwise Google Fonts will return an error
// If only normal is set, we can skip returning the ital axis as normal is the default
const ital = hasItalic ? [...(hasNormal ? ['0'] : []), '1'] : undefined;
// Weights will always contain one element if it's a variable font
if (weights[0] === 'variable') {
// Get all the available axes for the current font from the metadata file
const allAxes = google_fonts_metadata_1.googleFontsMetadata[fontFamily].axes;
if (!allAxes) {
throw new Error('invariant variable font without axes');
}
if (selectedVariableAxes) {
// The axes other than weight and style that can be defined for the current variable font
const defineAbleAxes = allAxes
.map(({ tag }) => tag)
.filter((tag) => tag !== 'wght');
if (defineAbleAxes.length === 0) {
(0, next_font_error_1.nextFontError)(`Font \`${fontFamily}\` has no definable \`axes\``);
}
if (!Array.isArray(selectedVariableAxes)) {
(0, next_font_error_1.nextFontError)(`Invalid axes value for font \`${fontFamily}\`, expected an array of axes.\nAvailable axes: ${(0, format_available_values_1.formatAvailableValues)(defineAbleAxes)}`);
}
selectedVariableAxes.forEach((key) => {
if (!defineAbleAxes.some((tag) => tag === key)) {
(0, next_font_error_1.nextFontError)(`Invalid axes value \`${key}\` for font \`${fontFamily}\`.\nAvailable axes: ${(0, format_available_values_1.formatAvailableValues)(defineAbleAxes)}`);
}
});
}
let weightAxis;
let variableAxes;
for (const { tag, min, max } of allAxes) {
if (tag === 'wght') {
// In variable fonts the weight is a range
weightAxis = `${min}..${max}`;
}
else if (selectedVariableAxes === null || selectedVariableAxes === void 0 ? void 0 : selectedVariableAxes.includes(tag)) {
if (!variableAxes) {
variableAxes = [];
}
variableAxes.push([tag, `${min}..${max}`]);
}
}
return {
wght: weightAxis ? [weightAxis] : undefined,
ital,
variableAxes,
};
}
else {
return {
ital,
wght: weights,
};
}
}
exports.getFontAxes = getFontAxes;
-1
View File
@@ -1 +0,0 @@
export {};
-22
View File
@@ -1,22 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const get_font_axes_1 = require("./get-font-axes");
describe('getFontAxes errors', () => {
test('Setting axes on font without definable axes', () => {
expect(() => (0, get_font_axes_1.getFontAxes)('Lora', ['variable'], [], [])).toThrowErrorMatchingInlineSnapshot(`"Font \`Lora\` has no definable \`axes\`"`);
});
test('Invalid axes value', async () => {
expect(() => (0, get_font_axes_1.getFontAxes)('Inter', ['variable'], [], true))
.toThrowErrorMatchingInlineSnapshot(`
"Invalid axes value for font \`Inter\`, expected an array of axes.
Available axes: \`opsz\`"
`);
});
test('Invalid value in axes array', async () => {
expect(() => (0, get_font_axes_1.getFontAxes)('Roboto Flex', ['variable'], [], ['INVALID']))
.toThrowErrorMatchingInlineSnapshot(`
"Invalid axes value \`INVALID\` for font \`Roboto Flex\`.
Available axes: \`GRAD\`, \`XOPQ\`, \`XTRA\`, \`YOPQ\`, \`YTAS\`, \`YTDE\`, \`YTFI\`, \`YTLC\`, \`YTUC\`, \`opsz\`, \`slnt\`, \`wdth\`"
`);
});
});
-8
View File
@@ -1,8 +0,0 @@
/**
* Generate the Google Fonts URL given the requested weight(s), style(s) and additional variable axes
*/
export declare function getGoogleFontsUrl(fontFamily: string, axes: {
wght?: string[];
ital?: string[];
variableAxes?: [string, string][];
}, display: string): string;
-56
View File
@@ -1,56 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGoogleFontsUrl = void 0;
const sort_fonts_variant_values_1 = require("./sort-fonts-variant-values");
/**
* Generate the Google Fonts URL given the requested weight(s), style(s) and additional variable axes
*/
function getGoogleFontsUrl(fontFamily, axes, display) {
var _a, _b;
// Variants are all combinations of weight and style, each variant will result in a separate font file
const variants = [];
if (axes.wght) {
for (const wght of axes.wght) {
if (!axes.ital) {
variants.push([['wght', wght], ...((_a = axes.variableAxes) !== null && _a !== void 0 ? _a : [])]);
}
else {
for (const ital of axes.ital) {
variants.push([
['ital', ital],
['wght', wght],
...((_b = axes.variableAxes) !== null && _b !== void 0 ? _b : []),
]);
}
}
}
}
else if (axes.variableAxes) {
// Variable fonts might not have a range of weights, just add optional variable axes in that case
variants.push([...axes.variableAxes]);
}
// Google api requires the axes to be sorted, starting with lowercase words
if (axes.variableAxes) {
variants.forEach((variant) => {
variant.sort(([a], [b]) => {
const aIsLowercase = a.charCodeAt(0) > 96;
const bIsLowercase = b.charCodeAt(0) > 96;
if (aIsLowercase && !bIsLowercase)
return -1;
if (bIsLowercase && !aIsLowercase)
return 1;
return a > b ? 1 : -1;
});
});
}
let url = `https://fonts.googleapis.com/css2?family=${fontFamily.replace(/ /g, '+')}`;
if (variants.length > 0) {
url = `${url}:${variants[0].map(([key]) => key).join(',')}@${variants
.map((variant) => variant.map(([, val]) => val).join(','))
.sort(sort_fonts_variant_values_1.sortFontsVariantValues)
.join(';')}`;
}
url = `${url}&display=${display}`;
return url;
}
exports.getGoogleFontsUrl = getGoogleFontsUrl;
-6
View File
@@ -1,6 +0,0 @@
/// <reference types="node" />
import type { Agent } from 'https';
/**
* If the http(s)_proxy environment variables is set, return a proxy agent.
*/
export declare function getProxyAgent(): Agent | undefined;
-24
View File
@@ -1,24 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProxyAgent = void 0;
// @ts-ignore
const https_proxy_agent_1 = __importDefault(require("next/dist/compiled/https-proxy-agent"));
// @ts-ignore
const http_proxy_agent_1 = __importDefault(require("next/dist/compiled/http-proxy-agent"));
/**
* If the http(s)_proxy environment variables is set, return a proxy agent.
*/
function getProxyAgent() {
const httpsProxy = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
if (httpsProxy) {
return new https_proxy_agent_1.default(httpsProxy);
}
const httpProxy = process.env['http_proxy'] || process.env['HTTP_PROXY'];
if (httpProxy) {
return new http_proxy_agent_1.default(httpProxy);
}
}
exports.getProxyAgent = getProxyAgent;
-15
View File
@@ -1,15 +0,0 @@
type GoogleFontsMetadata = {
[fontFamily: string]: {
weights: string[];
styles: string[];
subsets: string[];
axes?: Array<{
tag: string;
min: number;
max: number;
defaultValue: number;
}>;
};
};
export declare const googleFontsMetadata: GoogleFontsMetadata;
export {};
-8
View File
@@ -1,8 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.googleFontsMetadata = void 0;
const font_data_json_1 = __importDefault(require("./font-data.json"));
exports.googleFontsMetadata = font_data_json_1.default;
-16360
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -1,2 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-3
View File
@@ -1,3 +0,0 @@
import type { FontLoader } from 'next/font';
declare const nextFontGoogleFontLoader: FontLoader;
export default nextFontGoogleFontLoader;
-165
View File
@@ -1,165 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
const Log = __importStar(require("next/dist/build/output/log"));
const validate_google_font_function_call_1 = require("./validate-google-font-function-call");
const get_font_axes_1 = require("./get-font-axes");
const get_google_fonts_url_1 = require("./get-google-fonts-url");
const next_font_error_1 = require("../next-font-error");
const find_font_files_in_css_1 = require("./find-font-files-in-css");
const get_fallback_font_override_metrics_1 = require("./get-fallback-font-override-metrics");
const fetch_css_from_google_fonts_1 = require("./fetch-css-from-google-fonts");
const fetch_font_file_1 = require("./fetch-font-file");
const cssCache = new Map();
const fontCache = new Map();
// regexp is based on https://github.com/sindresorhus/escape-string-regexp
const reHasRegExp = /[|\\{}()[\]^$+*?.-]/;
const reReplaceRegExp = /[|\\{}()[\]^$+*?.-]/g;
function escapeStringRegexp(str) {
// see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23
if (reHasRegExp.test(str)) {
return str.replace(reReplaceRegExp, '\\$&');
}
return str;
}
const nextFontGoogleFontLoader = async ({ functionName, data, emitFontFile, isDev, isServer, }) => {
var _a;
const { fontFamily, weights, styles, display, preload, selectedVariableAxes, fallback, adjustFontFallback, variable, subsets, } = (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)(functionName, data[0]);
// Validate and get the font axes required to generated the URL
const fontAxes = (0, get_font_axes_1.getFontAxes)(fontFamily, weights, styles, selectedVariableAxes);
// Generate the Google Fonts URL from the font family, axes and display value
const url = (0, get_google_fonts_url_1.getGoogleFontsUrl)(fontFamily, fontAxes, display);
// Get precalculated fallback font metrics, used to generate the fallback font CSS
const adjustFontFallbackMetrics = adjustFontFallback ? (0, get_fallback_font_override_metrics_1.getFallbackFontOverrideMetrics)(fontFamily) : undefined;
const result = {
fallbackFonts: fallback,
weight: weights.length === 1 && weights[0] !== 'variable'
? weights[0]
: undefined,
style: styles.length === 1 ? styles[0] : undefined,
variable,
adjustFontFallback: adjustFontFallbackMetrics,
};
try {
/**
* Hacky way to make sure the fetch is only done once.
* Otherwise both the client and server compiler would fetch the CSS.
* The reason we need to return the actual CSS from both the server and client is because a hash is generated based on the CSS content.
*/
const hasCachedCSS = cssCache.has(url);
// Fetch CSS from Google Fonts or get it from the cache
let fontFaceDeclarations = hasCachedCSS
? cssCache.get(url)
: await (0, fetch_css_from_google_fonts_1.fetchCSSFromGoogleFonts)(url, fontFamily, isDev).catch((err) => {
console.error(err);
return null;
});
if (!hasCachedCSS) {
cssCache.set(url, fontFaceDeclarations !== null && fontFaceDeclarations !== void 0 ? fontFaceDeclarations : null);
}
else {
cssCache.delete(url);
}
if (fontFaceDeclarations == null) {
(0, next_font_error_1.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
}
// CSS Variables may be set on a body tag, ignore them to keep the CSS module pure
fontFaceDeclarations = fontFaceDeclarations.split('body {', 1)[0];
// Find font files to download, provide the array of subsets we want to preload if preloading is enabled
const fontFiles = (0, find_font_files_in_css_1.findFontFilesInCss)(fontFaceDeclarations, preload ? subsets : undefined);
// Download the font files extracted from the CSS
const downloadedFiles = await Promise.all(fontFiles.map(async ({ googleFontFileUrl, preloadFontFile }) => {
const hasCachedFont = fontCache.has(googleFontFileUrl);
// Download the font file or get it from cache
const fontFileBuffer = hasCachedFont
? fontCache.get(googleFontFileUrl)
: await (0, fetch_font_file_1.fetchFontFile)(googleFontFileUrl, isDev).catch((err) => {
console.error(err);
return null;
});
if (!hasCachedFont) {
fontCache.set(googleFontFileUrl, fontFileBuffer !== null && fontFileBuffer !== void 0 ? fontFileBuffer : null);
}
else {
fontCache.delete(googleFontFileUrl);
}
if (fontFileBuffer == null) {
(0, next_font_error_1.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
}
const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(googleFontFileUrl)[1];
// Emit font file to .next/static/media
const selfHostedFileUrl = emitFontFile(fontFileBuffer, ext, preloadFontFile, !!adjustFontFallbackMetrics);
return {
googleFontFileUrl,
selfHostedFileUrl,
};
}));
/**
* Replace the @font-face sources with the self-hosted files we just downloaded to .next/static/media
*
* E.g.
* @font-face {
* font-family: 'Inter';
* src: url(https://fonts.gstatic.com/...) -> url(/_next/static/media/_.woff2)
* }
*/
let updatedCssResponse = fontFaceDeclarations;
for (const { googleFontFileUrl, selfHostedFileUrl } of downloadedFiles) {
updatedCssResponse = updatedCssResponse.replace(new RegExp(escapeStringRegexp(googleFontFileUrl), 'g'), selfHostedFileUrl);
}
return {
...result,
css: updatedCssResponse,
};
}
catch (err) {
if (isDev) {
if (isServer) {
Log.error(`Failed to download \`${fontFamily}\` from Google Fonts. Using fallback font instead.\n\n${err.message}}`);
}
// In dev we should return the fallback font instead of throwing an error
let css = `@font-face {
font-family: '${fontFamily} Fallback';
src: local("${(_a = adjustFontFallbackMetrics === null || adjustFontFallbackMetrics === void 0 ? void 0 : adjustFontFallbackMetrics.fallbackFont) !== null && _a !== void 0 ? _a : 'Arial'}");`;
if (adjustFontFallbackMetrics) {
css += `
ascent-override:${adjustFontFallbackMetrics.ascentOverride};
descent-override:${adjustFontFallbackMetrics.descentOverride};
line-gap-override:${adjustFontFallbackMetrics.lineGapOverride};
size-adjust:${adjustFontFallbackMetrics.sizeAdjust};`;
}
css += '\n}';
return {
...result,
css,
};
}
else {
throw err;
}
}
};
exports.default = nextFontGoogleFontLoader;
-1
View File
@@ -1 +0,0 @@
export {};
-144
View File
@@ -1,144 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const loader_1 = __importDefault(require("./loader"));
// @ts-ignore
const node_fetch_1 = __importDefault(require("next/dist/compiled/node-fetch"));
jest.mock('next/dist/compiled/node-fetch');
describe('next/font/google loader', () => {
afterEach(() => {
jest.resetAllMocks();
});
describe('URL from options', () => {
const fixtures = [
[
'Inter',
{},
'https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap',
],
[
'Inter',
{ weight: '400' },
'https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap',
],
[
'Inter',
{ weight: '900', display: 'block' },
'https://fonts.googleapis.com/css2?family=Inter:wght@900&display=block',
],
[
'Source_Sans_3',
{ weight: '900', display: 'auto' },
'https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@900&display=auto',
],
[
'Source_Sans_3',
{ weight: '200', style: 'italic' },
'https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@1,200&display=swap',
],
[
'Roboto_Flex',
{ display: 'swap' },
'https://fonts.googleapis.com/css2?family=Roboto+Flex:wght@100..1000&display=swap',
],
[
'Roboto_Flex',
{ display: 'fallback', weight: 'variable', axes: ['opsz'] },
'https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=fallback',
],
[
'Roboto_Flex',
{
display: 'optional',
axes: ['YTUC', 'slnt', 'wdth', 'opsz', 'XTRA', 'YTAS'],
},
'https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,slnt,wdth,wght,XTRA,YTAS,YTUC@8..144,-10..0,25..151,100..1000,323..603,649..854,528..760&display=optional',
],
[
'Oooh_Baby',
{ weight: '400' },
'https://fonts.googleapis.com/css2?family=Oooh+Baby:wght@400&display=swap',
],
[
'Albert_Sans',
{ weight: 'variable', style: 'italic' },
'https://fonts.googleapis.com/css2?family=Albert+Sans:ital,wght@1,100..900&display=swap',
],
[
'Fraunces',
{ weight: 'variable', style: 'italic', axes: ['WONK', 'opsz', 'SOFT'] },
'https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght,SOFT,WONK@1,9..144,100..900,0..100,0..1&display=swap',
],
[
'Molle',
{ weight: '400' },
'https://fonts.googleapis.com/css2?family=Molle:ital,wght@1,400&display=swap',
],
[
'Roboto',
{ weight: ['500', '300', '400'], style: ['normal', 'italic'] },
'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap',
],
[
'Roboto Mono',
{ style: ['italic', 'normal'] },
'https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap',
],
[
'Fraunces',
{
style: ['normal', 'italic'],
axes: ['WONK', 'opsz', 'SOFT'],
},
'https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght,SOFT,WONK@0,9..144,100..900,0..100,0..1;1,9..144,100..900,0..100,0..1&display=swap',
],
[
'Poppins',
{ weight: ['900', '400', '100'] },
'https://fonts.googleapis.com/css2?family=Poppins:wght@100;400;900&display=swap',
],
[
'Nabla',
{},
'https://fonts.googleapis.com/css2?family=Nabla&display=swap',
],
[
'Nabla',
{ axes: ['EDPT', 'EHLT'] },
'https://fonts.googleapis.com/css2?family=Nabla:EDPT,EHLT@0..200,0..24&display=swap',
],
[
'Ballet',
{},
'https://fonts.googleapis.com/css2?family=Ballet&display=swap',
],
];
test.each(fixtures)('%s', async (functionName, fontFunctionArguments, expectedUrl) => {
node_fetch_1.default.mockResolvedValue({
ok: true,
text: async () => 'OK',
});
const { css } = await (0, loader_1.default)({
functionName,
data: [
{
adjustFontFallback: false,
subsets: [],
...fontFunctionArguments,
},
],
emitFontFile: jest.fn(),
resolve: jest.fn(),
loaderContext: {},
isDev: false,
isServer: true,
variableName: 'myFont',
});
expect(css).toBe('OK');
expect(node_fetch_1.default).toHaveBeenCalledTimes(1);
expect(node_fetch_1.default).toHaveBeenCalledWith(expectedUrl, expect.any(Object));
});
});
});
-2
View File
@@ -1,2 +0,0 @@
import asyncRetry from 'next/dist/compiled/async-retry';
export declare function retry<T>(fn: asyncRetry.RetryFunction<T>, retries: number): Promise<any>;
-19
View File
@@ -1,19 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.retry = void 0;
// eslint-disable-next-line import/no-extraneous-dependencies
// @ts-expect-error File exists
const async_retry_1 = __importDefault(require("next/dist/compiled/async-retry"));
async function retry(fn, retries) {
return await (0, async_retry_1.default)(fn, {
retries,
onRetry(e, attempt) {
console.error(e.message + `\n\nRetrying ${attempt}/${retries}...`);
},
minTimeout: 100,
});
}
exports.retry = retry;
-5
View File
@@ -1,5 +0,0 @@
/**
* Callback function for sorting font variant values.
* Used as a parameter in `Array.prototype.sort` function to ensure correct sorting.
*/
export declare function sortFontsVariantValues(valA: string, valB: string): number;
-27
View File
@@ -1,27 +0,0 @@
"use strict";
/**
* Callback function for sorting font variant values.
* Used as a parameter in `Array.prototype.sort` function to ensure correct sorting.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.sortFontsVariantValues = void 0;
function sortFontsVariantValues(valA, valB) {
// If both values contain commas, it indicates they are in "ital,wght" format
if (valA.includes(',') && valB.includes(',')) {
// Split the values into prefix and suffix
const [aPrefix, aSuffix] = valA.split(',', 2);
const [bPrefix, bSuffix] = valB.split(',', 2);
// Compare the prefixes (ital values)
if (aPrefix === bPrefix) {
// If prefixes are equal, then compare the suffixes (wght values)
return parseInt(aSuffix) - parseInt(bSuffix);
}
else {
// If prefixes are different, then compare the prefixes directly
return parseInt(aPrefix) - parseInt(bPrefix);
}
}
// If values are not in "ital,wght" format, then directly compare them as integers
return parseInt(valA) - parseInt(valB);
}
exports.sortFontsVariantValues = sortFontsVariantValues;
@@ -1 +0,0 @@
export {};
-31
View File
@@ -1,31 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sort_fonts_variant_values_1 = require("./sort-fonts-variant-values");
describe('sortFontsVariantValues', () => {
it('should correctly compare and return result for plain integer values', () => {
// Testing plain integer values
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('100', '200')).toBe(-100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('200', '100')).toBe(100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('50', '150')).toBe(-100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('150', '50')).toBe(100);
});
it('should correctly compare and return result for comma-separated values', () => {
// Testing "ital,wght" format
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('1,100', '0,200')).toBe(1);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('0,200', '1,100')).toBe(-1);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('1,100', '1,200')).toBe(-100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('1,200', '1,100')).toBe(100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('0,100', '0,200')).toBe(-100);
expect((0, sort_fonts_variant_values_1.sortFontsVariantValues)('0,200', '0,100')).toBe(100);
});
it('should sort an array of plain integer values correctly', () => {
const unsortedArray = ['100', '1000', '300', '200', '500'];
const sortedArray = unsortedArray.slice().sort(sort_fonts_variant_values_1.sortFontsVariantValues);
expect(sortedArray).toEqual(['100', '200', '300', '500', '1000']);
});
it('should sort an array of values with comma-separated values correctly', () => {
const unsortedArray = ['1,100', '1,200', '0,100', '0,200'];
const sortedArray = unsortedArray.slice().sort(sort_fonts_variant_values_1.sortFontsVariantValues);
expect(sortedArray).toEqual(['0,100', '0,200', '1,100', '1,200']);
});
});
@@ -1,17 +0,0 @@
type FontOptions = {
fontFamily: string;
weights: string[];
styles: string[];
display: string;
preload: boolean;
selectedVariableAxes?: string[];
fallback?: string[];
adjustFontFallback: boolean;
variable?: string;
subsets: string[];
};
/**
* Validate the data recieved from next-swc next-transform-font on next/font/google calls
*/
export declare function validateGoogleFontFunctionCall(functionName: string, fontFunctionArgument: any): FontOptions;
export {};
@@ -1,97 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateGoogleFontFunctionCall = void 0;
const constants_1 = require("../constants");
const format_available_values_1 = require("../format-available-values");
const next_font_error_1 = require("../next-font-error");
const google_fonts_metadata_1 = require("./google-fonts-metadata");
/**
* Validate the data recieved from next-swc next-transform-font on next/font/google calls
*/
function validateGoogleFontFunctionCall(functionName, fontFunctionArgument) {
let { weight, style, preload = true, display = 'swap', axes, fallback, adjustFontFallback = true, variable, subsets, } = fontFunctionArgument || {};
if (functionName === '') {
(0, next_font_error_1.nextFontError)(`next/font/google has no default export`);
}
const fontFamily = functionName.replace(/_/g, ' ');
// Get the Google font metadata, we'll use this to validate the font arguments and to print better error messages
const fontFamilyData = google_fonts_metadata_1.googleFontsMetadata[fontFamily];
if (!fontFamilyData) {
(0, next_font_error_1.nextFontError)(`Unknown font \`${fontFamily}\``);
}
const availableSubsets = fontFamilyData.subsets;
if (availableSubsets.length === 0) {
// If the font doesn't have any preloadeable subsets, disable preload
preload = false;
}
else if (preload) {
if (!subsets) {
(0, next_font_error_1.nextFontError)(`Preload is enabled but no subsets were specified for font \`${fontFamily}\`. Please specify subsets or disable preloading if your intended subset can't be preloaded.\nAvailable subsets: ${(0, format_available_values_1.formatAvailableValues)(availableSubsets)}\n\nRead more: https://nextjs.org/docs/messages/google-fonts-missing-subsets`);
}
subsets.forEach((subset) => {
if (!availableSubsets.includes(subset)) {
(0, next_font_error_1.nextFontError)(`Unknown subset \`${subset}\` for font \`${fontFamily}\`.\nAvailable subsets: ${(0, format_available_values_1.formatAvailableValues)(availableSubsets)}`);
}
});
}
const fontWeights = fontFamilyData.weights;
const fontStyles = fontFamilyData.styles;
// Get the unique weights and styles from the function call
const weights = !weight
? []
: [...new Set(Array.isArray(weight) ? weight : [weight])];
const styles = !style
? []
: [...new Set(Array.isArray(style) ? style : [style])];
if (weights.length === 0) {
// Set variable as default, throw if not available
if (fontWeights.includes('variable')) {
weights.push('variable');
}
else {
(0, next_font_error_1.nextFontError)(`Missing weight for font \`${fontFamily}\`.\nAvailable weights: ${(0, format_available_values_1.formatAvailableValues)(fontWeights)}`);
}
}
if (weights.length > 1 && weights.includes('variable')) {
(0, next_font_error_1.nextFontError)(`Unexpected \`variable\` in weight array for font \`${fontFamily}\`. You only need \`variable\`, it includes all available weights.`);
}
weights.forEach((selectedWeight) => {
if (!fontWeights.includes(selectedWeight)) {
(0, next_font_error_1.nextFontError)(`Unknown weight \`${selectedWeight}\` for font \`${fontFamily}\`.\nAvailable weights: ${(0, format_available_values_1.formatAvailableValues)(fontWeights)}`);
}
});
if (styles.length === 0) {
if (fontStyles.length === 1) {
// Handle default style for fonts that only have italic
styles.push(fontStyles[0]);
}
else {
// Otherwise set default style to normal
styles.push('normal');
}
}
styles.forEach((selectedStyle) => {
if (!fontStyles.includes(selectedStyle)) {
(0, next_font_error_1.nextFontError)(`Unknown style \`${selectedStyle}\` for font \`${fontFamily}\`.\nAvailable styles: ${(0, format_available_values_1.formatAvailableValues)(fontStyles)}`);
}
});
if (!constants_1.allowedDisplayValues.includes(display)) {
(0, next_font_error_1.nextFontError)(`Invalid display value \`${display}\` for font \`${fontFamily}\`.\nAvailable display values: ${(0, format_available_values_1.formatAvailableValues)(constants_1.allowedDisplayValues)}`);
}
if (weights[0] !== 'variable' && axes) {
(0, next_font_error_1.nextFontError)('Axes can only be defined for variable fonts');
}
return {
fontFamily,
weights,
styles,
display,
preload,
selectedVariableAxes: axes,
fallback,
adjustFontFallback,
variable,
subsets,
};
}
exports.validateGoogleFontFunctionCall = validateGoogleFontFunctionCall;
@@ -1 +0,0 @@
export {};
@@ -1,75 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validate_google_font_function_call_1 = require("./validate-google-font-function-call");
describe('validateFontFunctionCall errors', () => {
test('Missing function name', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('', // default import
undefined)).toThrowErrorMatchingInlineSnapshot(`"next/font/google has no default export"`);
});
test('Unknown font', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Unknown_Font', undefined)).toThrowErrorMatchingInlineSnapshot(`"Unknown font \`Unknown Font\`"`);
});
test('Unknown weight', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Inter', {
weight: '123',
subsets: ['latin'],
})).toThrowErrorMatchingInlineSnapshot(`
"Unknown weight \`123\` for font \`Inter\`.
Available weights: \`100\`, \`200\`, \`300\`, \`400\`, \`500\`, \`600\`, \`700\`, \`800\`, \`900\`, \`variable\`"
`);
});
test('Missing weight for non variable font', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Abel', { subsets: ['latin'] }))
.toThrowErrorMatchingInlineSnapshot(`
"Missing weight for font \`Abel\`.
Available weights: \`400\`"
`);
});
test('Unknown style', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Molle', {
weight: '400',
style: 'normal',
subsets: ['latin'],
})).toThrowErrorMatchingInlineSnapshot(`
"Unknown style \`normal\` for font \`Molle\`.
Available styles: \`italic\`"
`);
});
test('Invalid display value', () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Inter', {
display: 'Invalid',
subsets: ['latin'],
})).toThrowErrorMatchingInlineSnapshot(`
"Invalid display value \`Invalid\` for font \`Inter\`.
Available display values: \`auto\`, \`block\`, \`swap\`, \`fallback\`, \`optional\`"
`);
});
test('Variable in weight array', async () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Inter', {
weight: ['100', 'variable'],
subsets: ['latin'],
})).toThrowErrorMatchingInlineSnapshot(`"Unexpected \`variable\` in weight array for font \`Inter\`. You only need \`variable\`, it includes all available weights."`);
});
test('Invalid subset in call', async () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Inter', { subsets: ['latin', 'oops'] })).toThrowErrorMatchingInlineSnapshot(`
"Unknown subset \`oops\` for font \`Inter\`.
Available subsets: \`cyrillic\`, \`cyrillic-ext\`, \`greek\`, \`greek-ext\`, \`latin\`, \`latin-ext\`, \`vietnamese\`"
`);
});
test('Missing subsets in config and call', async () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Inter', {}))
.toThrowErrorMatchingInlineSnapshot(`
"Preload is enabled but no subsets were specified for font \`Inter\`. Please specify subsets or disable preloading if your intended subset can't be preloaded.
Available subsets: \`cyrillic\`, \`cyrillic-ext\`, \`greek\`, \`greek-ext\`, \`latin\`, \`latin-ext\`, \`vietnamese\`
Read more: https://nextjs.org/docs/messages/google-fonts-missing-subsets"
`);
});
test('Setting axes on non variable font', async () => {
expect(() => (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)('Abel', {
weight: '400',
axes: [],
subsets: ['latin'],
})).toThrowErrorMatchingInlineSnapshot(`"Axes can only be defined for variable fonts"`);
});
});
@@ -1,18 +0,0 @@
import type { Font } from 'fontkit';
import type { AdjustFontFallback } from 'next/font';
/**
* Given a font file and category, calculate the fallback font override values.
* The returned values can be used to generate a CSS @font-face declaration.
*
* For example:
* @font-face {
* font-family: local-font;
* src: local(Arial);
* size-adjust: 90%;
* }
*
* Read more about this technique in these texts by the Google Aurora team:
* https://developer.chrome.com/blog/font-fallbacks/
* https://docs.google.com/document/d/e/2PACX-1vRsazeNirATC7lIj2aErSHpK26hZ6dA9GsQ069GEbq5fyzXEhXbvByoftSfhG82aJXmrQ_sJCPBqcx_/pub
*/
export declare function getFallbackMetricsFromFontFile(font: Font, category?: string): AdjustFontFallback;
@@ -1,86 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFallbackMetricsFromFontFile = void 0;
// The font metadata of the fallback fonts, retrieved with fontkit on system font files
// The average width is calculated with the calcAverageWidth function below
const DEFAULT_SANS_SERIF_FONT = {
name: 'Arial',
azAvgWidth: 934.5116279069767,
unitsPerEm: 2048,
};
const DEFAULT_SERIF_FONT = {
name: 'Times New Roman',
azAvgWidth: 854.3953488372093,
unitsPerEm: 2048,
};
/**
* Calculate the average character width of a font file.
* Used to calculate the size-adjust property by comparing the fallback average with the loaded font average.
*/
function calcAverageWidth(font) {
try {
/**
* Finding the right characters to use when calculating the average width is tricky.
* We can't just use the average width of all characters, because we have to take letter frequency into account.
* We also have to take word length into account, because the font's space width usually differ a lot from other characters.
* The goal is to find a string that'll give you a good average width, given most texts in most languages.
*
* TODO: Currently only works for the latin alphabet. Support more languages by finding the right characters for additional languages.
*
* The used characters were decided through trial and error with letter frequency and word length tables as a guideline.
* E.g. https://en.wikipedia.org/wiki/Letter_frequency
*/
const avgCharacters = 'aaabcdeeeefghiijklmnnoopqrrssttuvwxyz ';
// Check if the font file has all the characters we need to calculate the average width
const hasAllChars = font
.glyphsForString(avgCharacters)
.flatMap((glyph) => glyph.codePoints)
.every((codePoint) => font.hasGlyphForCodePoint(codePoint));
if (!hasAllChars)
return undefined;
const widths = font
.glyphsForString(avgCharacters)
.map((glyph) => glyph.advanceWidth);
const totalWidth = widths.reduce((sum, width) => sum + width, 0);
return totalWidth / widths.length;
}
catch {
// Could not calculate average width from the font file, skip size-adjust
return undefined;
}
}
function formatOverrideValue(val) {
return Math.abs(val * 100).toFixed(2) + '%';
}
/**
* Given a font file and category, calculate the fallback font override values.
* The returned values can be used to generate a CSS @font-face declaration.
*
* For example:
* @font-face {
* font-family: local-font;
* src: local(Arial);
* size-adjust: 90%;
* }
*
* Read more about this technique in these texts by the Google Aurora team:
* https://developer.chrome.com/blog/font-fallbacks/
* https://docs.google.com/document/d/e/2PACX-1vRsazeNirATC7lIj2aErSHpK26hZ6dA9GsQ069GEbq5fyzXEhXbvByoftSfhG82aJXmrQ_sJCPBqcx_/pub
*/
function getFallbackMetricsFromFontFile(font, category = 'serif') {
const fallbackFont = category === 'serif' ? DEFAULT_SERIF_FONT : DEFAULT_SANS_SERIF_FONT;
const azAvgWidth = calcAverageWidth(font);
const { ascent, descent, lineGap, unitsPerEm } = font;
const fallbackFontAvgWidth = fallbackFont.azAvgWidth / fallbackFont.unitsPerEm;
let sizeAdjust = azAvgWidth
? azAvgWidth / unitsPerEm / fallbackFontAvgWidth
: 1;
return {
ascentOverride: formatOverrideValue(ascent / (unitsPerEm * sizeAdjust)),
descentOverride: formatOverrideValue(descent / (unitsPerEm * sizeAdjust)),
lineGapOverride: formatOverrideValue(lineGap / (unitsPerEm * sizeAdjust)),
fallbackFont: fallbackFont.name,
sizeAdjust: formatOverrideValue(sizeAdjust),
};
}
exports.getFallbackMetricsFromFontFile = getFallbackMetricsFromFontFile;
-21
View File
@@ -1,21 +0,0 @@
import type { CssVariable, Display, NextFont, NextFontWithVariable } from '../types';
type LocalFont<T extends CssVariable | undefined = undefined> = {
src: string | Array<{
path: string;
weight?: string;
style?: string;
}>;
display?: Display;
weight?: string;
style?: string;
adjustFontFallback?: 'Arial' | 'Times New Roman' | false;
fallback?: string[];
preload?: boolean;
variable?: T;
declarations?: Array<{
prop: string;
value: string;
}>;
};
export default function localFont<T extends CssVariable | undefined = undefined>(options: LocalFont<T>): T extends undefined ? NextFont : NextFontWithVariable;
export {};
-6
View File
@@ -1,6 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function localFont(options) {
throw new Error();
}
exports.default = localFont;
-3
View File
@@ -1,3 +0,0 @@
import type { FontLoader } from 'next/font';
declare const nextFontLocalFontLoader: FontLoader;
export default nextFontLocalFontLoader;
-75
View File
@@ -1,75 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
// eslint-disable-next-line import/no-extraneous-dependencies
let fontFromBuffer;
try {
const mod = require('../fontkit').default;
fontFromBuffer = mod.default || mod;
}
catch { }
const util_1 = require("util");
const pick_font_file_for_fallback_generation_1 = require("./pick-font-file-for-fallback-generation");
const get_fallback_metrics_from_font_file_1 = require("./get-fallback-metrics-from-font-file");
const validate_local_font_function_call_1 = require("./validate-local-font-function-call");
const nextFontLocalFontLoader = async ({ functionName, variableName, data, emitFontFile, resolve, loaderContext, }) => {
const { src, display, fallback, preload, variable, adjustFontFallback, declarations, weight: defaultWeight, style: defaultStyle, } = (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)(functionName, data[0]);
// Load all font files and emit them to the .next output directory
// Also generate a @font-face CSS for each font file
const fontFiles = await Promise.all(src.map(async ({ path, style, weight, ext, format }) => {
const resolved = await resolve(path);
const fileBuffer = await (0, util_1.promisify)(loaderContext.fs.readFile)(resolved);
const fontUrl = emitFontFile(fileBuffer, ext, preload, typeof adjustFontFallback === 'undefined' || !!adjustFontFallback);
// Try to load font metadata from the font file using fontkit.
// The data is used to calculate the fallback font override values.
let fontMetadata;
try {
fontMetadata = fontFromBuffer === null || fontFromBuffer === void 0 ? void 0 : fontFromBuffer(fileBuffer);
}
catch (e) {
console.error(`Failed to load font file: ${resolved}\n${e}`);
}
// Get all values that should be added to the @font-face declaration
const fontFaceProperties = [
...(declarations
? declarations.map(({ prop, value }) => [prop, value])
: []),
['font-family', variableName],
['src', `url(${fontUrl}) format('${format}')`],
['font-display', display],
...((weight !== null && weight !== void 0 ? weight : defaultWeight)
? [['font-weight', weight !== null && weight !== void 0 ? weight : defaultWeight]]
: []),
...((style !== null && style !== void 0 ? style : defaultStyle)
? [['font-style', style !== null && style !== void 0 ? style : defaultStyle]]
: []),
];
// Generate the @font-face CSS from the font-face properties
const css = `@font-face {\n${fontFaceProperties
.map(([property, value]) => `${property}: ${value};`)
.join('\n')}\n}\n`;
return {
css,
fontMetadata,
weight,
style,
};
}));
// Calculate the fallback font override values using the font file metadata
let adjustFontFallbackMetrics;
if (adjustFontFallback !== false) {
const fallbackFontFile = (0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)(fontFiles);
if (fallbackFontFile.fontMetadata) {
adjustFontFallbackMetrics = (0, get_fallback_metrics_from_font_file_1.getFallbackMetricsFromFontFile)(fallbackFontFile.fontMetadata, adjustFontFallback === 'Times New Roman' ? 'serif' : 'sans-serif');
}
}
return {
css: fontFiles.map(({ css }) => css).join('\n'),
fallbackFonts: fallback,
weight: src.length === 1 ? src[0].weight : undefined,
style: src.length === 1 ? src[0].style : undefined,
variable,
adjustFontFallback: adjustFontFallbackMetrics,
};
};
exports.default = nextFontLocalFontLoader;
-1
View File
@@ -1 +0,0 @@
export {};
-228
View File
@@ -1,228 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const loader_1 = __importDefault(require("./loader"));
describe('next/font/local loader', () => {
describe('generated CSS', () => {
test('Default CSS', async () => {
const { css } = await (0, loader_1.default)({
functionName: '',
data: [{ src: './my-font.woff2' }],
emitFontFile: () => '/_next/static/media/my-font.woff2',
resolve: jest.fn(),
isDev: false,
isServer: true,
variableName: 'myFont',
loaderContext: {
fs: {
readFile: (_, cb) => cb(null, 'fontdata'),
},
},
});
expect(css).toMatchInlineSnapshot(`
"@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
}
"
`);
});
test('Weight and style', async () => {
const { css } = await (0, loader_1.default)({
functionName: '',
data: [{ src: './my-font.woff2', weight: '100 900', style: 'italic' }],
emitFontFile: () => '/_next/static/media/my-font.woff2',
resolve: jest.fn(),
isDev: false,
isServer: true,
variableName: 'myFont',
loaderContext: {
fs: {
readFile: (_, cb) => cb(null, 'fontdata'),
},
},
});
expect(css).toMatchInlineSnapshot(`
"@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 100 900;
font-style: italic;
}
"
`);
});
test('Other properties', async () => {
const { css } = await (0, loader_1.default)({
functionName: '',
data: [
{
src: './my-font.woff2',
declarations: [
{ prop: 'font-feature-settings', value: '"smcp" on' },
{ prop: 'ascent-override', value: '90%' },
],
},
],
emitFontFile: () => '/_next/static/media/my-font.woff2',
resolve: jest.fn(),
isDev: false,
isServer: true,
variableName: 'myFont',
loaderContext: {
fs: {
readFile: (_, cb) => cb(null, 'fontdata'),
},
},
});
expect(css).toMatchInlineSnapshot(`
"@font-face {
font-feature-settings: "smcp" on;
ascent-override: 90%;
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
}
"
`);
});
test('Multiple weights default style', async () => {
const { css } = await (0, loader_1.default)({
functionName: '',
data: [
{
style: 'italic',
src: [
{
path: './fonts/font1.woff2',
weight: '100',
},
{
path: './fonts/font2.woff2',
weight: '400',
},
{
path: './fonts/font3.woff2',
weight: '700',
},
{
path: './fonts/font2.woff2',
weight: '400',
style: 'normal',
},
],
adjustFontFallback: false,
},
],
emitFontFile: () => `/_next/static/media/my-font.woff2`,
resolve: jest.fn(),
isDev: false,
isServer: true,
variableName: 'myFont',
loaderContext: {
fs: {
readFile: (path, cb) => cb(null, path),
},
},
});
expect(css).toMatchInlineSnapshot(`
"@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 100;
font-style: italic;
}
@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 400;
font-style: normal;
}
"
`);
});
test('Multiple styles default weight', async () => {
const { css } = await (0, loader_1.default)({
functionName: '',
data: [
{
weight: '400',
src: [
{
path: './fonts/font1.woff2',
style: 'normal',
},
{
path: './fonts/font3.woff2',
style: 'italic',
},
{
path: './fonts/font2.woff2',
weight: '700',
},
],
adjustFontFallback: false,
},
],
emitFontFile: () => `/_next/static/media/my-font.woff2`,
resolve: jest.fn(),
isDev: false,
isServer: true,
variableName: 'myFont',
loaderContext: {
fs: {
readFile: (path, cb) => cb(null, path),
},
},
});
expect(css).toMatchInlineSnapshot(`
"@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: myFont;
src: url(/_next/static/media/my-font.woff2) format('woff2');
font-display: swap;
font-weight: 700;
}
"
`);
});
});
});
@@ -1,13 +0,0 @@
/**
* If multiple font files are provided for a font family, we need to pick one to use for the automatic fallback generation.
* This function returns the font file that is most likely to be used for the bulk of the text on a page.
*
* There are some assumptions here about the text on a page when picking the font file:
* - Most of the text will have normal weight, use the one closest to 400
* - Most of the text will have normal style, prefer normal over italic
* - If two font files have the same distance from normal weight, the thinner one will most likely be the bulk of the text
*/
export declare function pickFontFileForFallbackGeneration<T extends {
style?: string;
weight?: string;
}>(fontFiles: T[]): T;
@@ -1,86 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pickFontFileForFallbackGeneration = void 0;
const next_font_error_1 = require("../next-font-error");
const NORMAL_WEIGHT = 400;
const BOLD_WEIGHT = 700;
/**
* Convert the weight string to a number so it can be used for comparison.
* Weights can be defined as a number, 'normal' or 'bold'. https://developer.mozilla.org/docs/Web/CSS/@font-face/font-weight
*/
function getWeightNumber(weight) {
return weight === 'normal'
? NORMAL_WEIGHT
: weight === 'bold'
? BOLD_WEIGHT
: Number(weight);
}
/**
* Get the distance from normal (400) weight for the provided weight.
* If it's not a variable font we can just return the distance.
* If it's a variable font we need to compare its weight range to 400.
*/
function getDistanceFromNormalWeight(weight) {
if (!weight)
return 0;
// If it's a variable font the weight is defined with two numbers "100 900", rather than just one "400"
const [firstWeight, secondWeight] = weight
.trim()
.split(/ +/)
.map(getWeightNumber);
if (Number.isNaN(firstWeight) || Number.isNaN(secondWeight)) {
(0, next_font_error_1.nextFontError)(`Invalid weight value in src array: \`${weight}\`.\nExpected \`normal\`, \`bold\` or a number.`);
}
// If the weight doesn't have have a second value, it's not a variable font
// If that's the case, just return the distance from normal weight
if (!secondWeight) {
return firstWeight - NORMAL_WEIGHT;
}
// Normal weight is within variable font range
if (firstWeight <= NORMAL_WEIGHT && secondWeight >= NORMAL_WEIGHT) {
return 0;
}
// Normal weight is outside variable font range
// Return the distance of normal weight to the variable font range
const firstWeightDistance = firstWeight - NORMAL_WEIGHT;
const secondWeightDistance = secondWeight - NORMAL_WEIGHT;
if (Math.abs(firstWeightDistance) < Math.abs(secondWeightDistance)) {
return firstWeightDistance;
}
return secondWeightDistance;
}
/**
* If multiple font files are provided for a font family, we need to pick one to use for the automatic fallback generation.
* This function returns the font file that is most likely to be used for the bulk of the text on a page.
*
* There are some assumptions here about the text on a page when picking the font file:
* - Most of the text will have normal weight, use the one closest to 400
* - Most of the text will have normal style, prefer normal over italic
* - If two font files have the same distance from normal weight, the thinner one will most likely be the bulk of the text
*/
function pickFontFileForFallbackGeneration(fontFiles) {
return fontFiles.reduce((usedFontFile, currentFontFile) => {
if (!usedFontFile)
return currentFontFile;
const usedFontDistance = getDistanceFromNormalWeight(usedFontFile.weight);
const currentFontDistance = getDistanceFromNormalWeight(currentFontFile.weight);
// Prefer normal style if they have the same weight
if (usedFontDistance === currentFontDistance &&
(typeof currentFontFile.style === 'undefined' ||
currentFontFile.style === 'normal')) {
return currentFontFile;
}
const absUsedDistance = Math.abs(usedFontDistance);
const absCurrentDistance = Math.abs(currentFontDistance);
// Use closest absolute distance to normal weight
if (absCurrentDistance < absUsedDistance)
return currentFontFile;
// Prefer the thinner font if both have the same absolute distance from normal weight
if (absUsedDistance === absCurrentDistance &&
currentFontDistance < usedFontDistance) {
return currentFontFile;
}
return usedFontFile;
});
}
exports.pickFontFileForFallbackGeneration = pickFontFileForFallbackGeneration;
@@ -1 +0,0 @@
export {};
@@ -1,113 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const pick_font_file_for_fallback_generation_1 = require("./pick-font-file-for-fallback-generation");
describe('pickFontFileForFallbackGeneration', () => {
it('should pick the weight closest to 400', () => {
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{
weight: '300',
},
{
weight: '600',
},
])).toEqual({
weight: '300',
});
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ weight: '200' },
{
weight: '500',
},
])).toEqual({
weight: '500',
});
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{
weight: 'normal',
},
{
weight: '700',
},
])).toEqual({
weight: 'normal',
});
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{
weight: 'bold',
},
{
weight: '900',
},
])).toEqual({
weight: 'bold',
});
});
it('should pick the thinner weight if both have the same distance to 400', () => {
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{
weight: '300',
},
{
weight: '500',
},
])).toEqual({
weight: '300',
});
});
it('should pick variable range closest to 400', () => {
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{
weight: '100 300',
},
{
weight: '600 900',
},
])).toEqual({
weight: '100 300',
});
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ weight: '100 200' },
{
weight: '500 800',
},
])).toEqual({
weight: '500 800',
});
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ weight: '100 900' },
{
weight: '300 399',
},
])).toEqual({
weight: '100 900',
});
});
it('should prefer normal style over italic', () => {
expect((0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ weight: '400', style: 'normal' },
{ weight: '400', style: 'italic' },
])).toEqual({ weight: '400', style: 'normal' });
});
it('should error on invalid weight in array', async () => {
expect(() => (0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ path: './font1.woff2', weight: 'normal bold' },
{ path: './font2.woff2', weight: '400 bold' },
{ path: './font3.woff2', weight: 'normal 700' },
{ path: './font4.woff2', weight: '100 abc' },
])).toThrowErrorMatchingInlineSnapshot(`
"Invalid weight value in src array: \`100 abc\`.
Expected \`normal\`, \`bold\` or a number."
`);
});
test('Invalid variable weight in array', async () => {
expect(() => (0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)([
{ path: './font1.woff2', weight: 'normal bold' },
{ path: './font2.woff2', weight: '400 bold' },
{ path: './font3.woff2', weight: 'normal 700' },
{ path: './font4.woff2', weight: '100 abc' },
])).toThrowErrorMatchingInlineSnapshot(`
"Invalid weight value in src array: \`100 abc\`.
Expected \`normal\`, \`bold\` or a number."
`);
});
});
@@ -1,25 +0,0 @@
type FontOptions = {
src: Array<{
path: string;
weight?: string;
style?: string;
ext: string;
format: string;
}>;
display: string;
weight?: string;
style?: string;
fallback?: string[];
preload: boolean;
variable?: string;
adjustFontFallback?: string | false;
declarations?: Array<{
prop: string;
value: string;
}>;
};
/**
* Validate the data recieved from next-swc next-transform-font on next/font/local calls
*/
export declare function validateLocalFontFunctionCall(functionName: string, fontData: any): FontOptions;
export {};
@@ -1,73 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateLocalFontFunctionCall = void 0;
const constants_1 = require("../constants");
const format_available_values_1 = require("../format-available-values");
const next_font_error_1 = require("../next-font-error");
const extToFormat = {
woff: 'woff',
woff2: 'woff2',
ttf: 'truetype',
otf: 'opentype',
eot: 'embedded-opentype',
};
/**
* Validate the data recieved from next-swc next-transform-font on next/font/local calls
*/
function validateLocalFontFunctionCall(functionName, fontData) {
if (functionName) {
(0, next_font_error_1.nextFontError)(`next/font/local has no named exports`);
}
let { src, display = 'swap', weight, style, fallback, preload = true, variable, adjustFontFallback, declarations, } = fontData || {};
if (!constants_1.allowedDisplayValues.includes(display)) {
(0, next_font_error_1.nextFontError)(`Invalid display value \`${display}\`.\nAvailable display values: ${(0, format_available_values_1.formatAvailableValues)(constants_1.allowedDisplayValues)}`);
}
if (!src) {
(0, next_font_error_1.nextFontError)('Missing required `src` property');
}
if (!Array.isArray(src)) {
src = [{ path: src, weight, style }];
}
else {
if (src.length === 0) {
(0, next_font_error_1.nextFontError)('Unexpected empty `src` array.');
}
}
src = src.map((fontFile) => {
var _a;
const ext = (_a = /\.(woff|woff2|eot|ttf|otf)$/.exec(fontFile.path)) === null || _a === void 0 ? void 0 : _a[1];
if (!ext) {
(0, next_font_error_1.nextFontError)(`Unexpected file \`${fontFile.path}\``);
}
return {
...fontFile,
ext,
format: extToFormat[ext],
};
});
if (Array.isArray(declarations)) {
declarations.forEach((declaration) => {
if ([
'font-family',
'src',
'font-display',
'font-weight',
'font-style',
].includes(declaration === null || declaration === void 0 ? void 0 : declaration.prop)) {
(0, next_font_error_1.nextFontError)(`Invalid declaration prop: \`${declaration.prop}\``);
}
});
}
return {
src,
display,
weight,
style,
fallback,
preload,
variable,
adjustFontFallback,
declarations,
};
}
exports.validateLocalFontFunctionCall = validateLocalFontFunctionCall;
@@ -1 +0,0 @@
export {};
@@ -1,34 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validate_local_font_function_call_1 = require("./validate-local-font-function-call");
describe('validateLocalFontFunctionCall', () => {
test('Not using default export', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('Named', {})).toThrowErrorMatchingInlineSnapshot(`"next/font/local has no named exports"`);
});
test('Missing src', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('', {})).toThrowErrorMatchingInlineSnapshot(`"Missing required \`src\` property"`);
});
test('Invalid file extension', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('', { src: './font/font-file.abc' })).toThrowErrorMatchingInlineSnapshot(`"Unexpected file \`./font/font-file.abc\`"`);
});
test('Invalid display value', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('', {
src: './font-file.woff2',
display: 'invalid',
})).toThrowErrorMatchingInlineSnapshot(`
"Invalid display value \`invalid\`.
Available display values: \`auto\`, \`block\`, \`swap\`, \`fallback\`, \`optional\`"
`);
});
test('Invalid declaration', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('', {
src: './font-file.woff2',
declarations: [{ prop: 'src', value: '/hello.woff2' }],
})).toThrowErrorMatchingInlineSnapshot(`"Invalid declaration prop: \`src\`"`);
});
test('Empty src array', async () => {
expect(() => (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)('', {
src: [],
})).toThrowErrorMatchingInlineSnapshot(`"Unexpected empty \`src\` array."`);
});
});
-4
View File
@@ -1,4 +0,0 @@
/**
* Throw NextFontError error. Used by the WellKnownErrorsPlugin to format errors thrown by next/font.
*/
export declare function nextFontError(message: string): never;
-12
View File
@@ -1,12 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nextFontError = void 0;
/**
* Throw NextFontError error. Used by the WellKnownErrorsPlugin to format errors thrown by next/font.
*/
function nextFontError(message) {
const err = new Error(message);
err.name = 'NextFontError';
throw err;
}
exports.nextFontError = nextFontError;
-13
View File
@@ -1,13 +0,0 @@
export type CssVariable = `--${string}`;
export type Display = 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
export type NextFont = {
className: string;
style: {
fontFamily: string;
fontWeight?: number;
fontStyle?: string;
};
};
export type NextFontWithVariable = NextFont & {
variable: string;
};
-2
View File
@@ -1,2 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-1
View File
@@ -1 +0,0 @@
export * from '../dist/google'
-15
View File
@@ -1,15 +0,0 @@
// Validate next version
const semver = require('next/dist/compiled/semver')
if (semver.lt(require('next/package.json').version, '13.0.0')) {
throw new Error('`@next/font` is only available in Next.js 13 and newer.')
}
let message = '@next/font/google failed to run or is incorrectly configured.'
if (process.env.NODE_ENV === 'development') {
message +=
'\nIf you just installed `@next/font`, please try restarting `next dev` and resaving your file.'
}
message += `\n\nRead more: https://nextjs.org/docs/basic-features/font-optimization`
throw new Error(message)
-1
View File
@@ -1 +0,0 @@
export { default } from '../dist/google/loader'
-1
View File
@@ -1 +0,0 @@
module.exports = require('../dist/google/loader')
-1
View File
@@ -1 +0,0 @@
/* target file for webpack loader */
-1
View File
@@ -1 +0,0 @@
export { default } from '../dist/local/index'
-15
View File
@@ -1,15 +0,0 @@
// Validate next version
const semver = require('next/dist/compiled/semver')
if (semver.lt(require('next/package.json').version, '13.0.0')) {
throw new Error('`@next/font` is only available in Next.js 13 and newer.')
}
let message = '@next/font/local failed to run or is incorrectly configured.'
if (process.env.NODE_ENV === 'development') {
message +=
'\nIf you just installed `@next/font`, please try restarting `next dev` and resaving your file.'
}
message += `\n\nRead more: https://nextjs.org/docs/basic-features/font-optimization`
throw new Error(message)
-1
View File
@@ -1 +0,0 @@
export { default } from '../dist/local/loader'
-1
View File
@@ -1 +0,0 @@
module.exports = require('../dist/local/loader')
-1
View File
@@ -1 +0,0 @@
/* target file for webpack loader */
-30
View File
@@ -1,30 +0,0 @@
{
"name": "@next/font",
"version": "14.2.15",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
},
"types": "dist/types.d.ts",
"files": [
"dist",
"google",
"local"
],
"license": "MIT",
"scripts": {
"build": "node ../../scripts/rm.mjs dist && pnpm ncc-fontkit && tsc -d -p tsconfig.json",
"prepublishOnly": "cd ../../ && turbo run build",
"dev": "pnpm ncc-fontkit && tsc -d -w -p tsconfig.json",
"typescript": "tsec --noEmit -p tsconfig.json",
"ncc-fontkit": "ncc build ./fontkit.js --minify -o dist/fontkit"
},
"devDependencies": {
"@types/fontkit": "2.0.0",
"@vercel/ncc": "0.34.0",
"fontkit": "2.0.2"
},
"peerDependencies": {
"next": "*"
}
}
-3
View File
@@ -1,3 +0,0 @@
# `@next/swc-linux-x64-gnu`
This is the **x86_64-unknown-linux-gnu** binary for `@next/swc`
Binary file not shown.
-26
View File
@@ -1,26 +0,0 @@
{
"name": "@next/swc-linux-x64-gnu",
"version": "15.3.4",
"repository": {
"type": "git",
"url": "https://github.com/vercel/next.js",
"directory": "crates/napi/npm/linux-x64-gnu"
},
"os": [
"linux"
],
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"main": "next-swc.linux-x64-gnu.node",
"files": [
"next-swc.linux-x64-gnu.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}
-7
View File
@@ -1,7 +0,0 @@
# @swc/counter
## 0.1.3
### Patch Changes
- a87f28d: Refactoring for @swc/counter

Some files were not shown because too many files have changed in this diff Show More