diff --git a/src/assets/index.ts b/src/assets/index.ts deleted file mode 100644 index cd0fecbd1..000000000 --- a/src/assets/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react'; -import { - FaBookOpen as ApiReferenceIcon, - FaCloud as WebServiceIcon, - FaCogs as IntegrationsIcon, - FaDatabase as DatabaseIcon, - FaFileCsv as CsvIcon, - FaMapMarkedAlt as GeolocateIAddressIcon, -} from 'react-icons/fa'; - -import GeoIPIcon from './svgs/geoip-icon.svg'; -import MinFraudIcon from './svgs/minfraud-icon.svg'; - -export const Icons: Record>> = { - ApiReferenceIcon, - CsvIcon, - DatabaseIcon, - GeoIPIcon, - GeolocateIAddressIcon, - IntegrationsIcon, - MinFraudIcon, - WebServiceIcon, -}; diff --git a/src/assets/svgs/geoip-icon.svg b/src/assets/svgs/geoip-icon.svg deleted file mode 100644 index afb9461af..000000000 --- a/src/assets/svgs/geoip-icon.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/svgs/icon-ccpa-opt-out.svg b/src/assets/svgs/icon-ccpa-opt-out.svg deleted file mode 100644 index 69336d465..000000000 --- a/src/assets/svgs/icon-ccpa-opt-out.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/svgs/maxmind-footer-logo.svg b/src/assets/svgs/maxmind-footer-logo.svg deleted file mode 100644 index c25e8f93f..000000000 --- a/src/assets/svgs/maxmind-footer-logo.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/assets/svgs/maxmind-logo.svg b/src/assets/svgs/maxmind-logo.svg deleted file mode 100644 index 20f766c2e..000000000 --- a/src/assets/svgs/maxmind-logo.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/svgs/minfraud-icon.svg b/src/assets/svgs/minfraud-icon.svg deleted file mode 100644 index 6ede5f177..000000000 --- a/src/assets/svgs/minfraud-icon.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/src/assets/svgs/under-construction.svg b/src/assets/svgs/under-construction.svg deleted file mode 100644 index 758750941..000000000 --- a/src/assets/svgs/under-construction.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/baseQuery.ts b/src/baseQuery.ts deleted file mode 100644 index ede11336d..000000000 --- a/src/baseQuery.ts +++ /dev/null @@ -1,29 +0,0 @@ -export interface IBaseQuery { - fields: { - slug: string; - }; - fileAbsolutePath: string; - frontmatter: { - description: string; - draft: boolean; - image: string; - keywords: string[]; - title: string; - }; -} - -export const BaseQuery = ` - fragment BaseQuery on Mdx { - fields { - slug - } - fileAbsolutePath - frontmatter { - title - description - image - keywords - draft - } - } -`; diff --git a/src/components/Alert.module.scss b/src/components/Alert.module.scss deleted file mode 100644 index 5fe6e8f48..000000000 --- a/src/components/Alert.module.scss +++ /dev/null @@ -1,85 +0,0 @@ -@use '../styles/variables'; - -.alert { - --mm-color-primary-text: #444; - --mm-spacing: 20px; - - background: linear-gradient(#fff, var(--mm-color-sidebar)); - border: 1px solid #eee; - border-bottom: 1px solid #ddd; - border-left: 6px solid #7eadda; - border-radius: 0 var(--mm-border-radius) var(--mm-border-radius) 0; - border-top: 1px solid rgb(245, 245, 245); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - color: var(--mm-color-primary-text); - display: flex; - margin: calc(var(--mm-spacing) * 2) 0; - padding-left: calc(var(--mm-spacing) / 2); - position: relative; -} - -.iconWrapper { - background: var(--mm-color-active-blue); - border-radius: 50%; - display: grid; - height: 35px; - left: -2px; - overflow: hidden; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); - width: 35px; - z-index: 3; - - &::before { - border-radius: 50%; - box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.35); - content: ' '; - display: block; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: -1; - } -} - -.icon { - align-self: center; - color: #fff; - font-size: 14px; - justify-self: center; -} - -.content { - padding: 0 var(--mm-spacing); -} - -.content * { - font-size: 14px !important; -} - -.error { - border-left-color: #f09791; -} - -.error .iconWrapper { - background: #e9594c; -} - -.success { - border-left-color: #87d8aa; -} - -.success .iconWrapper { - background: #3ac279; -} - -.warning { - border-left-color: rgba(232, 159, 41, 1); -} - -.warning .iconWrapper { - background: #e89f29; -} diff --git a/src/components/Alert.tsx b/src/components/Alert.tsx deleted file mode 100644 index c11021fb1..000000000 --- a/src/components/Alert.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import { IconType } from 'react-icons'; -import { - FaCheck, - FaExclamation, - FaInfo, - FaTimes, -} from 'react-icons/fa'; - -// eslint-disable-next-line css-modules/no-unused-class -import * as styles from './Alert.module.scss'; - -interface IAlert { - children: React.ReactNode, - type: 'error' | 'info' | 'success' | 'warning', -} - -const Alert: React.FC = (props) => { - const { children, type } = props; - let Icon: IconType; - - switch(type) { - case 'error': - Icon = FaTimes; - break; - case 'success': - Icon = FaCheck; - break; - case 'warning': - Icon = FaExclamation; - break; - case 'info': - Icon = FaInfo; - break; - } - - return ( -
-
- -
-
- {children} -
-
- ); -}; - -Alert.defaultProps = { - type: 'info', -}; - -Alert.propTypes = { - children: PropTypes.node.isRequired, - type: PropTypes.oneOf([ - 'error', - 'info', - 'success', - 'warning', - ] as const).isRequired, -}; - -export default Alert; diff --git a/src/components/CsvBlockTable.tsx b/src/components/CsvBlockTable.tsx deleted file mode 100644 index 390c4dc68..000000000 --- a/src/components/CsvBlockTable.tsx +++ /dev/null @@ -1,565 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { - a as A, - inlineCode as Code, - li as Li, - strong as Strong, - table as Table, - td as Td, - th as Th, - tr as Tr, - ul as Ul, -} from './Mdx'; -import ServiceTag from './Schema/ServiceTag'; - -interface ICsvBlockTable { - isEnterprise?: boolean; -} - -const CsvBlockTable: React.FC = (props) => { - const { isEnterprise } = props; - return ( - - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - { isEnterprise && ( - <> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - )} - - - - - { !isEnterprise && ( - - )} - - -
NameTypeDescriptionIncluded in...
networkIP network as a string - This is the IPv4 or IPv6 network in CIDR format such as - "2.21.92.0/29" or "2001:4b0::/80". We offer a - utility to convert this column to start/end IPs or start/end - integers. See - {' '} - - the conversion utility - section - - {' '} - for details. - - - -
geoname_idinteger - A unique identifier for the network's location as specified - by - {' '} - - GeoNames - - . This ID can be - used to look up the location information in the Location file. -
-
- - Learn more about GeoNames IDs on our Knowledge Base. - -
- - -
registered_country_geoname_idinteger - The registered country is the country in which the ISP has - registered the network. This column contains a unique identifier - for the network's registered country as specified - by - {' '} - - GeoNames - - . This ID can be - used to look up the location information in the Location file. -
-
- - Learn more about registered countries on our Knowledge Base. - -
- - -
represented_country_geoname_idinteger - The represented country is the country which is represented by - users of the IP address. For instance, the country represented by - an overseas military base. This column contains a unique - identifier for the network's represented country as specified - by - {' '} - - GeoNames - - . This ID can be - used to look up the location information in the Location file. -
-
- - Learn more about represented countries on our Knowledge Base. - -
- - -
is_anonymous_proxyboolean - Deprecated. - {' '} - Please see our - {' '} - - GeoIP2 Anonymous IP database - - {' '} - to determine whether the IP address is used by an anonymizing - service. - - - -
is_satellite_providerboolean - Deprecated. - - - -
postal_codestring - A postal code close to the user's location. For the following - countries, we return partial postal codes with the number of - characters indicated below: - -
    -
  • United States: 5
  • -
  • Canada: 3
  • -
  • United Kingdom: 2-4
  • -
  • Brazil: 5
  • -
  • Ireland: 3
  • -
  • - Japan: 7 (specified for the first 6. The last digit defaults to - 1) -
  • -
  • Netherlands: 4
  • -
  • - Portugal: 7 (accurate for the first 4. The last 3 often defaults - to - {' '} - -001 - ) -
  • -
  • Singapore: 2
  • -
-
- - -
latitude*decimal - The approximate - {' '} - - WGS84 - - {' '} - latitude of the location associated with the network. -
-
- - Learn about the geolocation area defined by latitude, longitude, - and accuracy radius, on our Knowledge Base. - -
- - -
longitude*decimal - The approximate - {' '} - - WGS84 - - {' '} - longitude of the location associated with the network. -
-
- - Learn about the geolocation area defined by latitude, longitude, - and accuracy radius, on our Knowledge Base. - -
- - -
accuracy_radiusinteger - The radius in kilometers around the specified location where the IP - address is likely to be. -
-
- - Learn about the geolocation area defined by latitude, longitude, - and accuracy radius, on our Knowledge Base. - -
- - -
isp_idinteger - A identifier for the ISP. This ID can be used to look up the - location information in the ISP file. -
-
- - Learn more about ISP data on our Knowledge Base. - -
domainstring - The domain associated with the network. -
-
- - Learn more about domain name data on our Knowledge Base. - -
country_confidencedecimal (1-100) - The confidence that the country was correctly geolocated. -
-
- - Learn more about confidence factors on our Knowledge Base. - -
subdivision_confidencedecimal (1-100) - The confidence that the most specific subdivision was correctly - geolocated. -
-
- - Learn more about confidence factors on our Knowledge Base. - -
city_confidencedecimal (1-100) - The confidence that the city was correctly geolocated. -
-
- - Learn more about confidence factors on our Knowledge Base. - -
postal_confidencedecimal (1-100) - The confidence that the postal code was correctly geolocated. -
-
- - Learn more about confidence factors on our Knowledge Base. - -
is_legitimate_proxyboolean - Deprecated. - {' '} - Use the - {' '} - user_type - {' '} - data to identify traffic from businesses. - {' '} - - Learn more about - {' '} - user_type - {' '} - data on our knowledge base - - . To identify anonymous proxies, you can learn - more about the GeoIP2 Anonymous IP database in - {' '} - - the developer portal - - {' '} - or - {' '} - - our main website - - . -
is_anycastboolean - This is - {' '} - 1 - {' '} - if the network is an - {' '} - - anycast network - - . - { !isEnterprise && ( -
- This column will be empty in GeoLite2-Country and GeoLite2-City. -
- )} -
- - -
- ); -}; - -CsvBlockTable.propTypes = { - isEnterprise: PropTypes.bool, -}; - -export default CsvBlockTable; diff --git a/src/components/CsvExampleFiles.tsx b/src/components/CsvExampleFiles.tsx deleted file mode 100644 index 19d602279..000000000 --- a/src/components/CsvExampleFiles.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { a as A, li as Li, p as P, ul as Ul } from './Mdx'; - -interface IExampleFiles { - files: { - filename: string; - link: string; - }[] -} - -const CsvExampleFiles: React.FC = (props) => { - const { files } = props; - const fileItems = files.map((file) => ( -
  • - - {file.filename} - -
  • - )); - - return ( - <> -

    - We maintain examples of the CSV files as they would be downloaded from - the account portal: -

    - -

    -

      - {fileItems} -
    -

    - - ); -}; - -CsvExampleFiles.propTypes = { - files: PropTypes.array.isRequired, -}; - -export default CsvExampleFiles; diff --git a/src/components/CsvLocationTable.tsx b/src/components/CsvLocationTable.tsx deleted file mode 100644 index 02926b92a..000000000 --- a/src/components/CsvLocationTable.tsx +++ /dev/null @@ -1,454 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { - a as A, - inlineCode as Code, - strong as Strong, - table as Table, - td as Td, - th as Th, - tr as Tr, -} from './Mdx'; -import ServiceTag from './Schema/ServiceTag'; - -interface ICsvLocationTable { - isEnterprise?: boolean; -} - -const CsvLocationTable: React.FC = (props) => { - const { isEnterprise } = props; - return ( - - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - - - - - { !isEnterprise && ( - - )} - - -
    NameTypeDescriptionIncluded in...
    geoname_idinteger - A unique identifier for the a location as specified - by - {' '} - - GeoNames - - . This ID can be - used as a key for the Location file. -
    -
    - - Learn more about GeoNames IDs on our Knowledge Base. - -
    - - -
    locale_codestring - The locale that the names in this row are in. This will always - correspond to the locale name of the file. - - - -
    continent_codestring (2) -

    The continent code for this location. Possible codes are:

    -
      -
    • - AF - {' '} - - Africa -
    • -
    • - AN - {' '} - - Antarctica -
    • -
    • - AS - {' '} - - Asia -
    • -
    • - EU - {' '} - - Europe -
    • -
    • - NA - {' '} - - North America -
    • -
    • - OC - {' '} - - Oceania -
    • -
    • - SA - {' '} - - South America -
    • -
    -
    - - -
    continent_namestring - The continent name for this location in the file's locale. -
    -
    - - Learn more about localized names on our Knowledge Base. - -
    - - -
    country_iso_codestring (2) - A two-character - {' '} - - ISO - 3166-1 - - {' '} - country code for the country associated with the location. - - - -
    country_namestring - The country name for this location in the file's locale. -
    -
    - - Learn more about localized names on our Knowledge Base. - -
    - - -
    subdivision_1_iso_codestring (1-3) - A string of up to three characters containing the region-portion of - the - {' '} - - ISO 3166-2 - - {' '} - code for the first level region associated with the IP address. - Some countries have two levels of subdivisions, in which case this - is the least specific. For example, in the United Kingdom this will - be a country like "England", not a county like - "Devon". - - - -
    subdivision_1_namestring - The subdivision name for this location in the file's locale. - As with the subdivision code, this is the least specific - subdivision for the location. -
    -
    - - Learn more about localized names on our Knowledge Base. - -
    - - -
    subdivision_2_iso_codestring (1-3) - A string of up to three characters containing the region-portion of - the - {' '} - - ISO 3166-2 - - {' '} - code for the second level region associated with the IP address. - Some countries have two levels of subdivisions, in which case this - is the most specific. For example, in the United Kingdom this will - be a a county like "Devon", not a country like - "England". - - - -
    subdivision_2_namestring - The subdivision name for this location in the file's locale. - As with the subdivision code, this is the most specific subdivision - for the location. -
    -
    - - Learn more about localized names on our Knowledge Base. - -
    - - -
    city_namestring - The city name for this location in the file's locale. -
    -
    - - Learn more about localized names on our Knowledge Base. - -
    - - -
    metro_codeinteger - Metro code is a geolocation target code from Google. - - - -
    time_zonestring - The time zone associated with location, as specified by - the - {' '} - - IANA Time Zone - Database - - , e.g., “America/New_York”. - - - -
    is_in_european_unionboolean - This is - {' '} - 1 - {' '} - if the country associated with the location is a member - state of the European Union. It is - {' '} - 0 - {' '} - otherwise. - - - -
    - ); -}; - -CsvLocationTable.propTypes = { - isEnterprise: PropTypes.bool, -}; - -export default CsvLocationTable; diff --git a/src/components/DatabaseChanges.tsx b/src/components/DatabaseChanges.tsx deleted file mode 100644 index 23c7897d4..000000000 --- a/src/components/DatabaseChanges.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { a as A, p as P } from './Mdx'; - -interface IDatabaseName { - product: string; -} - -const DatabaseChanges: React.FC = (props) => { - const { product } = props; - return ( - <> -

    - We may add new data fields to the - {' '} - {product} - {' '} - database at any time. -

    - -

    - New database fields are added as new columns to the right of existing - {' '} - columns in our CSV files, and as additional data in our MMDB files. -

    - -

    - Subscribe to our - {' '} - - GeoIP2 release notes - - {' '} - to be notified when new data is added to our databases. -

    - - ); -}; - -DatabaseChanges.propTypes = { - product: PropTypes.string.isRequired, -}; - -export default DatabaseChanges; diff --git a/src/components/DatabaseSizes.tsx b/src/components/DatabaseSizes.tsx deleted file mode 100644 index 906052e7f..000000000 --- a/src/components/DatabaseSizes.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { li as Li, p as P, table as Table, tbody as Tbody, td as Td, th as Th, thead as Thead, tr as Tr, ul as Ul } from './Mdx'; - -interface IDatabaseSizes { - databaseChanges: { - csvSizeRange: string; - databaseName: string; - ipv4Range: string; - ipv6Range: string; - mmdbSizeRange: string; - }[]; - dateRange: string; -} - -const DatabaseSizes: React.FC = (props) => { - const { databaseChanges , dateRange } = props; - const databaseChangesItems = databaseChanges.map((databaseChange) => ( - <> - - - {databaseChange.databaseName} - - - {databaseChange.csvSizeRange} - - - {databaseChange.mmdbSizeRange} - - - {databaseChange.ipv4Range} - - - {databaseChange.ipv6Range} - - - - )); - return ( - <> -

    - MaxMind databases can vary in size from release to release. If you are - working with file size limitations that are concerning, you should build - your integrations to fail gracefully in event of a significant size - change. -

    - -

    - From - {' '} - {dateRange} - , the database files varied in file size and number of networks as - follows: -

    - - - - - - - - - - - - - {databaseChangesItems} - -
    - Database - - CSV File Size - - MMDB File Size - - IPv4 Networks - - IPv6 Networks -
    - -

    - The listed file sizes are for unpacked databases. Databases are - downloaded in a compressed format. -

    - - ); -}; - -DatabaseSizes.propTypes = { - databaseChanges: PropTypes.array.isRequired, - dateRange: PropTypes.string.isRequired, -}; - -export default DatabaseSizes; diff --git a/src/components/Example.module.scss b/src/components/Example.module.scss deleted file mode 100644 index 213745701..000000000 --- a/src/components/Example.module.scss +++ /dev/null @@ -1,29 +0,0 @@ -@use '../styles/variables'; - -.container { - margin: calc(var(--mm-spacing) / 2) 0; -} - -.label { - font-size: 14px; - font-weight: 500; - margin-bottom: 15px; -} - -.value { - margin: calc(var(--mm-spacing) / 4) 0 0 0; - max-width: calc(100vw - calc(var(--mm-spacing) * 2 - 2px)); - padding-top: 0; -} - -@include variables.breakpoint('lg') { - .value { - max-width: calc(100vw - var(--mm-layout-sidebar-width) - calc(var(--mm-spacing) * 3) - 4px); - } -} - -@include variables.breakpoint('xl') { - .value { - max-width: calc(680px - var(--mm-spacing)); - } -} diff --git a/src/components/Example.tsx b/src/components/Example.tsx deleted file mode 100644 index 1b96059d8..000000000 --- a/src/components/Example.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { pre as Pre } from './Mdx'; - -import * as styles from './Example.module.scss'; - -interface IExample { - children: React.ReactNode, - className?: string; - label?: string; - language: 'bash' | 'json'; -} - -const Example: React.FC = (props) => { - const { children, className, label, language } = props; - - const languageClass = `language-${language}`; - - return ( -
    - {label && ( -
    - {label} -
    - )} - -
    -        
    -          {children}
    -        
    -      
    -
    - ); -}; - -Example.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - label: PropTypes.string, - language: PropTypes.oneOf([ - 'bash', - 'json', - ] as const).isRequired, -}; - -export default Example; diff --git a/src/components/Layout/AccessibilityNav.module.scss b/src/components/Layout/AccessibilityNav.module.scss deleted file mode 100644 index 88f259fd7..000000000 --- a/src/components/Layout/AccessibilityNav.module.scss +++ /dev/null @@ -1,54 +0,0 @@ -@use '../../styles/variables'; - -.container { - @include variables.opaque-overlay; - width: 100%; - - &:focus-within { - display: grid; - grid-template-columns: 1fr; - grid-template-rows: min-content; - height: 100%; - /* autoprefixer: ignore next */ - justify-items: center; - } -} - -.list { - background-color: var(--mm-color-background); - border: 1px solid var(--mm-color-border); - border-radius: 12px; - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); - margin: var(--mm-spacing); - max-width: 70vh; -} - -.listItem { - border-bottom: 1px solid var(--mm-color-border); - - &:last-of-type { - border: 0; - } -} - -.link { - border-left: 2vh solid transparent; - border-right: 2vh solid transparent; - color: var(--mm-color-primary-text); - display: block; - font-family: var(--mm-font-stack-display); - font-size: 5vh; - line-height: 1em; - padding: 5vh; - text-decoration: none; - - &:hover, - &:focus { - color: var(--mm-color-display-text); - } - - &:focus { - background-color: var(--mm-color-sidebar); - font-weight: 700; - } -} diff --git a/src/components/Layout/AccessibilityNav.tsx b/src/components/Layout/AccessibilityNav.tsx deleted file mode 100644 index b1061bb1a..000000000 --- a/src/components/Layout/AccessibilityNav.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import * as styles from './AccessibilityNav.module.scss'; - -const AccessibilityNav: React.FC> = (props) => ( - // eslint-disable-next-line jsx-a11y/no-access-key -
    - -
    -); - -AccessibilityNav.propTypes = { - className: PropTypes.string, -}; - -export default AccessibilityNav; diff --git a/src/components/Layout/Footer.module.scss b/src/components/Layout/Footer.module.scss deleted file mode 100644 index 2ad296339..000000000 --- a/src/components/Layout/Footer.module.scss +++ /dev/null @@ -1,247 +0,0 @@ -@use '../../styles/variables'; - -.footer { - background: rgb(46, 58, 71); - color: #fff; - font-size: 14px; - position: relative; - - @include variables.pattern; - - &::after { - background: rgba(25, 19, 6, 0.7); - } -} - -.container { - column-gap: 0; - display: grid; - grid-template-areas: - 'a b' - 'c d' - 'branding branding' - 'copyright copyright'; - grid-template-columns: 50% 50%; - position: relative; - row-gap: 0; - z-index: 2; -} - -.group { - padding: var(--mm-spacing); - padding-bottom: 0; -} - -.group__products { - grid-area: a; -} - -.group__support { - grid-area: b; -} - -.group__developers { - grid-area: c; -} - -.group__company { - grid-area: d; -} - -.heading { - color: #c0d2e4; - font-family: var(--mm-font-stack-display); - font-size: 16px; - font-weight: 500; - margin-bottom: calc(var(--mm-spacing) / 2); -} - -.link { - color: #fff; - display: block; - margin-bottom: 10px; - text-decoration: none; - - &:hover { - text-decoration: underline; - } -} - -.status, -.ccpa { - position: relative; - - &:hover { - text-decoration: none; - } -} - -.statusIcon { - left: -10px; - position: absolute; - top: 50%; - transform: translate(-100%, -50%); -} - -.status:hover .statusText { - text-decoration: underline; -} - -.ccpaIcon { - left: -10px; - position: absolute; - top: 57%; - transform: translate(-100%, -50%); - - svg { - height: 14px; - } -} - -.branding { - /* autoprefixer: ignore next */ - align-items: flex-end; - display: flex; - flex: 1 0 0; - grid-area: branding; - justify-content: space-between; - padding: var(--mm-spacing) var(--mm-spacing) 0; -} - -.logo { - display: inline-block; - margin-right: 10px; - width: 160px; -} - -.social { - margin-bottom: 14px; -} - -.socialIcon { - color: #fff; - display: inline-block; - font-size: 30px; - margin-left: calc(var(--mm-spacing) / 4); -} - -.copyright { - font-size: 12px; - grid-area: copyright; - padding: var(--mm-spacing) var(--mm-spacing) calc(var(--mm-spacing) * 2.5); - text-align: center; -} - -.terms { - margin-top: calc(var(--mm-spacing) / 2); - text-align: center; -} - -.termsLink { - color: #fff; - text-decoration: none; - - &:first-child::after { - color: rgba(255, 255, 255, 0.2); - content: '|'; - padding: 0 10px; - } -} - -@include variables.breakpoint('md') { - .container { - grid-template-areas: - 'a b c d' - 'branding branding copyright copyright'; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: max-content; - } - - .branding { - grid-column: span 2; - justify-content: left; - order: 1; - padding-bottom: var(--mm-spacing); - } - - .logo { - width: 200px; - } - - .copyright { - grid-column: 3 / span 2; - text-align: right; - } - - .terms { - text-align: right; - } -} - -@include variables.breakpoint('xl') { - .container { - grid-template-areas: - 'branding a b c d' - 'branding copyright copyright copyright copyright'; - grid-template-columns: var(--mm-layout-sidebar-width) 1fr 1fr 1fr 1fr; - } - - .branding { - /* autoprefixer: ignore next */ - align-content: flex-start; - border-top: 0; - display: grid; - grid-area: branding; - grid-template-areas: - 'logo' - 'social'; - /* autoprefixer: ignore next */ - justify-content: center; - order: 0; - } - - .logo { - display: block; - grid-area: logo; - margin: 0 0 calc(var(--mm-spacing) / 4); - width: 200px; - } - - .social { - display: flex; - grid-area: social; - justify-content: center; - } - - .socialIcon:first-of-type { - margin-left: 0; - } - - .copyright { - /* autoprefixer: ignore next */ - align-items: top; - display: grid; - /* autoprefixer: ignore next */ - grid-area: copyright; - grid-column-gap: var(--mm-spacing); - grid-template-areas: 'p terms'; - grid-template-columns: 3fr 1fr; - text-align: left; - } - - .copyright p { - grid-area: p; - } - - .terms { - grid-area: terms; - margin-top: 0; - text-align: right; - } -} - -@include variables.breakpoint('xxxl') { - .container { - max-width: map-get(variables.$breakpoints, 'xxxl'); - } -} diff --git a/src/components/Layout/Footer.tsx b/src/components/Layout/Footer.tsx deleted file mode 100644 index ff8fe3860..000000000 --- a/src/components/Layout/Footer.tsx +++ /dev/null @@ -1,306 +0,0 @@ -import classNames from 'classnames'; -import React from 'react'; -import { FaLinkedin, FaTwitterSquare } from 'react-icons/fa'; - -import CcpaIcon from '../../assets/svgs/icon-ccpa-opt-out.svg'; -import Logo from '../../assets/svgs/maxmind-footer-logo.svg'; -import useSystemStatus from '../../hooks/useSystemStatus'; - -import * as styles from './Footer.module.scss'; - -const Footer: React.FC> = (props) => { - const systemStatus = useSystemStatus(); - - return ( - - ); -}; - -export default Footer; diff --git a/src/components/Layout/Header.module.scss b/src/components/Layout/Header.module.scss deleted file mode 100644 index 104b6fa15..000000000 --- a/src/components/Layout/Header.module.scss +++ /dev/null @@ -1,201 +0,0 @@ -@use '../../styles/variables'; - -.systemStatus { - background-color: #2e3a47; - padding: 10px; - - &::after { - background: rgba(25, 19, 6, 0.7); - } -} - -.systemStatus__content { - align-items: center; - color: #c0d2e4; - display: grid; - font-size: 14px; - gap: 10px; - grid-auto-flow: column; - grid-template-columns: repeat(3, max-content); - justify-content: center; - position: relative; - z-index: 1; -} - -.systemStatus__content a { - color: #fff; -} - -.header { - background: var(--mm-color-background); - box-shadow: rgba(0, 0, 0, 0.1) 0 1px 13px 0, rgba(0, 0, 0, 0.06) 0 1px 5px 0; - height: var(--page-header-height); - padding-top: 10px; - position: sticky; - top: 0; - width: 100%; - z-index: 10; - - @include variables.pattern-border; -} - -.accessibilityNav { - height: 0; - left: 0; - overflow: hidden; - position: fixed; - top: 0; - z-index: 20; - - &:focus-within { - height: 100%; - } -} - -.nav { - display: grid; - grid-template-areas: 'logo search menu'; - grid-template-columns: max-content 1fr max-content; - grid-template-rows: auto; - height: calc(var(--page-header-height) - 10px); - padding: 0 var(--mm-spacing); -} - -/* IE11 content alignment fix */ -.nav > * { align-self: center; } - -.logo { - display: grid; - gap: 8px; - grid-area: logo; - grid-template-areas: 'svg site-name'; - grid-template-columns: auto; - margin-right: calc(var(--mm-spacing) / -4); - padding: calc(var(--mm-spacing) / 4); - text-decoration: none; - transform: translateX(calc(var(--mm-spacing) / -4)); -} - -.logo__svg { - align-self: center; - grid-area: svg; - max-width: 125px; - width: 100%; -} - -.logo__siteName { - align-self: center; - color: var(--mm-color-primary-text); - font-family: var(--mm-font-stack-display); - font-size: 10px; - font-style: italic; - font-weight: 600; - grid-area: site-name; - letter-spacing: 1px; - line-height: 1; - overflow: hidden; - padding-left: 9px; - position: relative; - text-transform: uppercase; - - &::before { - background: #ccc; - content: ' '; - display: block; - height: 100%; - left: 0; - position: absolute; - top: 50%; - transform: rotate(20deg) translateY(-50%); - width: 1px; - } -} - -.eloper { - display: none; -} - -.search { - grid-area: search; - width: 100%; -} - -@include variables.breakpoint('sm') { - .logo { - gap: 10px; - grid-template-areas: 'svg site-name'; - grid-template-columns: auto; - } - - .logo__siteName { - padding-left: 18px; - } - - .eloper { - display: inline; - } -} - -@include variables.breakpoint('lg') { - .nav { - grid-template-columns: calc(var(--mm-layout-sidebar-width) - var(--mm-spacing)) 1fr; - grid-template-rows: auto; - } - - .logo__svg { - max-width: initial; - } - - .logo__siteName { - font-size: 12px; - } - - .search { - padding-left: var(--mm-spacing); - } -} - -@include variables.breakpoint('xl') { - .search { - align-self: center; - display: flex; - justify-self: center; - max-width: 880px; - padding-left: var(--mm-spacing); - width: calc(100% - var(--mm-layout-sidebar-width) - calc(var(--mm-spacing) * 2)); - width: 100%; - } -} - -@media only screen and (min-width: 1230px) { - .search { - max-width: 840px; - } -} - -@include variables.breakpoint('xxl') { - .search { - justify-self: start; - width: calc(100% - var(--mm-layout-sidebar-width) + 60px); - } -} - -@media only screen and (min-width: 1480px) { - .search { - justify-self: center; - max-width: 840px; - transform: translateX(calc(var(--mm-layout-toc-width) * -0.5)); - } -} - -.toggle { - @include variables.menu-button; - grid-area: menu; - z-index: 4; -} - -@include variables.breakpoint('lg') { - .toggle { - display: none; - } -} diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx deleted file mode 100644 index 98d3801dd..000000000 --- a/src/components/Layout/Header.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaBars, FaTimes } from 'react-icons/fa'; - -import Logo from '../../assets/svgs/maxmind-logo.svg'; -import useSystemStatus from '../../hooks/useSystemStatus'; -import Link from '../Link'; -import AccessibilityNav from './AccessibilityNav'; -import SearchBar from './SearchBar'; - -import * as styles from './Header.module.scss'; - -interface IHeader { - isSidebarOpen?: boolean; - toggleSidebar: () => void; -} - -const Header: React.FC = (props) => { - const systemStatus = useSystemStatus(); - const { isSidebarOpen, toggleSidebar } = props; - return ( - <> - - {systemStatus && systemStatus.class !== 'operational' && ( -
    -
    - {systemStatus.icon} - {' '} - {systemStatus.title} - {': '} - {systemStatus.message} - {' '} - - More info » - -
    -
    - )} -
    -
    - - - - Dev - - eloper - - s - - - - -
    -
    - - ); -}; - -Header.propTypes = { - isSidebarOpen: PropTypes.bool, - toggleSidebar: PropTypes.func.isRequired, -}; - -export default Header; diff --git a/src/components/Layout/Layout.module.scss b/src/components/Layout/Layout.module.scss deleted file mode 100644 index b69515673..000000000 --- a/src/components/Layout/Layout.module.scss +++ /dev/null @@ -1,82 +0,0 @@ -@use '../../styles/variables'; -@use '../../styles/global'; - -$transition: all 0.15s ease-out; - -.container { - display: flex; - flex-direction: column; - min-height: 100vh; -} - -.main { - background: var(--mm-color-background); - display: grid; - flex: 1 1 auto; - /* autoprefixer: ignore next */ - grid-template-areas: 'article sidebar'; - grid-template-columns: 360px var(--mm-layout-sidebar-width); - grid-template-rows: 100%; - transition: $transition; -} - -.main__hasSidebar { - visibility: visible; -} - -.content { - grid-area: article; - scroll-margin-top: calc(var(--page-header-height) + var(--mm-spacing)); - transition: $transition; -} - -.sidebar__open::after { - @include variables.opaque-overlay; - content: ' '; - display: block; - height: 100vh; - left: 0; - position: fixed; - top: 0; - width: 100vw; - z-index: 8; -} - -.sidebar__hidden [class*='Sidebar-module--sidebar--'] { - transform: translate3d(360px, 0, 0); -} - -@include variables.breakpoint('xs') { - .main { - grid-template-columns: 100vw var(--mm-layout-sidebar-width); - grid-template-rows: 100%; - } - - .sidebar__hidden [class*='Sidebar-module--sidebar--'] { - transform: translate3d(100vw, 0, 0); - } -} - -@include variables.breakpoint('lg') { - .main__hasSidebar { - /* autoprefixer: ignore next */ - grid-template-areas: 'sidebar article'; - grid-template-columns: var(--mm-layout-sidebar-width) calc(100vw - var(--mm-layout-sidebar-width)); - } - - .main [class^='Sidebar-module'] { - display: none; - } - - .main__hasSidebar [class^='Sidebar-module'] { - display: block; - } - - .content { - grid-area: article; - } - - .sidebar--open::after { - display: none; - } -} diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx deleted file mode 100644 index 9ab473a8f..000000000 --- a/src/components/Layout/Layout.tsx +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Layout component that queries for data - * with Gatsby's useStaticQuery component - * - * See: https://www.gatsbyjs.org/docs/use-static-query/ - */ - -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React, { useState } from 'react'; - -import Footer from './Footer'; -import Header from './Header'; -import SEO from './Seo'; -import Sidebar from './Sidebar'; - -import * as styles from './Layout.module.scss'; - -interface ILayout { - children: React.ReactNode; - className?: string; - description?: string; - hasSidebar?: boolean; - image?: string; - isSidebarOpen?: boolean; - keywords?: string[]; - title: string; - type?: 'geoip' | 'minfraud'; -} - -const Layout: React.FC = (props) => { - const { - className, - children, - description, - hasSidebar, - image, - isSidebarOpen: sidebarState, - keywords, - title, - type, - } = props; - - const [ - isSidebarOpen, - setIsSidebarOpen, - ] = useState(sidebarState); - - const toggleSidebar = (): void => setIsSidebarOpen(!isSidebarOpen); - - const pageTypeClass: string | undefined = [ - 'geoip', - 'minfraud', - ].includes( - type as string - ) - ? `page-type--${type}` - : undefined; - - return ( -
    - - -
    - -
    - - -
    - {children} -
    -
    - -
    -
    - ); -}; - -Layout.defaultProps = { - hasSidebar: true, -}; - -Layout.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - description: PropTypes.string, - hasSidebar: PropTypes.bool, - isSidebarOpen: PropTypes.bool, - keywords: PropTypes.array, - title: PropTypes.string.isRequired, - type: PropTypes.oneOf([ - 'geoip', - 'minfraud', - ]), -}; - -export default Layout; diff --git a/src/components/Layout/SearchBar.module.scss b/src/components/Layout/SearchBar.module.scss deleted file mode 100644 index bf35f7b31..000000000 --- a/src/components/Layout/SearchBar.module.scss +++ /dev/null @@ -1,72 +0,0 @@ -@use '../../styles/variables'; - -.searchbar { - display: none; - position: relative; -} - -@include variables.breakpoint('lg') { - .searchbar { - display: inline-block; - width: 100%; - } -} - -@media only screen and (max-width: map-get(variables.$breakpoints, 'lg')) { - .searchbar__mobileOpen { - display: inline-block; - left: 0; - margin: 0 var(--mm-spacing); - position: absolute; - top: calc(50% + 5px); - transform: translateY(-50%); - width: calc(100% - (2 * var(--mm-spacing))); - z-index: 100; - } -} - -.mag { - color: var(--mm-color-primary-text); - left: calc(var(--mm-spacing) / 2); - position: absolute; - top: 50%; - transform: translateY(-50%); -} - -.searchMobile { - position: relative; -} - -@include variables.breakpoint('lg') { - .searchMobile { - display: none; - } -} - -.mobileButton { - @include variables.menu-button; - float: right; - margin-right: calc(var(--mm-spacing) / 4); -} - -.input { - appearance: none !important; - border: 1px solid var(--mm-color-border); - border-radius: var(--mm-border-radius); - color: var(--mm-color-primary-text); - padding: 12px 10px 12px calc(var(--mm-spacing) + 15px); - width: 100%; - - &::placeholder { - opacity: 0.5; - } - - &:focus { - box-shadow: 0 0 0 2px var(--mm-color-logo-blue-light); - outline: none; - } -} - -.hidden { - display: none; -} diff --git a/src/components/Layout/SearchBar.tsx b/src/components/Layout/SearchBar.tsx deleted file mode 100644 index 31cf072c1..000000000 --- a/src/components/Layout/SearchBar.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import classNames from 'classnames'; -import { navigate } from 'gatsby'; -import PropTypes from 'prop-types'; -import React, { useEffect, useRef, useState } from 'react'; -import { FaSearch } from 'react-icons/fa'; - -import * as styles from './SearchBar.module.scss'; - -interface ISearchBar { - className?: string; -} - -const SearchBar: React.FC = (props) => { - const [ - isMobileOpen, - setIsMobileOpen, - ] = useState(false); - - const [ - searchQuery, - setSearchQuery, - ] = useState(''); - - const inputRef = useRef(null); - - const toggleMobileOpen = (): void => { - setIsMobileOpen(true); - setTimeout(() => { - inputRef.current?.focus(); - }, 1); - }; - - const handleChange = (event: React.ChangeEvent) => { - setSearchQuery(event.target.value); - }; - - const handleSubmit = ((event: React.FormEvent) => { - event.preventDefault(); - navigate(`/search-results?q=${searchQuery}`); - }); - - let locationSearch: string; - - if (typeof window !== 'undefined') { - locationSearch = window.location.search; - } else { - locationSearch = ''; - } - - useEffect(() => { - const urlParams = new URLSearchParams(locationSearch); - setSearchQuery(urlParams.get('q') as string); - }, [ - locationSearch, - ]); - - return ( -
    -
    - - setIsMobileOpen(false)} - onChange={handleChange} - placeholder="Search" - ref={inputRef} - type="search" - /> - - -
    - -
    -
    - ); -}; - -SearchBar.propTypes = { - className: PropTypes.string, -}; - -export default SearchBar; diff --git a/src/components/Layout/Seo.tsx b/src/components/Layout/Seo.tsx deleted file mode 100644 index 5f9e5a5b8..000000000 --- a/src/components/Layout/Seo.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/** - * SEO component that queries for data with - * Gatsby's useStaticQuery React hook - * - * See: https://www.gatsbyjs.org/docs/use-static-query/ - */ - -import { useLocation } from '@reach/router'; -import { graphql, useStaticQuery } from 'gatsby'; -import PropTypes from 'prop-types'; -import React from 'react'; -import Helmet, { HelmetProps } from 'react-helmet'; - -export interface ISEO extends HelmetProps { - description?: string; - image?: string; - lang?: string; -} - -const SEO: React.FC = (props) => { - const { bodyAttributes, description, image, lang, meta = [], title } = props; - const { site } = useStaticQuery( - graphql` - query { - site { - siteMetadata { - title - description - author - siteUrl - } - } - } - ` - ); - - const metaDescription = description || site.siteMetadata.description; - - const metaImage = new URL( - image ?? '/images/og-image.jpg', - site.siteMetadata.siteUrl - ).href; - - return ( - - ); -}; - -SEO.defaultProps = { - description: '', - lang: 'en', - meta: [], -}; - -SEO.propTypes = { - bodyAttributes: PropTypes.any, - description: PropTypes.string, - lang: PropTypes.string, - meta: PropTypes.arrayOf(PropTypes.any), - title: PropTypes.string.isRequired, -}; - -export default SEO; diff --git a/src/components/Layout/Sidebar.module.scss b/src/components/Layout/Sidebar.module.scss deleted file mode 100644 index 4e2bd1514..000000000 --- a/src/components/Layout/Sidebar.module.scss +++ /dev/null @@ -1,248 +0,0 @@ -@use '../../styles/variables'; - -.sidebar { - background: var(--mm-color-sidebar); - border-left: 1px solid var(--mm-color-border); - box-shadow: -2px -1px 3px rgba(0, 0, 0, 0.1); - grid-area: sidebar; - height: 100%; - max-width: var(--mm-layout-sidebar-width); - position: fixed; - right: 0; - transition: all 0.15s ease-out; - width: 100%; - z-index: 9; -} - -.nav { - height: calc(100vh - var(--page-header-height)); - overflow-y: auto; - position: sticky; - top: var(--page-header-height); -} - -.list { - background: transparent; -} - -.item { - border-top: 1px solid var(--mm-color-border); - color: #666; - margin: 2px 0 3px; - position: relative; -} - -.item:first-of-type { - border-top: 1px solid transparent; -} - -.item__active { - background: var(--mm-color-background); - border-right: 0 !important; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - padding-bottom: 5px; -} - -.item__active + .item { - border-top: 1px solid transparent; -} - -.itemLink { - color: #444; - display: inline-block; - font-family: var(--mm-font-stack-display); - font-size: 16px; - font-weight: 700; - padding: calc(var(--mm-spacing) * 0.25) calc(var(--mm-spacing) * 0.25); - text-decoration: none; - transition: all 0.15s ease-out; - width: 100%; - - &:hover { - background: rgba(255, 255, 255, 0.5); - } -} - -.itemIcon { - border-radius: var(--mm-border-radius); - box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.35); - height: 40px; - width: 40px; - - &::before { - border-radius: var(--mm-border-radius); - } -} - -.item:not(.item__active) .itemIcon { - background: none; - border: 0; - box-shadow: none; - - &::before { - background: none; - } - - svg { - fill: var(--mm-color-primary-text); - filter: none; - } -} - -.item__active .itemLink { - background: transparent; - border: 0; - border-left: 4px solid transparent; - color: var(--mm-color-primary-text); - font-weight: 500; - - &:hover { - color: var(--mm-color-display-text); - } -} - -.item__active .list { - display: block; -} - -.externalLinkIcon { - margin-left: 5px; - transform: translateY(-1px); -} - -.list__level0 > .item > .itemLink { - border-left: 0; - column-gap: calc(var(--mm-spacing) / 4); - display: grid; - grid-template-columns: max-content auto; - grid-template-rows: auto auto; -} - -.list__level0 > .item__active > .itemLink { - color: var(--mm-color-display-text); - font-weight: 700; -} - -.list__level0 > .item > .itemLink > * { - align-self: center; -} - -.list__level1 { - display: none; -} - -.list__level1 .item { - border-top: 0; -} - -.list__level1 .item:last-of-type { - margin-bottom: calc(var(--mm-spacing) / 2); -} - -.list__level1 .item__hasDivider::before { - border-top: 1px dashed var(--mm-color-border); - content: ' '; - display: block; - height: 0; - margin: calc(var(--mm-spacing) / 2) 0; - width: 100%; -} - -/* stylelint-disable-next-line no-descending-specificity */ -.list__level1 .itemLink { - color: var(--mm-color-primary-text); - font-size: 14px; - font-weight: 500; - margin-left: 46px; - max-width: calc(100% - 46px); - padding: 5px 10px; - - &:hover { - color: var(--mm-color-display-text); - } -} - -.list__level1 .item__active { - border: 0; - box-shadow: none; - padding-bottom: 0; -} - -.list__level1 .item__current > .itemLink { - background: var(--mm-color-sidebar); - border-left: 4px solid var(--mm-color-active-blue); - color: var(--mm-color-display-text) !important; -} - -.list__level1 [href*='#']:focus { - position: relative; -} - -.list__level1 [href*='#']:focus::before { - background: var(--mm-color-active-blue); - border-radius: 50%; - content: ' '; - display: block; - height: 6px; - left: 0; - position: absolute; - top: 50%; - transform: translateY(-50%); - width: 6px; -} - -/* stylelint-disable-next-line no-descending-specificity */ -.list__level2 .item { - margin-left: calc(var(--mm-spacing) / 2); -} - -.list__level2 .item:last-of-type { - margin-bottom: 0; -} - -.item__nonProduct.item__current { - background-color: var(--mm-color-sidebar); -} - -.item__nonProduct.item__current > .itemLink { - background: var(--mm-color-background); -} - -@include variables.breakpoint('lg') { - .sidebar { - border-left: 0; - grid-area: sidebar; - position: relative; - transform: initial !important; - transition: none; - - &::after { - background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 100%); - content: ' '; - display: block; - height: 100%; - position: absolute; - right: 0; - top: 0; - width: 5px; - } - } - - .nav { - height: 100%; - margin: var(--mm-spacing) 0; - max-height: calc(100vh - calc(var(--page-header-height) + 41px)); - top: calc(var(--page-header-height) + var(--mm-spacing)); - } - - .list__level0 > .item > .itemLink { - padding-left: 30px; - padding-right: 30px; - } - - /* stylelint-disable-next-line no-descending-specificity */ - .list__level1 .itemLink { - margin-left: 66px; - max-width: calc(100% - 66px); - } -} diff --git a/src/components/Layout/Sidebar.tsx b/src/components/Layout/Sidebar.tsx deleted file mode 100644 index 2e855a094..000000000 --- a/src/components/Layout/Sidebar.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { useLocation } from '@reach/router'; -import classNames from 'classnames'; -import React from 'react'; -import { FaExternalLinkAlt as ExternalLinkIcon } from 'react-icons/fa'; - -import navigation from '../../../content/navigation'; -import { - IItem, - isInternalItem, -} from '../../types/Item'; -import Link from '../Link'; - -import * as styles from './Sidebar.module.scss'; - -const renderItems = ( - items: IItem[], - currentPath: string, - level = 0 -): React.ReactElement => ( -
      - {items.map((item, index) => { - let isItemActive = false; - let isItemCurrent = false; - let isItemNonProduct = false; - - if (isInternalItem(item)) { - isItemActive = currentPath.startsWith(item.to); - isItemCurrent = currentPath === item.to; - isItemNonProduct = !item.to.startsWith('/minfraud') - && !item.to.startsWith('/geoip'); - } - - if (item.icon) { - item.icon = React.cloneElement(item.icon, { - className: classNames( - styles.itemIcon, - ), - }); - } - - return ( -
    • - {isInternalItem(item) ? ( - <> - - {item.icon} - - {item.title} - - - - {item.items && renderItems(item.items, currentPath, level + 1)} - - {isItemActive - && item.secondaryItems - && renderItems(item.secondaryItems, currentPath, level + 1) - } - - ) : ( - - {item.icon} - - {item.title} - - - - )} -
    • - ); - } - )} -
    -); - -const Sidebar: React.FC = () => { - let pathname = useLocation().pathname; - - if (pathname.slice(pathname.length -1) === '/') { - pathname = pathname.slice(0, -1); - } - - return ( -
    - -
    - ); -}; - -export default Sidebar; diff --git a/src/components/Layout/index.ts b/src/components/Layout/index.ts deleted file mode 100644 index 67fc7d38d..000000000 --- a/src/components/Layout/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as default } from './Layout'; diff --git a/src/components/Link.tsx b/src/components/Link.tsx deleted file mode 100644 index de6043fcc..000000000 --- a/src/components/Link.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { GatsbyLinkProps, Link as GatsbyLink } from 'gatsby'; -import * as React from 'react'; - -type ILink = Omit>,'ref'> - -const Link: React.FC = (props) => { - const { to, ...rest } = props; - - return ( - - ); -}; - -export default Link; diff --git a/src/components/LinkButton.module.scss b/src/components/LinkButton.module.scss deleted file mode 100644 index c97a6b321..000000000 --- a/src/components/LinkButton.module.scss +++ /dev/null @@ -1,41 +0,0 @@ -@use '../styles/variables'; - -.link { - align-items: center; - background: linear-gradient(var(--mm-color-background), var(--mm-color-sidebar)); - border-radius: 4px; - box-shadow: rgb(0 0 0 / 10%) 0 1px 3px 0, rgb(0 0 0 / 6%) 0 1px 2px 0; - color: var(--mm-color-primary-text); - display: grid; - font-family: var(--mm-font-stack-display); - font-size: 14px; - font-weight: 400; - gap: 10px; - grid-auto-flow: column; - grid-template-columns: max-content auto; - overflow: hidden; - padding: 12px 10px 8px; - position: relative; - text-decoration: none; - top: 0; - transition: all 0.1s ease-in-out; - @include variables.pattern-border; - - &::after, - &::before { - height: 4px !important; - } - - &:hover { - background-color: var(--mm-color-active-blue); - box-shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - top: -2px; - } -} - -.icon { - border-right: 1px solid var(--mm-color-border); - color: var(--mm-color-active-blue); - display: inline-block; - padding-right: 10px; -} diff --git a/src/components/LinkButton.tsx b/src/components/LinkButton.tsx deleted file mode 100644 index bd5cde31a..000000000 --- a/src/components/LinkButton.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import Link from './Link'; - -import * as styles from './LinkButton.module.scss'; - -interface ILinkButton { - Icon?: React.FC>; - children?: React.ReactNode; - text?: string; - to: string; -} - -const LinkButton: React.FC = (props) => { - const { children, Icon, text, to } = props; - return ( - - {Icon && ( - - - - )} - {text || children} - - ); -}; - -LinkButton.propTypes = { - Icon: PropTypes.any, - children: PropTypes.node, - text: PropTypes.string, - to: PropTypes.string.isRequired, -}; - -export default LinkButton; diff --git a/src/components/LinkGroup/LinkGroup.module.scss b/src/components/LinkGroup/LinkGroup.module.scss deleted file mode 100644 index defa4117a..000000000 --- a/src/components/LinkGroup/LinkGroup.module.scss +++ /dev/null @@ -1,94 +0,0 @@ -@use '../../styles/variables'; - -.section { - margin-top: var(--mm-spacing); -} - -.sectionHeading { - color: var(--mm-color-primary-text); - font-size: 18px; - font-weight: 500; - margin-bottom: 20px; -} - -.cards { - display: grid; - gap: var(--mm-spacing); - grid-template-areas: - 'first' - 'second'; - grid-template-columns: 1fr; - grid-template-rows: auto; -} - -.cards:nth-of-type(1) { - grid-area: first; -} - -.cards:nth-of-type(2) { - grid-area: second; -} - -.cards__isCompact { - gap: calc(var(--mm-spacing) / 2); - grid-template-columns: 1fr; - grid-template-rows: auto; -} - -.card { - width: 100%; -} - -@include variables.breakpoint('sm') { - .cards__isCompact { - grid-template-areas: 'first second'; - grid-template-columns: 1fr 1fr; - } -} - -@include variables.breakpoint('md') { - .cards { - grid-template-areas: 'first second'; - grid-template-columns: 1fr 1fr; - } - - .cards__isCompact { - grid-template-areas: 'first second third'; - grid-template-columns: 1fr 1fr 1fr; - } - - .cards__isCompact:nth-of-type(3) { - grid-area: third; - } -} - -@include variables.breakpoint('lg') { - .cards { - grid-template-areas: - 'first' - 'second'; - grid-template-columns: 1fr; - } - - .cards__isCompact { - gap: calc(var(--mm-spacing) / 2); - grid-template-areas: 'first second'; - grid-template-columns: 1fr 1fr; - } -} - -@include variables.breakpoint('xl') { - .cards { - grid-template-areas: 'first second'; - grid-template-columns: 1fr 1fr; - } - - .cards__isCompact { - grid-template-areas: 'first second third'; - grid-template-columns: 1fr 1fr 1fr; - } - - .cards__isCompact:nth-of-type(3) { - grid-area: third; - } -} diff --git a/src/components/LinkGroup/LinkGroup.tsx b/src/components/LinkGroup/LinkGroup.tsx deleted file mode 100644 index 2aca7302e..000000000 --- a/src/components/LinkGroup/LinkGroup.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { ILinkGroupCard } from './LinkGroupCard'; - -import * as styles from './LinkGroup.module.scss'; - -export interface ILinkGroup { - children: React.ReactElement - | React.ReactElement[]; - heading?: string; - isCompact?: boolean -} - -const LinkGroup: React.FC = (props) => ( -
    - {props.heading && ( -

    - {props.heading} -

    - )} -
    - {React.Children.map( - props.children, - ( - child: React.ReactElement, - index: number, - ) => React.cloneElement((child), { - className: styles.card, - isCompact: props.isCompact, - key: `link-group-child-${index}`, - }) - )} -
    -
    -); - -LinkGroup.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.element.isRequired).isRequired, - PropTypes.element.isRequired, - ]).isRequired, - heading: PropTypes.string, - isCompact: PropTypes.bool, -}; - -export default LinkGroup; diff --git a/src/components/LinkGroup/LinkGroupCard.module.scss b/src/components/LinkGroup/LinkGroupCard.module.scss deleted file mode 100644 index 923b8b49d..000000000 --- a/src/components/LinkGroup/LinkGroupCard.module.scss +++ /dev/null @@ -1,100 +0,0 @@ -@use '../../styles/variables'; - -.container { - background: linear-gradient(#fff, var(--mm-color-sidebar)); - border: 1px solid #eee; - border-bottom: 1px solid #ddd; - border-radius: var(--mm-border-radius); - box-shadow: rgba(0, 0, 0, 0.1) 0 1px 3px 0, rgba(0, 0, 0, 0.06) 0 1px 2px 0; - display: grid; - gap: calc(var(--mm-spacing) / 2); - grid-template-areas: - 'icon heading arrow' - '. description arrow'; - grid-template-columns: min-content 1fr min-content; - grid-template-rows: auto; - margin-top: 0; - overflow: hidden; - padding: calc(var(--mm-spacing) / 2); - padding-top: calc(calc(var(--mm-spacing) / 2) + 6px); - position: relative; - text-decoration: none; - top: 0; - transition: all 0.1s ease-in-out; - @include variables.pattern-border; - - &::before, - &::after { - height: 6px !important; - } - - &:hover { - box-shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - top: -5px; - } -} - -.container__isCompact { - gap: calc(var(--mm-spacing) / 4); - grid-template-columns: min-content 1fr min-content; - grid-template-rows: auto; - padding: calc(var(--mm-spacing) / 4); - padding-top: calc(calc(var(--mm-spacing) / 4) + 6px); -} - -.container__noDescription { - grid-template-areas: 'icon heading arrow'; -} - -.icon { - align-self: center; - color: var(--mm-color-active-blue); - grid-area: icon; - height: 30px; - width: 30px; -} - -.container__isCompact .icon { - height: 18px; - width: 18px; -} - -.heading { - align-self: center; - color: var(--mm-color-display-text); - font-size: 18px; - font-weight: 500; - grid-area: heading; -} - -.container__isCompact .heading { - font-size: 14px; -} - -.description { - color: var(--mm-color-primary-text); - font-size: 14px; - grid-area: description; -} - -.container__isCompact .description { - font-size: 12px; -} - -.arrow { - border-left: 1px solid var(--mm-color-border); - color: var(--mm-color-active-blue); - display: grid; - grid-area: arrow; - height: 100%; - padding-left: calc(var(--mm-spacing) / 2); - - > * { - align-self: center; - } -} - -.container__isCompact .arrow { - font-size: 14px; - padding-left: calc(var(--mm-spacing) / 4); -} diff --git a/src/components/LinkGroup/LinkGroupCard.tsx b/src/components/LinkGroup/LinkGroupCard.tsx deleted file mode 100644 index 4f67cc8ce..000000000 --- a/src/components/LinkGroup/LinkGroupCard.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import { IconType } from 'react-icons'; -import { FaArrowRight } from 'react-icons/fa'; - -import Link from '../Link'; - -import * as styles from './LinkGroupCard.module.scss'; - -export interface ILinkGroupCard { - className?: string; - description?: string; - heading: string; - icon: IconType, - isCompact?: boolean, - to: string; -} - -const LinkGroupCard: React.FC = (props) => { - const { className, description, icon: Icon, isCompact, to } = props; - return ( - - -

    - {props.heading} -

    - {description && ( -

    - {description} -

    - )} -
    - -
    - - ); -}; - -LinkGroupCard.propTypes = { - className: PropTypes.string, - description: PropTypes.string, - heading: PropTypes.string.isRequired, - icon: PropTypes.any.isRequired, - isCompact: PropTypes.bool, - to: PropTypes.string.isRequired, -}; - -export default LinkGroupCard; diff --git a/src/components/LinkGroup/LinkGroupContainer.module.scss b/src/components/LinkGroup/LinkGroupContainer.module.scss deleted file mode 100644 index debba877a..000000000 --- a/src/components/LinkGroup/LinkGroupContainer.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.container { - display: block; -} diff --git a/src/components/LinkGroup/LinkGroupContainer.tsx b/src/components/LinkGroup/LinkGroupContainer.tsx deleted file mode 100644 index 6705e61da..000000000 --- a/src/components/LinkGroup/LinkGroupContainer.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { ILinkGroup } from './LinkGroup'; - -import * as styles from './LinkGroupContainer.module.scss'; - -interface ILinkGroupContainer { - children: React.ReactElement | React.ReactElement[], -} - -const LinkGroupContainer: React.FC = (props) => { - return( -
    - {props.children} -
    - ); -}; - -LinkGroupContainer.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.element.isRequired).isRequired, - PropTypes.element.isRequired, - ]).isRequired, -}; - -export default LinkGroupContainer; diff --git a/src/components/LinkGroup/index.ts b/src/components/LinkGroup/index.ts deleted file mode 100644 index 07d94f462..000000000 --- a/src/components/LinkGroup/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as LinkGroup } from './LinkGroup'; -export { default as LinkGroupCard } from './LinkGroupCard'; -export { default as LinkGroupContainer } from './LinkGroupContainer'; diff --git a/src/components/Loading.module.scss b/src/components/Loading.module.scss deleted file mode 100644 index ea084b7f7..000000000 --- a/src/components/Loading.module.scss +++ /dev/null @@ -1,103 +0,0 @@ -.image, -.dotContainer { - height: 100px; - position: relative; - width: 100px; -} - -.image { - animation: anirotate 10s linear infinite; - transform-origin: center; -} - -.dot { - background: var(--mm-color-logo-blue-light); - border-radius: 5px; - height: 10px; - position: absolute; - transform: translate(0, 0); - width: 10px; - - &:nth-child(1) { - animation: ani1 2s infinite; - left: calc(50% - 5px); - top: 0; - } - - &:nth-child(2) { - animation: ani2 2s infinite; - bottom: calc(28% - 5px); - left: calc(11% - 5px); - } - - &:nth-child(3) { - animation: ani3 2s infinite; - bottom: calc(28% - 5px); - right: calc(11% - 5px); - - } -} - -.dotContainer { - border: 0 solid var(--mm-color-logo-blue-light); - border-radius: 50px; - position: absolute; - - &:nth-child(2) { - .dot { - animation-delay: -0.5s; - } - transform: rotate(40deg); - } - - &:nth-child(3) { - .dot { - animation-delay: -1s; - } - transform: rotate(80deg); - } -} - -@keyframes anirotate { - 0% { - transform: rotate(0deg); - - } - - 100% { - transform: rotate(-359deg); - } -} - -@keyframes ani1 { - 0% { - transform: translate(0, 0); - - } - - 100% { - transform: translate(-40px, 67px); - } -} - -@keyframes ani2 { - 0% { - transform: translate(0, 0); - - } - - 100% { - transform: translate(77px, 0); - } -} - -@keyframes ani3 { - 0% { - transform: translate(0, 0); - - } - - 100% { - transform: translate(-39px, -67px); - } -} diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx deleted file mode 100644 index 44a558d5c..000000000 --- a/src/components/Loading.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; - -import * as styles from './Loading.module.scss'; - -const Loading: React.FC = () => ( -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -); - -export default Loading; diff --git a/src/components/Mdx/A.module.scss b/src/components/Mdx/A.module.scss deleted file mode 100644 index 565560d79..000000000 --- a/src/components/Mdx/A.module.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use '../../styles/variables'; - -.a { - align-items: center; - border-bottom: 2px dotted var(--mm-color-display-text); - color: var(--mm-color-display-text); - font-weight: 500; - height: 20px; - padding-bottom: 2px; - text-decoration: none; -} - -a:hover { - border-bottom-style: solid; -} - -.icon { - margin-left: 5px; - transform: translateY(-2px); -} diff --git a/src/components/Mdx/A.tsx b/src/components/Mdx/A.tsx deleted file mode 100644 index e2ccaf67b..000000000 --- a/src/components/Mdx/A.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaExternalLinkAlt } from 'react-icons/fa'; - -import Link from '../Link'; - -import * as styles from './A.module.scss'; - -const A: React.FC> = (props) => { - const { className, children, href, target, ...rest } = props; - let isEmail = false; - let targetHref = href; - - // remark-external-links sets target='_blank' - const isExternal = target === '_blank'; - - if (targetHref) { - isEmail = targetHref.startsWith('mailto'); - - // Get rid of trailing non-alpha characters like commas and periods. - if (isEmail && targetHref.slice(targetHref.length -1).match(/[^a-z]/i)) { - targetHref = targetHref.slice(0, -1); - } - } - - return ( - <> - { (isExternal || isEmail) && - - {children} - - {!isEmail && ( - - )} - - } - { !isExternal && !isEmail && ( - - {children} - - )} - - ); -}; - -A.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - href: PropTypes.string, - target: PropTypes.string, -}; - -export default A; diff --git a/src/components/Mdx/Blockquote.module.scss b/src/components/Mdx/Blockquote.module.scss deleted file mode 100644 index 4e1b32dcb..000000000 --- a/src/components/Mdx/Blockquote.module.scss +++ /dev/null @@ -1,34 +0,0 @@ -@use '../../styles/variables'; - -.wrapper { - border-left: 0; - border-right: 0; - padding: var(--mm-spacing); - position: relative; -} - -.blockquote { - position: relative; - z-index: 3; - - p { - font-family: var(--mm-font-stack-display); - font-size: 20px; - font-style: italic; - font-weight: 500; - line-height: 1.5em; - text-align: center; - } - - > p:first-of-type { - margin-top: 0; - } - - > p:last-of-type { - margin-bottom: 0; - } - - .blockquote:last-of-type { - margin-bottom: 0; - } -} diff --git a/src/components/Mdx/Blockquote.tsx b/src/components/Mdx/Blockquote.tsx deleted file mode 100644 index f33a6e5fa..000000000 --- a/src/components/Mdx/Blockquote.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Blockquote.module.scss'; - -const Blockquote: React.FC> = ({ - className, - ...props -}) => ( -
    -
    - {props.children} -
    -
    -); - -Blockquote.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Blockquote; diff --git a/src/components/Mdx/Code.module.scss b/src/components/Mdx/Code.module.scss deleted file mode 100644 index a14693d7b..000000000 --- a/src/components/Mdx/Code.module.scss +++ /dev/null @@ -1,21 +0,0 @@ -@use '../../styles/variables'; - -.code { - background: #fff; - border: 1px solid var(--mm-color-border); - border-radius: 4px; - color: var(--mm-color-display-text); - font-family: var(--mm-font-stack-monospace); - font-size: 14px; - font-weight: 700; - padding: 2px 6px; - transition: background-color 0.2s ease-out; -} - -a > .code { - padding-bottom: 0; -} - -.code:hover { - background: #f5f5f5; -} diff --git a/src/components/Mdx/Code.tsx b/src/components/Mdx/Code.tsx deleted file mode 100644 index e76135fc3..000000000 --- a/src/components/Mdx/Code.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Code.module.scss'; - -const Code: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Code.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Code; diff --git a/src/components/Mdx/Del.module.scss b/src/components/Mdx/Del.module.scss deleted file mode 100644 index 0778ab0e5..000000000 --- a/src/components/Mdx/Del.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.del { - /* stylelint-disable-next-line plugin/no-unsupported-browser-features */ - text-decoration-color: #333; -} diff --git a/src/components/Mdx/Del.tsx b/src/components/Mdx/Del.tsx deleted file mode 100644 index f54f1e8d1..000000000 --- a/src/components/Mdx/Del.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Del.module.scss'; - -const Del: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Del.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Del; diff --git a/src/components/Mdx/Em.module.scss b/src/components/Mdx/Em.module.scss deleted file mode 100644 index 09923e01e..000000000 --- a/src/components/Mdx/Em.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.em { - font-style: italic; -} diff --git a/src/components/Mdx/Em.tsx b/src/components/Mdx/Em.tsx deleted file mode 100644 index 0563d256c..000000000 --- a/src/components/Mdx/Em.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Em.module.scss'; - -const Em: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Em.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Em; diff --git a/src/components/Mdx/H1.module.scss b/src/components/Mdx/H1.module.scss deleted file mode 100644 index 61e022e5b..000000000 --- a/src/components/Mdx/H1.module.scss +++ /dev/null @@ -1,16 +0,0 @@ -@use '../../styles/variables'; - -.h1 { - @include variables.heading; - font-size: 28px; - font-weight: 600; - margin: var(--mm-spacing); - margin-top: 0; - padding-top: var(--mm-spacing); -} - -@include variables.breakpoint('md') { - .h1 { - font-size: 42px; - } -} diff --git a/src/components/Mdx/H1.tsx b/src/components/Mdx/H1.tsx deleted file mode 100644 index 35205b520..000000000 --- a/src/components/Mdx/H1.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './H1.module.scss'; - -const H1: React.FC> = ({ - className, - ...props -}) => ( -

    - {props.children} -

    -); - -H1.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default H1; diff --git a/src/components/Mdx/H2.module.scss b/src/components/Mdx/H2.module.scss deleted file mode 100644 index 9e106cedf..000000000 --- a/src/components/Mdx/H2.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -@use '../../styles/variables'; - -.h2 { - @include variables.heading; - font-size: 24px; - font-weight: 700; -} diff --git a/src/components/Mdx/H2.tsx b/src/components/Mdx/H2.tsx deleted file mode 100644 index 90af7d851..000000000 --- a/src/components/Mdx/H2.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaLink } from 'react-icons/fa'; - -import * as styles from './H2.module.scss'; - -const H2: React.FC> = ({ - className, - ...props -}) => ( -

    - - {props.children} - - -

    -); - -H2.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - id: PropTypes.string, -}; - -export default H2; diff --git a/src/components/Mdx/H3.module.scss b/src/components/Mdx/H3.module.scss deleted file mode 100644 index 5c1c2bba9..000000000 --- a/src/components/Mdx/H3.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use '../../styles/variables'; - -.h3 { - @include variables.heading; - font-size: 20px; -} diff --git a/src/components/Mdx/H3.tsx b/src/components/Mdx/H3.tsx deleted file mode 100644 index f9bd01855..000000000 --- a/src/components/Mdx/H3.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaLink } from 'react-icons/fa'; - -import * as styles from './H3.module.scss'; - -const H3: React.FC> = ({ - className, - ...props -}) => ( -

    - - {props.children} - - -

    -); - -H3.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - id: PropTypes.string, -}; - -export default H3; diff --git a/src/components/Mdx/H4.module.scss b/src/components/Mdx/H4.module.scss deleted file mode 100644 index caa5dab66..000000000 --- a/src/components/Mdx/H4.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use '../../styles/variables'; - -.h4 { - @include variables.heading; - font-size: 18px; -} diff --git a/src/components/Mdx/H4.tsx b/src/components/Mdx/H4.tsx deleted file mode 100644 index 8a704147f..000000000 --- a/src/components/Mdx/H4.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaLink } from 'react-icons/fa'; - -import * as styles from './H4.module.scss'; - -const H4: React.FC> = ({ - className, - ...props -}) => ( -

    - - {props.children} - - -

    -); - -H4.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - id: PropTypes.string, -}; - -export default H4; diff --git a/src/components/Mdx/H5.module.scss b/src/components/Mdx/H5.module.scss deleted file mode 100644 index aac04e32e..000000000 --- a/src/components/Mdx/H5.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use '../../styles/variables'; - -.h5 { - @include variables.heading; - font-size: 16px; -} diff --git a/src/components/Mdx/H5.tsx b/src/components/Mdx/H5.tsx deleted file mode 100644 index bed6befab..000000000 --- a/src/components/Mdx/H5.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaLink } from 'react-icons/fa'; - -import * as styles from './H5.module.scss'; - -const H5: React.FC> = ({ - className, - ...props -}) => ( -
    - - {props.children} - - -
    -); - -H5.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - id: PropTypes.string, -}; - -export default H5; diff --git a/src/components/Mdx/H6.module.scss b/src/components/Mdx/H6.module.scss deleted file mode 100644 index 8066b37ff..000000000 --- a/src/components/Mdx/H6.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use '../../styles/variables'; - -.h6 { - @include variables.heading; - font-size: 16px; - text-transform: uppercase; - - a { - color: rgba(57, 61, 100, 0.5) !important; - } -} diff --git a/src/components/Mdx/H6.tsx b/src/components/Mdx/H6.tsx deleted file mode 100644 index 518e7145e..000000000 --- a/src/components/Mdx/H6.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaLink } from 'react-icons/fa'; - -import * as styles from './H6.module.scss'; - -const H6: React.FC> = ({ - className, - ...props -}) => ( -
    - - {props.children} - - -
    -); - -H6.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, - id: PropTypes.string, -}; - -export default H6; diff --git a/src/components/Mdx/Hr.module.scss b/src/components/Mdx/Hr.module.scss deleted file mode 100644 index e696b09ad..000000000 --- a/src/components/Mdx/Hr.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -@use '../../styles/variables'; - -.hr { - border: 0; - border-top: 1px dashed var(--mm-color-border); - height: 0; - margin: var(--mm-spacing) auto; - padding: 0 !important; - width: 200px; -} diff --git a/src/components/Mdx/Hr.tsx b/src/components/Mdx/Hr.tsx deleted file mode 100644 index f4a0b7a2e..000000000 --- a/src/components/Mdx/Hr.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Hr.module.scss'; - -const Hr: React.FC> = ({ - className, - ...props -}) => ( -
    -); - -Hr.propTypes = { - className: PropTypes.string, -}; - -export default Hr; diff --git a/src/components/Mdx/Img.module.scss b/src/components/Mdx/Img.module.scss deleted file mode 100644 index 51acbe356..000000000 --- a/src/components/Mdx/Img.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.img { - margin: 0 40px; -} diff --git a/src/components/Mdx/Img.tsx b/src/components/Mdx/Img.tsx deleted file mode 100644 index 086ac76b1..000000000 --- a/src/components/Mdx/Img.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import classNames from 'classnames'; -import { graphql,useStaticQuery } from 'gatsby'; -import { GatsbyImage } from 'gatsby-plugin-image'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Img.module.scss'; - -const Img: React.FC> = (props) => { - const data = useStaticQuery(graphql`{ - placeholderImage: file(relativePath: {eq: "gatsby-astronaut.png"}) { - childImageSharp { - gatsbyImageData(width: 300, layout: CONSTRAINED) - } - } -} -`); - - return ( - - ); -}; - -Img.propTypes = { - alt: PropTypes.string, - className: PropTypes.string, - title: PropTypes.string, -}; - -export default Img; diff --git a/src/components/Mdx/Li.module.scss b/src/components/Mdx/Li.module.scss deleted file mode 100644 index 560d029b3..000000000 --- a/src/components/Mdx/Li.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use '../../styles/variables'; - -.li { - font-size: 16px; - line-height: 26px; - margin-bottom: calc(var(--mm-spacing) / 3); -} - -.li::marker { - color: #ccc; -} diff --git a/src/components/Mdx/Li.tsx b/src/components/Mdx/Li.tsx deleted file mode 100644 index 91d919a3d..000000000 --- a/src/components/Mdx/Li.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Li.module.scss'; - -const Li: React.FC> = ({ - className, - ...props -}) => ( -
  • - {props.children} -
  • -); - -Li.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Li; diff --git a/src/components/Mdx/Ol.module.scss b/src/components/Mdx/Ol.module.scss deleted file mode 100644 index 695580177..000000000 --- a/src/components/Mdx/Ol.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use '../../styles/variables'; - -.ol { - list-style-type: decimal; - margin: calc(var(--mm-spacing) / 2) var(--mm-spacing); - padding-left: calc(var(--mm-spacing) / 2); -} - -.ol .ol { - margin: calc(var(--mm-spacing) / 4) 0; -} diff --git a/src/components/Mdx/Ol.tsx b/src/components/Mdx/Ol.tsx deleted file mode 100644 index fc5f32679..000000000 --- a/src/components/Mdx/Ol.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Ol.module.scss'; - -// Using React.HTMLProps throws an error -const Ol: React.FC> = ({ - className, - ...props -}) => ( -
      - {props.children} -
    -); - -Ol.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Ol; diff --git a/src/components/Mdx/P.module.scss b/src/components/Mdx/P.module.scss deleted file mode 100644 index 4e2327b63..000000000 --- a/src/components/Mdx/P.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -@use '../../styles/variables'; - -.p { - color: var(--mm-color-primary-text); - font-size: 16px; - line-height: 26px; - margin: calc(var(--mm-spacing) / 2) 0; -} diff --git a/src/components/Mdx/P.tsx b/src/components/Mdx/P.tsx deleted file mode 100644 index d1acf3ebf..000000000 --- a/src/components/Mdx/P.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './P.module.scss'; - -const P: React.FC> = ({ - className, - ...props -}) => ( -

    - {props.children} -

    -); - -P.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default P; diff --git a/src/components/Mdx/Pre/Button.module.scss b/src/components/Mdx/Pre/Button.module.scss deleted file mode 100644 index d71a125ab..000000000 --- a/src/components/Mdx/Pre/Button.module.scss +++ /dev/null @@ -1,39 +0,0 @@ -.button { - background: none; - border: 0; - border-left: 1px solid rgba(255, 255, 255, 0.2); - border-right: 1px solid rgba(0, 0, 0, 0.2); - color: #ccc; - cursor: pointer; - font-size: 12px; - font-weight: 500; - height: 100%; - letter-spacing: 1px; - padding: 0 calc(var(--mm-spacing) / 4); - position: relative; -} - -.button:hover { - background: rgba(255, 255, 255, 0.07); - color: #ddd; -} - -.button:first-of-type { - border-radius: var(--mm-border-radius) 0 0 0; -} - -.button:last-of-type::after { - background-color: rgba(255, 255, 255, 0.2); - content: ' '; - display: inline-block; - height: 100%; - position: absolute; - right: -2px; - top: 0; - width: 1px; -} - -.button.active { - background: rgba(255, 255, 255, 0.16); - color: #fff; -} diff --git a/src/components/Mdx/Pre/Button.tsx b/src/components/Mdx/Pre/Button.tsx deleted file mode 100644 index 54a156be2..000000000 --- a/src/components/Mdx/Pre/Button.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Button.module.scss'; - -interface IButton { - children: React.ReactNode; - className?: string; - isActive?: boolean; -} - -const Button: React.FC< - IButton & React.HTMLProps -> = (props) => { - const { children, className, isActive, ...rest } = props; - - return ( - - ); -}; - -Button.propTypes = { - children: PropTypes.any.isRequired, - className: PropTypes.string, - isActive: PropTypes.bool, -}; - -export default Button; diff --git a/src/components/Mdx/Pre/Code.dark-theme.css b/src/components/Mdx/Pre/Code.dark-theme.css deleted file mode 100644 index 02a081311..000000000 --- a/src/components/Mdx/Pre/Code.dark-theme.css +++ /dev/null @@ -1,274 +0,0 @@ -/* stylelint-disable */ -code[class*='language-'], -pre[class*='language-'] { - color: #b3bac6; - font-family: var(--mm-font-stack-monospace); - font-size: 14px; - - hyphens: none; - line-height: 1.5em; - - tab-size: 2; - text-align: left; - white-space: pre; - word-break: normal; - word-spacing: normal; - word-wrap: normal; -} - -code[class*='language-'] ::selection, -pre[class*='language-'] ::selection { - background: rgba(255, 255, 255, 0.08); -} - -code[class*='language-'] ::selection, -pre[class*='language-'] ::selection { - background: rgba(255, 255, 255, 0.08); -} - -:not(pre) > code[class*='language-'] { - border-radius: 0.2em; - padding: 0.1em; - white-space: normal; -} - -pre[class*='language-'] { - margin: 0.5em 0; - overflow: auto; - padding: calc(var(--mm-spacing) / 2); - position: relative; -} - -.language-css > code, -.language-javascript > code, -.language-sass > code, -.language-scss > code { - color: #e9c782; -} - -.language-typescript > code { - color: #e5767e; -} - -[class*='language-'] .namespace { - opacity: 0.7; -} - -.token.atrule { - color: #cd83e3; -} - -.token.attr-name { - color: #e9c782; -} - -.token.attr-value { - color: #a2ca82; -} - -.token.attribute { - color: #a2ca82; -} - -.token.boolean { - color: #e9c782; -} - -.token.builtin { - color: #e9c782; -} - -.token.cdata { - color: #80cbc4; -} - -.token.char { - color: #80cbc4; -} - -.token.class { - color: #e9c782; -} - -.token.class-name { - color: #e9c782; -} - -.token.color { - color: #e9c782; -} - -.token.comment { - color: #898e98; - font-style: italic; -} - -.token.constant { - color: #e9c782; -} - -.token.deleted { - color: #e5767e; -} - -.token.doctype { - color: #546e7a; -} - -.token.entity { - color: #e5767e; -} - -.token.function { - color: #6ab9f3; -} - -.token.hexcode { - color: #e9c782; -} - -.token.id { - color: #cd83e3; -} - -.token.important { - color: #cd83e3; -} - -.token.interpolation-punctuation.punctuation { - color: #cd83e3; -} - -.token.inserted { - color: #80cbc4; -} - -.token.keyword { - color: #cd83e3; -} - -.token.number { - color: #e9c782; -} - -.token.operator { - color: #5ab2be; -} - -.language-javascript .token.operator, -.language-typescript .token.operator { - color: #b4bbc7; -} - -.token.prolog { - color: #546e7a; -} - -.token.parameter { - color: #e5767e; -} - -.token.property { - color: #e5767e; -} - -.token.pseudo-class { - color: #a2ca82; -} - -.token.pseudo-element { - color: #a2ca82; -} - -.token.punctuation { - color: #b4bbc7; -} - -.token.regex { - color: #e9c782; -} - -.token.selector { - color: #e5767e; -} - -.token.string { - color: #a2ca82; -} - -.token.symbol { - color: #c792ea; -} - -.token.tag { - color: #e5767e; -} - -.token.unit { - color: #e5767e; -} - -.token.url { - color: #e5767e; -} - -.token.variable { - color: #e5767e; -} - -.line-numbers .line-numbers-rows { - border-color: transparent !important; - font-family: var(--mm-font-stack-monospace) !important; - font-size: 18px; -} - -.line-numbers-rows > span::before { - color: #898e98 !important; -} - -.token.tab::before { - content: '\279D' !important; -} - -.token.tab:not(:empty)::before, -.token.cr::before, -.token.crlf::before, -.token.lf::before, -.token.space::before { - color: #58577e !important; - opacity: 1 !important; -} - -.token.cr::before, -.token.crlf::before, -.token.lf::before { - display: none; -} - -.token.indent { - border-left: 1px solid #58577e; - margin-left: 4px; - padding-left: 4px; -} - -.token.indent:blank { - display: none; -} - -.token.indent .token.space:nth-of-type(2n), -.token.indent .token.tab { - border-right: 1px solid #58577e; - margin-right: 4px; - padding-right: 4px; -} - -.token.indent .token.space:last-of-type, -.token.indent .token.tab:last-of-type { - border-right: 0; - margin-right: 0; -} - -.line-highlight { - background: rgba(255, 255, 255, 0.05) !important; - background: linear-gradient(90deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0)) !important; -} diff --git a/src/components/Mdx/Pre/Code.module.scss b/src/components/Mdx/Pre/Code.module.scss deleted file mode 100644 index e64ede844..000000000 --- a/src/components/Mdx/Pre/Code.module.scss +++ /dev/null @@ -1,82 +0,0 @@ -/* stylelint-disable */ -@use '../../../styles/variables'; - -.container { - background-color: var(--mm-color-background-code); - border-left: 1px solid rgba(255, 255, 255, 0.1); - border-radius: var(--mm-border-radius); - border-right: 1px solid rgba(255, 255, 255, 0.1); - border-top: 1px solid rgba(255, 255, 255, 0.3); - padding: 5px; - position: relative; - z-index: 2; -} - -.container__expandable { - padding: 5px 5px 45px; - - &::after { - background: linear-gradient(0deg, rgb(25, 62, 78) 10%, rgba(0, 0, 0, 0)) !important; - bottom: 40px; - content: ' '; - height: 100%; - left: 0; - max-height: 300px; - opacity: 1; - pointer-events: none; - position: absolute; - width: 100%; - } -} - -.container__expandable.container__expanded::after { - opacity: 0; -} - -.pre { - display: flex; - font-family: var(--mm-font-stack-monospace) !important; - grid-area: code; - height: 100%; - margin: var(--mm-spacing) auto 0 !important; - max-height: 500px; - - overflow-y: hidden !important; - - @include variables.scrollbars(); -} - -.container__expanded .pre { - max-height: 100000px; - transition: max-height 0.5s cubic-bezier(0, 1, 0, 1); -} - -.pre code { - background: transparent; -} - -.expandBtn { - background: rgba(255, 255, 255, 0.1); - border: 0; - border-radius: 0 0 var(--mm-border-radius) var(--mm-border-radius); - border-top: 1px solid rgba(255, 255, 255, 0.15); - bottom: 0; - color: #bbb; - cursor: pointer; - display: inline-block; - height: 40px; - left: 50%; - line-height: 40px; - position: absolute; - transform: translateX(-50%); - width: 100%; -} - -.expandBtn:hover { - background: rgba(255, 255, 255, 0.15); - color: lighten(#b4bbc7, 10); -} - -.container__expanded .expandBtn svg { - transform: rotate(180deg); -} diff --git a/src/components/Mdx/Pre/Code.tsx b/src/components/Mdx/Pre/Code.tsx deleted file mode 100644 index cbf7d64d5..000000000 --- a/src/components/Mdx/Pre/Code.tsx +++ /dev/null @@ -1,173 +0,0 @@ -/* eslint-disable simple-import-sort/imports */ -// Disabling import sort because prismjs needs to be imported before -// the theme and components - -import classNames from 'classnames'; -import Prism from 'prismjs'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaAngleDoubleDown } from 'react-icons/fa'; - -import { ILanguage } from '../../../languages'; -import * as styles from './Code.module.scss'; -import './Code.dark-theme.css'; - -import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace.js'; - -interface ICode { - children: React.ReactNode; - highlightLines?: string; - language: ILanguage; - showLineNumbers?: boolean; -} - -const hasScrollbar = ( - $el: HTMLElement -): boolean => $el.scrollHeight > $el.offsetHeight; - -const Code: React.FC = (props) => { - const { - children, - language, - highlightLines, - showLineNumbers, - } = props; - - const preRef = React.createRef(); - const [ - isExpandable, - setIsExpandable, - ] = React.useState(false); - const [ - isExpanded, - setIsExpanded, - ] = React.useState(false); - - let promises: Promise[] = []; - - if (language.prismSettings.importScript) { - promises = [ - ...promises, - // Needed for PHP - import('prismjs/components/prism-markup-templating.js' as string), - // To add/remove languages, you also have to update languages.ts - import(`prismjs/components/prism-${language.id}.js`), - ]; - } - - if (language.prismSettings.cli) { - promises = [ - ...promises, - import( - 'prismjs/plugins/command-line/prism-command-line.css' as string - ), - import( - 'prismjs/plugins/command-line/prism-command-line.js' as string - ), - ]; - } else { - promises = [ - ...promises, - Promise.all([ - import( - 'prismjs/plugins/line-numbers/prism-line-numbers.css' as string - ), - import( - 'prismjs/plugins/line-numbers/prism-line-numbers.js' as string - ), - ]).then(() => Promise.all([ - import( - 'prismjs/plugins/line-highlight/prism-line-highlight.js' as string - ), - import( - 'prismjs/plugins/line-highlight/prism-line-highlight.css' as string - ), - ])), - ]; - } - - const mmReactCodeMount = new CustomEvent('mm-react-code-mount'); - - React.useEffect(() => { - Promise.race(promises).then(() => { - document.dispatchEvent(mmReactCodeMount); - }); - - Promise.all(promises).then(() => { - const { indentSize, indentStyle } = language.prismSettings.whitespace; - - Prism.plugins.NormalizeWhitespace.setDefaults({ - 'left-trim': true, - 'remove-indent': true, - 'remove-initial-line-feed': true, - 'remove-trailing': true, - 'right-trim': true, - 'spaces-to-tabs': indentStyle === 'tab' ? indentSize : undefined, - 'tabs-to-spaces': indentStyle === 'space' ? indentSize : undefined, - }); - - if(preRef.current) { - Prism.highlightAllUnder(preRef.current as Element); - } - }); - }); - - React.useEffect(() => { - setIsExpandable(hasScrollbar(preRef.current as HTMLElement)); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - isExpandable, - ]); - - const handleExpansionToggle = (): void => setIsExpanded(!isExpanded); - - return ( -
    -
    -        {children}
    -      
    - {isExpandable && ( - - )} -
    - ); -}; - -Code.defaultProps = { - showLineNumbers: true, -}; - -Code.propTypes = { - children: PropTypes.node.isRequired, - highlightLines: PropTypes.string, - language: PropTypes.any.isRequired, - // eslint-disable-next-line react/boolean-prop-naming - showLineNumbers: PropTypes.bool.isRequired, -}; - -export default Code; diff --git a/src/components/Mdx/Pre/Pre.module.scss b/src/components/Mdx/Pre/Pre.module.scss deleted file mode 100644 index 63577aaf6..000000000 --- a/src/components/Mdx/Pre/Pre.module.scss +++ /dev/null @@ -1,86 +0,0 @@ -@use '../../../styles/variables'; - -.container { - color: #d5ddeb; - display: inline-block; - font-size: 14px; - position: relative; - width: 100%; -} - -.toolbar { - background-color: #3d5c6a; - border-radius: var(--mm-border-radius) var(--mm-border-radius) 0 0; - border-top: 1px solid rgba(255, 255, 255, 0.3); - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - display: grid; - grid-auto-flow: column; - grid-template-columns: 1fr max-content; - height: var(--mm-spacing); - position: sticky; - top: calc(var(--page-header-height) + 15px); - width: 100%; - z-index: 3; -} - -.toolbar::before { - background: #fff; - content: ' '; - display: block; - height: 15px; - position: absolute; - top: -16px; - width: 100%; -} - -.toolbar + [class^='Pre-module--content'] [class^='Code-module--container'] { - border-radius: 0 0 var(--mm-border-radius) var(--mm-border-radius); - border-top: 0; -} - -.copyBtn { - border-radius: 0 !important; - position: relative; -} - -.copyBtn__checkedContent { - display: none; -} - -.copyBtn__checkedContent svg { - fill: #56f000; -} - -.copyBtn__isCopying .copyBtn__content { - visibility: hidden; -} - -.copyBtn__isCopying .copyBtn__checkedContent { - display: inline-block; - left: 50%; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); -} - -@include variables.breakpoint('lg') { - .toolbar__buttons { - display: block; - } -} - -.content { - position: relative; - top: 0; -} - -/* TODO - target class names instead of element */ -.container pre { - margin-top: 0 !important; -} - -.hidden { - max-height: 0; - overflow: hidden; - visibility: hidden; -} diff --git a/src/components/Mdx/Pre/Pre.tsx b/src/components/Mdx/Pre/Pre.tsx deleted file mode 100644 index d36d47d54..000000000 --- a/src/components/Mdx/Pre/Pre.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import classNames from 'classnames'; -import debounce from 'lodash.debounce'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaCheck, FaCopy } from 'react-icons/fa'; - -import useIsClient from '../../../hooks/useIsClient'; -import { ILanguage,languages } from '../../../languages'; -import Button from './Button'; -import Code from './Code'; -import Wrapper from './Wrapper'; - -import * as styles from './Pre.module.scss'; - -interface IPre { - className?: string; - hasWrapper?: boolean; - hidden?: boolean; - highlightLines?: string; - select?: React.ReactElement>; - showLineNumbers?: boolean; - tabs?: React.ReactElement>; -} - -const extractCli = (className: string): string => className && className - .startsWith('language-cli-') ? 'language-markdown' : className; - -const Pre: React.FC & IPre> = (props) => { - const { - children, - className, - hasWrapper, - highlightLines, - select, - showLineNumbers, - tabs, - ...rest - } = props; - - const { isClient, key } = useIsClient(); - - let child = React.Children.toArray(children)[0] as React.ReactElement; - - const extractedClassName = extractCli(child.props.className); - - child = React.cloneElement(child, { - className: extractedClassName, - }); - - const language = languages.find( - language => `language-${language.id}` === extractedClassName - ) || { - id: extractedClassName?.replace('language-', ''), - label: extractedClassName?.replace('language-', ''), - prismSettings: languages.find( - language => language.id === '*' - )?.prismSettings, - } as ILanguage; - - /* ---------- */ - - const [ - isCopying, - setIsCopying, - ] = React.useState(false); - - const handleCopyClick = (): void => { - setIsCopying(true); - - if (navigator.clipboard) { - navigator.clipboard.writeText(child.props.children.trim()) - .then(() => { - setTimeout(() => { - setIsCopying(false); - }, 3000); - }); - } - }; - - /* ---------- */ - - const [ - cachedTabsWidth, - cacheTabsWidth, - ] = React.useState(0); - - const [ - languageUIType, - setLanguageUIType, - ] = React.useState<'select' | 'tabs'>('tabs'); - - const toolbarRef = React.useRef(null); - const tabsRef = React.useRef(null); - - const handleWindowResize = React.useCallback(() => { - const tabsWidth = cachedTabsWidth || tabsRef.current?.offsetWidth || 0; - - if (!cachedTabsWidth && tabsRef.current?.offsetWidth) { - cacheTabsWidth(tabsRef.current.offsetWidth); - } - - if (!toolbarRef.current?.offsetWidth) { - return; - } - - const toolbarWidth = toolbarRef.current.offsetWidth; - - if (toolbarWidth - tabsWidth < 200 ) { - setLanguageUIType('select'); - } else { - setLanguageUIType('tabs'); - } - }, [ - cachedTabsWidth, - ]); - - const debouncedHandleWindowResize = React.useMemo( - () => debounce(handleWindowResize, 300), - [ - handleWindowResize, - ] - ); - - // eslint-disable-next-line react-hooks/exhaustive-deps - React.useLayoutEffect(() => { - if (tabsRef.current?.offsetWidth) { - cacheTabsWidth(tabsRef.current.offsetWidth); - } - - window.addEventListener('resize', debouncedHandleWindowResize); - handleWindowResize(); - - return () => window.removeEventListener( - 'resize', - debouncedHandleWindowResize - ); - }); - - if ( !isClient ) return null; - - const codeExample = ( -
    -
    -
    - {languageUIType === 'tabs' ? ( - - {tabs} - - ) : select} -
    -
    - {Object.prototype.hasOwnProperty.call(navigator, 'clipboard') && ( - - )} -
    -
    -
    - - {child} - -
    -
    - ); - - if (hasWrapper) { - return ( - - {codeExample} - - ); - } - - return codeExample; -}; - - -Pre.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - hasWrapper: PropTypes.bool, - hidden: PropTypes.bool, - highlightLines: PropTypes.string, - select: PropTypes.any, - showLineNumbers: PropTypes.bool, - tabs: PropTypes.any, -}; - -export default Pre; diff --git a/src/components/Mdx/Pre/Wrapper.module.scss b/src/components/Mdx/Pre/Wrapper.module.scss deleted file mode 100644 index d34943961..000000000 --- a/src/components/Mdx/Pre/Wrapper.module.scss +++ /dev/null @@ -1,9 +0,0 @@ -@use '../../../styles/variables'; - -.wrapper { - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: var(--mm-spacing) 0 0; -} diff --git a/src/components/Mdx/Pre/Wrapper.tsx b/src/components/Mdx/Pre/Wrapper.tsx deleted file mode 100644 index 0db227793..000000000 --- a/src/components/Mdx/Pre/Wrapper.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Wrapper.module.scss'; - -interface IWrapper { - children?: React.ReactNode; - className?: string; -} - -const Wrapper: React.FC = (props) => { - const { children, className, ...rest } = props; - return ( -
    - {children} -
    - ); -}; - -Wrapper.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -}; - -export default Wrapper; diff --git a/src/components/Mdx/Pre/index.ts b/src/components/Mdx/Pre/index.ts deleted file mode 100644 index 361c4757d..000000000 --- a/src/components/Mdx/Pre/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as default } from './Pre'; diff --git a/src/components/Mdx/Strong.module.scss b/src/components/Mdx/Strong.module.scss deleted file mode 100644 index b69cce902..000000000 --- a/src/components/Mdx/Strong.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.strong { - font-weight: 700; -} diff --git a/src/components/Mdx/Strong.tsx b/src/components/Mdx/Strong.tsx deleted file mode 100644 index e1bb1e267..000000000 --- a/src/components/Mdx/Strong.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Strong.module.scss'; - -const Strong: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Strong.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Strong; diff --git a/src/components/Mdx/Table.module.scss b/src/components/Mdx/Table.module.scss deleted file mode 100644 index 6f32f423a..000000000 --- a/src/components/Mdx/Table.module.scss +++ /dev/null @@ -1,36 +0,0 @@ -@use '../../styles/variables'; - -.wrapper { - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: var(--mm-spacing) 0; -} - -.container { - background-color: var(--mm-color-sidebar); - border-bottom: 1px solid var(--mm-color-border); - border-left: 1px solid #eee; - border-radius: var(--mm-border-radius); - border-right: 1px solid #eee; - border-top: 1px solid #eee; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - color: #ccc; - display: inline-block; - margin: 0 auto; - max-width: 100%; - overflow-x: scroll; - position: relative; - width: 100%; - z-index: 2; - - @include variables.scrollbars(rgba(0,0,0,0.2)); -} - -.table { - font-size: 1rem; - line-height: 1rem; - overflow-x: auto; - width: 100%; -} diff --git a/src/components/Mdx/Table.tsx b/src/components/Mdx/Table.tsx deleted file mode 100644 index 85e93f235..000000000 --- a/src/components/Mdx/Table.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Table.module.scss'; - -const Table: React.FC> = ({ - className, - ...props -}) => ( -
    -
    - - {props.children} -
    -
    -
    -); - -Table.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Table; diff --git a/src/components/Mdx/Tbody.tsx b/src/components/Mdx/Tbody.tsx deleted file mode 100644 index 8405dcedb..000000000 --- a/src/components/Mdx/Tbody.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -const Tbody: React.FC> = ({ ...props }) => ( - - {props.children} - -); - -Tbody.propTypes = { - children: PropTypes.node.isRequired, -}; - -export default Tbody; diff --git a/src/components/Mdx/Td.module.scss b/src/components/Mdx/Td.module.scss deleted file mode 100644 index 484049967..000000000 --- a/src/components/Mdx/Td.module.scss +++ /dev/null @@ -1,34 +0,0 @@ -.td { - border-top: 1px solid #eee; - color: var(--mm-color-primary-text); - font-size: 12px !important; - line-height: 18px !important; - padding: 16px; -} - -.td * { - max-width: initial !important; - min-width: initial !important; - width: auto !important; -} - -.td *:not([class^='Tag-module--']) { - font-size: 12px; - line-height: 2em; - margin: calc(var(--mm-spacing) / 4) 0; - max-width: initial !important; - min-width: initial !important; - width: auto !important; -} - -.td > *:first-child { - margin-top: 0; -} - -.td > *:last-child { - margin-bottom: 0; -} - -.td [class^='Code-module'] { - white-space: nowrap; -} diff --git a/src/components/Mdx/Td.tsx b/src/components/Mdx/Td.tsx deleted file mode 100644 index f12517f44..000000000 --- a/src/components/Mdx/Td.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Td.module.scss'; - -const Td: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Td.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -}; - -export default Td; diff --git a/src/components/Mdx/Th.module.scss b/src/components/Mdx/Th.module.scss deleted file mode 100644 index cf2f14f03..000000000 --- a/src/components/Mdx/Th.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -.th { - border-bottom: 1px solid var(--mm-color-border); - color: var(--mm-color-display-text); - font-family: var(--mm-font-stack-display); - font-size: 14px; - font-weight: 700; - padding: 16px; - position: sticky; - text-align: left; - white-space: nowrap; -} diff --git a/src/components/Mdx/Th.tsx b/src/components/Mdx/Th.tsx deleted file mode 100644 index 6dfb5e2e1..000000000 --- a/src/components/Mdx/Th.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { MDXProvider } from '@mdx-js/react'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Th.module.scss'; - -const Th: React.FC> = ({ - className, - ...props -}) => ( - - {/* eslint-disable-next-line max-len */ } - {/* @ts-expect-error: @type for @mdx-js/react has implicit children which is incompat with react 18 */} - - {props.children} - - -); - -Th.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Th; diff --git a/src/components/Mdx/Thead.module.scss b/src/components/Mdx/Thead.module.scss deleted file mode 100644 index faa996667..000000000 --- a/src/components/Mdx/Thead.module.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use '../../styles/variables'; - -.thead { - border-bottom: 1px solid var(--mm-color-border); -} diff --git a/src/components/Mdx/Thead.tsx b/src/components/Mdx/Thead.tsx deleted file mode 100644 index c57b3b79f..000000000 --- a/src/components/Mdx/Thead.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Thead.module.scss'; - -const Thead: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Thead.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Thead; diff --git a/src/components/Mdx/Tr.module.scss b/src/components/Mdx/Tr.module.scss deleted file mode 100644 index 68521d0cd..000000000 --- a/src/components/Mdx/Tr.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -thead .tr th { - background: rgba(255, 255, 255, 0.7); -} - -tbody .tr:nth-of-type(even) td { - background: rgba(255, 255, 255, 0.7); -} diff --git a/src/components/Mdx/Tr.tsx b/src/components/Mdx/Tr.tsx deleted file mode 100644 index 6f0cb36e9..000000000 --- a/src/components/Mdx/Tr.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Tr.module.scss'; - -const Tr: React.FC> = ({ - className, - ...props -}) => ( - - {props.children} - -); - -Tr.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Tr; diff --git a/src/components/Mdx/Ul.module.scss b/src/components/Mdx/Ul.module.scss deleted file mode 100644 index eb35111f1..000000000 --- a/src/components/Mdx/Ul.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use '../../styles/variables'; - -.ul { - list-style-type: disc; - margin: var(--mm-spacing) 0 var(--mm-spacing) calc(var(--mm-spacing) / 2); - padding-left: calc(var(--mm-spacing) / 2); -} - -.ul .ul { - margin: calc(var(--mm-spacing) / 4) 0; -} diff --git a/src/components/Mdx/Ul.tsx b/src/components/Mdx/Ul.tsx deleted file mode 100644 index 9c2508017..000000000 --- a/src/components/Mdx/Ul.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import * as styles from './Ul.module.scss'; - -const Ul: React.FC> = ({ - className, - ...props -}) => ( -
      - {props.children} -
    -); - -Ul.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Ul; diff --git a/src/components/Mdx/index.ts b/src/components/Mdx/index.ts deleted file mode 100644 index cf2ac3f9c..000000000 --- a/src/components/Mdx/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Any component exported here will be made available for use in MDX files -// eslint-disable-next-line max-len -// Reference: https://github.com/mdx-js/mdx/blob/master/docs/getting-started/_table-of-components.mdx -export { Link } from 'gatsby'; - -export { default as Alert } from '../Alert'; -export { default as CodeSet } from '../CodeSet'; -export { default as Example } from '../Example'; -export { default as GeoIPCrontab } from '../GeoIPCrontab'; -export { default as IpAddresses } from '../IpAddresses'; -export * from '../LinkGroup'; -export * from '../Schema'; -export { default as ReleaseNote } from '../ReleaseNote'; - -export { default as a } from './A'; -export { default as blockquote } from './Blockquote'; -export { default as CsvBlockTable } from '../CsvBlockTable'; -export { default as CsvLocationTable } from '../CsvLocationTable'; -export { default as inlineCode } from './Code'; -export { default as del } from './Del'; -export { default as em } from './Em'; -export { default as h1 } from './H1'; -export { default as h2 } from './H2'; -export { default as h3 } from './H3'; -export { default as h4 } from './H4'; -export { default as h5 } from './H5'; -export { default as h6 } from './H6'; -export { default as hr } from './Hr'; -export { default as img } from './Img'; -export { default as li } from './Li'; -export { default as ol } from './Ol'; -export { default as p } from './P'; -export { default as pre } from './Pre'; -export { default as strong } from './Strong'; -export { default as table } from './Table'; -export { default as tbody } from './Tbody'; -export { default as td } from './Td'; -export { default as th } from './Th'; -export { default as tr } from './Tr'; -export { default as thead } from './Thead'; -export { default as ul } from './Ul'; -export { default as CsvFileExamples } from '../CsvExampleFiles'; -export { default as DatabaseChanges } from '../DatabaseChanges'; -export { default as DatabaseSizes } from '../DatabaseSizes'; -export { default as MmdbFileExamples } from '../MmdbExampleFiles'; -export { default as ZipFileContent } from '../ZipFileContent'; diff --git a/src/components/MmdbExampleFiles.tsx b/src/components/MmdbExampleFiles.tsx deleted file mode 100644 index 4a232a629..000000000 --- a/src/components/MmdbExampleFiles.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { a as A, li as Li, p as P, ul as Ul } from './Mdx'; - -interface IExampleFiles { - files: { - filename: string; - link: string; - }[] -} - -const MmdbExampleFiles: React.FC = (props) => { - const { files } = props; - const fileItems = files.map((file) => ( -
  • - - {file.filename} - -
  • - )); - - return ( - <> -

    We maintain test MMDB files on GitHub:

    - -

    -

      - {fileItems} -
    -

    - -

    - Alternatively, you can - {' '} - - view all of our MMDB test data on GitHub - - . -

    - - ); -}; - -MmdbExampleFiles.propTypes = { - files: PropTypes.array.isRequired, -}; - -export default MmdbExampleFiles; diff --git a/src/components/ProductIcon.module.scss b/src/components/ProductIcon.module.scss deleted file mode 100644 index a0d79bdb4..000000000 --- a/src/components/ProductIcon.module.scss +++ /dev/null @@ -1,52 +0,0 @@ -.container { - --mm-product-icon-stroke-width: 6px; - background: linear-gradient(var(--page-type-color), rgba(0, 119, 194, 1)); - border-radius: calc(var(--mm-border-radius) * 3); - box-shadow: var(--mm-overview-heading-drop-shadow), - inset 0 0 0 var(--mm-product-icon-stroke-width) rgba(255, 255, 255, 0.35); - display: grid; - height: 100px; - width: 100px; -} - -@supports (transform-style: preserve-3d) { - .container { - position: relative; - transform-style: preserve-3d; - z-index: 1; - - &::before { - background: #00a7e5; - border-radius: calc(var(--mm-border-radius) * 3); - content: ' '; - display: block; - height: 100%; - position: absolute; - transform: translateZ(-1px); - width: 100%; - } - } -} - -.icon { - align-self: center; - fill: #fff; - filter: drop-shadow(1px 2px 5px rgba(0, 119, 194, 1)); - height: 100%; - justify-self: center; - max-height: 70%; - max-width: 70%; - width: 100%; -} - -.geoip { - --page-type-color: rgba(0, 255, 102, 0.5); -} - -.geolite { - --page-type-color: rgba(255, 255, 0, 0.5); -} - -.minfraud { - --page-type-color: rgba(255, 0, 136, 0.5); -} diff --git a/src/components/ProductIcon.tsx b/src/components/ProductIcon.tsx deleted file mode 100644 index 32b9f4160..000000000 --- a/src/components/ProductIcon.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import { IconType } from 'react-icons'; - -import { Icons } from '../assets'; - -import * as styles from './ProductIcon.module.scss'; - -type SvgElement = React.FC> - -type Icon = SvgElement | string | IconType; - -interface IProductIcon { - className?: string; - family?: 'geoip' | 'geolite' | 'minfraud', - svg: Icon; -} - -export const isSvgString = ( - svg: Icon -): svg is string => typeof svg === 'string' - || (svg as unknown) instanceof String; - -const ProductIcon: React.FC< - React.HTMLProps & IProductIcon -> = (props) => { - const svg = props.svg; - - // eslint-disable-next-line security/detect-object-injection - const Icon = isSvgString(svg) ? Icons[svg] : svg; - - return ( -
    - -
    - ); -}; - -ProductIcon.propTypes = { - className: PropTypes.string, - family: PropTypes.oneOf([ - 'geoip', - 'geolite', - 'minfraud', - ] as const), - svg: PropTypes.oneOfType([ - PropTypes.func.isRequired, - PropTypes.string.isRequired, - ]).isRequired, -}; - -export default ProductIcon; diff --git a/src/components/ReleaseNote.module.scss b/src/components/ReleaseNote.module.scss deleted file mode 100644 index f47cde742..000000000 --- a/src/components/ReleaseNote.module.scss +++ /dev/null @@ -1,16 +0,0 @@ -@use '../styles/variables'; - -.article { - margin-bottom: calc(var(--mm-spacing) * 2); -} - -.title { - margin-bottom: calc(var(--mm-spacing) / 4); - margin-top: 0; -} - -.date { - display: block; - font-size: 16px; - font-style: italic; -} diff --git a/src/components/ReleaseNote.spec.tsx b/src/components/ReleaseNote.spec.tsx deleted file mode 100644 index a2c83ccd5..000000000 --- a/src/components/ReleaseNote.spec.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import H2 from './Mdx/H2'; -import ReleaseNote from './ReleaseNote'; - -// eslint-disable-next-line css-modules/no-unused-class -import * as styles from './ReleaseNote.module.scss'; - -describe('ReleaseNote', () => { - const component = mount( - -

    Hello world

    -
    - ); - - it('renders children', () => { - expect(component.find('p')).toHaveText('Hello world'); - }); - - it('renders humanized date', () => { - expect(component.find(`.${styles.date}`)).toHaveText('October 23, 2021'); - }); - - it('renders title with slugified id', () => { - const $title = component.find(H2); - - expect($title).toHaveText('Test Title'); - expect($title.prop('id')).toBe('test-title'); - }); - - it('throws an error if date prop is in wrong format', () => { - // silence prop type console error - console.error = jest.fn(); - - const badDate = () => { - mount( - -

    Hello world

    -
    - ); - }; - - expect(badDate).toThrow(); - }); -}); diff --git a/src/components/ReleaseNote.tsx b/src/components/ReleaseNote.tsx deleted file mode 100644 index 4d87523b0..000000000 --- a/src/components/ReleaseNote.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import GithubSlugger from 'github-slugger'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import H2 from './Mdx/H2'; - -import * as styles from './ReleaseNote.module.scss'; - -type Year = `${number}${number}${number}${number}`; -type Month = '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' - | '11' | '12'; -type Day = '01' | '02'| '03'| '04' | '05' | '06' | '07' | '08' | '09' | '10' - | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' - | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31'; - -interface IReleaseNote { - children: React.ReactNode; - date: `${Year}-${Month}-${Day}`; - title: string; -} - -const dateOptions = { - day: 'numeric', - month: 'long', - timeZone: 'America/New_York', - year: 'numeric', -}; - -const ReleaseNote: React.FC = (props) => { - // Assume publish time is around noon office standard time - const date = new Date(`${props.date} 12:00:00`); - //@ts-expect-error: Types are broken for DateTimeFormat - const humanDate = new Intl.DateTimeFormat('en-US', dateOptions).format(date); - - return ( -
    -

    - {props.title} -

    - - {humanDate} - - {props.children} -
    - ); -}; - -ReleaseNote.propTypes = { - children: PropTypes.node.isRequired, - date: function(props, propName, componentName) { - if ( - !/^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/.test( - // eslint-disable-next-line security/detect-object-injection - props[propName] - ) - ) - { - return new Error( - // eslint-disable-next-line security/detect-object-injection - `Invalid date \`${props[propName]}\` supplied to ${componentName}.` - ); - } - return null; - }, - title: PropTypes.string.isRequired, -}; - -export default ReleaseNote; diff --git a/src/components/Schema/Footnote.module.scss b/src/components/Schema/Footnote.module.scss deleted file mode 100644 index 7d50ece40..000000000 --- a/src/components/Schema/Footnote.module.scss +++ /dev/null @@ -1,29 +0,0 @@ -.container { - background: var(--mm-color-sidebar); - border-radius: 0 var(--mm-border-radius) var(--mm-border-radius) 0; - border-top: 1px solid var(--mm-color-border); - padding: calc(var(--mm-spacing) / 2); -} - -.container * { - color: #545454 !important; - font-size: 12px !important; - font-style: italic; - font-weight: 500; - line-height: 22px !important; - max-width: initial !important; - min-width: initial !important; - width: auto !important; -} - -.container > * { - margin: calc(var(--mm-spacing) / 4) 0; -} - -.container > *:first-child { - margin-top: 0; -} - -.container > *:last-child { - margin-bottom: 0; -} diff --git a/src/components/Schema/Footnote.spec.tsx b/src/components/Schema/Footnote.spec.tsx deleted file mode 100644 index f5352edd4..000000000 --- a/src/components/Schema/Footnote.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import Footnote from './Footnote'; - -describe('', () => { - it('renders children', () => { - const text = 'foo'; - const component = mount( - - {text} - - ); - - expect(component.text()).toBe(text); - }); -}); diff --git a/src/components/Schema/Footnote.tsx b/src/components/Schema/Footnote.tsx deleted file mode 100644 index 22dd4ced6..000000000 --- a/src/components/Schema/Footnote.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import * as styles from './Footnote.module.scss'; - -const Footnote: React.FC = (props) => { - const { children } = props; - - return ( -
    - {children} -
    - ); -}; - -Footnote.propTypes = { - children: PropTypes.node.isRequired, -}; - -export default Footnote; diff --git a/src/components/Schema/GeoIpSchema.spec.tsx b/src/components/Schema/GeoIpSchema.spec.tsx deleted file mode 100644 index b015ed65c..000000000 --- a/src/components/Schema/GeoIpSchema.spec.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import GeoIpSchema from './GeoIpSchema'; - -describe('', () => { - it('passes props to schema component', () => { - const props = { - children: ( -

    Foo

    - ), - json:{ - foo: 'foo', - }, - jsonPointer: '/', - name: 'Foo', - services: '*' as GeoIpServices, - }; - const component = mount( - - ); - - const schemaComponent = component.find('Schema'); - - expect(schemaComponent.props()).toStrictEqual({ - ...props, - productFamily: 'geoip', - }); - }); -}); diff --git a/src/components/Schema/GeoIpSchema.tsx b/src/components/Schema/GeoIpSchema.tsx deleted file mode 100644 index 40b037940..000000000 --- a/src/components/Schema/GeoIpSchema.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import Schema, { ISchema, schemaPropTypes } from './Schema'; - -interface IGeoIpSchema extends Omit{ - services?: GeoIpServices; -} - -const GeoIpSchema: React.FC = (props) => { - return ( - - ); -}; - -GeoIpSchema.propTypes = { - ...schemaPropTypes, - services: PropTypes.oneOfType([ - PropTypes.oneOf([ - '*', - ] as const), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'country', - 'city', - 'insights', - ] as const).isRequired, - ), - ]), -}; - -export default GeoIpSchema; diff --git a/src/components/Schema/GeoIpServiceTags.spec.tsx b/src/components/Schema/GeoIpServiceTags.spec.tsx deleted file mode 100644 index 290c1b98f..000000000 --- a/src/components/Schema/GeoIpServiceTags.spec.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import GeoIpServiceTags from './GeoIpServiceTags'; - -// eslint-disable-next-line css-modules/no-unused-class -import * as styles from './ServiceTag.module.scss'; - -describe('', () => { - it('renders all service tags', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Country"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="City"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).not.toHaveClassName(styles['tag__disabled']); - }); - - it('renders `country` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Country"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="City"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).toHaveClassName(styles['tag__disabled']); - }); - - it('renders `city` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Country"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="City"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).toHaveClassName(styles['tag__disabled']); - }); - - it('renders `insights` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Country"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="City"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).not.toHaveClassName(styles['tag__disabled']); - }); -}); diff --git a/src/components/Schema/GeoIpServiceTags.tsx b/src/components/Schema/GeoIpServiceTags.tsx deleted file mode 100644 index ce3db4372..000000000 --- a/src/components/Schema/GeoIpServiceTags.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import ServiceTag from './ServiceTag'; - -interface IServiceTags { - services: GeoIpServices; -} - -const GeoIpServiceTags: React.FC = (props) => { - const { services } = props; - - return ( -
    - - - - - -
    - ); -}; - -GeoIpServiceTags.propTypes = { - services: PropTypes.any.isRequired, -}; - -export default GeoIpServiceTags; diff --git a/src/components/Schema/MinFraudSchema.spec.tsx b/src/components/Schema/MinFraudSchema.spec.tsx deleted file mode 100644 index 4c9bcc60f..000000000 --- a/src/components/Schema/MinFraudSchema.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import MinFraudSchema from './MinFraudSchema'; - -describe('', () => { - it('passes props to schema component', () => { - const props = { - children: ( -

    Foo

    - ), - json:{ - foo: 'foo', - }, - jsonPointer: '/', - name: 'Foo', - services: '*' as MinFraudServices, - }; - - const component = mount( - - ); - - const schemaComponent = component.find('Schema'); - - expect(schemaComponent.props()).toStrictEqual({ - ...props, - productFamily: 'minfraud', - }); - }); -}); diff --git a/src/components/Schema/MinFraudSchema.tsx b/src/components/Schema/MinFraudSchema.tsx deleted file mode 100644 index 6c547e8a4..000000000 --- a/src/components/Schema/MinFraudSchema.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import Schema, { ISchema, schemaPropTypes } from './Schema'; - -interface IMinFraudSchema extends Omit { - services?: MinFraudServices; -} - -const MinFraudSchema: React.FC = (props) => { - - return ( - - ); -}; - -MinFraudSchema.propTypes = { - ...schemaPropTypes, - services: PropTypes.oneOfType([ - PropTypes.oneOf([ - '*', - ] as const), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'score', - 'insights', - 'factors', - ] as const).isRequired, - ), - ]), -}; - -export default MinFraudSchema; diff --git a/src/components/Schema/MinFraudServiceTags.spec.tsx b/src/components/Schema/MinFraudServiceTags.spec.tsx deleted file mode 100644 index 9e5b1f94e..000000000 --- a/src/components/Schema/MinFraudServiceTags.spec.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import MinFraudServiceTags from './MinFraudServiceTags'; - -// eslint-disable-next-line css-modules/no-unused-class -import * as styles from './ServiceTag.module.scss'; - -describe('', () => { - it('renders all service tags', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Score"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Factors"]') - ).not.toHaveClassName(styles['tag__disabled']); - }); - - it('renders `score` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Score"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Factors"]') - ).toHaveClassName(styles['tag__disabled']); - }); - - it('renders `insights` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Score"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).not.toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Factors"]') - ).toHaveClassName(styles['tag__disabled']); - }); - - it('renders `factors` service tag', () => { - const component = mount( - - ); - - expect( - component.find('Tag[children="Score"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Insights"]') - ).toHaveClassName(styles['tag__disabled']); - - expect( - component.find('Tag[children="Factors"]') - ).not.toHaveClassName(styles['tag__disabled']); - }); -}); diff --git a/src/components/Schema/MinFraudServiceTags.tsx b/src/components/Schema/MinFraudServiceTags.tsx deleted file mode 100644 index 65e458c44..000000000 --- a/src/components/Schema/MinFraudServiceTags.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import ServiceTag from './ServiceTag'; - -interface IServiceTags { - className?: string; - services: MinFraudServices; -} - -const MinFraudServiceTags: React.FC = (props) => { - const { className, services } = props; - - return ( -
    - - - - - -
    - ); -}; - -MinFraudServiceTags.propTypes = { - className: PropTypes.string, - services: PropTypes.any.isRequired, -}; - -export default MinFraudServiceTags; diff --git a/src/components/Schema/Property.module.scss b/src/components/Schema/Property.module.scss deleted file mode 100644 index ae0e1e64f..000000000 --- a/src/components/Schema/Property.module.scss +++ /dev/null @@ -1,166 +0,0 @@ -@use '../../styles/variables'; - -.row { - border: 2px solid transparent; - padding: calc(var(--mm-spacing) / 2); - position: relative; - scroll-margin-top: calc(var(--page-header-height) + var(--mm-spacing) + 46px); -} - -.row::before { - background: var(--mm-color-border); - content: ' '; - height: 1px; - left: calc(var(--mm-spacing) / 2); - position: absolute; - top: -3px; - width: calc(100% - var(--mm-spacing)); -} - -:not(.row) + .row::before { - border-top: 1px solid var(--mm-color-border); - height: 0; - left: -2px; - width: calc(100% + 4px); -} - -.row:last-of-type { - border-radius: 0 0 var(--mm-border-radius) var(--mm-border-radius); -} - -.row:last-of-type::after { - display: none; -} - -.row__targeted { - background: #effbff; - border: var(--mm-outline); - z-index: 2; -} - -.row__targeted::after { - display: none; -} - -.name { - border-bottom: 2px dotted var(--mm-color-primary-text); - color: var(--mm-color-primary-text); - font-family: var(--mm-font-stack-monospace); - font-size: 14px; - font-weight: 500; - line-height: 26px; - text-decoration: none; -} - -.type { - margin-left: calc(var(--mm-spacing) / 4); - vertical-align: middle; -} - -.deprecated { - background: #ffefee; - border-color: #ffd8d6; - color: #8c362e; - margin-left: calc(var(--mm-spacing) / 4); - vertical-align: middle; -} - -.row__targeted .type { - background: #fff; -} - -.description { - color: var(--mm-color-primary-text); - font-size: 14px; - line-height: 21px; - margin: calc(var(--mm-spacing) / 2) 0; -} - -.description [class^='P-module'] { - font-size: 14px; - margin-left: 0; - margin-right: 0; -} - -.description [class^='Table-module--wrapper'] { - padding: calc(var(--mm-spacing) / 2) 0; -} - -.description [class^='Th-module'], -.description [class^='Table-module--table'] [class^='P-module'], -.description [class^='Table-module--table'] [class^='Code-module'] { - font-size: 12px; - line-height: 20px; -} - -.description [class^='Th-module'], -.description [class^='Td-module'] { - padding: 8px; -} - -.description > [class^='Ul-module'] { - margin-left: 0; - margin-right: 0; - max-width: calc(100vw - calc(var(--mm-spacing) * 3 + 6px)); - overflow-x: scroll; - padding-left: calc(var(--mm-spacing) / 2) !important; -} - -.description > * { - max-width: auto !important; - min-width: auto !important; -} - -.description > *:first-child { - margin-top: 0 !important; -} - -.description > *:last-child { - margin-bottom: 0 !important; -} - - -.row__targeted .example-value { - background: var(--mm-color-background); -} - -.schemaLink__tag { - margin: 0 calc(var(--mm-spacing) / 4) calc(var(--mm-spacing) / 4) 0; -} - -.schemaLink__tag:hover { - background: #fff; -} - -.schemaLink__tag::after { - content: '→'; - margin-left: 4px; -} - -.tags__schemaTag { - background: #fffaf1; - border-color: #ffe5bb; - color: #764b13; - margin: 0 calc(var(--mm-spacing) / 4) calc(var(--mm-spacing) / 4) 0; -} - -.tags__schemaTagValue { - font-weight: 500; -} - -.tags__schemaTag:last-of-type { - margin-right: 0; -} - -.row__targeted .tags__schemaTag { - background: var(--mm-color-background); -} - -@include variables.breakpoint('sm') { - .tags { - display: grid; - gap: var(--mm-spacing); - grid-template-columns: 1fr max-content; - grid-template-rows: auto; - } -} diff --git a/src/components/Schema/Property.spec.tsx b/src/components/Schema/Property.spec.tsx deleted file mode 100644 index 2f6a19d68..000000000 --- a/src/components/Schema/Property.spec.tsx +++ /dev/null @@ -1,408 +0,0 @@ -import { ReactWrapper } from 'enzyme'; -import * as React from 'react'; - -import Link from '../Link'; -import { p as P } from '../Mdx'; -import Property from './Property'; -import Schema from './Schema'; -import SchemaContext from './SchemaContext'; - -import * as styles from './Property.module.scss'; - -const json = { - arr: [ - 'foo', - 'bar', - ], - boolean: true, - null: null, - number: 42, - obj: { - bar: 'bar', - foo: 'foo', - }, - string: 'string', -}; - -const withContext = (element: React.ReactElement) => global.mountWithRouter( - - {element} - -); - -describe('', () => { - it('can be marked as deprecated', () => { - const component1 = withContext( - - ); - - expect(component1.find(`.${styles.deprecated}`)).not.toExist(); - - const component2 = withContext( - - ); - - expect(component2.find(`.${styles.deprecated}`).first()).toExist(); - }); - - describe('is linkable', () => { - const name = 'bar'; - const schemaId = 'foo'; - const propertyId = `schema--${schemaId}__${name}`; - let component: ReactWrapper; - - beforeAll(() => { - component = global.mountWithRouter( - - - - ); - }); - - it('adds correct `id` to property container', () => { - expect( - component.find(`[id="${propertyId}"]`) - ).toExist(); - }); - - it('has a component', () => { - expect(component.find(Link)).toExist(); - }); - - describe(' component', () => { - let link: any; - - beforeAll(() => { - link = component.find('Property').find(Link); - }); - - it('has correct `to` value', () => { - expect(link.props().to).toBe(`#${propertyId}`); - }); - - it('has correct text value', () => { - expect(link.text()).toBe(name); - }); - }); - }); - - describe('a type', () => { - it('is inferred if no type property is defined', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.type}`).first().text()).toBe('string'); - }); - - it('can be defined on the `Property` component', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.type}`).first().text()).toBe('object'); - }); - }); - - describe('a description', () => { - it('is not shown if component has no children', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.description}`)).not.toExist(); - }); - - it('is shown if component has children', () => { - const component = withContext( - -

    This is a property!

    -
    - ); - - expect(component.find(`.${styles.description}`)).toExist(); - }); - }); - - describe('an example', () => { - it('is not shown if schema json is not an object', () => { - const component = global.mountWithRouter( - - - - ); - - expect(component.find('Example')).not.toExist(); - }); - - it('is not shown if property name does not exist in schema json', () => { - const component = withContext( - - ); - - expect(component.find('Example')).not.toExist(); - }); - - it('is not shown if property name has null value', () => { - const component = withContext( - - ); - - expect(component.find('Example')).not.toExist(); - }); - - it('contains stringified json for object properties', () => { - const component = withContext( - - ); - - const exampleValue = component.find('Example').first().text(); - expect(exampleValue).toContain(JSON.stringify(json.obj, null, 2)); - }); - - it('contains stringified json for array properties', () => { - const component = withContext( - - ); - - const exampleValue = component.find('Example').first().text(); - expect(exampleValue).toContain(JSON.stringify(json.arr, null, 2)); - }); - - it('contains quotes around for string properties', () => { - const component = withContext( - - ); - - const exampleValue = component.find('Example').first().text(); - expect(exampleValue).toEqual(expect.stringMatching(/\s+"string"/)); - }); - - it('stringifies boolean values', () => { - const component = withContext( - - ); - - const exampleValue = component.find('Example').first().text(); - const regex = new RegExp(/\s+true/); - - expect(regex.test(exampleValue)).toBe(true); - }); - - it('does not format numbers', () => { - const component = withContext( - - ); - - const exampleValue = component.find('Example').first().text(); - const regex = new RegExp(/\s+42/); - - expect(regex.test(exampleValue)).toBe(true); - }); - }); - - describe('tags section', () => { - describe('is not shown if', () => { - it( - '`linkToSchemaName`, `services`, and `tags` props are undefined', - () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.tags}`)).not.toExist(); - } - ); - - it('`isDeprecated` prop is true', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.tags}`)).not.toExist(); - }); - }); - - describe('is shown if', () => { - it('`linkToSchemaName` is defined', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.tags}`)).toExist(); - }); - - it('`services` is defined', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.tags}`)).toExist(); - }); - - it('`tags` is defined', () => { - const component = withContext( - - ); - - expect(component.find(`.${styles.tags}`)).toExist(); - }); - }); - - describe('lists service tags', () => { - it('for `geoip` product family', () => { - const component = global.mountWithRouter( - - - - ); - - expect(component.find('GeoIpServiceTags')).toExist(); - }); - - it('for `minfraud` product family', () => { - const component = global.mountWithRouter( - - - - ); - - expect(component.find('MinFraudServiceTags')).toExist(); - }); - }); - - describe('schema tags', () => { - let schemaTags: ReactWrapper; - - beforeAll(() => { - const component = withContext( - - ); - - schemaTags = component.find('Tag') - .filter(`.${styles['tags__schemaTag']}`); - }); - - it('are listed', () => { - expect(schemaTags.length).toBe(3); - }); - - it('text is key / value pairs', () => { - expect(schemaTags.at(0).text()).toBe('bar: bar'); - expect(schemaTags.at(2).text()).toBe('foo: foo'); - }); - - it('keys without values only show key', () => { - expect(schemaTags.at(1).text()).toBe('baz'); - }); - }); - }); -}); diff --git a/src/components/Schema/Property.tsx b/src/components/Schema/Property.tsx deleted file mode 100644 index 4a496538e..000000000 --- a/src/components/Schema/Property.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import { useLocation } from '@reach/router'; -import CustomPropTypes from 'airbnb-prop-types'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import Example from '../Example'; -import Link from '../Link'; -import GeoIpServiceTags from './GeoIpServiceTags'; -import MinFraudServiceTags from './MinFraudServiceTags'; -import PropertyValues from './PropertyValues'; -import SchemaContext from './SchemaContext'; -import Tag from './Tag'; - -import * as styles from './Property.module.scss'; - -type TagValue = boolean | string | number | null; - -export interface IProperty { - children?: React.ReactElement | React.ReactElement[], - isDeprecated?: boolean; - linkToSchemaName?: string; - name: string; - schemaId?: string; - services?: GeoIpServices | MinFraudServices; - tags?: Record; - type?: SchemaPropertyType; -} - -const Property: React.FC = (props) => { - const { - children: description, - isDeprecated, - linkToSchemaName, - tags: schemaTags, - name, - services, - } = props; - const location = useLocation(); - - const schema = React.useContext(SchemaContext); - - const { - example, - linkToSchemaId, - id: propertyId, - type, - } = new PropertyValues({ - property: { - linkToSchemaName, - name, - type: props.type, - }, - schema, - }); - - const serviceTags = services || schema.services; - - return ( -
    - - {name} - - - {type && ( - - {type} - - )} - - {isDeprecated && ( - - deprecated - - )} - - {description && ( -
    - {description} -
    - )} - - {example && ( - - <> - {example.language === 'json' ? '//' : '#'} - {` JSON Pointer: ${example.jsonPointer}\n`} - {example.value} - - - )} - - {(linkToSchemaId || schemaTags || serviceTags) && !isDeprecated && ( -
    -
    - {linkToSchemaId && ( - - - View object schema - - - )} - - {schemaTags && Object.entries(schemaTags).map( - ( - [ - name, - value, - ] : [ - string, - TagValue, - ], - index: number - ) => ( - - - {name} - {typeof value !== 'undefined' && value !== null && ( - <> - : - {' '} - - {value} - - - )} - - ))} -
    - - {serviceTags && schema.productFamily === 'geoip' && ( - - )} - - {serviceTags && schema.productFamily === 'minfraud' && ( - - )} -
    - )} -
    - ); -}; - -Property.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.element, - PropTypes.arrayOf(PropTypes.element.isRequired), - ]), - isDeprecated: PropTypes.bool, - linkToSchemaName: PropTypes.string, - name: PropTypes.string.isRequired, - services: PropTypes.oneOfType([ - PropTypes.oneOf([ - '*', - ] as const), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'score', - 'factors', - 'insights', - ] as const).isRequired, - ), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'country', - 'city', - 'insights', - ] as const).isRequired, - ), - ]), - tags: PropTypes.objectOf( - CustomPropTypes.or([ - PropTypes.bool, - PropTypes.number, - PropTypes.string, - CustomPropTypes.explicitNull(), - ]).isRequired - ), - type: PropTypes.oneOf([ - 'array', - 'array', - 'array', - 'array', - 'array', - 'boolean', - 'number', - 'integer', - 'object', - 'string', - ] as const), -}; - -export default Property; diff --git a/src/components/Schema/PropertyValues.ts b/src/components/Schema/PropertyValues.ts deleted file mode 100644 index 439f39a3b..000000000 --- a/src/components/Schema/PropertyValues.ts +++ /dev/null @@ -1,95 +0,0 @@ -import GithubSlugger from 'github-slugger'; - -import { - inferType, - isArray, - isBoolean, - isObject, - isString, -} from '../../utils/json'; -import { formatSchemaName } from '../../utils/openapi'; -import { IProperty } from './Property'; -import { SchemaContextProps } from './SchemaContext'; - -const slug = GithubSlugger.slug; - -class PropertyValues { - public example?: { - jsonPointer: string; - language: 'bash' | 'json'; - value: string; - }; - public id?: string; - public linkToSchemaId?: string; - public type?: string; - - constructor({ - schema, - property, - }: { - property: Pick; - schema: Pick - }) { - this.type = property.type; - - this.id = `${schema.id}__${slug(property.name)}`; - - this.linkToSchemaId = property.linkToSchemaName && - slug(formatSchemaName(property.linkToSchemaName)); - - if (!isObject(schema.json)) { - return; - } - - // eslint-disable-next-line security/detect-object-injection - const example = schema.json[property.name]; - - if (typeof example === 'undefined' || example === null) { - return; - } - - if (!this.type) { - this.type = inferType(example); - } - - this.example = { - jsonPointer: this.formatPointer(schema.jsonPointer, property.name), - language: this.getLanguage(this.type), - value: this.formatExample(example), - }; - } - - private formatPointer(base: string, property: string) { - return base === '/' - ? `${base}${property}` - : `${base}/${property}`; - } - - private formatExample(example: NonNullable) { - if (isArray(example) || isObject(example)) { - return JSON.stringify( - example, - null, - 2 - ); - } - - if (isString(example)) { - return `"${example}"`; - } - - if (isBoolean(example)) { - return example.toString(); - } - - return example.toString(); - } - - private getLanguage (type: string) { - return type === 'object' || type.startsWith('array') - ? 'json' as const - : 'bash' as const; - } -} - -export default PropertyValues; diff --git a/src/components/Schema/Schema.module.scss b/src/components/Schema/Schema.module.scss deleted file mode 100644 index 3249d616e..000000000 --- a/src/components/Schema/Schema.module.scss +++ /dev/null @@ -1,140 +0,0 @@ -@use '../../styles/variables'; - -.container { - margin: var(--mm-spacing) 0 calc(var(--mm-spacing) + 1px); - position: relative; - scroll-margin-top: calc(var(--page-header-height) + var(--mm-spacing)); - width: 100%; - - [class^='Pre-module--toolbar'] { - top: calc(var(--page-header-height) + 102px); - } -} - -.heading { - background: linear-gradient(#fff, var(--mm-color-sidebar)); - border: 1px solid var(--mm-color-border); - border-radius: var(--mm-border-radius) var(--mm-border-radius) 0 0; - box-shadow: 0 -4px 0 0 var(--mm-color-background); - display: grid; - gap: calc(var(--mm-spacing) / 4); - grid-template-areas: 'name type'; - grid-template-columns: max-content 1fr; - grid-template-rows: max-content; - padding: calc(var(--mm-spacing) / 4) calc(var(--mm-spacing) / 2); - position: sticky; - top: calc(var(--page-header-height) + var(--mm-spacing)); - transform-style: preserve-3d; - z-index: 5; - - &::before { - background: var(--mm-color-background); - content: ' '; - display: block; - height: calc(var(--mm-spacing) + 1px); - left: -1px; - position: absolute; - top: -1px; - transform: translateY(-100%); - width: calc(100% + 2px); - } -} - -/* For IE11 support, align items via the children, not the `.heading` parent */ -.heading > * { - align-self: center; -} - -.heading -.heading__name { - font-weight: 700; - grid-area: name; -} - -.heading__link { - color: var(--mm-color-primary-text); - display: inline-block; - font-size: 12px; - position: relative; - text-decoration: none; -} - -.heading__linkIcon { - font-size: 14px; - left: 0; - opacity: 0.5; - padding-right: 5px; - position: absolute; - top: 50%; - transform: translate(-100%, -50%); -} - -.heading__link:hover .heading__linkIcon { - opacity: 1; -} - -.heading__type { - grid-area: type; -} - -.content { - border: 1px solid var(--mm-color-border); - border-radius: 0 0 var(--mm-border-radius) var(--mm-border-radius); - border-top: 1px solid transparent; - - > :not([class^='Property-module']) { - margin: calc(var(--mm-spacing) / 2) 0; - padding: 0 calc(var(--mm-spacing) / 2); - } - - > :not([class^='Property-module']), - [class^='Li-module'], - [class^='Code-module'] { - font-size: 14px; - line-height: 26px; - } - - [class^='Ol-module'], - [class^='Ul-module'] { - padding-left: var(--mm-spacing); - } - - > [class^='Footnote-module'] { - margin: 0; - padding: calc(var(--mm-spacing) / 2) calc(var(--mm-spacing) / 2); - } - - > [class^='Alert-module'] { - margin-left: var(--mm-spacing); - margin-right: var(--mm-spacing); - } - - [class^='Example-module--value'] { - max-width: calc(100vw - calc(var(--mm-spacing) * 3 + 6px)); - } -} - -@include variables.breakpoint('md') { - .heading { - grid-template-areas: 'name type'; - grid-template-columns: max-content 1fr; - } - - .heading__link { - font-size: 14px; - } - - .content [class^='Example-module--value'] { - max-width: calc(680px - var(--mm-spacing) - 14px); - } -} - -@include variables.breakpoint('xxl') { - .heading__link { - font-size: 16px; - } - - .content [class^='Example-module--value'] { - max-width: calc(680px - var(--mm-spacing) - 6px); - } -} diff --git a/src/components/Schema/Schema.spec.tsx b/src/components/Schema/Schema.spec.tsx deleted file mode 100644 index 5a2c2d114..000000000 --- a/src/components/Schema/Schema.spec.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import * as React from 'react'; - -import { p as P } from '../Mdx'; -import Property from './Property'; -import Schema from './Schema'; - -import * as styles from './Schema.module.scss'; - -const json = { - bar: 'bar', - baz: { - baz: 'baz', - }, - foo: 'foo', -}; - -describe('Schema', () => { - it('renders children', async () => { - const component = global.mountWithRouter( - -

    This is example text.

    - - -

    This is a property value.

    -
    - - -

    This is a property value.

    -
    -
    - ); - expect(component.find('P')).toHaveLength(1); - expect(component.find('Property')).toHaveLength(2); - }); - - it('infers the schema type', async () => { - const component = global.mountWithRouter( - -

    This is example text.

    -
    - ); - - expect( - component.find(`.${styles['heading__type']}`) - .first().text() - ).toBe('object'); - }); - - it('does not infer the schema type if `json` prop is undefined', async () => { - const spy = jest.spyOn(console, 'error').mockImplementation(); - - const component = global.mountWithRouter( - // @ts-expect-error leaving `json` undefined - -

    This is example text.

    -
    - ); - - expect(component.find(`.${styles['heading__type']}`)).not.toExist(); - expect(console.error).toHaveBeenCalled(); - spy.mockRestore(); - }); - - it('allows a custom schema type to be set', async () => { - const component = global.mountWithRouter( - '} - > -

    This is example text.

    -
    - ); - - expect( - component.find(`.${styles['heading__type']}`) - .first().text() - ).toBe('array'); - }); - - describe('`services` property', () => { - let component: any; - - beforeEach(() => { - component = global.mountWithRouter( - -

    This is example text.

    - - - - -
    - ); - }); - - it( - // eslint-disable-next-line max-len - 'passes `services` to `Property` children that do not have `service` property', - () => { - const property = component.find('Property').at(0); - const serviceTags = property.find('MinFraudServiceTags'); - expect(serviceTags).toHaveLength(1); - expect(serviceTags.props().services).toBe('*'); - } - ); - - it( - // eslint-disable-next-line max-len - '`Property` children that have `services` property defined overrides `service` property of Schema', - () => { - const property = component.find('Property').at(1); - const serviceTags = property.find('MinFraudServiceTags'); - expect(serviceTags).toHaveLength(1); - expect(serviceTags.props().services).toStrictEqual([ - 'factors', - ]); - } - ); - }); -}); diff --git a/src/components/Schema/Schema.tsx b/src/components/Schema/Schema.tsx deleted file mode 100644 index 2b06e4317..000000000 --- a/src/components/Schema/Schema.tsx +++ /dev/null @@ -1,166 +0,0 @@ -// TODO - Figure out correct typings for React children that implement ISchema -/* eslint-disable @typescript-eslint/no-explicit-any */ -import GithubSlugger from 'github-slugger'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import { FaLink as LinkIcon } from 'react-icons/fa'; - -import { inferType } from '../../utils/json'; -import { formatSchemaName } from '../../utils/openapi'; -import Example from '../Example'; -import Link from '../Link'; -import SchemaContext from './SchemaContext'; -import Tag from './Tag'; - -import * as styles from './Schema.module.scss'; - -export interface ISchema { - children: React.ReactElement | React.ReactElement[]; - json: Json; - jsonPointer: string; - name: string; - productFamily: ProductFamily; - services?: GeoIpServices | MinFraudServices; - type?: SchemaType; -} - -const slug = GithubSlugger.slug; - -const Schema: React.FC = (props) => { - const { - children, - json, - jsonPointer, - name, - productFamily, - services, - type, - } = props; - - const formattedSchemaName = formatSchemaName(name); - - const schemaId = `schema--${slug(formattedSchemaName)}`; - - let inferredType = ''; - - if (typeof json !== 'undefined') { - inferredType = inferType(json); - } - - const schemaContent = React.Children.toArray(children); - - const firstPropertyComponentIndex = schemaContent.findIndex( - (child: any) => child.props.mdxType === 'Property' - ); - - const propertyContent = schemaContent.splice(firstPropertyComponentIndex); - - return ( -
    -
    - - - - {formattedSchemaName} - - - - {(type || inferredType) && ( - - - {type || inferredType} - - - )} -
    -
    - - {schemaContent} - - {json && ( - - <> - {`// JSON Pointer: ${jsonPointer}\n`} - {JSON.stringify(json, null, 2)} - - - )} - - {propertyContent} - -
    -
    - ); -}; - -export const schemaPropTypes = { - children: PropTypes.oneOfType([ - PropTypes.element, - PropTypes.arrayOf( - PropTypes.element.isRequired - ), - ]).isRequired, - json: PropTypes.any.isRequired, - jsonPointer: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - type: PropTypes.oneOf([ - 'array', - 'object', - ] as const), -}; - -Schema.propTypes = { - ...schemaPropTypes, - productFamily: PropTypes.oneOf([ - 'geoip', - 'minfraud', - ] as const).isRequired, - services: PropTypes.oneOfType([ - PropTypes.oneOf([ - '*', - ] as const), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'score', - 'factors', - 'insights', - ] as const).isRequired, - ), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'country', - 'city', - 'insights', - ] as const).isRequired, - ), - ]), -}; - -export default Schema; diff --git a/src/components/Schema/SchemaContext.ts b/src/components/Schema/SchemaContext.ts deleted file mode 100644 index 21d4fefd8..000000000 --- a/src/components/Schema/SchemaContext.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - -export type SchemaContextProps = { - id: string; - json: Json; - jsonPointer: string; - productFamily?: ProductFamily; - services?: GeoIpServices | MinFraudServices; -} - -export default React.createContext({ - id: '', - json: {}, - jsonPointer: '', -}); diff --git a/src/components/Schema/ServiceTag.module.scss b/src/components/Schema/ServiceTag.module.scss deleted file mode 100644 index f15704bd8..000000000 --- a/src/components/Schema/ServiceTag.module.scss +++ /dev/null @@ -1,30 +0,0 @@ -.tag { - background: #e9f8f0; - border: 1px solid #c7e4d5; - color: #1c5e3b; - margin: 0 calc(var(--mm-spacing) / 4) calc(var(--mm-spacing) / 4) 0; -} - -.tag::before { - content: '✓'; - margin-right: 4px; -} - -.tag:first-of-type { - margin-left: 0; -} - -.tag:last-of-type { - margin-right: 0; -} - - -.tag__disabled { - background: #eee; - border: 1px solid #ddd; - color: #4f4f4f; -} - -.tag__disabled::before { - content: '✗'; -} diff --git a/src/components/Schema/ServiceTag.spec.tsx b/src/components/Schema/ServiceTag.spec.tsx deleted file mode 100644 index 6977e6329..000000000 --- a/src/components/Schema/ServiceTag.spec.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { mount } from 'enzyme'; -import * as React from 'react'; - -import ServiceTag from './ServiceTag'; - -// eslint-disable-next-line css-modules/no-unused-class -import * as styles from './ServiceTag.module.scss'; - -describe('', () => { - it('renders provided text', () => { - const component = mount( - - ); - - expect( - component.find('ServiceTag').text() - ).toBe('Foo'); - }); - - it('can be disabled', () => { - const component = mount( - - ); - - expect( - component.find('Tag') - ).toHaveClassName(styles['tag__disabled']); - }); -}); diff --git a/src/components/Schema/ServiceTag.tsx b/src/components/Schema/ServiceTag.tsx deleted file mode 100644 index ca7f2e760..000000000 --- a/src/components/Schema/ServiceTag.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import Tag from './Tag'; - -import * as styles from './ServiceTag.module.scss'; - -interface IServiceTag { - isDisabled?: boolean; - text: string; -} - -const ServiceTag: React.FC = (props) => { - const { text, isDisabled } = props; - return ( - - {text} - - ); -}; - -ServiceTag.propTypes = { - isDisabled: PropTypes.bool, - text: PropTypes.string.isRequired, -}; - -export default ServiceTag; diff --git a/src/components/Schema/Tag.module.scss b/src/components/Schema/Tag.module.scss deleted file mode 100644 index 346c02afe..000000000 --- a/src/components/Schema/Tag.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -.container { - background: #effbff; - border: 1px solid #d5e3f0; - border-radius: var(--mm-border-radius); - color: #1e588b; - display: inline-block; - font-size: 10px; - font-weight: 700; - letter-spacing: 1px; - padding: 0 10px; -} diff --git a/src/components/Schema/Tag.tsx b/src/components/Schema/Tag.tsx deleted file mode 100644 index 1df415a3e..000000000 --- a/src/components/Schema/Tag.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import * as styles from './Tag.module.scss'; - -interface ITag { - children: React.ReactNode, - className?: string, -} - -const Tag: React.FC = (props) => { - const { children, className } = props; - - return ( - - {children} - - ); -}; - -Tag.propTypes = { - children: PropTypes.node.isRequired, - className: PropTypes.string, -}; - -export default Tag; diff --git a/src/components/Schema/index.ts b/src/components/Schema/index.ts deleted file mode 100644 index bbc63dfe2..000000000 --- a/src/components/Schema/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { default as Footnote } from './Footnote'; -export { default as GeoIpSchema } from './GeoIpSchema'; -export { default as MinFraudSchema } from './MinFraudSchema'; -export { default as Property } from './Property'; -export { default as Schema } from './Schema'; diff --git a/src/components/Schema/types.d.ts b/src/components/Schema/types.d.ts deleted file mode 100644 index 1f3809615..000000000 --- a/src/components/Schema/types.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -declare type ProductFamily = 'geoip' | 'minfraud'; - -declare type MinFraudService = 'score' | 'factors' | 'insights'; -declare type MinFraudServices = '*' | MinFraudService[]; - -declare type GeoIpService = 'country' | 'city' | 'insights'; -declare type GeoIpServices = '*' | GeoIpService[]; - -declare type SchemaType = 'array' | 'object'; -declare type SchemaPropertyType = 'array' - | 'array' - | 'array' - | 'array' - | 'array' - | 'boolean' - | 'number' - | 'integer' - | 'object' - | 'string'; diff --git a/src/components/SearchResult.module.scss b/src/components/SearchResult.module.scss deleted file mode 100644 index 47242ecd3..000000000 --- a/src/components/SearchResult.module.scss +++ /dev/null @@ -1,30 +0,0 @@ -.title b, -.snippet b { - font-weight: bold; -} - -.title { - color: var(--mm-color-logo-blue-light); - display: inline-block; - font-size: 20px; - margin-bottom: 3px; - text-decoration: none; - - &:hover { - text-decoration: underline; - } -} - -.url { - display: block; - font-size: 12px; - margin-bottom: 3px; -} - -.snippet { - font-size: 16px; - - br { - display: none; - } -} diff --git a/src/components/SearchResult.tsx b/src/components/SearchResult.tsx deleted file mode 100644 index 95bfcc483..000000000 --- a/src/components/SearchResult.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { sanitize } from 'dompurify'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import Link from './Link'; - -import * as styles from './SearchResult.module.scss'; - -interface ISearchResult { - className?: string; - snippet: string; - title: string; - url: string; -} - -const sanitizeOpts = { - ALLOWED_TAGS: [ - 'b', - ], -}; - -const SearchResult: React.FC = (props) => ( -
    -

    - -

    - - {props.url} - -

    -

    -); - -SearchResult.propTypes = { - className: PropTypes.string, - snippet: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - url: PropTypes.string.isRequired, -}; - -export default SearchResult; diff --git a/src/components/SystemsStatusIcons.module.scss b/src/components/SystemsStatusIcons.module.scss deleted file mode 100644 index fdf3e4d2c..000000000 --- a/src/components/SystemsStatusIcons.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -.operational { - color: #56f000; -} - -.warning { - color: #fce83a; -} diff --git a/src/components/SystemsStatusIcons.tsx b/src/components/SystemsStatusIcons.tsx deleted file mode 100644 index 70274b9df..000000000 --- a/src/components/SystemsStatusIcons.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { - FaCheckCircle, - FaExclamationTriangle, -} from 'react-icons/fa'; - -import * as styles from './SystemsStatusIcons.module.scss'; - -export const OperationalIcon: React.FC = () => ( - -); - -export const WarningIcon: React.FC = () => ( - -); diff --git a/src/components/ZipFileContent.tsx b/src/components/ZipFileContent.tsx deleted file mode 100644 index 246b8d600..000000000 --- a/src/components/ZipFileContent.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; - -import { - inlineCode as Code, - p as P, - table as Table, - td as Td, - th as Th, - tr as Tr, -} from './Mdx'; - -interface IZipFileContent { - isTableExcluded?: boolean; - productName: string; -} - -const ZipFileContent: React.FC = (props) => { - const { isTableExcluded, productName } = props; - return ( - <> -

    - The zip file itself is named   - - {productName} - -CSV_ - {'{YYYYMMDD}'} - .zip - - . The downloaded zip file contains a single directory which in turn - contains several files. That directory is named   - - {productName} - -CSV_ - {'{YYYYMMDD}'} - - . -

    - { !isTableExcluded && ( - <> -

    - The files in this zip archive are: -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FilenameDescription
    LICENSE.txtEnd user license
    COPYRIGHT.txtCopyright statement
    - - {productName} - -Blocks-IPv4.csv - - CSV file containing data on IPv4 addresses
    - - {productName} - -Blocks-IPv6.csv - - CSV file containing data on IPv6 addresses
    - - )} - - ); -}; - -ZipFileContent.propTypes = { - isTableExcluded: PropTypes.bool, - productName: PropTypes.string.isRequired, -}; - -export default ZipFileContent; diff --git a/src/gatsby/gatsby-browser/index.ts b/src/gatsby/gatsby-browser/index.ts deleted file mode 100644 index c13a569d5..000000000 --- a/src/gatsby/gatsby-browser/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './onClientEntry'; -export * from './onRouteUpdate'; -export * from './wrapRootElement'; diff --git a/src/gatsby/gatsby-browser/onClientEntry.ts b/src/gatsby/gatsby-browser/onClientEntry.ts deleted file mode 100644 index 142c0f472..000000000 --- a/src/gatsby/gatsby-browser/onClientEntry.ts +++ /dev/null @@ -1,31 +0,0 @@ -import cssVars from 'css-vars-ponyfill'; -import { GatsbyBrowser } from 'gatsby'; - -export const onClientEntry: GatsbyBrowser['onClientEntry'] = async () => { - cssVars(); - - if (!Element.prototype.matches) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Element.prototype.matches = (Element as any).prototype.msMatchesSelector; - } - - if (typeof CustomEvent !== 'function') { - await require('custom-event-polyfill'); - } - - if (typeof fetch === 'undefined') { - await require('whatwg-fetch'); - } - - if (typeof IntersectionObserver === 'undefined') { - await require('intersection-observer'); - } - - if (typeof Promise.all === undefined || typeof Promise.race === 'undefined') { - await require('promise-polyfill/src/polyfill'); - } - - if (typeof URLSearchParams === 'undefined') { - await require('url-search-params-polyfill'); - } -}; diff --git a/src/gatsby/gatsby-browser/onRouteUpdate.ts b/src/gatsby/gatsby-browser/onRouteUpdate.ts deleted file mode 100644 index 00e27230f..000000000 --- a/src/gatsby/gatsby-browser/onRouteUpdate.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GatsbyBrowser, RouteUpdateArgs } from 'gatsby'; - -const scrollIntoView = (props: RouteUpdateArgs) => - document - .getElementById(props.location.hash.replace('#', ''))?.scrollIntoView(); - -export const onRouteUpdate: GatsbyBrowser['onRouteUpdate'] = (props) => { - if (props.location.hash) { - document.addEventListener('mm-react-code-mount', function handler(e) { - e.currentTarget?.removeEventListener(e.type, handler); - scrollIntoView(props); - }); - - scrollIntoView(props); - } -}; diff --git a/src/gatsby/gatsby-browser/wrapRootElement.tsx b/src/gatsby/gatsby-browser/wrapRootElement.tsx deleted file mode 100644 index 358be42bf..000000000 --- a/src/gatsby/gatsby-browser/wrapRootElement.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { MDXProvider } from '@mdx-js/react'; -import { GatsbyBrowser, WrapRootElementBrowserArgs } from 'gatsby'; -import React from 'react'; -import { IconContext } from 'react-icons'; - -import * as components from '../../components/Mdx'; -import { StoreProvider } from '../../store'; - -export const wrapRootElement: GatsbyBrowser['wrapRootElement'] = ( - props: WrapRootElementBrowserArgs -) => ( - - {/* eslint-disable-next-line max-len */ } - {/* @ts-expect-error: @type for @mdx-js/react has implicit children which is incompat with react 18 */} - - - {props.element} - - - -); diff --git a/src/gatsby/gatsby-config/feeds/createReleaseNotesFeed.ts b/src/gatsby/gatsby-config/feeds/createReleaseNotesFeed.ts deleted file mode 100644 index 8512e5526..000000000 --- a/src/gatsby/gatsby-config/feeds/createReleaseNotesFeed.ts +++ /dev/null @@ -1,98 +0,0 @@ -import GithubSlugger from 'github-slugger'; -import toHtml from 'hast-util-to-html'; -import toHast from 'mdast-util-to-hast'; -// eslint-disable-next-line import/no-unresolved -import type { Parent } from 'unist'; - -interface IFeed { - description: string; - inputUrl: string; - outputUrl: string; - title: string; -} - -export default (feed: IFeed): any => ({ - description: `${feed.description}`, - generator: '', - output: `${feed.outputUrl}`, - query: ` - { - allMdx( - filter: { - fields: { - slug: { - eq: "${feed.inputUrl}" - } - } - } - ) { - nodes { - frontmatter { - title - description - image - keywords - draft - } - fields { - slug - } - mdxAST - } - } - } - `, - serialize: (args: any) => { - const { query } = args; - const { site, allMdx } = query; - - return allMdx.nodes.flatMap((node: any) => { - const releaseNotes = (node.mdxAST as Parent).children.filter( - (child: any) => child.name === 'ReleaseNote' - ); - - return releaseNotes.map((releaseNote: any) => { - const dateAttribute = (releaseNote.attributes as any[]).find( - (attribute: any) => attribute.name === 'date' - ); - - const titleAttribute = (releaseNote.attributes as any[]).find( - (attribute: any) => attribute.name === 'title' - ); - - if (!dateAttribute?.value) { - throw Error('`date` attribute value is missing'); - } - - if (!titleAttribute?.value) { - throw Error('`title` attribute value is missing'); - } - - // Assume publish time is around noon office standard time - const dateString = `${dateAttribute.value} 12:00:00 GMT -0400`; - - const url = [ - site.siteMetadata.siteUrl, - node.fields.slug, - `#${GithubSlugger.slug(titleAttribute.value)}`, - ].join(''); - - return { - ...node.frontmatter, - custom_elements: [ - { - 'content:encoded': (releaseNote.children as any[]) - .map((child: any) => toHtml(toHast(child))) - .join(''), - }, - ], - date: new Date(dateString), - guid: url, - title: titleAttribute.value, - url, - }; - }); - }); - }, - title: feed.title, -}); diff --git a/src/gatsby/gatsby-config/feeds/createServerIpAddressesFeed.ts b/src/gatsby/gatsby-config/feeds/createServerIpAddressesFeed.ts deleted file mode 100644 index 868c9703d..000000000 --- a/src/gatsby/gatsby-config/feeds/createServerIpAddressesFeed.ts +++ /dev/null @@ -1,48 +0,0 @@ -export default (): any => ({ - description: 'Feed of MaxMind server addresses.', - generator: '', - output: 'maxmind-server-ip-addresses.xml', - query: ` - { - allJson { - nodes { - IPv4 - IPv6 - lastUpdated - } - } - site { - siteMetadata { - siteUrl - } - } - } - `, - serialize: (args: any) => { - const { query } = args; - const { allJson } = query; - const { siteUrl } = query.site.siteMetadata; - - const date = new Date(allJson.nodes[0].lastUpdated); - - return [ - { - custom_elements: [ - { - // eslint-disable-next-line security/detect-object-injection - 'content:encoded': [ - ...allJson.nodes[0].IPv4, - '', - ...allJson.nodes[0].IPv6, - ].join('
    '), - }, - ], - date, - guid: `${siteUrl}/maxmind-server-ip-addresses?t=${date.getTime()}`, - title: 'MaxMind Server IP Addresses', - url: `${siteUrl}/maxmind-server-ip-addresses`, - }, - ]; - }, - title: 'MaxMind Server IP Addresses', -}); diff --git a/src/gatsby/gatsby-config/index.ts b/src/gatsby/gatsby-config/index.ts deleted file mode 100644 index 006cf7413..000000000 --- a/src/gatsby/gatsby-config/index.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { GatsbyConfig } from 'gatsby'; -import remarkExternalLinks from 'remark-external-links'; - -import createReleaseNotesFeed from './feeds/createReleaseNotesFeed'; -import createServerIpAddressesFeed from './feeds/createServerIpAddressesFeed'; -import sectionize from './remark/sectionize'; - -const { GATSBY_URL = 'http://localhost:5000' } = process.env; - -/** - * The plugins below must come last in the ordering of the plugins because they - * are dependent on transforming output of the previously listed plugins. - */ -const THESE_PLUGINS_MUST_COME_LAST = [ - 'gatsby-plugin-sri', -]; - -const GATSBY_ROOT = `${__dirname}/../../../`; - -const GLOBALLY_IGNORED_SOURCE_FILES = [ - '**/_**/*', - '**/_*', -]; - -export default { - plugins: [ - { - options: { - id: 'GTM-M8K593P', - includeInDevelopment: false, - }, - resolve: 'gatsby-plugin-google-tagmanager', - }, - { - options: { - typeName: 'Json', - }, - resolve: 'gatsby-transformer-json', - }, - { - options: { - name: 'maxmindServerIps', - path: `${GATSBY_ROOT}/static/maxmind-server-ip-addresses.json`, - }, - resolve: 'gatsby-source-filesystem', - }, - { - options: { - ignore: [ - ...GLOBALLY_IGNORED_SOURCE_FILES, - '**/index.mdx', - ], - name: 'pages', - path: `${GATSBY_ROOT}/content/`, - }, - resolve: 'gatsby-source-filesystem', - }, - { - options: { - ignore: [ - ...GLOBALLY_IGNORED_SOURCE_FILES, - '**/!(content)/index.mdx', - ], - name: 'home', - path: `${GATSBY_ROOT}/content/`, - }, - resolve: 'gatsby-source-filesystem', - }, - { - options: { - ignore: [ - ...GLOBALLY_IGNORED_SOURCE_FILES, - '**/!(index).mdx', - ], - name: 'overviews', - path: `${GATSBY_ROOT}/content/`, - }, - resolve: 'gatsby-source-filesystem', - }, - { - options: { - defaultLayouts: { - home: require.resolve(`${GATSBY_ROOT}src/templates/Home`), - overviews: require.resolve(`${GATSBY_ROOT}src/templates/Overview`), - pages: require.resolve(`${GATSBY_ROOT}src/templates/Page`), - }, - extensions: [ - '.mdx', - '.md', - ], - remarkPlugins: [ - sectionize, - remarkExternalLinks, - ], - }, - resolve: 'gatsby-plugin-mdx', - }, - 'gatsby-plugin-react-helmet', - { - options: { - name: 'images', - path: `${GATSBY_ROOT}src/images`, - }, - resolve: 'gatsby-source-filesystem', - }, - 'gatsby-plugin-typescript', - 'gatsby-plugin-ts-checker', - 'gatsby-plugin-image', - 'gatsby-transformer-sharp', - 'gatsby-plugin-sharp', - { - options: { - background_color: '#0b8ad0', - display: 'minimal-ui', - icon: 'src/images/maxmind-icon.png', - name: 'MaxMind Developer Portal', - start_url: '/', - theme_color: '#0b8ad0', - }, - resolve: 'gatsby-plugin-manifest', - }, - { - options: { - rule: { - include: /assets/, - }, - }, - resolve: 'gatsby-plugin-react-svg', - }, - { - options: { - feeds: [ - // The year needs to be hardcoded. A page for the new year's - // release notes won't exist until a new MDX file is created - // in the /content//release-notes folder for that new year. - createReleaseNotesFeed({ - description: 'Release notes for MaxMind\'s GeoIP2 product line', - inputUrl: '/geoip/release-notes/2024', - outputUrl: '/geoip/release-notes/rss.xml', - title: 'GeoIP2 Release Notes', - }), - createReleaseNotesFeed({ - description: 'Release notes for MaxMind\'s minFraud product line', - inputUrl: '/minfraud/release-notes/2024', - outputUrl: '/minfraud/release-notes/rss.xml', - title: 'minFraud Release Notes', - }), - createServerIpAddressesFeed(), - ], - query: ` - { - site { - siteMetadata { - title - description - siteUrl - site_url: siteUrl - } - } - } - `, - }, - resolve: 'gatsby-plugin-feed', - }, - 'gatsby-plugin-advanced-sitemap', - { - options: { - env: { - nonProduction: { - policy: [ - { - disallow: [ - '/', - ], - userAgent: '*', - }, - ], - }, - production: { - policy: [ - { - allow: '/', - userAgent: '*', - }, - ], - }, - }, - host: GATSBY_URL, - resolveEnv: () => GATSBY_URL === 'https://dev.maxmind.com' - ? 'production' - : 'nonProduction', - sitemap: `${GATSBY_URL}/sitemap.xml`, - }, - resolve: 'gatsby-plugin-robots-txt', - }, - ...THESE_PLUGINS_MUST_COME_LAST, - ], - siteMetadata: { - author: '@maxmind', - // eslint-disable-next-line max-len - description: 'Develop applications using industry-leading IP intelligence and risk scoring.', - siteUrl: GATSBY_URL, - title: 'MaxMind Developer Portal', - }, - trailingSlash: 'never', -} as GatsbyConfig; diff --git a/src/gatsby/gatsby-config/remark/sectionize.spec.ts b/src/gatsby/gatsby-config/remark/sectionize.spec.ts deleted file mode 100644 index 45697cecb..000000000 --- a/src/gatsby/gatsby-config/remark/sectionize.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import remark from 'remark'; -import html from 'remark-html'; - -import sectionize from './sectionize'; - -const content = -`# Heading 1 -## Heading 2 -Additional text. - -Additional text. - -### Heading 3 -Additional text. - -Additional text. - -## Heading 2 -Additional text. -`.trim(); - -describe('sectionize', () => { - it('default export returns a function', () => { - expect(sectionize()).toBeInstanceOf(Function); - }); - - it('generated output matches expected html structure', async () => { - const output = await remark() - .use(sectionize) - .use(html) - .process(content) - .then((result: any) => String(result).trim()); - - const expected = [ - /* eslint-disable indent */ - '
    ', - '

    Heading 1

    ', - - '
    ', - '

    Heading 2

    ', - '

    Additional text.

    ', - '

    Additional text.

    ', - - '
    ', - '

    Heading 3

    ', - '

    Additional text.

    ', - '

    Additional text.

    ', - '
    ', - '
    ', - - '
    ', - '

    Heading 2

    ', - '

    Additional text.

    ', - '
    ', - '
    ', - /* eslint-enable indent */ - ].join(''); - - expect(output).toEqual(`${expected}`); - }); -}); diff --git a/src/gatsby/gatsby-config/remark/sectionize.ts b/src/gatsby/gatsby-config/remark/sectionize.ts deleted file mode 100644 index 4903745a7..000000000 --- a/src/gatsby/gatsby-config/remark/sectionize.ts +++ /dev/null @@ -1,69 +0,0 @@ -import GithubSlugger from 'github-slugger'; -import toString from 'mdast-util-to-string'; -// eslint-disable-next-line import/no-unresolved -import { Parent } from 'unist'; -import visitParents, { Visitor } from 'unist-util-visit-parents'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const findAfter = require('unist-util-find-after'); - -const MAX_HEADING_DEPTH = 6; - -const slugger = new GithubSlugger(); - -type TransformFn = (tree: any) => void; - -const transform: TransformFn = (tree: any) => { - slugger.reset(); - - for (let depth = MAX_HEADING_DEPTH; depth > 0; depth--) { - visitParents( - tree, - (node: any) => node.type === 'heading' && node.depth === depth, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - visitor as Visitor, - ); - } -}; - -const visitor = (node: any, ancestors: Parent[]) => { - const data = node.data || (node.data = {}); - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const props = data.hProperties || (data.hProperties = {}) as any; - - props.id = props.id - ? slugger.slug(props.id, true) - : slugger.slug(toString(node)); - - const start = node; - const depth = start.depth as number; - const parent = ancestors[ancestors.length - 1]; - - const isEnd = (node: any) => node.type === 'heading' - && (node.depth as number) <= depth || node.type === 'export'; - - const end = findAfter(parent, start, isEnd); - - const startIndex = parent.children.indexOf(start); - const endIndex = parent.children.indexOf(end); - - const section = { - children: parent.children.slice( - startIndex, - endIndex > 0 ? endIndex : undefined - ), - data: { - hName: 'div', - hProperties: { - id: `toc-${props.id}`, - }, - }, - depth: depth, - type: 'div', - }; - - parent.children.splice(startIndex, section.children.length, section); -}; - -export default (): TransformFn => transform; diff --git a/src/gatsby/gatsby-node/createPages.ts b/src/gatsby/gatsby-node/createPages.ts deleted file mode 100644 index a89374b6f..000000000 --- a/src/gatsby/gatsby-node/createPages.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CreatePagesArgs, GatsbyNode } from 'gatsby'; - -import createMdxPages from './pages/createMdxPages'; - -export const createPages: GatsbyNode['createPages'] = async ( - props: CreatePagesArgs -) => { - await Promise.all([ - createMdxPages(props), - ]); -}; diff --git a/src/gatsby/gatsby-node/createResolvers.ts b/src/gatsby/gatsby-node/createResolvers.ts deleted file mode 100644 index 29af4269e..000000000 --- a/src/gatsby/gatsby-node/createResolvers.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -import { - CreateResolversArgs, - GatsbyNode, -} from 'gatsby'; - -const genMDX = require('gatsby-plugin-mdx/utils/gen-mdx'); - -// eslint-disable-next-line max-len -import generateTableOfContents, { createImportPathMap } from '../../utils/get-toc-items'; - -const geoipImportPathMap = createImportPathMap( - `${process.cwd()}/content/geoip/docs/web-services/_schemas` -); - -const minFraudImportPathMap = createImportPathMap( - `${process.cwd()}/content/minfraud/api-documentation/_schemas` -); - -export const createResolvers: GatsbyNode['createResolvers'] = async( - args: CreateResolversArgs, -): Promise => { - const { - createResolvers, - store, - } = args; - - const plugins = store.getState().flattenedPlugins; - - const mdxPlugin = plugins.find( - (plugin: any) => plugin.name === 'gatsby-plugin-mdx' - ); - - const processMDX = ({ node }: any) => - genMDX({ - ...args, - node, - options: mdxPlugin.pluginOptions, - }); - - createResolvers({ - Mdx: { - customTableOfContents: { - args: { - maxDepth: { - default: 6, - type: 'Int', - }, - }, - async resolve(mdxNode: any) { - const { mdast } = await processMDX({ - node: mdxNode, - }); - - if (mdxNode.fields.slug.startsWith('/minfraud')) { - return generateTableOfContents(mdast, minFraudImportPathMap); - } - - if (mdxNode.fields.slug.startsWith('/geoip')) { - return generateTableOfContents(mdast, geoipImportPathMap); - } - - return; - }, - type: 'JSON', - }, - }, - }); -}; diff --git a/src/gatsby/gatsby-node/createSchemaCutomization.ts b/src/gatsby/gatsby-node/createSchemaCutomization.ts deleted file mode 100644 index a31ecb96d..000000000 --- a/src/gatsby/gatsby-node/createSchemaCutomization.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CreatePagesArgs, GatsbyNode } from 'gatsby'; - -export const createSchemaCustomization: GatsbyNode['createSchemaCustomization'] = - async ({ actions }) => { - const { createTypes } = actions; - const typeDefs = ` - type Mdx implements Node { - frontmatter: MdxFrontmatter! - } - type MdxFrontmatter { - image: String - } - `; - createTypes(typeDefs); - }; diff --git a/src/gatsby/gatsby-node/index.ts b/src/gatsby/gatsby-node/index.ts deleted file mode 100644 index 422272c13..000000000 --- a/src/gatsby/gatsby-node/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './createPages'; -export * from './createResolvers'; -export * from './onCreateNode'; -export * from './onCreateWebpackConfig'; -export * from './createSchemaCutomization'; diff --git a/src/gatsby/gatsby-node/onCreateNode.ts b/src/gatsby/gatsby-node/onCreateNode.ts deleted file mode 100644 index b863a45e3..000000000 --- a/src/gatsby/gatsby-node/onCreateNode.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { CreateNodeArgs, GatsbyNode } from 'gatsby'; -import { createFilePath } from 'gatsby-source-filesystem'; - -const addLayoutField = (args: CreateNodeArgs): void => { - const { actions, getNode, node } = args; - const { createNodeField } = actions; - - if (node?.internal?.type === 'Mdx') { - const parentId = node?.parent; - - if (!parentId) { - return; - } - - const parentNode = getNode(parentId); - - createNodeField({ - name: 'layout', - node, - value: parentNode?.sourceInstanceName, - }); - } -}; - -const addSlugField = (args: CreateNodeArgs): void => { - const { actions, getNode, node } = args; - const { createNodeField } = actions; - - if (node.internal.type === 'Mdx') { - const slug = createFilePath({ - getNode, - node, - trailingSlash: false, - }); - - createNodeField({ - name: 'slug', - node, - value: slug, - }); - } - -}; - -export const onCreateNode: GatsbyNode['onCreateNode'] = ( - args: CreateNodeArgs, -) => { - addLayoutField(args); - addSlugField(args); -}; diff --git a/src/gatsby/gatsby-node/onCreateWebpackConfig.ts b/src/gatsby/gatsby-node/onCreateWebpackConfig.ts deleted file mode 100644 index f20540093..000000000 --- a/src/gatsby/gatsby-node/onCreateWebpackConfig.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { exec } from 'child_process'; -import { CreateWebpackConfigArgs, GatsbyNode } from 'gatsby'; -import reporter from 'gatsby-cli/lib/reporter'; - -/* eslint-disable @typescript-eslint/no-var-requires */ -const ESLintPlugin = require('eslint-webpack-plugin'); -const StylelintPlugin = require('stylelint-webpack-plugin'); - -export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig']= ( - props: CreateWebpackConfigArgs, -) => { - const IS_DEVELOP = props.stage === 'develop'; - const IS_PRODUCTION = !IS_DEVELOP; - const IS_SSR = props.stage.includes('html'); - - const sassLoader = { - loader: 'sass-loader', - options: { - sourceMap: IS_PRODUCTION, - }, - }; - - const sassRule = { - test: /\.s(a|c)ss$/, - use: IS_SSR - ? [ - props.loaders.null(), - ] - : [ - props.loaders.miniCssExtract(), - props.loaders.css({ - camelCase: true, - importLoaders: 2, - }), - { - loader: 'postcss-loader', - }, - sassLoader, - ], - }; - - const sassRuleModules = { - test: /\.module\.s(a|c)ss$/, - use: [ - !IS_SSR && props.loaders.miniCssExtract({ - modules: true, - }), - props.loaders.css({ - camelCase: true, - importLoaders: 2, - modules: true, - }), - { - loader: 'postcss-loader', - }, - sassLoader, - ].filter(Boolean), - }; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let configRules: any = []; - - switch (props.stage) { - case 'develop': - case 'build-javascript': - case 'build-html': - case 'develop-html': { - configRules = configRules.concat([ - { - oneOf: [ - sassRuleModules, - sassRule, - ], - }, - ]); - break; - } - } - - props.actions.setWebpackConfig({ - module: { - rules: configRules, - }, - }); - - /** - * In the development environment, we want eslint to parse files on change and - * output any issues to console. - */ - if (IS_DEVELOP) { - props.actions.setWebpackConfig({ - plugins: [ - new ESLintPlugin({ - exclude: [ - 'node_modules', - '.cache', - 'public', - ], - extensions: [ - 'js', - 'json', - 'md', - 'mdx', - 'ts', - 'tsx', - ], - }), - new StylelintPlugin({ - configFile: './.stylelintrc.js', - files: 'src/**/*.s(a|c)ss', - }), - { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - apply: (compiler: any) => { - compiler.hooks.afterEmit.tapAsync( - 'RemarkLint', - (_: unknown, next: () => void) => exec( - 'remark . --ext mdx --quiet', - (_: unknown, stdout: string, stderr: string) => { - if (stdout) { - reporter.info(stdout); - } - - if (stderr) { - reporter.warn(`RemarkLint error:\n${stderr}`); - } - - next(); - } - )); - }, - }, - ], - }); - } -}; diff --git a/src/gatsby/gatsby-node/pages/createMdxPages.ts b/src/gatsby/gatsby-node/pages/createMdxPages.ts deleted file mode 100644 index 69362e75c..000000000 --- a/src/gatsby/gatsby-node/pages/createMdxPages.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import { CreatePagesArgs } from 'gatsby'; - -import { IBaseQuery } from '../../../baseQuery'; -import homeQuery from '../../../templates/Home/query'; -import overviewQuery from '../../../templates/Overview/query'; -import pageQuery from '../../../templates/Page/query'; - -const queries = [ - homeQuery, - overviewQuery, - pageQuery, -]; - -const createMdxPages = async (args: CreatePagesArgs): Promise => { - const { actions, graphql, reporter } = args; - const { createPage } = actions; - - return Promise.all( - queries.map(async (query) => { - const result = await query(graphql); - - if (result.errors) { - reporter.panicOnBuild('🚨 ERROR: error!'); - console.log(result.errors); - throw new Error(`🚨 ERROR: Loading "${query.name}" query`); - } - - if (!result.data) { - reporter.panicOnBuild('🚨 ERROR: No data!'); - throw new Error('🚨 ERROR: No data!'); - } - - result.data.allMdx.nodes.forEach((node: IBaseQuery) => { - if ( - process.env.gatsby_executing_command === 'develop' - || !node.frontmatter.draft - ) { - createPage({ - component: node.fileAbsolutePath, - context: node, - path: node.fields.slug, - }); - } - }); - }) - ); -}; - -export default createMdxPages; diff --git a/src/gatsby/gatsby-ssr/index.ts b/src/gatsby/gatsby-ssr/index.ts deleted file mode 100644 index c2be55e74..000000000 --- a/src/gatsby/gatsby-ssr/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './replaceRenderer'; -export * from './wrapRootElement'; diff --git a/src/gatsby/gatsby-ssr/replaceRenderer.tsx b/src/gatsby/gatsby-ssr/replaceRenderer.tsx deleted file mode 100644 index 318505067..000000000 --- a/src/gatsby/gatsby-ssr/replaceRenderer.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import cheerio from 'cheerio'; -import crypto from 'crypto'; -import fs from 'fs'; -import { GatsbySSR, ReplaceRendererArgs } from 'gatsby'; -import GithubSlugger from 'github-slugger'; -import React from 'react'; -import { renderToString } from 'react-dom/server'; - -const slugger = new GithubSlugger(); - -const extractInlinedStyles = (args: ReplaceRendererArgs) => { - const { - bodyComponent, - pathname, - replaceBodyHTMLString, - setHeadComponents, - } = args; - - const $ = cheerio.load( - renderToString(bodyComponent as React.ReactElement) - ); - const cssRules: string[] = []; - - const $elements = $('[style]'); - - $elements.map((_: number, element) => { - const $element = $(element); - const styles = $element.attr('style'); - const className = `inlined__${crypto - .randomBytes(4) - .toString('hex') - }`; - $element.addClass(className); - cssRules.push(`.${className} { ${styles}; }`); - $element.removeAttr('style'); - }); - - // eslint-disable-next-line quotes - const css = cssRules.join("\n"); - - const filenameHash = crypto - .randomBytes(10) - .toString('hex'); - - const cssFileNameBase = (pathname as string) - .replace(/^\/|\/$/g, '') - .replace('.html', ''); - - const cssFileName = - `inline---${slugger.slug(cssFileNameBase) || 'index'}.${filenameHash}.css`; - - const integrityHash = crypto - .createHash('sha512') - .update(css) - .digest('base64'); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(`public/${cssFileName}`, css, 'utf-8'); - - setHeadComponents([ - ( - - ), - ] as React.ReactNode[]); - - replaceBodyHTMLString($('body').html() as string); -}; - -const addHubspotChat = (args: ReplaceRendererArgs) => { - const { setPostBodyComponents } = args; - - /* eslint-disable react/jsx-key */ - setPostBodyComponents([ - , - ]); - /* eslint-enable react/jsx-key */ -}; - -export const replaceRenderer: GatsbySSR['replaceRenderer'] = ( - args: ReplaceRendererArgs -): any => { // eslint-disable-line @typescript-eslint/no-explicit-any - addHubspotChat(args); - extractInlinedStyles(args); -}; diff --git a/src/gatsby/gatsby-ssr/wrapRootElement.tsx b/src/gatsby/gatsby-ssr/wrapRootElement.tsx deleted file mode 100644 index 8e63e45ff..000000000 --- a/src/gatsby/gatsby-ssr/wrapRootElement.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { MDXProvider } from '@mdx-js/react'; -import { GatsbySSR, WrapRootElementNodeArgs } from 'gatsby'; -import React from 'react'; -import { IconContext } from 'react-icons'; - -import * as components from '../../components/Mdx'; -import { StoreProvider } from '../../store'; - -export const wrapRootElement: GatsbySSR['wrapRootElement'] = ( - props: WrapRootElementNodeArgs -): any => ( // eslint-disable-line @typescript-eslint/no-explicit-any - - {/* eslint-disable-next-line max-len */ } - {/* @ts-expect-error: @type for @mdx-js/react has implicit children which is incompat with react 18 */} - - - {props.element} - - - -); diff --git a/src/globals.d.ts b/src/globals.d.ts deleted file mode 100644 index 9f9e13019..000000000 --- a/src/globals.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare module '*.scss' { - const content: {[className: string]: string}; - export = content; -} - -declare module '*.svg' { - import * as React from 'react'; - export const ReactComponent: React.FC>; - export default ReactComponent; -} diff --git a/src/hooks/useActiveHeading.ts b/src/hooks/useActiveHeading.ts deleted file mode 100644 index 75da6b48f..000000000 --- a/src/hooks/useActiveHeading.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import forEach from 'lodash.foreach'; -import { useEffect, useState } from 'react'; - -const useActiveHeading = (headingIds: string[]): string => { - const [ - activeHeading, - setActiveHeading, - ] = useState(''); - - useEffect(() => { - const observer = new IntersectionObserver( - (entries) => { - forEach(entries, (entry) => { - if (entry.isIntersecting) { - setActiveHeading(entry.target.id); - } - }); - }, - { - // TODO - Adjust margin from bottom based on height of viewport in px - rootMargin: '0% 0% -80% 0%', - }, - ); - - const headings: HTMLElement[] = headingIds.reduce( - (accumulator: HTMLElement[], headingId: string) => { - const element = headingId.startsWith('schema--') - ? document.getElementById(headingId) - : document.getElementById(`toc-${headingId}`); - - if (!element) { - return accumulator; - } - - return [ - ...accumulator, - element, - ]; - }, - [], - ); - - headings.forEach((heading: HTMLElement) => { - observer.observe(heading); - }); - - return () => { - headings.forEach((heading: HTMLElement) => { - observer.unobserve(heading); - }); - }; - }, [ - headingIds, - ]); - - return activeHeading; -}; - -export default useActiveHeading; diff --git a/src/hooks/useIsClient.ts b/src/hooks/useIsClient.ts deleted file mode 100644 index 2ae69ca98..000000000 --- a/src/hooks/useIsClient.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import { useEffect, useState } from 'react'; - -type IsClient = { - isClient: boolean; - key: string; -} - -const useIsClient = (): IsClient => { - const [ - isClient, - setClient, - ] = useState(false); - const key = isClient ? 'client' : 'server'; - - useEffect(() => { - setClient(true); - }, []); - - return { - isClient, - key, - }; -}; - -export default useIsClient; diff --git a/src/hooks/useSystemStatus.tsx b/src/hooks/useSystemStatus.tsx deleted file mode 100644 index fcfc7d887..000000000 --- a/src/hooks/useSystemStatus.tsx +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import * as React from 'react'; - -import { - OperationalIcon, - WarningIcon, -} from '../components/SystemsStatusIcons'; - -type SystemStatus = { - class: string; - icon: JSX.Element; - message?: string; - title: string; -} - -// https://kb.status.io/developers/status-codes/ -const status: Record = { - 100: { - class: 'operational', - icon: , - title: 'Operational', - }, - 200: { - class: 'planned_maintenance', - icon: , - message: 'We are currently undergoing some scheduled maintenance.', - title: 'Planned Maintenance', - }, - 300: { - class: 'degraded_performance', - icon: , - // eslint-disable-next-line max-len - message: 'We are currently experiencing degraded performance in some of our web services.', - title: 'Degraded Performance', - }, - 400: { - class: 'partial_service_disruption', - icon: , - message: 'Some of our web services are temporarily unavailable.', - title: 'Partial Service Disruption', - }, - 500: { - class: 'service_disruption', - icon: , - message: 'Our web services are temporarily unavailable.', - title: 'Service Disruption', - }, - 600: { - class: 'security_event', - icon: , - // eslint-disable-next-line max-len - message: 'We are currently mitigating issues relating to some of our web services.', - title: 'Security Event', - }, -}; - -const useSystemStatus = (): null | SystemStatus => { - const [ - systemStatus, - setSystemStatus, - ] = React.useState(null); - - const getSystemStatus = () => fetch( - 'https://status.maxmind.com/1.0/status/53fcfbb2ac0c957972000235', - ) - .then(res => res.json()) - .then(json => { - const status_code = Number(json.result.status_overall.status_code); - if (!(status_code in status)) { - throw new TypeError('status_code invalid'); - } - if (json.result.incidents.length != 0) { - setSystemStatus({ - class: '', - icon: , - message: json.result.incidents[0].name, - title: status[Number(status_code)].title, - }); - return; - } - else if (json.result.maintenance.active.length != 0) { - setSystemStatus({ - class: '', - icon: , - message: json.result.maintenance.active[0].name, - title: status[Number(status_code)].title, - }); - return; - } - setSystemStatus(status[Number(status_code)]); - }) - .catch(() => { - /** - * No-op - * - * If something goes wrong, we intentionally want to swallow the error - * and prevent the UI from knowing - */ - }); - - React.useEffect(() => { - getSystemStatus(); - - const intervalId = setInterval(() => { - getSystemStatus(); - }, 30 * 1000); - - return () => clearInterval(intervalId); - }, []); - - return systemStatus; -}; - -export default useSystemStatus; diff --git a/src/images/maxmind-icon.png b/src/images/maxmind-icon.png deleted file mode 100644 index 8f11ac2b2..000000000 Binary files a/src/images/maxmind-icon.png and /dev/null differ diff --git a/src/languages.ts b/src/languages.ts deleted file mode 100644 index 0b73f8287..000000000 --- a/src/languages.ts +++ /dev/null @@ -1,235 +0,0 @@ -type IndentStyle = 'space' | 'tab'; - -interface IPrismSettings { - cli?: { - 'data-filter-output'?: string; - 'data-host'?: string; - 'data-user'?: string; - }; - importScript?: boolean; - whitespace: { - indentSize: number; - indentStyle: 'space' | 'tab'; - }; -} - -export interface ILanguage { - id: string; - label: string; - prismSettings: IPrismSettings; -} - -export const languages: ILanguage[] = [ - { - id: '*', - label: '*', - prismSettings: { - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'bash', - label: 'Bash', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'css', - label: 'CSS', - prismSettings: { - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'curl', - label: 'Curl', - prismSettings: { - cli: { - 'data-filter-output': '> ', - 'data-host': 'maxmind', - 'data-user': 'docs', - }, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'cli', - label: 'CLI', - prismSettings: { - cli: { - 'data-filter-output': ' >', - }, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'c', - label: 'C', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'csharp', - label: 'C#', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 4, - indentStyle: 'tab' as IndentStyle, - }, - }, - }, - { - id: 'csv', - label: 'CSV', - prismSettings: { - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'go', - label: 'Go', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'tab' as IndentStyle, - }, - }, - }, - { - id: 'java', - label: 'Java', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'javascript', - label: 'Node', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'json', - label: 'JSON', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'markdown', - label: 'Markdown', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'perl', - label: 'Perl', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 4, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'php', - label: 'PHP', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 4, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'python', - label: 'Python', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 4, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'ruby', - label: 'Ruby', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'sql', - label: 'Sql', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, - { - id: 'typescript', - label: 'TypeScript', - prismSettings: { - importScript: true, - whitespace: { - indentSize: 2, - indentStyle: 'space' as IndentStyle, - }, - }, - }, -]; diff --git a/src/pages/search-results.module.scss b/src/pages/search-results.module.scss deleted file mode 100644 index 0b2b425be..000000000 --- a/src/pages/search-results.module.scss +++ /dev/null @@ -1,91 +0,0 @@ -@use '../styles/variables'; - -.loading { - align-items: center; - display: flex; - height: 50vh; - justify-content: center; -} - -.wrapper { - margin: 0 var(--mm-spacing); - max-width: 960px; - min-height: 500px; -} - -.header { - margin-bottom: calc(var(--mm-spacing) / 2); -} - -.heading { - font-size: 20px; - margin: 0; - - strong { - font-weight: bold; - } -} - -@include variables.breakpoint('lg') { - .heading { - font-size: 30px; - } -} - -.query { - font-weight: bold; -} - -.count { - font-size: 14px; -} - -.results { - margin-bottom: var(--mm-spacing); -} - -.result { - margin-bottom: calc(var(--mm-spacing) / 1.5); -} - -.pagination { - margin-bottom: var(--mm-spacing); - - &::after { - clear: both; - content: ''; - display: table; - } -} - -.spellingLink, -.previous, -.next { - border-bottom: 2px dotted var(--mm-color-display-text); - color: var(--mm-color-display-text); - text-decoration: none; -} - -.previous { - float: left; - - &::before { - content: '<'; - margin-right: 5px; - } -} - -.next { - float: right; - - &::after { - content: '>'; - margin-left: 5px; - } -} - -.spellingLink:hover, -.previous:hover, -.next:hover { - border-bottom-style: solid; -} diff --git a/src/pages/search-results.tsx b/src/pages/search-results.tsx deleted file mode 100644 index fac04d96e..000000000 --- a/src/pages/search-results.tsx +++ /dev/null @@ -1,261 +0,0 @@ -/* eslint-disable react/prop-types */ - -import { globalHistory } from '@reach/router'; -import { RouteUpdateArgs } from 'gatsby'; -import React, { useEffect, useState } from 'react'; - -import Layout from '../components/Layout/Layout'; -import Link from '../components/Link'; -import Loading from '../components/Loading'; -import H1 from '../components/Mdx/H1'; -import SearchResult from '../components/SearchResult'; -import GoogleSearch, { ISearchResults } from '../services/GoogleSearch'; - -import * as styles from './search-results.module.scss'; - -type queryValue = number | string | undefined; - -const SearchResultsPage: React.FC = (props) => { - const urlParams = new URLSearchParams(props.location.search); - - const getQueryUrl = (param: string, q: queryValue): string => { - if (!q) { - return ''; - } - - const urlParams = new URLSearchParams(props.location.search); - urlParams.set(param, q.toString()); - - return `${props.uri}?${urlParams.toString()}`; - }; - - const [ - query, - setQuery, - ] = useState(urlParams.get('q') as string); - - const [ - startIndex, - setStartIndex, - ] = useState(urlParams.get('start') as string); - - const [ - results, - setResults, - ] = useState({} as ISearchResults); - - const [ - isLoading, - setIsLoading, - ] = useState(true); - - const [ - hasError, - setHasError, - ] = useState(false); - - useEffect(() => { - globalHistory.listen((history) => { - const historyParams = new URLSearchParams(history.location.search); - setQuery(historyParams.get('q') as string); - setStartIndex(historyParams.get('start') as string); - props.location.search = history.location.search; - }); - }); - - useEffect(() => { - const fetchResults = async () => { - window.scrollTo(0,0); - try { - setHasError(false); - setIsLoading(true); - setResults(await GoogleSearch(query, startIndex)); - } catch { - setHasError(true); - } - setIsLoading(false); - }; - - if (query) { - fetchResults(); - } - }, [ - query, - startIndex, - ]); - - - return ( - - { - // Loading - isLoading && query && -
    - -
    - } - - { - // No Query - !query && -
    -
    -

    - Please enter a search query -

    -
    -
    - } - - { - // There's a server error - hasError && -
    -
    -

    - There was an issue performing the search. -

    -

    - Please try again. -

    -
    -
    - } - - { - // There's no search results - !isLoading && !hasError && !results.items && query && -
    -
    -

    - No results found for - {' '} - {query} -

    - { results.spelling && -

    - Try searching for - {' '} - - {results.spelling?.correctedQuery} - -

    - } -
    -
    - - } - - { - // We found stuff - !isLoading && results.items && query && -
    -
    - <> -

    - Search results for - {' '} - - {query} - -

    - - Displaying results - {' '} - {results.queries.request[0].startIndex} - - - {results.queries.request[0].startIndex - + results.queries.request[0].count - - 1} - {' '} - of - {' '} - {results.queries.request[0].totalResults} - - -
    -
    - { - results.items?.map((result) => { - return ( - - ); - }) - } -
    - -
    - } -
    - );}; - -export default SearchResultsPage; diff --git a/src/services/GoogleSearch.ts b/src/services/GoogleSearch.ts deleted file mode 100644 index 98e998090..000000000 --- a/src/services/GoogleSearch.ts +++ /dev/null @@ -1,53 +0,0 @@ -interface IItems { - cacheId: string; - htmlSnippet: string; - htmlTitle: string; - link: string; -} - -interface IQuery { - count: number; - startIndex: number; - totalResults: string; -} - -export interface ISearchResults { - items?: IItems[]; - queries: { - nextPage?: IQuery[]; - previousPage?: IQuery[]; - request: IQuery[]; - } - spelling?: { - correctedQuery: string; - } -} - -const endpoint = - 'https://www.googleapis.com/customsearch/v1/siterestrict?cx={cx}&key={key}'; - -const cx = 'cde039a7678700a13'; -const key = 'AIzaSyAI4atAz3I5ujXCjoEXRvdwqcYn3AIsCA8'; - -const url = endpoint - .replace('{cx}', cx) - .replace('{key}', key); - - -const GoogleSearch = - async (query: string, startIndex: string | null): Promise => { - let requestUrl = `${url}&q=${query}`; - - if (startIndex) { - requestUrl = requestUrl + `&start=${startIndex}`; - } - const response = await fetch(requestUrl); - - if (!response.ok) { - throw new Error(`There was an error searching for ${query}`); - } - - return await response.json() as ISearchResults; - }; - -export default GoogleSearch; diff --git a/src/store/index.tsx b/src/store/index.tsx deleted file mode 100644 index b7dd0ce20..000000000 --- a/src/store/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; - -interface IContext { - selectedLanguage: string; -} - -interface IAction { - payload: string; - type: 'change_language' | undefined; -} - -let initialContext: IContext; -if (typeof window !== 'undefined') { - initialContext = { - selectedLanguage: window.localStorage.getItem('mm-selected-language') || '', - }; -} else { - initialContext = { - selectedLanguage: '', - }; -} - -const reducer = (context: IContext, action: IAction): IContext => { - switch (action.type) { - case 'change_language': - window.localStorage.setItem('mm-selected-language', action.payload); - return { - ...context, - selectedLanguage: action.payload, - }; - default: - return context; - } -}; - -export const Store = - React.createContext< - { - context: IContext; - dispatch: React.Dispatch; - }>({ - context: initialContext, - dispatch: () => null, - }); - -export const StoreProvider: React.FC = (props) => { - const [ - context, - dispatch, - ] = React.useReducer(reducer, initialContext); - - return ( - - {props.children} - - ); -}; diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss deleted file mode 100644 index f8fedd640..000000000 --- a/src/styles/_reset.scss +++ /dev/null @@ -1,136 +0,0 @@ -/* stylelint-disable */ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ - -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -img, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -b, -u, -i, -center, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td, -article, -aside, -canvas, -details, -embed, -figure, -figcaption, -footer, -header, -hgroup, -menu, -nav, -output, -ruby, -section, -summary, -time, -mark, -audio, -video { - border: 0; - font: inherit; - font-size: 100%; - margin: 0; - padding: 0; - vertical-align: baseline; -} - -/* HTML5 display-role reset for older browsers */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { - display: block; -} - -body { - line-height: 1; -} - -ol, -ul { - list-style: none; -} - -blockquote, -q { - quotes: none; -} - -blockquote::before, -blockquote::after, -q::before, -q::after { - content: ''; - content: none; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss deleted file mode 100644 index 1cae19e91..000000000 --- a/src/styles/_variables.scss +++ /dev/null @@ -1,198 +0,0 @@ -$breakpoints: ( - xs: 360px, - sm: 576px, - md: 768px, - lg: 992px, - xl: 1200px, - xxl: 1400px, - xxxl: 1660px -); - -@mixin breakpoint($size) { - $width: map-get($breakpoints, $size); - - @media only screen and (min-width: $width) { - @content; - } -} - -@mixin max-breakpoint($size) { - $width: map-get($breakpoints, $size); - - @media only screen and (max-width: $width) { - @content; - } -} - -$containers: ( - sm: 540px, - md: 720px, - lg: 960px, - xl: 1140px, - xxl: 1320px, - xxxl: 1600px -); - -@mixin container($size) { - $width: map-get($containers, $size); - max-width: $width; - padding: 0; -} - -@mixin max-width { - @include breakpoint('xl') { - max-width: 880px; - width: 100%; - } -} - -@mixin heading { - color: #00374c; - font-family: var(--mm-font-stack-display); - font-weight: 500; - line-height: 1.2em; - margin: calc(var(--mm-spacing) * 2) 0 calc(var(--mm-spacing) / 4); - position: relative; - scroll-margin-top: calc(var(--page-header-height) + var(--mm-spacing)); - - + [id^='toc-'] { - h3, - h4, - h5, - h6 { - margin-top: calc(var(--mm-spacing) / 4); - } - } - - + [class^='Table-module'] { - margin-top: calc(var(--mm-spacing) / 4); - } - - .link { - color: #00374c; - text-decoration: none; - } - - .icon { - font-size: 12px; - left: -5px; - margin-bottom: 0 !important; - opacity: 0.2; - position: absolute; - top: 50%; - transform: translate(-100%, -50%); - transition: all 0.15s ease-out; - } - - .link:hover .icon { - font-size: 14px; - opacity: 0.75; - } -} - -@mixin scrollbars($scroll-color: rgba(255, 255, 255, 0.2)) { - scrollbar-color: $scroll-color transparent; - scrollbar-width: thin; - - &::-webkit-scrollbar { - height: var(--mm-border-radius); - width: var(--mm-border-radius); - } - - &::-webkit-scrollbar-thumb { - background-color: $scroll-color; - border-radius: var(--mm-border-radius); - } - - &::-webkit-scrollbar-corner { - background: transparent; - } -} - -$pattern-scale: 1; - -@mixin pattern-base { - background-color: #00a7e5; - background-image: url('/static/svg/bg-pattern.svg'); - background-position: center center; - background-size: (80px * $pattern-scale) (140px * $pattern-scale); - content: ' '; - height: 100%; - left: 0; - position: absolute; - top: 0; - transform: translateZ(0); - width: 100%; - will-change: transform; /* stylelint-disable-line */ -} - -@mixin pattern-gradient { - background: rgb(0, 119, 194); - background: linear-gradient(90deg, rgba(0, 119, 194, 0.5) 0%, var(--page-type-color)); - content: ' '; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; -} - -@mixin pattern { - position: relative; - - &::before { - @include pattern-base; - } - - &::after { - @include pattern-gradient; - } -} - -@mixin pattern-border { - &::before, - &::after { - display: block; - height: 10px !important; - overflow: hidden; - } - - &::before { - @include pattern-base; - } - - &::after { - @include pattern-gradient; - } -} - -@mixin menu-button { - background: var(--mm-color-background); - border: 1px solid var(--mm-color-border); - border-radius: var(--mm-border-radius); - box-sizing: border-box; - color: var(--mm-color-primary-color); - cursor: pointer; - font-size: 12px; - height: 30px; - min-width: 30px; - padding: 0; - width: 30px; - - &:hover { - background-color: var(--mm-color-sidebar); - } - - @media only screen and (min-width: 420px) { - font-size: 16px; - height: 50px; - min-width: 50px; - width: 50px; - } -} - - -@mixin opaque-overlay { - backdrop-filter: blur(3px); - background-color: rgba(255, 255, 255, 0.7); -} diff --git a/src/styles/global.scss b/src/styles/global.scss deleted file mode 100644 index 3e9950b45..000000000 --- a/src/styles/global.scss +++ /dev/null @@ -1,91 +0,0 @@ -@use './reset'; - -/* stylelint-disable no-invalid-position-at-import-rule */ -@import '~normalize.css/normalize.css'; -@import '~@fontsource/montserrat/500.css'; -@import '~@fontsource/montserrat/700.css'; -@import '~@fontsource/montserrat/900.css'; -@import '~@fontsource/roboto/500.css'; -@import '~@fontsource/roboto/700.css'; -@import '~@fontsource/source-code-pro/500.css'; -@import '~@fontsource/source-code-pro/700.css'; -/* stylelint-enable no-invalid-position-at-import-rule */ - -:host { - --gatsby: #274958; -} - -:root { - --gatsby: #274958; - --mm-color-active-blue: #2b7ec6; - --mm-color-background: #fff; - --mm-color-background-code: #274958; - --mm-color-sidebar: #f5f6f7; - --mm-color-border: #ddd; - --mm-color-logo-blue-light: #00aeef; - --mm-color-logo-blue-dark: #005f83; - --mm-color-primary-text: #595959; - --mm-color-display-text: #005f83; - --mm-border-radius: 6px; - --mm-font-stack-default: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Ubuntu, sans-serif; - --mm-font-stack-display: 'montserrat', var(--mm-font-stack-default); - --mm-font-stack-monospace: 'Source Code Pro', monospace; - --mm-layout-toc-width: 290px; - --mm-layout-sidebar-width: 350px; - --mm-outline: 2px solid var(--mm-color-logo-blue-light); - --mm-spacing: 40px; - --page-header-height: 80px; - --page-type-color: rgba(255, 255, 255, 0.3); -} - -:global(.fa-icon) { - vertical-align: middle; -} - -:global(#___gatsby) { - min-height: 100vh; -} - -:global(#gatsby-focus-wrapper) { - display: flex; - flex-direction: column; - min-height: 100vh; -} - -/* Not sure why .page-type--minfraud does not work here */ -[class='page-type--minfraud'] { - --page-type-color: rgba(255, 0, 136, 0.5); -} - -/* Not sure why .page-type--geoip does not work here */ -[class='page-type--geoip'] { - --page-type-color: rgba(0, 255, 102, 0.5); -} - -html { - min-width: 360px; -} - -body { - color: var(--mm-color-primary-text); - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Ubuntu, sans-serif; - font-size: 1.1rem; - line-height: 1.3em; - min-height: 100vh; - min-width: 360px; - position: relative; -} - -* { - box-sizing: border-box; -} - -*:focus { - outline-color: var(--mm-color-logo-blue-light); - outline-style: solid; - outline-width: 2px; -} - -[class='geoip-icon-st0'] { - fill: none; -} diff --git a/src/templates/Home/Home.module.scss b/src/templates/Home/Home.module.scss deleted file mode 100644 index 4390cbe75..000000000 --- a/src/templates/Home/Home.module.scss +++ /dev/null @@ -1,76 +0,0 @@ -@use '../../styles/variables'; - -.layout [class^='Layout-module--content'] { - --mm-spacing: 20px; - background-color: var(--mm-color-sidebar); - display: grid; - grid-auto-rows: minmax(min-content, max-content); - justify-items: center; -} - -.callout { - padding: var(--mm-spacing) var(--mm-spacing) 0; - text-align: center; -} - -.calloutHeading { - font-family: var(--mm-font-stack-display); - font-size: 20px; - font-weight: 700; - line-height: 1.2em; - margin-bottom: calc(var(--mm-spacing) / 2); -} - -.noWrap { - white-space: nowrap; -} - -.calloutSubheading { - font-family: var(--mm-font-stack-monospace); - font-size: 14px; - font-weight: 700; -} - -.products { - display: grid; - gap: var(--mm-spacing); - padding: var(--mm-spacing); -} - -.signUp { - padding: 0 var(--mm-spacing) var(--mm-spacing) var(--mm-spacing); - - h3 { - font-size: 16px !important; - } - - svg { - width: 25px !important; - } - - > * { - --page-type-color: rgba(0, 255, 102, 0.5); - } -} - - -@include variables.breakpoint('md') { - .layout [class^='Layout-module--content'] { - --mm-spacing: 40px; - background-color: var(--mm-color-sidebar); - } - - .calloutHeading { - font-size: 35px; - } - - .calloutSubheading { - font-size: 20px; - } - - .products { - gap: var(--mm-spacing); - grid-template-columns: repeat(2, minmax(0, 600px)); - justify-content: center; - } -} diff --git a/src/templates/Home/Home.tsx b/src/templates/Home/Home.tsx deleted file mode 100644 index e89cee3dc..000000000 --- a/src/templates/Home/Home.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { - FaBookOpen as ViewDocsIcon, - FaRocket as QuickstartIcon, - FaUserCheck as SignUpIcon, -} from 'react-icons/fa'; - -import Layout from '../../components/Layout/Layout'; -import LinkButton from '../../components/LinkButton'; -import { - a as A, - LinkGroupCard, -} from '../../components/Mdx'; -import Product from './Product'; -import { IHomeContext } from './query'; - -import * as styles from './Home.module.scss'; - -interface IHome { - pageContext: IHomeContext; -} - -const Home: React.FC = (props) => { - const { pageContext } = props; - const { frontmatter } = pageContext; - const { description, keywords, title } = frontmatter; - - return ( - -
    -

    - - 👋 - - {' '} - Welcome to the - {' '} - - MaxMind Developer Portal - - ! -

    -

    - Develop applications using industry-leading - {' '} - - IP intelligence and risk scoring. - -

    -
    -
    - - Learn more about - {' '} - - minFraud Web Services - - . - - )} - heading="minFraud Web Services" - icon="MinFraudIcon" - links={( - <> - - - - )} - subheading="Transaction Risk API" - > - Use risk scoring and data to identify high-risk activity in - e-commerce payments, platform user activity, incentivized traffic, - and more. - - - Learn more about - {' '} - - GeoIP2 - - {' '} - and - {' '} - - GeoLite2 - - . - - )} - heading="GeoIP2 and GeoLite2" - icon="GeoIPIcon" - links={( - <> - - - - )} - subheading="Databases and Web Services" - > - Use GeoIP intelligence for content customization, advertising, - digital rights management, compliance, fraud detection, security and - more. - -
    -
    - -
    -
    - ); -}; - -Home.propTypes = { - pageContext: PropTypes.any, -}; - -export default Home; diff --git a/src/templates/Home/Product.module.scss b/src/templates/Home/Product.module.scss deleted file mode 100644 index 994230ce8..000000000 --- a/src/templates/Home/Product.module.scss +++ /dev/null @@ -1,211 +0,0 @@ -@use '../../styles/variables'; - -.container { - --mm-spacing: 20px; - background-color: var(--mm-color-background); - border-radius: var(--mm-border-radius); - box-shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - display: grid; - grid-template-rows: max-content auto max-content max-content; - overflow: hidden; - position: relative; -} - -.container__geoip { - --page-type-color: rgba(0, 255, 102, 0.5); -} - -.container__minfraud { - --page-type-color: rgba(255, 0, 136, 0.5); -} - -.header { - padding: var(--mm-spacing); - @include variables.pattern; -} - -.lockup { - --mm-overview-heading-drop-shadow: 1px 3px 0 rgba(0, 0, 0, 0.25); - display: grid; - grid-auto-flow: column; - grid-template-areas: - 'logo' - 'heading' - 'subheading'; - position: relative; - z-index: 1; -} - -.lockup > * { - align-self: center; - justify-self: center; -} - -.icon { - grid-area: logo; - height: 90px; - margin-bottom: var(--mm-spacing); - width: 90px; -} - -.heading { - color: #fff; - font-family: var(--mm-font-stack-display); - font-size: 20px; - font-weight: 700; - grid-area: heading; - line-height: 1em; - margin-bottom: 5px; - text-align: center; - text-shadow: var(--mm-overview-heading-drop-shadow); -} - -.subheading { - color: #fff; - font-family: var(--mm-font-stack-display); - font-size: 16px; - font-weight: 700; - grid-area: subheading; - line-height: 1em; - text-align: center; - text-shadow: var(--mm-overview-heading-drop-shadow); -} - -.content { - background-color: var(--mm-color-background); - font-size: 14px; - padding: var(--mm-spacing); - text-align: center; -} - -.content * { - font-size: 14px; -} - -.links { - background-color: var(--mm-color-sidebar); - border-top: 1px solid var(--mm-color-border); - display: grid; - gap: var(--mm-spacing); - grid-auto-flow: column; - grid-template-columns: repeat(2, max-content); - justify-content: center; - padding: var(--mm-spacing); - width: 100%; -} - -.footer { - background-color: #f0f8ff; - border-top: 1px solid #cfdee8; - display: grid; - gap: calc(var(--mm-spacing) / 4); - grid-auto-flow: column; - grid-template-columns: max-content max-content; - grid-template-rows: max-content; - justify-content: center; - padding: calc(var(--mm-spacing) / 2); - text-align: center; -} - -.footer * { - align-self: center; - font-size: 12px; -} - -.infoIcon { - color: var(--mm-color-active-blue); - font-size: 16px; -} - -.learnMore { - color: #545454; - margin: 0; -} - -.learnMore [class^='A-module'] { - color: #005270; - font-weight: 600; -} - -.links > * { - justify-self: center; -} - -.content > *:first-child { - margin-top: 0; -} - -.content > *:last-child { - margin-bottom: 0; -} - -@include variables.breakpoint('xl') { - .container { - --mm-spacing: 40px; - display: grid; - grid-template-areas: - 'header header' - 'content links' - 'learnMore learnMore'; - } - - .header { - --mm-spacing: 40px; - display: grid; - grid-area: header; - justify-content: center; - } - - .lockup { - column-gap: calc(var(--mm-spacing) / 2); - grid-template-areas: - 'logo heading' - 'logo subheading'; - grid-template-columns: max-content max-content; - } - - .lockup > * { - justify-self: left; - } - - .icon { - margin-bottom: 0; - } - - .heading { - align-self: end; - font-size: 24px; - } - - .subheading { - align-self: start; - font-size: 18px; - } - - .content { - grid-area: content; - text-align: left; - } - - .content * { - font-size: initial; - } - - .links { - border-left: 1px solid var(--mm-color-border); - border-top: 0; - display: grid; - gap: calc(var(--mm-spacing) / 2); - grid-area: links; - grid-template-columns: auto; - grid-template-rows: max-content max-content; - } - - .links > * { - justify-self: auto; - } - - .footer { - grid-area: learnMore; - } -} diff --git a/src/templates/Home/Product.tsx b/src/templates/Home/Product.tsx deleted file mode 100644 index cad7de875..000000000 --- a/src/templates/Home/Product.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import { FaInfoCircle as InfoIcon } from 'react-icons/fa'; - -import { p as P } from '../../components/Mdx'; -import ProductIcon from '../../components/ProductIcon'; - -import * as styles from './Product.module.scss'; - -interface IProduct { - children: React.ReactNode; - family: ProductFamily; - footer: React.ReactNode, - heading: string; - icon: string; - links: React.ReactNode, - subheading: string; -} - -const Product: React.FC = (props) => { - const { - children, - family, - icon, - heading, - footer, - links, - subheading, - } = props; - - return ( -
    -
    -
    - -

    - {heading} -

    -

    - {subheading} -

    -
    -
    -
    -

    {children}

    -
    -
    - {links} -
    -
    - -

    - {footer} -

    -
    -
    - ); -}; - -Product.propTypes = { - children: PropTypes.node.isRequired, - family: PropTypes.oneOf([ - 'minfraud', - 'geoip', - ] as const).isRequired, - footer: PropTypes.node.isRequired, - heading: PropTypes.string.isRequired, - icon: PropTypes.string.isRequired, - links: PropTypes.node.isRequired, - subheading: PropTypes.string.isRequired, -}; - -export default Product; diff --git a/src/templates/Home/index.ts b/src/templates/Home/index.ts deleted file mode 100644 index 30c358a55..000000000 --- a/src/templates/Home/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as default } from './Home'; diff --git a/src/templates/Home/query.ts b/src/templates/Home/query.ts deleted file mode 100644 index dac36d2b3..000000000 --- a/src/templates/Home/query.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import { BaseQuery, IBaseQuery } from '../../baseQuery'; - -export type IHomeContext = Pick; - -const query: QueryFn = ( - graphql: GraphqlFn -) => graphql(` - ${BaseQuery} - - query PageTemplateQuery { - allMdx(filter: {fields: {layout: {eq: "home"}}}) { - nodes { - ... BaseQuery - } - } - } -`); - -export default query; diff --git a/src/templates/Overview/Overview.module.scss b/src/templates/Overview/Overview.module.scss deleted file mode 100644 index 8a7ea15b2..000000000 --- a/src/templates/Overview/Overview.module.scss +++ /dev/null @@ -1,121 +0,0 @@ -@use '../../styles/variables'; - -.header { - --mm-overview-heading-drop-shadow: 2px 4px 0 rgba(0, 0, 0, 0.25); - @include variables.pattern; - display: grid; - padding: var(--mm-spacing); - - > * { - position: relative; - z-index: 2; - } - - &::before { - background-attachment: fixed; - } -} - -.lockup { - column-gap: 20px; - display: grid; - grid-template-areas: - 'logo' - 'heading' - 'subheading'; - grid-template-columns: auto auto; - justify-self: center; - row-gap: 10px; -} - -.lockup > * { - align-self: center; - justify-self: center; -} - -.icon { - grid-area: logo; - margin-bottom: 25px; -} - -.heading { - color: #fff; - font-family: var(--mm-font-stack-display); - font-size: 30px; - font-weight: 700; - grid-area: heading; - line-height: 1em; - text-align: center; - text-shadow: var(--mm-overview-heading-drop-shadow); -} - -.subheading { - color: #fff; - font-family: var(--mm-font-stack-display); - font-size: 18px; - font-weight: 700; - grid-area: subheading; - line-height: 1em; - text-align: center; - text-shadow: var(--mm-overview-heading-drop-shadow); -} - -.content { - padding: var(--mm-spacing); -} - -.content > *:first-child { - margin-top: 0; -} - -@include variables.breakpoint('sm') { - .lockup { - grid-template-areas: - 'logo heading' - 'logo subheading'; - } - - .lockup > * { - justify-self: left; - } - - .icon { - margin-bottom: 0; - } - - .heading { - align-self: end; - text-align: left; - } - - .subheading { - align-self: start; - text-align: left; - } -} - -@include variables.breakpoint('xl') { - .heading { - font-size: 40px; - } - - .subheading { - font-size: 25px; - } - - .content { - display: grid; - } - - .content > * { - justify-self: center; - } - - .content [class^='LinkGroupContainer-module'] { - max-width: calc(680px + 300px); - } - - .content > *:not([class^='LinkGroupContainer-module']) { - @include variables.max-width; - } -} diff --git a/src/templates/Overview/Overview.tsx b/src/templates/Overview/Overview.tsx deleted file mode 100644 index 45d1c6699..000000000 --- a/src/templates/Overview/Overview.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useLocation } from '@reach/router'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import Layout from '../../components/Layout/Layout'; -import ProductIcon from '../../components/ProductIcon'; -import { IOverviewContext } from './query'; - -import * as styles from './Overview.module.scss'; - -interface IOverview { - children: React.ReactNode; - pageContext: IOverviewContext; -} - -const Overview: React.FC = (props) => { - const { frontmatter } = props.pageContext; - const location = useLocation(); - const { description, icon, keywords, title } = frontmatter; - - let type; - - if (location.pathname.startsWith('/minfraud')) { - type = 'minfraud'; - } - - if (location.pathname.startsWith('/geoip')) { - type = 'geoip'; - } - - return ( - -
    -
    -
    - - -

    - -

    - {frontmatter.subtitle} -

    -
    -
    - -
    - {props.children} -
    -
    -
    - ); -}; - -Overview.propTypes = { - children: PropTypes.node.isRequired, - pageContext: PropTypes.any, -}; - -export default Overview; diff --git a/src/templates/Overview/index.ts b/src/templates/Overview/index.ts deleted file mode 100644 index 6be1bace8..000000000 --- a/src/templates/Overview/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as default } from './Overview'; diff --git a/src/templates/Overview/query.ts b/src/templates/Overview/query.ts deleted file mode 100644 index 55f9a3da5..000000000 --- a/src/templates/Overview/query.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import { BaseQuery, IBaseQuery } from '../../baseQuery'; - -export type IOverviewContext = Pick & { - readonly frontmatter: { - readonly icon: string; - readonly subtitle: string; - }; -} - -const query: QueryFn = ( - graphql: GraphqlFn -) => graphql(` - ${BaseQuery} - - query OverviewTemplateQuery { - allMdx(filter: {fields: {layout: {eq: "overviews"}}}) { - nodes { - ... BaseQuery - frontmatter { - subtitle - icon - } - } - } - } -`); - -export default query; diff --git a/src/templates/Page/Page.module.scss b/src/templates/Page/Page.module.scss deleted file mode 100644 index 0d16fad98..000000000 --- a/src/templates/Page/Page.module.scss +++ /dev/null @@ -1,294 +0,0 @@ -@use '../../styles/variables'; - -.article { - padding: var(--mm-spacing); -} - -.header { - background: var(--mm-color-background); - z-index: 5; - @include variables.max-width; -} - -.heading { - margin: 0; - padding: 0 0 var(--mm-spacing); -} - -.aside { - background: var(--mm-color-sidebar); - margin: var(--mm-spacing) 0; - padding: var(--mm-spacing); - position: relative; - - @include variables.pattern-border; -} - -.header + .aside { - margin-top: 0; -} - -.content { - @include variables.max-width; -} - -.content > [id^='toc-']:first-child > *:first-child { - margin-top: 0; -} - -.footer { - border-top: 1px solid var(--mm-color-border); - display: grid; - gap: 20px; - grid-template-columns: 1fr; - grid-template-rows: auto; - padding: var(--mm-spacing) 0; -} - -.lastUpdated { - font-size: 12px; - font-style: italic; - font-weight: 400; - margin-top: calc(var(--mm-spacing) * 2); - text-align: center; -} - -.footerNext, -.footerPrevious { - border-radius: var(--mm-border-radius); - color: var(--mm-color-display-text); - column-gap: calc(var(--mm-spacing) / 2); - display: grid; - font-size: 18px; - font-weight: 500; - grid-template-columns: auto; - grid-template-rows: max-content 1fr; - padding: calc(var(--mm-spacing) / 4) calc(var(--mm-spacing) / 2); - text-decoration: none; - transition: padding 0.2s ease-in-out, background 0.1s ease-in-out; - - &:hover { - background: var(--mm-color-sidebar); - } -} - -/* stylelint-disable no-descending-specificity */ -.footerNext { - grid-template-areas: - 'direction arrow' - 'title arrow'; - grid-template-columns: 1fr min-content; - padding-right: var(--mm-spacing); - text-align: right; - - &:hover { - padding-right: calc(var(--mm-spacing) / 2); - } -} - -.footerPrevious { - grid-template-areas: - 'arrow direction' - 'arrow title'; - grid-template-columns: min-content 1fr; - padding-left: var(--mm-spacing); - - &:hover { - padding-left: calc(var(--mm-spacing) / 2); - } -} -/* stylelint-enable no-descending-specificity */ - -.footerDirection { - color: var(--mm-color-primary-text); - display: block; - font-size: 12px; - font-weight: 500; - grid-area: direction; - text-decoration: none; -} - -.footerTitle { - grid-area: title; -} - -.footerArrow { - align-self: center; - grid-area: arrow; - justify-self: center; -} - -@include variables.breakpoint('sm') { - .footer { - grid-template-areas: 'previous next'; - grid-template-columns: 1fr 1fr; - } - - .footerNext { - grid-area: next; - text-align: right; - } - - .footerPrevious { - grid-area: previous; - } -} - -@include variables.breakpoint('md') { - .article { - display: flex; - flex-direction: column; - height: 100%; - } - - .header, - .aside, - .content, - .footer { - justify-self: center; - } -} - -@include variables.breakpoint('xl') { - .article { - display: grid; - grid-template-areas: - 'header header' - 'aside aside' - 'content content' - 'last-updated last-updated' - 'footer footer'; - grid-template-columns: 50% 50%; - grid-template-rows: min-content min-content 1fr min-content; - height: 100%; - padding: var(--mm-spacing) 0; - } - - .header { - grid-area: header; - padding: 0 var(--mm-spacing) 0; - } - - .header ~ .content > *:first-child { - margin-top: 0; - } - - .aside { - grid-area: aside; - max-width: 800px; - width: 100%; - } - - .content { - grid-area: content; - padding: 0 var(--mm-spacing); - } - - .lastUpdated { - grid-area: last-updated; - } - - .footer { - grid-area: footer; - @include variables.max-width; - } -} - -@include variables.max-breakpoint('xl') { - .article.releaseNotes .aside, - .article.releaseNotes .header { - justify-self: auto; - } -} - - -@include variables.max-breakpoint('xxl') { - .article.releaseNotes { - display: grid; - grid-template-areas: - 'header header' - 'content content' - 'aside aside' - 'footer footer'; - grid-template-columns: 50% 50%; - grid-template-rows: min-content min-content 1fr min-content; - height: 100%; - } - - .article.releaseNotes .header { - grid-area: header; - } - - .article.releaseNotes .header ~ .content > *:first-child { - margin-top: 0; - } - - .article.releaseNotes .aside { - grid-area: aside; - @include variables.max-width; - } - - .article.releaseNotes .content { - grid-area: content; - } - - .article.releaseNotes .footer { - grid-area: footer; - } -} - -@include variables.breakpoint('xxl') { - .article { - grid-template-areas: - 'header aside' - 'content aside' - 'footer aside'; - grid-template-columns: calc(100vw - 640px) var(--mm-layout-toc-width); - grid-template-rows: min-content auto min-content; - /* autoprefixer: ignore next */ - justify-items: start; - } - - .header { - grid-area: header; - } - - .aside { - background: var(--mm-color-background); - border-bottom: 0; - grid-area: aside; - height: auto; - margin: 0; - min-width: auto; - padding: 0; - width: 100%; - } - - .aside::before, - .aside::after { - display: none; - } - - .tableOfContents { - max-height: calc(100vh - var(--page-header-height)); - overflow-y: scroll; - padding: var(--mm-spacing) var(--mm-spacing) 120px 20px; - position: sticky; - top: calc(var(--page-header-height)); - width: 100%; - } - - .content { - grid-area: content; - } -} - -@include variables.breakpoint('xxxl') { - .content { - margin: 0 auto; - } - - .content > [id^='toc-'] { - margin: calc(var(--mm-spacing) * 3) 0; - } -} diff --git a/src/templates/Page/Page.tsx b/src/templates/Page/Page.tsx deleted file mode 100644 index 2292e4214..000000000 --- a/src/templates/Page/Page.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { useLocation } from '@reach/router'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { FaArrowLeft, FaArrowRight } from 'react-icons/fa'; - -import Layout from '../../components/Layout/Layout'; -import Link from '../../components/Link'; -import { h1 as H1, p as P } from '../../components/Mdx'; -import { getNextPage, getPreviousPage } from '../../utils/pagination'; -import { IPageContext } from './query'; -import ReleaseNotesArchiveList from './ReleaseNotesArchiveList'; -import TableOfContents from './TableOfContents'; - -import * as styles from './Page.module.scss'; - -interface IPage { - children: React.ReactNode; - pageContext: IPageContext; -} - -const Page: React.FC = (props) => { - const { - frontmatter, - parent, - customTableOfContents: tableOfContents, - } = props.pageContext; - const location = useLocation(); - const { description, keywords, image, title } = frontmatter; - const { modifiedTime } = parent || {}; - - let type; - - if (location.pathname.startsWith('/minfraud')) { - type = 'minfraud'; - } - - if (location.pathname.startsWith('/geoip')) { - type = 'geoip'; - } - - let isReleaseNotesPage = false; - - if (location.pathname.split('/')[2] === 'release-notes' && type) { - isReleaseNotesPage = true; - } - - const nextPage = getNextPage(location.pathname); - const previousPage = getPreviousPage(location.pathname); - - return ( - -
    -
    -

    - {title} -

    -
    - - <> - {tableOfContents !== null && ( - - )} - - -
    - {props.children} - - {modifiedTime && ( -

    - This page was last updated on - {' '} - {modifiedTime} - . -

    - )} -
    - - <> - {(previousPage || nextPage) && ( -
    - <> - {previousPage && ( - - - - Previous - - - {previousPage.title} - - - )} - - - <> - {nextPage && ( - - - - Next - - - {nextPage.title} - - - )} - -
    - )} - -
    -
    - ); -}; - -Page.propTypes = { - children: PropTypes.node.isRequired, - pageContext: PropTypes.any, -}; - -export default Page; diff --git a/src/templates/Page/ReleaseNotesArchiveList.tsx b/src/templates/Page/ReleaseNotesArchiveList.tsx deleted file mode 100644 index 4146d07aa..000000000 --- a/src/templates/Page/ReleaseNotesArchiveList.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import TableOfContents from './TableOfContents'; - -type ProductSlug = 'geoip' | 'minfraud'; - -export interface IReleaseNotesArchiveList { - type: ProductSlug; -} - -const years: Record = { - geoip: [ - 2023, - 2022, - 2021, - 2020, - 2019, - 2018, - 2017, - 2016, - 2015, - 2014, - 2013, - ], - minfraud: [ - 2023, - 2022, - 2021, - 2020, - 2019, - 2018, - 2017, - 2016, - 2015, - 2014, - 2013, - ], -}; - -const generateItems = (type: ProductSlug) => { - // eslint-disable-next-line security/detect-object-injection - const items = years[type].map((year: number) => ({ - items: [], - title: year.toString(), - url: `/${type}/release-notes/${year}`, - })); - - return items; -}; - - -const ReleaseNotesArchiveList: React.FC< - IReleaseNotesArchiveList & React.HTMLProps -> = (props) => { - const { className, type } = props; - - return ( - - ); -}; - -ReleaseNotesArchiveList.propTypes = { - className: PropTypes.string, - type: PropTypes.oneOf([ - 'geoip', - 'minfraud', - ]).isRequired, -}; - -export default ReleaseNotesArchiveList; diff --git a/src/templates/Page/TableOfContents.module.scss b/src/templates/Page/TableOfContents.module.scss deleted file mode 100644 index deaf9370f..000000000 --- a/src/templates/Page/TableOfContents.module.scss +++ /dev/null @@ -1,117 +0,0 @@ -@use '../../styles/variables'; - -.heading { - border-bottom: 1px dashed var(--mm-color-border); - color: var(--mm-color-display-text); - display: inline-block; - font-family: var(--mm-font-stack-display); - font-size: 20px; - font-weight: 500; - margin: calc(var(--mm-spacing) / 2) 0; - padding-bottom: calc(var(--mm-spacing) / 2); - width: 100%; -} - -.list { - font-family: var(--mm-font-stack-display); - margin: calc(var(--mm-spacing) / 2) 0 0; -} - -.list * { - vertical-align: top !important; -} - -.list:last-child { - margin-bottom: 0; -} - -.list .list { - margin-left: 14px; -} - -.listItem { - color: #aaa; - font-size: 14px; - line-height: 1.2em; - margin-bottom: calc(var(--mm-spacing) * 0.75); - position: relative; - - &::before { - content: attr(data-item-number); - position: absolute; - transform: translateX(calc(-100% - 6px)); - } -} - -.listItem:last-child { - margin-bottom: 0; -} - -.listItem .listItem { - font-size: 12px; - margin-bottom: calc(var(--mm-spacing) / 2); -} - -.listItem .listItem:last-child { - margin-bottom: 0; -} - -.listItem a { - --psuedo-padding: 8px; - color: #555; - display: inline-block; - font-weight: 500; - position: relative; - text-decoration: none; - width: calc(100% - var(--mm-spacing)); - - &::before, - &::after { - content: ' '; - display: block; - height: 100%; - padding: var(--psuedo-padding) 0; - position: absolute; - right: 0; - top: 0; - transform: translate(calc(var(--mm-spacing) * 0.5), calc(var(--psuedo-padding) * -1)); - width: calc(100% + var(--mm-spacing) * 2); - z-index: -1; - } - - &::before { - left: 0; - right: initial; - transform: translate(-14px, calc(var(--psuedo-padding) * -1)); - } - - &:hover { - color: var(--mm-color-display-text); - } -} - -.listItem.item__active > a { - color: var(--mm-color-display-text); - - &::before { - border-left: 4px solid rgb(43, 126, 198); - } -} - -.listItem .listItem a::before { - transform: translate(-28px, calc(var(--psuedo-padding) * -1)); -} - -.listItem .listItem .listItem a::before { - transform: translate(-42px, calc(var(--psuedo-padding) * -1)); -} - -.listItem .listItem .listItem .listItem a::before { - transform: translate(-56px, calc(var(--psuedo-padding) * -1)); -} - -@include variables.breakpoint('xl') { - .list { - list-style-position: outside; - } -} diff --git a/src/templates/Page/TableOfContents.tsx b/src/templates/Page/TableOfContents.tsx deleted file mode 100644 index 3856cf293..000000000 --- a/src/templates/Page/TableOfContents.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { useLocation } from '@reach/router'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; - -import Link from '../../components/Link'; -import useActiveHeading from '../../hooks/useActiveHeading'; - -import * as styles from './TableOfContents.module.scss'; - -export interface IItem { - items: IItem[]; - title: string; - url: string; -} - -export interface ITableOfContents { - heading?: string; - items: IItem[]; -} - -const getIds = ( - items: IItem[] -): string[] => items.reduce((accumulator: string[], item: IItem) => { - const itemIds = item.items ? getIds(item.items) : []; - - return [ - ...accumulator, - item.url.slice(1), - ...itemIds, - ]; -}, []); - -const isActive = (url: string, pathname: string, currentItem?: string) => { - if ( - url === pathname - || ( - currentItem && ( - currentItem === `toc-${url.slice(1)}` - || currentItem === url.slice(1) - ) - ) - ) { - return true; - } - - return false; -}; - -const renderItems = ( - items: IItem[], - pathname: string, - currentItem?: string, -): React.ReactElement => ( -
      - {items.map((item, index) => { - let itemNumber; - let { title } = item; - const regex = new RegExp(/^(\d+)\.\s+([\s|\w|\W]*)$/); - const matches = title.match(regex); - - if (matches) { - itemNumber = `${matches[1]}. `; - title = matches[2]; - } - - return ( -
    • - - {title} - - {item.items && renderItems(item.items, pathname, currentItem)} -
    • - ); - })} -
    -); - -const TableOfContents: React.FC< - ITableOfContents & React.HTMLProps -> = (props) => { - const { heading, items, ...rest } = props; - - const pathname = useLocation().pathname; - const itemIds = getIds(items); - const currentItem = useActiveHeading(itemIds); - - return ( - - ); -}; - -TableOfContents.propTypes = { - heading: PropTypes.string, - items: PropTypes.any, -}; - -export default TableOfContents; diff --git a/src/templates/Page/index.ts b/src/templates/Page/index.ts deleted file mode 100644 index 2855c64f9..000000000 --- a/src/templates/Page/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as default } from './Page'; diff --git a/src/templates/Page/query.ts b/src/templates/Page/query.ts deleted file mode 100644 index 96c0bd95a..000000000 --- a/src/templates/Page/query.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable filenames/match-exported */ -import { BaseQuery, IBaseQuery } from '../../baseQuery'; -import { ITableOfContents } from './TableOfContents'; - -export type IPageContext = IBaseQuery & { - readonly customTableOfContents: ITableOfContents; - readonly parent: { - readonly modifiedTime: string; - }; - readonly timeToRead: number; -}; - -const query: QueryFn = (graphql: GraphqlFn) => - graphql(` - ${BaseQuery} - - query PageTemplateQuery { - allMdx(filter: { fields: { layout: { eq: "pages" } } }) { - nodes { - ...BaseQuery - customTableOfContents(maxDepth: 4) - timeToRead - parent { - ... on File { - modifiedTime(formatString: "MMMM D, YYYY", locale: "en-US") - } - } - } - } - } - `); - -export default query; diff --git a/src/types/Item.ts b/src/types/Item.ts deleted file mode 100644 index 2a924b53e..000000000 --- a/src/types/Item.ts +++ /dev/null @@ -1,22 +0,0 @@ -interface IBaseItem { - hasDivider?: boolean; - icon?: React.ReactElement; - title: string; -} - -export interface IInternalItem extends IBaseItem { - items?: IItem[]; - secondaryItems?: IItem[]; - to: string; -} - -export interface IExternalItem extends IBaseItem { - url: string; -} - -export type IItem = IExternalItem | IInternalItem; - -export const isInternalItem = ( - item: IItem - // eslint-disable-next-line no-prototype-builtins -): item is IInternalItem => item.hasOwnProperty('to'); diff --git a/src/types/globals/index.d.ts b/src/types/globals/index.d.ts deleted file mode 100644 index 566ed72fb..000000000 --- a/src/types/globals/index.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -declare type GraphqlFn = ( - query: string, - variables?: TVariables -) => Promise<{ - data?: { - allMdx: { - nodes: TData[], - }; - }; - errors?: any, -}> - -declare type QueryFn = { - (graphql: GraphqlFn): Promise<{ - data?: { - allMdx: { - nodes: T[]; - }; - }; - errors?: any; - }>; -} - -declare type JsonPrimitive = string | number | boolean | null - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -declare interface IJsonObject extends Record< - string, - JsonPrimitive | IJsonArray | IJsonObject -> {} - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -declare interface IJsonArray extends Array< - JsonPrimitive | IJsonArray | IJsonObject -> {} - -declare type Json = JsonPrimitive | IJsonObject | IJsonArray; diff --git a/src/types/openapi-types/index.d.ts b/src/types/openapi-types/index.d.ts deleted file mode 100644 index 1503cbb86..000000000 --- a/src/types/openapi-types/index.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/* eslint-disable max-len */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { OpenAPIV3 as OriginalOpenAPIV3 } from 'openapi-types'; - -declare module 'openapi-types' { - export namespace OpenAPIV3 { - interface BaseSchemaObject { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - 'x-compiled-example'?: any; - 'x-line-numbers'?: string; - } - - type PropertyObject = OriginalOpenAPIV3.ReferenceObject | OriginalOpenAPIV3.SchemaObject; - - interface PropertiesObject { - [name: string]: PropertyObject; - } - - type SchemaComponentObject = OriginalOpenAPIV3.ReferenceObject | OriginalOpenAPIV3.SchemaObject; - - interface SchemaComponentsObject { - [key: string]: SchemaComponentObject; - } - - type CompositeSchemaObject = OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject; - type CompositeSchemaObjects = CompositeSchemaObject[]; - } -} - diff --git a/src/types/remark/index.d.ts b/src/types/remark/index.d.ts deleted file mode 100644 index 0a2be09c7..000000000 --- a/src/types/remark/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'remark'; diff --git a/src/types/vfile-message/index.d.ts b/src/types/vfile-message/index.d.ts deleted file mode 100644 index 7581e7bc1..000000000 --- a/src/types/vfile-message/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'vfile-message' { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export type VFileMessage = any; -} diff --git a/src/utils/get-toc-items--direct.fixture.json b/src/utils/get-toc-items--direct.fixture.json deleted file mode 100644 index 04e07eedc..000000000 --- a/src/utils/get-toc-items--direct.fixture.json +++ /dev/null @@ -1,1303 +0,0 @@ -{ - "data": { - "allMdx": { - "nodes": [ - { - "customTableOfContents": { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 12, - "line": 2, - "offset": 12 - }, - "indent": [], - "start": { - "column": 4, - "line": 2, - "offset": 4 - } - }, - "type": "text", - "value": "Level 1a" - } - ], - "depth": 2, - "position": { - "end": { - "column": 12, - "line": 2, - "offset": 12 - }, - "indent": [], - "start": { - "column": 1, - "line": 2, - "offset": 1 - } - }, - "type": "heading" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 4, - "offset": 46 - }, - "start": { - "column": 9, - "line": 4, - "offset": 22 - } - }, - "type": "mdxAttribute", - "value": "Level 1a - Link 1" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 4, - "offset": 59 - }, - "start": { - "column": 34, - "line": 4, - "offset": 47 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 6, - "offset": 87 - }, - "start": { - "column": 5, - "line": 6, - "offset": 77 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 7, - "offset": 102 - }, - "start": { - "column": 5, - "line": 7, - "offset": 92 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 8, - "offset": 120 - }, - "start": { - "column": 5, - "line": 8, - "offset": 107 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 11, - "offset": 135 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 10, - "offset": 125 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 11, - "offset": 135 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 10, - "offset": 125 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 11, - "offset": 146 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 5, - "offset": 61 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 12, - "offset": 156 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 4, - "offset": 14 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 13, - "line": 14, - "offset": 170 - }, - "indent": [], - "start": { - "column": 5, - "line": 14, - "offset": 162 - } - }, - "type": "text", - "value": "Level 2a" - } - ], - "depth": 3, - "position": { - "end": { - "column": 13, - "line": 14, - "offset": 170 - }, - "indent": [], - "start": { - "column": 1, - "line": 14, - "offset": 158 - } - }, - "type": "heading" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 16, - "offset": 204 - }, - "start": { - "column": 9, - "line": 16, - "offset": 180 - } - }, - "type": "mdxAttribute", - "value": "Level 2a - Link 1" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 16, - "offset": 217 - }, - "start": { - "column": 34, - "line": 16, - "offset": 205 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 18, - "offset": 245 - }, - "start": { - "column": 5, - "line": 18, - "offset": 235 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 19, - "offset": 260 - }, - "start": { - "column": 5, - "line": 19, - "offset": 250 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 20, - "offset": 278 - }, - "start": { - "column": 5, - "line": 20, - "offset": 265 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 23, - "offset": 293 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 22, - "offset": 283 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 23, - "offset": 293 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 22, - "offset": 283 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 23, - "offset": 304 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 17, - "offset": 219 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 24, - "offset": 314 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 16, - "offset": 172 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 26, - "offset": 348 - }, - "start": { - "column": 9, - "line": 26, - "offset": 324 - } - }, - "type": "mdxAttribute", - "value": "Level 2a - Link 2" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 26, - "offset": 361 - }, - "start": { - "column": 34, - "line": 26, - "offset": 349 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 28, - "offset": 389 - }, - "start": { - "column": 5, - "line": 28, - "offset": 379 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 29, - "offset": 404 - }, - "start": { - "column": 5, - "line": 29, - "offset": 394 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 30, - "offset": 422 - }, - "start": { - "column": 5, - "line": 30, - "offset": 409 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 33, - "offset": 437 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 32, - "offset": 427 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 33, - "offset": 437 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 32, - "offset": 427 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 33, - "offset": 448 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 27, - "offset": 363 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 34, - "offset": 458 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 26, - "offset": 316 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 13, - "line": 36, - "offset": 472 - }, - "indent": [], - "start": { - "column": 5, - "line": 36, - "offset": 464 - } - }, - "type": "text", - "value": "Level 2b" - } - ], - "depth": 3, - "position": { - "end": { - "column": 13, - "line": 36, - "offset": 472 - }, - "indent": [], - "start": { - "column": 1, - "line": 36, - "offset": 460 - } - }, - "type": "heading" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 38, - "offset": 506 - }, - "start": { - "column": 9, - "line": 38, - "offset": 482 - } - }, - "type": "mdxAttribute", - "value": "Level 2b - Link 1" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 38, - "offset": 519 - }, - "start": { - "column": 34, - "line": 38, - "offset": 507 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 40, - "offset": 547 - }, - "start": { - "column": 5, - "line": 40, - "offset": 537 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 41, - "offset": 562 - }, - "start": { - "column": 5, - "line": 41, - "offset": 552 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 42, - "offset": 580 - }, - "start": { - "column": 5, - "line": 42, - "offset": 567 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 45, - "offset": 595 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 44, - "offset": 585 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 45, - "offset": 595 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 44, - "offset": 585 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 45, - "offset": 606 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 39, - "offset": 521 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 46, - "offset": 616 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 38, - "offset": 474 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 48, - "offset": 650 - }, - "start": { - "column": 9, - "line": 48, - "offset": 626 - } - }, - "type": "mdxAttribute", - "value": "Level 2b - Link 2" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 48, - "offset": 663 - }, - "start": { - "column": 34, - "line": 48, - "offset": 651 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 50, - "offset": 691 - }, - "start": { - "column": 5, - "line": 50, - "offset": 681 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 51, - "offset": 706 - }, - "start": { - "column": 5, - "line": 51, - "offset": 696 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 52, - "offset": 724 - }, - "start": { - "column": 5, - "line": 52, - "offset": 711 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 55, - "offset": 739 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 54, - "offset": 729 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 55, - "offset": 739 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 54, - "offset": 729 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 55, - "offset": 750 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 49, - "offset": 665 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 56, - "offset": 760 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 48, - "offset": 618 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 12, - "line": 58, - "offset": 773 - }, - "indent": [], - "start": { - "column": 4, - "line": 58, - "offset": 765 - } - }, - "type": "text", - "value": "Level 1b" - } - ], - "depth": 2, - "position": { - "end": { - "column": 12, - "line": 58, - "offset": 773 - }, - "indent": [], - "start": { - "column": 1, - "line": 58, - "offset": 762 - } - }, - "type": "heading" - }, - { - "attributes": [ - { - "name": "name", - "position": { - "end": { - "column": 33, - "line": 60, - "offset": 807 - }, - "start": { - "column": 9, - "line": 60, - "offset": 783 - } - }, - "type": "mdxAttribute", - "value": "Level 1b - Link 1" - }, - { - "name": "services", - "position": { - "end": { - "column": 46, - "line": 60, - "offset": 820 - }, - "start": { - "column": 34, - "line": 60, - "offset": 808 - } - }, - "type": "mdxAttribute", - "value": "*" - } - ], - "children": [ - { - "attributes": [ - { - "name": "example", - "position": { - "end": { - "column": 15, - "line": 62, - "offset": 848 - }, - "start": { - "column": 5, - "line": 62, - "offset": 838 - } - }, - "type": "mdxAttribute", - "value": "" - }, - { - "name": "name", - "position": { - "end": { - "column": 15, - "line": 63, - "offset": 863 - }, - "start": { - "column": 5, - "line": 63, - "offset": 853 - } - }, - "type": "mdxAttribute", - "value": "foo" - }, - { - "name": "type", - "position": { - "end": { - "column": 18, - "line": 64, - "offset": 881 - }, - "start": { - "column": 5, - "line": 64, - "offset": 868 - } - }, - "type": "mdxAttribute", - "value": "string" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 3, - "line": 67, - "offset": 896 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 66, - "offset": 886 - } - }, - "type": "text", - "value": "Foo" - } - ], - "position": { - "end": { - "column": 3, - "line": 67, - "offset": 896 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 66, - "offset": 886 - } - }, - "type": "paragraph" - } - ], - "name": "Property", - "position": { - "end": { - "column": 14, - "line": 67, - "offset": 907 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 61, - "offset": 822 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "Schema", - "position": { - "end": { - "column": 10, - "line": 68, - "offset": 917 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 60, - "offset": 775 - } - }, - "type": "mdxBlockElement" - }, - { - "position": { - "end": { - "column": 59, - "line": 71, - "offset": 978 - }, - "indent": [], - "start": { - "column": 1, - "line": 71, - "offset": 920 - } - }, - "type": "export", - "value": "export const _frontmatter = {\"draft\":false,\"title\":\"Test\"}" - } - ], - "position": { - "end": { - "column": 59, - "line": 71, - "offset": 978 - }, - "start": { - "column": 1, - "line": 1, - "offset": 0 - } - }, - "type": "root" - }, - "tableOfContents": { - "items": [ - { - "items": [ - { - "title": "Level 2a", - "url": "#level-2a" - }, - { - "title": "Level 2b", - "url": "#level-2b" - } - ], - "title": "Level 1a", - "url": "#level-1a" - }, - { - "title": "Level 1b", - "url": "#level-1b" - } - ] - } - } - ] - } - }, - "extensions": {} -} diff --git a/src/utils/get-toc-items--indirect.fixture.json b/src/utils/get-toc-items--indirect.fixture.json deleted file mode 100644 index 226aac33d..000000000 --- a/src/utils/get-toc-items--indirect.fixture.json +++ /dev/null @@ -1,4028 +0,0 @@ -{ - "data": { - "allMdx": { - "nodes": [ - { - "customTableOfContents": { - "children": [ - { - "position": { - "end": { - "column": 40, - "line": 3, - "offset": 87 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 2, - "offset": 1 - } - }, - "type": "import", - "value": "import requestJson from './_examples/request';\nimport * as Schemas from './_schemas/';" - }, - { - "children": [ - { - "position": { - "end": { - "column": 30, - "line": 5, - "offset": 118 - }, - "indent": [], - "start": { - "column": 4, - "line": 5, - "offset": 92 - } - }, - "type": "text", - "value": "Authorization and Security" - } - ], - "depth": 2, - "position": { - "end": { - "column": 30, - "line": 5, - "offset": 118 - }, - "indent": [], - "start": { - "column": 1, - "line": 5, - "offset": 89 - } - }, - "type": "heading" - }, - { - "children": [ - { - "position": { - "end": { - "column": 10, - "line": 7, - "offset": 129 - }, - "indent": [], - "start": { - "column": 1, - "line": 7, - "offset": 120 - } - }, - "type": "text", - "value": "The HTTP " - }, - { - "position": { - "end": { - "column": 25, - "line": 7, - "offset": 144 - }, - "indent": [], - "start": { - "column": 10, - "line": 7, - "offset": 129 - } - }, - "type": "inlineCode", - "value": "Authorization" - }, - { - "position": { - "end": { - "column": 6, - "line": 8, - "offset": 204 - }, - "indent": [ - 1 - ], - "start": { - "column": 25, - "line": 7, - "offset": 144 - } - }, - "type": "text", - "value": " header is required for authorization. The username is\nyour " - }, - { - "children": [ - { - "position": { - "end": { - "column": 25, - "line": 8, - "offset": 223 - }, - "indent": [], - "start": { - "column": 7, - "line": 8, - "offset": 205 - } - }, - "type": "text", - "value": "MaxMind account ID" - } - ], - "position": { - "end": { - "column": 83, - "line": 8, - "offset": 281 - }, - "indent": [], - "start": { - "column": 6, - "line": 8, - "offset": 204 - } - }, - "title": null, - "type": "link", - "url": "https://www.maxmind.com/en/accounts/current/license-key" - }, - { - "position": { - "end": { - "column": 22, - "line": 9, - "offset": 304 - }, - "indent": [ - 1 - ], - "start": { - "column": 83, - "line": 8, - "offset": 281 - } - }, - "type": "text", - "value": ".\nThe password is your " - }, - { - "children": [ - { - "position": { - "end": { - "column": 42, - "line": 9, - "offset": 324 - }, - "indent": [], - "start": { - "column": 23, - "line": 9, - "offset": 305 - } - }, - "type": "text", - "value": "MaxMind license key" - } - ], - "position": { - "end": { - "column": 100, - "line": 9, - "offset": 382 - }, - "indent": [], - "start": { - "column": 22, - "line": 9, - "offset": 304 - } - }, - "title": null, - "type": "link", - "url": "https://www.maxmind.com/en/accounts/current/license-key" - }, - { - "position": { - "end": { - "column": 101, - "line": 9, - "offset": 383 - }, - "indent": [], - "start": { - "column": 100, - "line": 9, - "offset": 382 - } - }, - "type": "text", - "value": "." - } - ], - "position": { - "end": { - "column": 101, - "line": 9, - "offset": 383 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 7, - "offset": 120 - } - }, - "type": "paragraph" - }, - { - "attributes": [ - { - "name": "type", - "position": { - "end": { - "column": 22, - "line": 11, - "offset": 406 - }, - "start": { - "column": 8, - "line": 11, - "offset": 392 - } - }, - "type": "mdxAttribute", - "value": "warning" - } - ], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 62, - "line": 13, - "offset": 544 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 12, - "offset": 408 - } - }, - "type": "text", - "value": "You must be approved for a trial or purchase credit for use with our web\nservices in order to receive an account ID and license key." - } - ], - "position": { - "end": { - "column": 62, - "line": 13, - "offset": 544 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 12, - "offset": 408 - } - }, - "type": "paragraph" - } - ], - "name": "Alert", - "position": { - "end": { - "column": 9, - "line": 14, - "offset": 553 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 11, - "offset": 385 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 8, - "line": 16, - "offset": 562 - }, - "indent": [], - "start": { - "column": 1, - "line": 16, - "offset": 555 - } - }, - "type": "text", - "value": "We use " - }, - { - "children": [ - { - "position": { - "end": { - "column": 34, - "line": 16, - "offset": 588 - }, - "indent": [], - "start": { - "column": 9, - "line": 16, - "offset": 563 - } - }, - "type": "text", - "value": "basic HTTP authentication" - } - ], - "position": { - "end": { - "column": 94, - "line": 16, - "offset": 648 - }, - "indent": [], - "start": { - "column": 8, - "line": 16, - "offset": 562 - } - }, - "title": null, - "type": "link", - "url": "https://en.wikipedia.org/wiki/Basic_access_authentication" - }, - { - "position": { - "end": { - "column": 38, - "line": 19, - "offset": 836 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 94, - "line": 16, - "offset": 648 - } - }, - "type": "text", - "value": ".\nThe APIs which require authentication are only available via HTTPS. The\ncredentials are never transmitted unencrypted. If you attempt to access this\nservice via HTTP, you will receive a " - }, - { - "position": { - "end": { - "column": 53, - "line": 19, - "offset": 851 - }, - "indent": [], - "start": { - "column": 38, - "line": 19, - "offset": 836 - } - }, - "type": "inlineCode", - "value": "403 Forbidden" - }, - { - "position": { - "end": { - "column": 68, - "line": 19, - "offset": 866 - }, - "indent": [], - "start": { - "column": 53, - "line": 19, - "offset": 851 - } - }, - "type": "text", - "value": " HTTP response." - } - ], - "position": { - "end": { - "column": 68, - "line": 19, - "offset": 866 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 16, - "offset": 555 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "position": { - "end": { - "column": 8, - "line": 22, - "offset": 955 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 21, - "offset": 868 - } - }, - "type": "text", - "value": "We require TLS 1.2 or greater for all requests to our servers to keep your data\nsecure." - } - ], - "position": { - "end": { - "column": 8, - "line": 22, - "offset": 955 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 21, - "offset": 868 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "position": { - "end": { - "column": 21, - "line": 24, - "offset": 977 - }, - "indent": [], - "start": { - "column": 4, - "line": 24, - "offset": 960 - } - }, - "type": "text", - "value": "Service Endpoints" - } - ], - "depth": 2, - "position": { - "end": { - "column": 21, - "line": 24, - "offset": 977 - }, - "indent": [], - "start": { - "column": 1, - "line": 24, - "offset": 957 - } - }, - "type": "heading" - }, - { - "children": [ - { - "position": { - "end": { - "column": 53, - "line": 26, - "offset": 1031 - }, - "indent": [], - "start": { - "column": 1, - "line": 26, - "offset": 979 - } - }, - "type": "text", - "value": "The endpoint for each service is as specified below." - } - ], - "position": { - "end": { - "column": 53, - "line": 26, - "offset": 1031 - }, - "indent": [], - "start": { - "column": 1, - "line": 26, - "offset": 979 - } - }, - "type": "paragraph" - }, - { - "align": [ - null, - null, - null - ], - "children": [ - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 10, - "line": 28, - "offset": 1042 - }, - "indent": [], - "start": { - "column": 3, - "line": 28, - "offset": 1035 - } - }, - "type": "text", - "value": "Service" - } - ], - "position": { - "end": { - "column": 11, - "line": 28, - "offset": 1043 - }, - "indent": [], - "start": { - "column": 3, - "line": 28, - "offset": 1035 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 25, - "line": 28, - "offset": 1057 - }, - "indent": [], - "start": { - "column": 14, - "line": 28, - "offset": 1046 - } - }, - "type": "text", - "value": "HTTP Method" - } - ], - "position": { - "end": { - "column": 25, - "line": 28, - "offset": 1057 - }, - "indent": [], - "start": { - "column": 14, - "line": 28, - "offset": 1046 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 36, - "line": 28, - "offset": 1068 - }, - "indent": [], - "start": { - "column": 28, - "line": 28, - "offset": 1060 - } - }, - "type": "text", - "value": "Endpoint" - } - ], - "position": { - "end": { - "column": 81, - "line": 28, - "offset": 1113 - }, - "indent": [], - "start": { - "column": 28, - "line": 28, - "offset": 1060 - } - }, - "type": "tableCell" - } - ], - "position": { - "end": { - "column": 83, - "line": 28, - "offset": 1115 - }, - "indent": [], - "start": { - "column": 1, - "line": 28, - "offset": 1033 - } - }, - "type": "tableRow" - }, - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 8, - "line": 30, - "offset": 1206 - }, - "indent": [], - "start": { - "column": 3, - "line": 30, - "offset": 1201 - } - }, - "type": "text", - "value": "Score" - } - ], - "position": { - "end": { - "column": 11, - "line": 30, - "offset": 1209 - }, - "indent": [], - "start": { - "column": 3, - "line": 30, - "offset": 1201 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 20, - "line": 30, - "offset": 1218 - }, - "indent": [], - "start": { - "column": 14, - "line": 30, - "offset": 1212 - } - }, - "type": "inlineCode", - "value": "POST" - } - ], - "position": { - "end": { - "column": 25, - "line": 30, - "offset": 1223 - }, - "indent": [], - "start": { - "column": 14, - "line": 30, - "offset": 1212 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 78, - "line": 30, - "offset": 1276 - }, - "indent": [], - "start": { - "column": 28, - "line": 30, - "offset": 1226 - } - }, - "type": "inlineCode", - "value": "https://minfraud.maxmind.com/minfraud/v2.0/score" - } - ], - "position": { - "end": { - "column": 81, - "line": 30, - "offset": 1279 - }, - "indent": [], - "start": { - "column": 28, - "line": 30, - "offset": 1226 - } - }, - "type": "tableCell" - } - ], - "position": { - "end": { - "column": 83, - "line": 30, - "offset": 1281 - }, - "indent": [], - "start": { - "column": 1, - "line": 30, - "offset": 1199 - } - }, - "type": "tableRow" - }, - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 11, - "line": 31, - "offset": 1292 - }, - "indent": [], - "start": { - "column": 3, - "line": 31, - "offset": 1284 - } - }, - "type": "text", - "value": "Insights" - } - ], - "position": { - "end": { - "column": 11, - "line": 31, - "offset": 1292 - }, - "indent": [], - "start": { - "column": 3, - "line": 31, - "offset": 1284 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 20, - "line": 31, - "offset": 1301 - }, - "indent": [], - "start": { - "column": 14, - "line": 31, - "offset": 1295 - } - }, - "type": "inlineCode", - "value": "POST" - } - ], - "position": { - "end": { - "column": 25, - "line": 31, - "offset": 1306 - }, - "indent": [], - "start": { - "column": 14, - "line": 31, - "offset": 1295 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 81, - "line": 31, - "offset": 1362 - }, - "indent": [], - "start": { - "column": 28, - "line": 31, - "offset": 1309 - } - }, - "type": "inlineCode", - "value": "https://minfraud.maxmind.com/minfraud/v2.0/insights" - } - ], - "position": { - "end": { - "column": 81, - "line": 31, - "offset": 1362 - }, - "indent": [], - "start": { - "column": 28, - "line": 31, - "offset": 1309 - } - }, - "type": "tableCell" - } - ], - "position": { - "end": { - "column": 83, - "line": 31, - "offset": 1364 - }, - "indent": [], - "start": { - "column": 1, - "line": 31, - "offset": 1282 - } - }, - "type": "tableRow" - }, - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 10, - "line": 32, - "offset": 1374 - }, - "indent": [], - "start": { - "column": 3, - "line": 32, - "offset": 1367 - } - }, - "type": "text", - "value": "Factors" - } - ], - "position": { - "end": { - "column": 11, - "line": 32, - "offset": 1375 - }, - "indent": [], - "start": { - "column": 3, - "line": 32, - "offset": 1367 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 20, - "line": 32, - "offset": 1384 - }, - "indent": [], - "start": { - "column": 14, - "line": 32, - "offset": 1378 - } - }, - "type": "inlineCode", - "value": "POST" - } - ], - "position": { - "end": { - "column": 25, - "line": 32, - "offset": 1389 - }, - "indent": [], - "start": { - "column": 14, - "line": 32, - "offset": 1378 - } - }, - "type": "tableCell" - }, - { - "children": [ - { - "position": { - "end": { - "column": 80, - "line": 32, - "offset": 1444 - }, - "indent": [], - "start": { - "column": 28, - "line": 32, - "offset": 1392 - } - }, - "type": "inlineCode", - "value": "https://minfraud.maxmind.com/minfraud/v2.0/factors" - } - ], - "position": { - "end": { - "column": 81, - "line": 32, - "offset": 1445 - }, - "indent": [], - "start": { - "column": 28, - "line": 32, - "offset": 1392 - } - }, - "type": "tableCell" - } - ], - "position": { - "end": { - "column": 83, - "line": 32, - "offset": 1447 - }, - "indent": [], - "start": { - "column": 1, - "line": 32, - "offset": 1365 - } - }, - "type": "tableRow" - } - ], - "position": { - "end": { - "column": 83, - "line": 32, - "offset": 1447 - }, - "indent": [ - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 28, - "offset": 1033 - } - }, - "type": "table" - }, - { - "children": [ - { - "position": { - "end": { - "column": 5, - "line": 34, - "offset": 1453 - }, - "indent": [], - "start": { - "column": 1, - "line": 34, - "offset": 1449 - } - }, - "type": "text", - "value": "The " - }, - { - "children": [ - { - "position": { - "end": { - "column": 27, - "line": 34, - "offset": 1475 - }, - "indent": [], - "start": { - "column": 7, - "line": 34, - "offset": 1455 - } - }, - "type": "text", - "value": "minfraud.maxmind.com" - } - ], - "position": { - "end": { - "column": 29, - "line": 34, - "offset": 1477 - }, - "indent": [], - "start": { - "column": 5, - "line": 34, - "offset": 1453 - } - }, - "type": "strong" - }, - { - "position": { - "end": { - "column": 31, - "line": 35, - "offset": 1553 - }, - "indent": [ - 1 - ], - "start": { - "column": 29, - "line": 34, - "offset": 1477 - } - }, - "type": "text", - "value": " hostname automatically picks the data center\ngeographically closest to you." - } - ], - "position": { - "end": { - "column": 31, - "line": 35, - "offset": 1553 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 34, - "offset": 1449 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "position": { - "end": { - "column": 11, - "line": 37, - "offset": 1565 - }, - "indent": [], - "start": { - "column": 4, - "line": 37, - "offset": 1558 - } - }, - "type": "text", - "value": "Headers" - } - ], - "depth": 2, - "position": { - "end": { - "column": 11, - "line": 37, - "offset": 1565 - }, - "indent": [], - "start": { - "column": 1, - "line": 37, - "offset": 1555 - } - }, - "type": "heading" - }, - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 17, - "line": 42, - "offset": 1610 - }, - "indent": [], - "start": { - "column": 11, - "line": 42, - "offset": 1604 - } - }, - "type": "text", - "value": "Header" - } - ], - "position": { - "end": { - "column": 17, - "line": 42, - "offset": 1610 - }, - "indent": [], - "start": { - "column": 11, - "line": 42, - "offset": 1604 - } - }, - "type": "paragraph" - } - ], - "name": "th", - "position": { - "end": { - "column": 22, - "line": 42, - "offset": 1615 - }, - "indent": [], - "start": { - "column": 1, - "line": 42, - "offset": 1594 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 16, - "line": 43, - "offset": 1631 - }, - "indent": [], - "start": { - "column": 11, - "line": 43, - "offset": 1626 - } - }, - "type": "text", - "value": "Notes" - } - ], - "position": { - "end": { - "column": 16, - "line": 43, - "offset": 1631 - }, - "indent": [], - "start": { - "column": 11, - "line": 43, - "offset": 1626 - } - }, - "type": "paragraph" - } - ], - "name": "th", - "position": { - "end": { - "column": 21, - "line": 43, - "offset": 1636 - }, - "indent": [], - "start": { - "column": 1, - "line": 43, - "offset": 1616 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "tr", - "position": { - "end": { - "column": 10, - "line": 44, - "offset": 1646 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 41, - "offset": 1585 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "thead", - "position": { - "end": { - "column": 11, - "line": 45, - "offset": 1657 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 40, - "offset": 1575 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 24, - "line": 49, - "offset": 1711 - }, - "indent": [], - "start": { - "column": 9, - "line": 49, - "offset": 1696 - } - }, - "type": "inlineCode", - "value": "Authorization" - } - ], - "position": { - "end": { - "column": 7, - "line": 50, - "offset": 1718 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 49, - "offset": 1688 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 50, - "offset": 1723 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 48, - "offset": 1677 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 19, - "line": 52, - "offset": 1753 - }, - "indent": [], - "start": { - "column": 11, - "line": 52, - "offset": 1745 - } - }, - "type": "text", - "value": "Required" - } - ], - "position": { - "end": { - "column": 21, - "line": 52, - "offset": 1755 - }, - "indent": [], - "start": { - "column": 9, - "line": 52, - "offset": 1743 - } - }, - "type": "strong" - }, - { - "position": { - "end": { - "column": 9, - "line": 53, - "offset": 1788 - }, - "indent": [ - 1 - ], - "start": { - "column": 21, - "line": 52, - "offset": 1755 - } - }, - "type": "text", - "value": " – For more details, see\n" - }, - { - "children": [ - { - "position": { - "end": { - "column": 36, - "line": 53, - "offset": 1815 - }, - "indent": [], - "start": { - "column": 10, - "line": 53, - "offset": 1789 - } - }, - "type": "text", - "value": "Authorization and Security" - } - ], - "position": { - "end": { - "column": 66, - "line": 53, - "offset": 1845 - }, - "indent": [], - "start": { - "column": 9, - "line": 53, - "offset": 1788 - } - }, - "title": null, - "type": "link", - "url": "#authorization-and-security" - }, - { - "position": { - "end": { - "column": 7, - "line": 54, - "offset": 1853 - }, - "indent": [ - 1 - ], - "start": { - "column": 66, - "line": 53, - "offset": 1845 - } - }, - "type": "text", - "value": "." - } - ], - "position": { - "end": { - "column": 7, - "line": 54, - "offset": 1853 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 52, - "offset": 1735 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 54, - "offset": 1858 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 51, - "offset": 1724 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "tr", - "position": { - "end": { - "column": 10, - "line": 55, - "offset": 1868 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 47, - "offset": 1668 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 17, - "line": 58, - "offset": 1905 - }, - "indent": [], - "start": { - "column": 9, - "line": 58, - "offset": 1897 - } - }, - "type": "inlineCode", - "value": "Accept" - } - ], - "position": { - "end": { - "column": 7, - "line": 59, - "offset": 1912 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 58, - "offset": 1889 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 59, - "offset": 1917 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 57, - "offset": 1878 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 19, - "line": 61, - "offset": 1947 - }, - "indent": [], - "start": { - "column": 11, - "line": 61, - "offset": 1939 - } - }, - "type": "text", - "value": "Optional" - } - ], - "position": { - "end": { - "column": 21, - "line": 61, - "offset": 1949 - }, - "indent": [], - "start": { - "column": 9, - "line": 61, - "offset": 1937 - } - }, - "type": "strong" - }, - { - "position": { - "end": { - "column": 49, - "line": 62, - "offset": 2054 - }, - "indent": [ - 1 - ], - "start": { - "column": 21, - "line": 61, - "offset": 1949 - } - }, - "type": "text", - "value": " – If you do set this header, you must accept any of the\nfollowing, substituting the appropriate " - }, - { - "position": { - "end": { - "column": 65, - "line": 62, - "offset": 2070 - }, - "indent": [], - "start": { - "column": 49, - "line": 62, - "offset": 2054 - } - }, - "type": "inlineCode", - "value": "[SERVICE TYPE]" - }, - { - "position": { - "end": { - "column": 9, - "line": 63, - "offset": 2090 - }, - "indent": [ - 1 - ], - "start": { - "column": 65, - "line": 62, - "offset": 2070 - } - }, - "type": "text", - "value": " for either\n" - }, - { - "position": { - "end": { - "column": 16, - "line": 63, - "offset": 2097 - }, - "indent": [], - "start": { - "column": 9, - "line": 63, - "offset": 2090 - } - }, - "type": "inlineCode", - "value": "score" - }, - { - "position": { - "end": { - "column": 18, - "line": 63, - "offset": 2099 - }, - "indent": [], - "start": { - "column": 16, - "line": 63, - "offset": 2097 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 27, - "line": 63, - "offset": 2108 - }, - "indent": [], - "start": { - "column": 18, - "line": 63, - "offset": 2099 - } - }, - "type": "inlineCode", - "value": "factors" - }, - { - "position": { - "end": { - "column": 32, - "line": 63, - "offset": 2113 - }, - "indent": [], - "start": { - "column": 27, - "line": 63, - "offset": 2108 - } - }, - "type": "text", - "value": ", or " - }, - { - "position": { - "end": { - "column": 42, - "line": 63, - "offset": 2123 - }, - "indent": [], - "start": { - "column": 32, - "line": 63, - "offset": 2113 - } - }, - "type": "inlineCode", - "value": "insights" - }, - { - "position": { - "end": { - "column": 43, - "line": 63, - "offset": 2124 - }, - "indent": [], - "start": { - "column": 42, - "line": 63, - "offset": 2123 - } - }, - "type": "text", - "value": ":" - } - ], - "position": { - "end": { - "column": 43, - "line": 63, - "offset": 2124 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 61, - "offset": 1929 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 29, - "line": 65, - "offset": 2154 - }, - "indent": [], - "start": { - "column": 11, - "line": 65, - "offset": 2136 - } - }, - "type": "inlineCode", - "value": "application/json" - } - ], - "position": { - "end": { - "column": 29, - "line": 65, - "offset": 2154 - }, - "indent": [], - "start": { - "column": 11, - "line": 65, - "offset": 2136 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 29, - "line": 65, - "offset": 2154 - }, - "indent": [], - "start": { - "column": 1, - "line": 65, - "offset": 2126 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 69, - "line": 66, - "offset": 2223 - }, - "indent": [], - "start": { - "column": 11, - "line": 66, - "offset": 2165 - } - }, - "type": "inlineCode", - "value": "application/vnd.maxmind.com-minfraud-[SERVICE TYPE]+json" - } - ], - "position": { - "end": { - "column": 69, - "line": 66, - "offset": 2223 - }, - "indent": [], - "start": { - "column": 11, - "line": 66, - "offset": 2165 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 69, - "line": 66, - "offset": 2223 - }, - "indent": [], - "start": { - "column": 1, - "line": 66, - "offset": 2155 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 97, - "line": 67, - "offset": 2320 - }, - "indent": [], - "start": { - "column": 11, - "line": 67, - "offset": 2234 - } - }, - "type": "inlineCode", - "value": "application/vnd.maxmind.com-minfraud-[SERVICE TYPE]+json; charset=UTF-8; version=2.0" - } - ], - "position": { - "end": { - "column": 97, - "line": 67, - "offset": 2320 - }, - "indent": [], - "start": { - "column": 11, - "line": 67, - "offset": 2234 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 97, - "line": 67, - "offset": 2320 - }, - "indent": [], - "start": { - "column": 1, - "line": 67, - "offset": 2224 - } - }, - "spread": false, - "type": "listItem" - } - ], - "ordered": false, - "position": { - "end": { - "column": 97, - "line": 67, - "offset": 2320 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 65, - "offset": 2126 - } - }, - "spread": false, - "start": null, - "type": "list" - }, - { - "children": [ - { - "position": { - "end": { - "column": 60, - "line": 70, - "offset": 2382 - }, - "indent": [], - "start": { - "column": 1, - "line": 70, - "offset": 2323 - } - }, - "type": "text", - "value": "A request for any other MIME type will result in a " - }, - { - "position": { - "end": { - "column": 88, - "line": 70, - "offset": 2410 - }, - "indent": [], - "start": { - "column": 60, - "line": 70, - "offset": 2382 - } - }, - "type": "inlineCode", - "value": "415 Unsupported Media Type" - }, - { - "position": { - "end": { - "column": 7, - "line": 71, - "offset": 2424 - }, - "indent": [ - 1 - ], - "start": { - "column": 88, - "line": 70, - "offset": 2410 - } - }, - "type": "text", - "value": " error." - } - ], - "position": { - "end": { - "column": 7, - "line": 71, - "offset": 2424 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 70, - "offset": 2323 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 71, - "offset": 2429 - }, - "indent": [ - 1, - 1, - 1, - 1, - 11, - 11, - 11, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 60, - "offset": 1918 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "tr", - "position": { - "end": { - "column": 10, - "line": 72, - "offset": 2439 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 11, - 11, - 11, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 56, - "offset": 1869 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "attributes": [], - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 25, - "line": 75, - "offset": 2484 - }, - "indent": [], - "start": { - "column": 9, - "line": 75, - "offset": 2468 - } - }, - "type": "inlineCode", - "value": "Accept-Charset" - } - ], - "position": { - "end": { - "column": 7, - "line": 76, - "offset": 2491 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 75, - "offset": 2460 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 76, - "offset": 2496 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 74, - "offset": 2449 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [ - { - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 19, - "line": 78, - "offset": 2526 - }, - "indent": [], - "start": { - "column": 11, - "line": 78, - "offset": 2518 - } - }, - "type": "text", - "value": "Optional" - } - ], - "position": { - "end": { - "column": 21, - "line": 78, - "offset": 2528 - }, - "indent": [], - "start": { - "column": 9, - "line": 78, - "offset": 2516 - } - }, - "type": "strong" - }, - { - "position": { - "end": { - "column": 71, - "line": 78, - "offset": 2578 - }, - "indent": [], - "start": { - "column": 21, - "line": 78, - "offset": 2528 - } - }, - "type": "text", - "value": " – If you do set this header, you must accept the " - }, - { - "position": { - "end": { - "column": 78, - "line": 78, - "offset": 2585 - }, - "indent": [], - "start": { - "column": 71, - "line": 78, - "offset": 2578 - } - }, - "type": "inlineCode", - "value": "UTF-8" - }, - { - "position": { - "end": { - "column": 56, - "line": 79, - "offset": 2641 - }, - "indent": [ - 1 - ], - "start": { - "column": 78, - "line": 78, - "offset": 2585 - } - }, - "type": "text", - "value": "\ncharacter set. If you don't you will receive a " - }, - { - "position": { - "end": { - "column": 76, - "line": 79, - "offset": 2661 - }, - "indent": [], - "start": { - "column": 56, - "line": 79, - "offset": 2641 - } - }, - "type": "inlineCode", - "value": "406 Not Acceptable" - }, - { - "position": { - "end": { - "column": 58, - "line": 80, - "offset": 2719 - }, - "indent": [ - 1 - ], - "start": { - "column": 76, - "line": 79, - "offset": 2661 - } - }, - "type": "text", - "value": "\nresponse, because this data is only available in " - }, - { - "position": { - "end": { - "column": 65, - "line": 80, - "offset": 2726 - }, - "indent": [], - "start": { - "column": 58, - "line": 80, - "offset": 2719 - } - }, - "type": "inlineCode", - "value": "UTF-8" - }, - { - "position": { - "end": { - "column": 7, - "line": 81, - "offset": 2734 - }, - "indent": [ - 1 - ], - "start": { - "column": 65, - "line": 80, - "offset": 2726 - } - }, - "type": "text", - "value": "." - } - ], - "position": { - "end": { - "column": 7, - "line": 81, - "offset": 2734 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 78, - "offset": 2508 - } - }, - "type": "paragraph" - } - ], - "name": "td", - "position": { - "end": { - "column": 12, - "line": 81, - "offset": 2739 - }, - "indent": [ - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 77, - "offset": 2497 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "tr", - "position": { - "end": { - "column": 10, - "line": 82, - "offset": 2749 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 73, - "offset": 2440 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "tbody", - "position": { - "end": { - "column": 11, - "line": 83, - "offset": 2760 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 11, - 11, - 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 46, - "offset": 1658 - } - }, - "type": "mdxBlockElement" - } - ], - "name": "table", - "position": { - "end": { - "column": 9, - "line": 84, - "offset": 2769 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 11, - 11, - 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 39, - "offset": 1567 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 10, - "line": 86, - "offset": 2780 - }, - "indent": [], - "start": { - "column": 4, - "line": 86, - "offset": 2774 - } - }, - "type": "text", - "value": "Bodies" - } - ], - "depth": 2, - "position": { - "end": { - "column": 10, - "line": 86, - "offset": 2780 - }, - "indent": [], - "start": { - "column": 1, - "line": 86, - "offset": 2771 - } - }, - "type": "heading" - }, - { - "children": [ - { - "position": { - "end": { - "column": 1, - "line": 90, - "offset": 2994 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 87, - "offset": 2781 - } - }, - "type": "text", - "value": "minFraud Score, Factors and Insights share the same request body format. Below\nis a full example of the JSON body document. For detailed explainations of each\nproperty within the request body, please refer to the\n" - }, - { - "children": [ - { - "position": { - "end": { - "column": 18, - "line": 90, - "offset": 3011 - }, - "indent": [], - "start": { - "column": 2, - "line": 90, - "offset": 2995 - } - }, - "type": "text", - "value": "object reference" - } - ], - "position": { - "end": { - "column": 38, - "line": 90, - "offset": 3031 - }, - "indent": [], - "start": { - "column": 1, - "line": 90, - "offset": 2994 - } - }, - "title": null, - "type": "link", - "url": "#object-reference" - }, - { - "position": { - "end": { - "column": 53, - "line": 90, - "offset": 3046 - }, - "indent": [], - "start": { - "column": 38, - "line": 90, - "offset": 3031 - } - }, - "type": "text", - "value": " section below." - } - ], - "position": { - "end": { - "column": 53, - "line": 90, - "offset": 3046 - }, - "indent": [ - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 87, - "offset": 2781 - } - }, - "type": "paragraph" - }, - { - "attributes": [ - { - "name": "language", - "position": { - "end": { - "column": 25, - "line": 92, - "offset": 3072 - }, - "start": { - "column": 10, - "line": 92, - "offset": 3057 - } - }, - "type": "mdxAttribute", - "value": "json" - } - ], - "children": [ - { - "position": { - "end": { - "column": 41, - "line": 93, - "offset": 3114 - }, - "indent": [], - "start": { - "column": 1, - "line": 93, - "offset": 3074 - } - }, - "type": "mdxBlockExpression", - "value": "JSON.stringify(requestJson, null, 2)" - } - ], - "name": "Example", - "position": { - "end": { - "column": 11, - "line": 94, - "offset": 3125 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 92, - "offset": 3048 - } - }, - "type": "mdxBlockElement" - }, - { - "children": [ - { - "position": { - "end": { - "column": 20, - "line": 96, - "offset": 3146 - }, - "indent": [], - "start": { - "column": 4, - "line": 96, - "offset": 3130 - } - }, - "type": "text", - "value": "Object Reference" - } - ], - "depth": 2, - "position": { - "end": { - "column": 20, - "line": 96, - "offset": 3146 - }, - "indent": [], - "start": { - "column": 1, - "line": 96, - "offset": 3127 - } - }, - "type": "heading" - }, - { - "children": [ - { - "position": { - "end": { - "column": 8, - "line": 99, - "offset": 3230 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 98, - "offset": 3148 - } - }, - "type": "text", - "value": "Below are the schema definitions of that make up the minFraud request body\nobject." - } - ], - "position": { - "end": { - "column": 8, - "line": 99, - "offset": 3230 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 98, - "offset": 3148 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "position": { - "end": { - "column": 22, - "line": 103, - "offset": 3412 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 101, - "offset": 3232 - } - }, - "type": "text", - "value": "Each schema definition contains a description of an object, along with a list of\nproperties that belong to the object. The following information is listed for\neach object property:" - } - ], - "position": { - "end": { - "column": 22, - "line": 103, - "offset": 3412 - }, - "indent": [ - 1, - 1 - ], - "start": { - "column": 1, - "line": 101, - "offset": 3232 - } - }, - "type": "paragraph" - }, - { - "children": [ - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 7, - "line": 105, - "offset": 3420 - }, - "indent": [], - "start": { - "column": 3, - "line": 105, - "offset": 3416 - } - }, - "type": "text", - "value": "name" - } - ], - "position": { - "end": { - "column": 7, - "line": 105, - "offset": 3420 - }, - "indent": [], - "start": { - "column": 3, - "line": 105, - "offset": 3416 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 7, - "line": 105, - "offset": 3420 - }, - "indent": [], - "start": { - "column": 1, - "line": 105, - "offset": 3414 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 9, - "line": 106, - "offset": 3429 - }, - "indent": [], - "start": { - "column": 3, - "line": 106, - "offset": 3423 - } - }, - "type": "text", - "value": "type (" - }, - { - "position": { - "end": { - "column": 22, - "line": 106, - "offset": 3442 - }, - "indent": [], - "start": { - "column": 9, - "line": 106, - "offset": 3429 - } - }, - "type": "inlineCode", - "value": "array" - }, - { - "position": { - "end": { - "column": 24, - "line": 106, - "offset": 3444 - }, - "indent": [], - "start": { - "column": 22, - "line": 106, - "offset": 3442 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 33, - "line": 106, - "offset": 3453 - }, - "indent": [], - "start": { - "column": 24, - "line": 106, - "offset": 3444 - } - }, - "type": "inlineCode", - "value": "boolean" - }, - { - "position": { - "end": { - "column": 35, - "line": 106, - "offset": 3455 - }, - "indent": [], - "start": { - "column": 33, - "line": 106, - "offset": 3453 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 43, - "line": 106, - "offset": 3463 - }, - "indent": [], - "start": { - "column": 35, - "line": 106, - "offset": 3455 - } - }, - "type": "inlineCode", - "value": "number" - }, - { - "position": { - "end": { - "column": 45, - "line": 106, - "offset": 3465 - }, - "indent": [], - "start": { - "column": 43, - "line": 106, - "offset": 3463 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 54, - "line": 106, - "offset": 3474 - }, - "indent": [], - "start": { - "column": 45, - "line": 106, - "offset": 3465 - } - }, - "type": "inlineCode", - "value": "integer" - }, - { - "position": { - "end": { - "column": 56, - "line": 106, - "offset": 3476 - }, - "indent": [], - "start": { - "column": 54, - "line": 106, - "offset": 3474 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 64, - "line": 106, - "offset": 3484 - }, - "indent": [], - "start": { - "column": 56, - "line": 106, - "offset": 3476 - } - }, - "type": "inlineCode", - "value": "object" - }, - { - "position": { - "end": { - "column": 66, - "line": 106, - "offset": 3486 - }, - "indent": [], - "start": { - "column": 64, - "line": 106, - "offset": 3484 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 74, - "line": 106, - "offset": 3494 - }, - "indent": [], - "start": { - "column": 66, - "line": 106, - "offset": 3486 - } - }, - "type": "inlineCode", - "value": "string" - }, - { - "position": { - "end": { - "column": 75, - "line": 106, - "offset": 3495 - }, - "indent": [], - "start": { - "column": 74, - "line": 106, - "offset": 3494 - } - }, - "type": "text", - "value": ")" - } - ], - "position": { - "end": { - "column": 75, - "line": 106, - "offset": 3495 - }, - "indent": [], - "start": { - "column": 3, - "line": 106, - "offset": 3423 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 75, - "line": 106, - "offset": 3495 - }, - "indent": [], - "start": { - "column": 1, - "line": 106, - "offset": 3421 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 14, - "line": 107, - "offset": 3509 - }, - "indent": [], - "start": { - "column": 3, - "line": 107, - "offset": 3498 - } - }, - "type": "text", - "value": "description" - } - ], - "position": { - "end": { - "column": 14, - "line": 107, - "offset": 3509 - }, - "indent": [], - "start": { - "column": 3, - "line": 107, - "offset": 3498 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 14, - "line": 107, - "offset": 3509 - }, - "indent": [], - "start": { - "column": 1, - "line": 107, - "offset": 3496 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 10, - "line": 108, - "offset": 3519 - }, - "indent": [], - "start": { - "column": 3, - "line": 108, - "offset": 3512 - } - }, - "type": "text", - "value": "example" - } - ], - "position": { - "end": { - "column": 10, - "line": 108, - "offset": 3519 - }, - "indent": [], - "start": { - "column": 3, - "line": 108, - "offset": 3512 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 10, - "line": 108, - "offset": 3519 - }, - "indent": [], - "start": { - "column": 1, - "line": 108, - "offset": 3510 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 13, - "line": 109, - "offset": 3532 - }, - "indent": [], - "start": { - "column": 3, - "line": 109, - "offset": 3522 - } - }, - "type": "text", - "value": "formatting" - } - ], - "position": { - "end": { - "column": 13, - "line": 109, - "offset": 3532 - }, - "indent": [], - "start": { - "column": 3, - "line": 109, - "offset": 3522 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 13, - "line": 109, - "offset": 3532 - }, - "indent": [], - "start": { - "column": 1, - "line": 109, - "offset": 3520 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 50, - "line": 110, - "offset": 3582 - }, - "indent": [], - "start": { - "column": 3, - "line": 110, - "offset": 3535 - } - }, - "type": "text", - "value": "constraints (format, min/max, max length, etc.)" - } - ], - "position": { - "end": { - "column": 50, - "line": 110, - "offset": 3582 - }, - "indent": [], - "start": { - "column": 3, - "line": 110, - "offset": 3535 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 50, - "line": 110, - "offset": 3582 - }, - "indent": [], - "start": { - "column": 1, - "line": 110, - "offset": 3533 - } - }, - "spread": false, - "type": "listItem" - }, - { - "checked": null, - "children": [ - { - "children": [ - { - "position": { - "end": { - "column": 23, - "line": 111, - "offset": 3605 - }, - "indent": [], - "start": { - "column": 3, - "line": 111, - "offset": 3585 - } - }, - "type": "text", - "value": "supported services (" - }, - { - "position": { - "end": { - "column": 30, - "line": 111, - "offset": 3612 - }, - "indent": [], - "start": { - "column": 23, - "line": 111, - "offset": 3605 - } - }, - "type": "inlineCode", - "value": "Score" - }, - { - "position": { - "end": { - "column": 32, - "line": 111, - "offset": 3614 - }, - "indent": [], - "start": { - "column": 30, - "line": 111, - "offset": 3612 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 41, - "line": 111, - "offset": 3623 - }, - "indent": [], - "start": { - "column": 32, - "line": 111, - "offset": 3614 - } - }, - "type": "inlineCode", - "value": "Factors" - }, - { - "position": { - "end": { - "column": 43, - "line": 111, - "offset": 3625 - }, - "indent": [], - "start": { - "column": 41, - "line": 111, - "offset": 3623 - } - }, - "type": "text", - "value": ", " - }, - { - "position": { - "end": { - "column": 53, - "line": 111, - "offset": 3635 - }, - "indent": [], - "start": { - "column": 43, - "line": 111, - "offset": 3625 - } - }, - "type": "inlineCode", - "value": "Insights" - }, - { - "position": { - "end": { - "column": 54, - "line": 111, - "offset": 3636 - }, - "indent": [], - "start": { - "column": 53, - "line": 111, - "offset": 3635 - } - }, - "type": "text", - "value": ")" - } - ], - "position": { - "end": { - "column": 54, - "line": 111, - "offset": 3636 - }, - "indent": [], - "start": { - "column": 3, - "line": 111, - "offset": 3585 - } - }, - "type": "paragraph" - } - ], - "position": { - "end": { - "column": 54, - "line": 111, - "offset": 3636 - }, - "indent": [], - "start": { - "column": 1, - "line": 111, - "offset": 3583 - } - }, - "spread": false, - "type": "listItem" - } - ], - "ordered": false, - "position": { - "end": { - "column": 54, - "line": 111, - "offset": 3636 - }, - "indent": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "start": { - "column": 1, - "line": 105, - "offset": 3414 - } - }, - "spread": false, - "start": null, - "type": "list" - }, - { - "children": [ - { - "position": { - "end": { - "column": 19, - "line": 113, - "offset": 3656 - }, - "indent": [], - "start": { - "column": 1, - "line": 113, - "offset": 3638 - } - }, - "type": "text", - "value": "Additionally, for " - }, - { - "position": { - "end": { - "column": 27, - "line": 113, - "offset": 3664 - }, - "indent": [], - "start": { - "column": 19, - "line": 113, - "offset": 3656 - } - }, - "type": "inlineCode", - "value": "object" - }, - { - "position": { - "end": { - "column": 56, - "line": 114, - "offset": 3768 - }, - "indent": [ - 1 - ], - "start": { - "column": 27, - "line": 113, - "offset": 3664 - } - }, - "type": "text", - "value": " properties, a link is provided to view a schema\ndefinition that further describes that specific object." - } - ], - "position": { - "end": { - "column": 56, - "line": 114, - "offset": 3768 - }, - "indent": [ - 1 - ], - "start": { - "column": 1, - "line": 113, - "offset": 3638 - } - }, - "type": "paragraph" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.Request", - "position": { - "end": { - "column": 20, - "line": 116, - "offset": 3789 - }, - "indent": [], - "start": { - "column": 1, - "line": 116, - "offset": 3770 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestDevice", - "position": { - "end": { - "column": 26, - "line": 117, - "offset": 3815 - }, - "indent": [], - "start": { - "column": 1, - "line": 117, - "offset": 3790 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestEvent", - "position": { - "end": { - "column": 25, - "line": 118, - "offset": 3840 - }, - "indent": [], - "start": { - "column": 1, - "line": 118, - "offset": 3816 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestAccount", - "position": { - "end": { - "column": 27, - "line": 119, - "offset": 3867 - }, - "indent": [], - "start": { - "column": 1, - "line": 119, - "offset": 3841 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestEmail", - "position": { - "end": { - "column": 25, - "line": 120, - "offset": 3892 - }, - "indent": [], - "start": { - "column": 1, - "line": 120, - "offset": 3868 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestBilling", - "position": { - "end": { - "column": 27, - "line": 121, - "offset": 3919 - }, - "indent": [], - "start": { - "column": 1, - "line": 121, - "offset": 3893 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestShipping", - "position": { - "end": { - "column": 28, - "line": 122, - "offset": 3947 - }, - "indent": [], - "start": { - "column": 1, - "line": 122, - "offset": 3920 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestPayment", - "position": { - "end": { - "column": 27, - "line": 123, - "offset": 3974 - }, - "indent": [], - "start": { - "column": 1, - "line": 123, - "offset": 3948 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestCreditCard", - "position": { - "end": { - "column": 30, - "line": 124, - "offset": 4004 - }, - "indent": [], - "start": { - "column": 1, - "line": 124, - "offset": 3975 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestOrder", - "position": { - "end": { - "column": 25, - "line": 125, - "offset": 4029 - }, - "indent": [], - "start": { - "column": 1, - "line": 125, - "offset": 4005 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestShoppingCart", - "position": { - "end": { - "column": 32, - "line": 126, - "offset": 4061 - }, - "indent": [], - "start": { - "column": 1, - "line": 126, - "offset": 4030 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestShoppingCartItem", - "position": { - "end": { - "column": 36, - "line": 127, - "offset": 4097 - }, - "indent": [], - "start": { - "column": 1, - "line": 127, - "offset": 4062 - } - }, - "type": "mdxBlockElement" - }, - { - "attributes": [], - "children": [], - "name": "Schemas.RequestCustomInputs", - "position": { - "end": { - "column": 32, - "line": 128, - "offset": 4129 - }, - "indent": [], - "start": { - "column": 1, - "line": 128, - "offset": 4098 - } - }, - "type": "mdxBlockElement" - }, - { - "position": { - "end": { - "column": 76, - "line": 131, - "offset": 4207 - }, - "indent": [], - "start": { - "column": 1, - "line": 131, - "offset": 4132 - } - }, - "type": "export", - "value": "export const _frontmatter = {\"draft\":false,\"title\":\"minFraud API Requests\"}" - } - ], - "position": { - "end": { - "column": 76, - "line": 131, - "offset": 4207 - }, - "start": { - "column": 1, - "line": 1, - "offset": 0 - } - }, - "type": "root" - } - } - ] - } - }, - "extensions": {} -} diff --git a/src/utils/get-toc-items.spec.ts b/src/utils/get-toc-items.spec.ts deleted file mode 100644 index 502564dda..000000000 --- a/src/utils/get-toc-items.spec.ts +++ /dev/null @@ -1,160 +0,0 @@ -import generateTableOfContents, { createImportPathMap } from './get-toc-items'; -import directSchemas from './get-toc-items--direct.fixture.json'; -import indirectSchemas from './get-toc-items--indirect.fixture.json'; - -const minFraudImportPathMap = createImportPathMap( - `${process.cwd()}/content/minfraud/api-documentation/_schemas` -); - -describe('getTocItems()', () => { - it('works with direct `Schema` component usage', async () => { - const mdast = ( - directSchemas as any - ).data.allMdx.nodes[0].customTableOfContents; - - const toc = generateTableOfContents(mdast, minFraudImportPathMap); - - const expected = { - items: [ - { - items: [ - { - title: 'Level 1a - Link 1', - url: '#schema--level-1a---link-1', - }, - { - items: [ - { - title: 'Level 2a - Link 1', - url: '#schema--level-2a---link-1', - }, - { - title: 'Level 2a - Link 2', - url: '#schema--level-2a---link-2', - }, - ], - title: 'Level 2a', - url: '#level-2a', - }, - { - items: [ - { - title: 'Level 2b - Link 1', - url: '#schema--level-2b---link-1', - }, - { - title: 'Level 2b - Link 2', - url: '#schema--level-2b---link-2', - }, - ], - title: 'Level 2b', - url: '#level-2b', - }, - ], - title: 'Level 1a', - url: '#level-1a', - }, - { - items: [ - { - title: 'Level 1b - Link 1', - url: '#schema--level-1b---link-1', - }, - ], - title: 'Level 1b', - url: '#level-1b', - }, - ], - }; - - expect(toc).toEqual(expected); - }); - - it('works with indirect `Schema` component usage', async () => { - const mdast = (indirectSchemas as any) - .data.allMdx.nodes[0].customTableOfContents; - - const toc = generateTableOfContents(mdast, minFraudImportPathMap); - - const expected = { - items: [ - { - title: 'Authorization and Security', - url: '#authorization-and-security', - }, - { - title: 'Service Endpoints', - url: '#service-endpoints', - }, - { - title: 'Headers', - url: '#headers', - }, - { - title: 'Bodies', - url: '#bodies', - }, - { - items: [ - { - title: 'Request', - url: '#schema--request', - }, - { - title: 'Request › Device', - url: '#schema--request--device', - }, - { - title: 'Request › Event', - url: '#schema--request--event', - }, - { - title: 'Request › Account', - url: '#schema--request--account', - }, - { - title: 'Request › Email', - url: '#schema--request--email', - }, - { - title: 'Request › Billing', - url: '#schema--request--billing', - }, - { - title: 'Request › Shipping', - url: '#schema--request--shipping', - }, - { - title: 'Request › Payment', - url: '#schema--request--payment', - }, - { - title: 'Request › Credit Card', - url: '#schema--request--credit-card', - }, - { - title: 'Request › Order', - url: '#schema--request--order', - }, - { - title: 'Request › Shopping Cart', - url: '#schema--request--shopping-cart', - }, - { - title: 'Request › Shopping Cart › Item', - url: '#schema--request--shopping-cart--item', - }, - { - title: 'Request › Custom Inputs', - url: '#schema--request--custom-inputs', - }, - ], - title: 'Object Reference', - url: '#object-reference', - }, - ], - }; - - expect(toc).toEqual(expected); - }); -}); diff --git a/src/utils/get-toc-items.ts b/src/utils/get-toc-items.ts deleted file mode 100644 index ccbdd578d..000000000 --- a/src/utils/get-toc-items.ts +++ /dev/null @@ -1,153 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -// eslint-disable-next-line import/no-unresolved -import { Parent } from 'unist'; - -/* eslint-disable @typescript-eslint/no-var-requires */ -// eslint-disable-next-line max-len -const getTableOfContents = require('gatsby-plugin-mdx/utils/get-table-of-content'); -const generateTOC = require('mdast-util-toc'); -const parse = require('remark-parse'); -const mdx = require('remark-mdx'); -const stringify = require('remark-stringify'); -const unified = require('unified'); -const map = require('unist-util-map'); -const find = require('unist-util-find'); -const findBefore = require('unist-util-find-before'); -const visitParents = require('unist-util-visit-parents'); - -/** - * To get the add `Schema` component names to the table of contents, the - * abstract syntax tree (AST) needs to be modified so that `mdast-util-toc` - * and `gatsby-plugin-mdx/utils/get-table-of-content` think `Schema` nodes are - * heading nodes. - * - * This code searches for AST nodes of direct `Schema` usage (node name of - * `Schema`) or indirect Schema usage (node name of `Schemas.*`), gets the - * `name` attribute value, and then replaces the node with a heading node that - * is one deeper than the closest heading. - */ - -/* eslint-disable security/detect-non-literal-fs-filename */ -export const createImportPathMap = ( - schemaDir: string -): Record => - fs.readdirSync(schemaDir).reduce((acc, file) => { - if (fs.lstatSync(path.resolve(schemaDir, file)).isDirectory()) { - return acc; - } - - return { - ...acc, - [`Schemas.${path.basename(file, '.mdx')}`]: path.resolve( - schemaDir, - file - ), - }; - }, {}); -/* eslint-enable security/detect-non-literal-fs-filename */ - -export default ( - sourceTree: any, - importPathMap: Record, -): any => { - const newTree = map( - sourceTree, - (node: any) => { - if ( - node.type !== 'mdxBlockElement' - || !(node.name as string).startsWith('Schema') - ) { - return node; - } - - let schemaNode: any = node; - - /** - * Schema component instances can either be used directly in an MDX file, - * or indirectly via an imported MDX file. Indirect instances require - * additional processing to find the imported MDX file and create it's own - * abstract syntax tree. - * - */ - if ((node.name as string).startsWith('Schemas')) { - const importedComponentName = node.name as string; - - // eslint-disable-next-line security/detect-object-injection - const importedFilePath = importPathMap[importedComponentName]; - - if (importedFilePath) { - let importedComponentTree; - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContents = fs.readFileSync(importedFilePath); - - unified() - .use(parse, { - position: false, - }) - .use(stringify) - .use(mdx) - .use(() => (node: any) => { - importedComponentTree = node; - }) - .processSync(fileContents); - - if (importedComponentTree) { - const foundNode = find( - importedComponentTree, - (node: any) => node.name - && (node.name as string).endsWith('Schema') - ); - - if (foundNode) { - schemaNode = foundNode; - } - } - } - } - - const schemaHeadingName = (schemaNode as any).attributes.find( - (attr: any) => attr.name === 'name' - )?.value; - - if (!schemaHeadingName) { - return; - } - - let closestHeadingNode; - - visitParents( - sourceTree, - node, - (node: any, ancestors: Parent[]) => { - ancestors.forEach((ancestor: Parent) => { - closestHeadingNode = findBefore(ancestor, node, 'heading'); - }); - } - ); - - node = { - ...node, - data: { - hProperties: { - id: `schema--${schemaHeadingName}`, - }, - }, - depth: closestHeadingNode ? (closestHeadingNode as any).depth + 1 : 1, - type: 'heading', - value: schemaHeadingName.split(' | ') - .map((part: string) => part.trim()) - .join(' › '), - }; - - return node; - } - ); - - const toc = generateTOC(newTree, { - maxDepth: 6, - }); - - return getTableOfContents(toc.map, {}); -}; diff --git a/src/utils/json.spec.ts b/src/utils/json.spec.ts deleted file mode 100644 index 1a8e558be..000000000 --- a/src/utils/json.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { - inferType, - isArray, - isBoolean, - isNumber, - isObject, - isString, -} from './json'; - -describe('json utils', () => { - describe('isArray()', () => { - it('returns `true` if value is an array', () => { - expect(isArray([])).toBe(true); - }); - - describe('returns `false` when', () => { - it('value is null', () => { - expect(isArray(null)).toBe(false); - }); - - it('value is a string', () => { - expect(isArray('')).toBe(false); - }); - - it('value is a boolean', () => { - expect(isArray(true)).toBe(false); - }); - - it('value is a number', () => { - expect(isArray(1)).toBe(false); - }); - - it('value is a object', () => { - expect(isArray({})).toBe(false); - }); - - }); - }); - - describe('isBoolean()', () => { - it('returns `true` if value is a boolean', () => { - expect(isBoolean(true)).toBe(true); - expect(isBoolean(false)).toBe(true); - }); - - describe('returns `false` when', () => { - it('value is null', () => { - expect(isBoolean(null)).toBe(false); - }); - - it('value is a string', () => { - expect(isBoolean('')).toBe(false); - }); - - it('value is a number', () => { - expect(isBoolean(1)).toBe(false); - }); - - it('value is a object', () => { - expect(isBoolean({})).toBe(false); - }); - - it('value is an array', () => { - expect(isBoolean([])).toBe(false); - }); - }); - }); - - describe('isNumber()', () => { - it('returns `true` if value is a number', () => { - expect(isNumber(0)).toBe(true); - expect(isNumber(1)).toBe(true); - expect(isNumber(1.1)).toBe(true); - }); - - describe('returns `false` when', () => { - it('value is null', () => { - expect(isNumber(null)).toBe(false); - }); - - it('value is a string', () => { - expect(isNumber('')).toBe(false); - }); - - it('value is a boolean', () => { - expect(isNumber(true)).toBe(false); - }); - - it('value is an object', () => { - expect(isNumber({})).toBe(false); - }); - - it('value is an array', () => { - expect(isNumber([])).toBe(false); - }); - }); - }); - - describe('isObject()', () => { - it('returns `true` if value is a boolean', () => { - expect(isObject({})).toBe(true); - }); - - describe('returns `false` when', () => { - it('value is null', () => { - expect(isObject(null)).toBe(false); - }); - - it('value is a string', () => { - expect(isObject('')).toBe(false); - }); - - it('value is a number', () => { - expect(isObject(1)).toBe(false); - }); - - it('value is a boolean', () => { - expect(isObject(false)).toBe(false); - }); - - it('value is an array', () => { - expect(isObject([])).toBe(false); - }); - }); - }); - - describe('isString()', () => { - it('returns `true` if value is a string', () => { - expect(isString('')).toBe(true); - }); - - describe('returns `false` when', () => { - it('value is null', () => { - expect(isString(null)).toBe(false); - }); - - it('value is a number', () => { - expect(isString(1)).toBe(false); - }); - - it('value is a boolean', () => { - expect(isString(false)).toBe(false); - }); - - it('value is an object', () => { - expect(isString({})).toBe(false); - }); - - it('value is an array', () => { - expect(isString([])).toBe(false); - }); - }); - }); - - describe('inferType()', () => { - it('returns `array` when given an array', () => { - expect(inferType([])).toBe('array'); - }); - - it('returns `boolean` when given an boolean', () => { - expect(inferType(true)).toBe('boolean'); - }); - - it('returns `number` when given a number', () => { - expect(inferType(1)).toBe('number'); - }); - - it('returns `object` when given an object', () => { - expect(inferType({})).toBe('object'); - }); - - it('returns `string` when given a string', () => { - expect(inferType('')).toBe('string'); - }); - - it('throws an error if a type cannot be inferred', () => { - const spy = jest.spyOn(console, 'error').mockImplementation(); - - expect(() => inferType(null)).toThrowError( - // eslint-disable-next-line max-len - 'Cannot infer type from value. See console error labeled: `Invalid Type`' - ); - - expect(console.error).toHaveBeenLastCalledWith('Invalid Type', null); - - spy.mockRestore(); - }); - }); -}); - - diff --git a/src/utils/json.ts b/src/utils/json.ts deleted file mode 100644 index 2041b0337..000000000 --- a/src/utils/json.ts +++ /dev/null @@ -1,51 +0,0 @@ -import _isBoolean from 'lodash.isboolean'; -import _isNumber from 'lodash.isnumber'; -import isPlainObject from 'lodash.isplainobject'; - -export const isArray = ( - value: Json -): value is IJsonArray => Array.isArray(value); - -export const isBoolean = ( - value: Json -): value is boolean => _isBoolean(value); - -export const isNumber = ( - value: Json -): value is number => _isNumber(value); - -export const isObject = ( - value: Json -): value is IJsonObject => isPlainObject(value); - -export const isString = ( - value: Json -): value is string => typeof value === 'string'; - -export const inferType = (value: Json): string => { - if (isArray(value)) { - return 'array'; - } - - if (isBoolean(value)) { - return 'boolean'; - } - - if (isObject(value)) { - return 'object'; - } - - if (isNumber(value)) { - return 'number'; - } - - if (isString(value)) { - return 'string'; - } - - console.error('Invalid Type', value); - - throw new Error( - 'Cannot infer type from value. See console error labeled: `Invalid Type`' - ); -}; diff --git a/src/utils/markdown.tsx b/src/utils/markdown.tsx deleted file mode 100644 index 2b2b970ab..000000000 --- a/src/utils/markdown.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { MDXProvider } from '@mdx-js/react'; -import MDX from '@mdx-js/runtime'; -import React from 'react'; - -import * as components from '../components/Mdx'; - -export const renderMarkdown = ( - content: any -): React.ReactElement => { - return ( - /* eslint-disable-next-line max-len */ - /* @ts-expect-error: @type for @mdx-js/react has implicit children which is incompat with react 18 */ - - - {content} - - - ); -}; diff --git a/src/utils/openapi.spec.ts b/src/utils/openapi.spec.ts deleted file mode 100644 index 3f54a710c..000000000 --- a/src/utils/openapi.spec.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { OpenAPIV3 } from 'openapi-types'; - -import { - formatSchemaName, - isArraySchemaObject, - isDocumentObject, - isNonArraySchemaObject, - isReferenceObject, - isSchemaObject, -} from './openapi'; - -describe('formatSchemaName()', () => { - describe( - 'replaces `|` with `›`, ensuring proper spacing before and after', - () => { - it.each([ - [ - 'foo', - 'foo', - ], - [ - ' foo ', - 'foo', - ], - [ - 'foo |', - 'foo |', - ], - [ - 'foo | bar', - 'foo › bar', - ], - ])('given `%s`, returns `%s`', (given: string, expected: string) => { - expect(formatSchemaName(given)).toBe(expected); - }); - } - ); -}); - -describe('isArraySchemaObject()', () => { - it('array type schema objects return true', () => { - const obj: OpenAPIV3.SchemaObject = { - items: { - type: 'string', - }, - type: 'array', - }; - expect(isArraySchemaObject(obj)).toBe(true); - }); - - it('non-array type schema objects return false', () => { - const obj: OpenAPIV3.SchemaObject = { - type: 'string', - }; - expect(isArraySchemaObject(obj)).toBe(false); - }); -}); - -describe('isDocumentObject()', () => { - it('document objects return true', () => { - const obj: OpenAPIV3.Document = { - info: { - title: '', - version: '', - }, - openapi: '', - paths: {}, - }; - expect(isDocumentObject(obj)).toBe(true); - }); - - it('non-document objects return false', () => { - const obj: OpenAPIV3.SchemaObject = { - type: 'string', - }; - expect(isDocumentObject(obj)).toBe(false); - }); -}); - -describe('isNonArraySchemaObject', () => { - it('array type schema objects return false', () => { - const obj: OpenAPIV3.SchemaObject = { - items: { - type: 'string', - }, - type: 'array', - }; - expect(isNonArraySchemaObject(obj)).toBe(false); - }); - - it('non-array type schema objects return true', () => { - const obj: OpenAPIV3.NonArraySchemaObject = { - type: 'string', - }; - expect(isNonArraySchemaObject(obj)).toBe(true); - }); -}); - -describe('isReferenceObject()', () => { - it('objects containing a `$ref` property are reference objects', () => { - const obj: OpenAPIV3.ReferenceObject = { - $ref: '', - }; - expect(isReferenceObject(obj)).toBe(true); - }); - - it( - 'objects that don\'t contain a `$ref` property are not reference objects', - () => { - const obj: OpenAPIV3.SchemaObject = {}; - expect(isReferenceObject(obj)).toBe(false); - } - ); -}); - -describe('isSchemaObject()', () => { - it('document objects are not schema objects', () => { - const obj: OpenAPIV3.Document = { - info: { - title: '', - version: '', - }, - openapi: '', - paths: {}, - }; - expect(isSchemaObject(obj)).toBe(false); - }); - - it('reference objects are not schema objects', () => { - const obj: OpenAPIV3.ReferenceObject = { - $ref: '', - }; - expect(isSchemaObject(obj)).toBe(false); - }); - - it('any non-reference, non-document objects are schema objects', () => { - const obj = {}; - expect(isSchemaObject(obj)).toBe(true); - }); -}); diff --git a/src/utils/openapi.ts b/src/utils/openapi.ts deleted file mode 100644 index 485ed7a8a..000000000 --- a/src/utils/openapi.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable no-prototype-builtins */ -import { OpenAPIV3 } from 'openapi-types'; - -export const formatSchemaName = (schemaPath: string): string => schemaPath - .split(' | ') - .map((part: string) => part.trim()) - .join(' › '); - -export const isReferenceObject = ( - obj: OpenAPIV3.Document - | OpenAPIV3.SchemaObject - | OpenAPIV3.ReferenceObject -): obj is OpenAPIV3.ReferenceObject => obj.hasOwnProperty('$ref'); - -export const isDocumentObject = ( - obj: OpenAPIV3.Document - | OpenAPIV3.SchemaObject - | OpenAPIV3.ReferenceObject -): obj is OpenAPIV3.Document => obj.hasOwnProperty('openapi'); - -export const isSchemaObject = ( - obj: OpenAPIV3.Document - | OpenAPIV3.SchemaObject - | OpenAPIV3.ReferenceObject -): obj is OpenAPIV3.SchemaObject => !isReferenceObject(obj) - && !isDocumentObject(obj); - -export const isArraySchemaObject = ( - obj: OpenAPIV3.SchemaObject -): obj is OpenAPIV3.ArraySchemaObject => isSchemaObject(obj) - && obj.type === 'array'; - -export const isNonArraySchemaObject = ( - obj: OpenAPIV3.SchemaObject -): obj is OpenAPIV3.NonArraySchemaObject => !isArraySchemaObject(obj); diff --git a/src/utils/pagination.spec.ts b/src/utils/pagination.spec.ts deleted file mode 100644 index f2ba49d0b..000000000 --- a/src/utils/pagination.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { getNextPage, getPreviousPage } from './pagination'; - -jest.mock('../../content/navigation', () => ([ - { - to: 'foo', - }, - { - items: [ - { - to: 'bar-item-foo', - }, - { - to: 'bar-item-bar', - }, - ], - to: 'bar', - }, - { - url: '#', - }, - { - items: [ - { - to: 'baz-item-foo', - }, - { - to: 'baz-item-bar', - }, - ], - secondaryItems: [ - { - to: 'baz-secondary-foo', - }, - { - to: 'baz-secondary-bar', - }, - ], - to: 'baz', - }, -])); - -describe('pagination', () => { - describe('getPreviousPage()', () => { - it('returns previous page', () => { - expect(getPreviousPage('bar')).toHaveProperty('to', 'foo'); - }); - - it('returns previous page when current url ends with a slash', () => { - expect(getPreviousPage('bar/')).toHaveProperty('to', 'foo'); - }); - - it('returns nothing if previous page does not exist', () => { - expect(getPreviousPage('foo')).toBeUndefined; - }); - - it('skips non-internal nodes', () => { - expect(getPreviousPage('baz')).toHaveProperty('to', 'bar-item-bar'); - }); - - it('considers `items` child pages', () => { - expect(getPreviousPage('baz')).toHaveProperty('to', 'bar-item-bar'); - }); - - it('considers `secondaryItems` child pages', () => { - expect(getPreviousPage('baz-secondary-bar')) - .toHaveProperty('to', 'baz-secondary-foo'); - }); - }); - - describe('getNextPage()', () => { - it('returns next page', () => { - expect(getNextPage('foo')).toHaveProperty('to', 'bar'); - }); - - it('returns nothing if next page does not exist', () => { - expect(getNextPage('baz-secondary-bar')).toBeUndefined(); - }); - - it('skips non-internal nodes', () => { - expect(getNextPage('bar-item-bar')).toHaveProperty('to', 'baz'); - }); - - it('considers `items` child pages', () => { - expect(getNextPage('bar')).toHaveProperty('to', 'bar-item-foo'); - }); - - it('considers `secondaryItems` child pages', () => { - expect(getNextPage('baz-item-bar')) - .toHaveProperty('to', 'baz-secondary-foo'); - }); - }); -}); diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts deleted file mode 100644 index 4b6bb041e..000000000 --- a/src/utils/pagination.ts +++ /dev/null @@ -1,51 +0,0 @@ -import findIndex from 'lodash.findindex'; - -import navigation from '../../content/navigation'; -import { - IInternalItem, - IItem, - isInternalItem, -} from '../types/Item'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const flattenDeep = (arr: any[]) : any[] => Array.isArray(arr) - ? arr.reduce( (a, b) => a.concat(flattenDeep(b)) , []) - : [ - arr, - ]; - -const flattenTree = (tree: IItem[]) : IInternalItem[] => flattenDeep( - tree.map((node: IItem) => { - if (!isInternalItem(node)) { - return []; - } - - return [ - node, - ...(node.items ? flattenTree(node?.items) : []), - ...(node.secondaryItems ? flattenTree(node?.secondaryItems) : []), - ]; - })); - -const flattenedNav = flattenTree(navigation); - -const findNodeIndex = (currentPath: string): number => findIndex( - flattenedNav, - (item: IInternalItem) => item.to === currentPath.replace(/\/$/, '') -); - -export const getPreviousPage = (currentPath: string): void | IInternalItem => { - const nodeIndex = findNodeIndex(currentPath); - - if (flattenedNav[nodeIndex - 1]) { - return flattenedNav[nodeIndex - 1]; - } -}; - -export const getNextPage = (currentPath: string): void | IInternalItem => { - const nodeIndex = findNodeIndex(currentPath); - - if (flattenedNav[nodeIndex + 1]) { - return flattenedNav[nodeIndex + 1]; - } -};