Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion codegen/validate-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function findSiteSection(filePath: string): SiteSection | undefined {
}

const absoluteUrlPattern = new RegExp(
`${baseUrl.replaceAll('.', '\\.')}[^)\\s]+`,
`${baseUrl.replaceAll('.', '\\.')}[^)"\\s]+`,
'g',
)

Expand All @@ -23,6 +23,15 @@ const absoluteUrlPattern = new RegExp(
const relativeLinkPattern =
/(?<!!)\]\((?!https?:\/\/|mailto:|#|{%|<|cursor:|file:)((?:[^)\\]|\\.)+)\)/g

// Matches HTML links like <a href="path"> but not external URLs or anchors.
const htmlRelativeLinkPattern = /<a\s+href="(?!https?:\/\/|mailto:|#)([^"]+)"/g

// Matches HTML links with absolute docs.seam.co URLs.
const htmlAbsoluteUrlPattern = new RegExp(
`<a\\s+href="(${baseUrl.replaceAll('.', '\\.')}[^"]+)"`,
'g',
)

interface BrokenLink {
file: string
line: number
Expand Down Expand Up @@ -160,6 +169,20 @@ for (const file of files) {
if (rawLink == null) continue
checkRelativeLink(file, i + 1, rawLink)
}

// Check HTML href links (relative)
for (const match of lineText.matchAll(htmlRelativeLinkPattern)) {
const rawLink = match[1]
if (rawLink == null) continue
checkRelativeLink(file, i + 1, rawLink)
}

// Check HTML href links (absolute docs.seam.co URLs)
for (const match of lineText.matchAll(htmlAbsoluteUrlPattern)) {
const rawUrl = match[1]
if (rawUrl == null) continue
checkAbsoluteUrl(file, i + 1, rawUrl)
}
}
}

Expand Down
67 changes: 66 additions & 1 deletion codegen/validate-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ function slugify(heading: string): string {
.trim()
}

function slugFromPath(linkPath: string): string {
return (
linkPath
.replace(/README\.md$/, '')
.replace(/\.md$/, '')
.replace(/\/$/, '')
.split('/')
.filter(Boolean)
.pop() ?? ''
)
}

interface PathMismatch {
section: string
line: number
Expand All @@ -37,6 +49,11 @@ for (const section of siteSections) {

let currentGroup: string | null = null

// Track nesting: each entry is { level, slug, path }
// GitBook builds URLs by joining ancestor slugs, so child file paths
// should be under their parent's directory.
const parentStack: Array<{ level: number; slug: string; path: string }> = []

for (let i = 0; i < lines.length; i++) {
const lineText = lines[i]
if (lineText == null) continue
Expand All @@ -48,7 +65,14 @@ for (const section of siteSections) {
continue
}

for (const match of lineText.matchAll(summaryLinkPattern)) {
// Only process list items
const stripped = lineText.trimStart()
if (!stripped.startsWith('* [')) continue

const indent = lineText.length - stripped.length
const level = Math.floor(indent / 2)

for (const match of stripped.matchAll(summaryLinkPattern)) {
const title = match[1] ?? ''
const linkPath = match[2] ?? ''

Expand Down Expand Up @@ -79,6 +103,47 @@ for (const section of siteSections) {
reason: `Path should start with "${currentGroup}/" (listed under "## ${currentGroup}")`,
})
}

// Check 3: nested items should have paths under their parent's directory.
// GitBook builds published URLs from the SUMMARY.md tree, so a child
// nested under a parent gets a URL like /parent-slug/child-slug.
// The file path must match this structure.
// Trim stack to current level
while (parentStack.length > 0) {
const top = parentStack[parentStack.length - 1]
if (top != null && top.level >= level) parentStack.pop()
else break
}

const slug = slugFromPath(linkPath)
const parent =
parentStack.length > 0 ? parentStack[parentStack.length - 1] : undefined

if (parent != null) {
// The parent's path determines the expected directory prefix.
// e.g., parent path "access_codes/simulate/README.md" means
// children should start with "access_codes/simulate/".
const parentDir = parent.path
.replace(/README\.md$/, '')
.replace(/\.md$/, '/')
if (!linkPath.startsWith(parentDir)) {
const publishedUrl =
section.urlPrefix +
'/' +
[...parentStack.map((p) => p.slug), slug].join('/')
mismatches.push({
section: section.name,
line: i + 1,
title,
path: linkPath,
reason: `Path should start with "${parentDir}" to match published URL ${publishedUrl}`,
})
}
}

if (slug !== '') {
parentStack.push({ level, slug, path: linkPath })
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/brand-guides/2n-intercom-systems/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The setup guide covers:
* Creating API credentials
* Connecting to Seam through the Connect Webview

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>System Set Up Guide</strong></td><td><a href="../../.gitbook/assets/image (29).png">image (29).png</a></td><td><a href="./2n-system-set-up-instructions.md">2n-system-set-up-instructions.md</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>System Set Up Guide</strong></td><td><a href="../.gitbook/assets/image (29).png">image (29).png</a></td><td><a href="./2n-system-set-up-instructions.md">2n-system-set-up-instructions.md</a></td></tr></tbody></table>

***

Expand All @@ -52,4 +52,4 @@ For more details, see [Customize Brands in Connect Webviews](https://docs.seam.c

Find your local 2N distributor using the following page:

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>Locate Your 2N Distributor</strong></td><td></td><td><a href="https://www.2n.com/en_GB/how-to-buy/where-to-buy">https://www.2n.com/en_GB/how-to-buy/where-to-buy</a></td><td><a href="../../.gitbook/assets/2n-logo.png">2n-logo.png</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>Locate Your 2N Distributor</strong></td><td></td><td><a href="https://www.2n.com/en_GB/how-to-buy/where-to-buy">https://www.2n.com/en_GB/how-to-buy/where-to-buy</a></td><td><a href="../.gitbook/assets/2n-logo.png">2n-logo.png</a></td></tr></tbody></table>
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,11 @@ Now that you've completed this guide, you can try to connect a real 2N device. T

In addition, if you'd like to explore other aspects of Seam, here is a list of helpful resources:

* [Yale Getting Started Guide](../get-started-with-yale-locks.md)
* [August Getting Started Guide](../get-started-with-august-locks.md)
* [Yale Getting Started Guide](../yale-locks/get-started-with-yale-locks.md)
* [August Getting Started Guide](../august-locks/get-started-with-august-locks.md)
* [Schlage Getting Started Guide](../schlage-locks/get-started-with-schlage-locks.md)
* [SmartThings Getting Started Guide](../smartthings-hubs-+-devices/get-started-with-smartthings-hubs-+-smart-locks.md)
* [Minut Getting Started Guide](../get-started-with-minut-sensors.md)
* [Minut Getting Started Guide](../minut-sensors/get-started-with-minut-sensors.md)
* [Receiving webhook](https://docs.seam.co/latest/developer-tools/webhooks) for [device events](https://docs.seam.co/latest/api/events/list)
* [Core Concepts](https://docs.seam.co/latest/core-concepts/overview)

Expand Down
4 changes: 2 additions & 2 deletions docs/brand-guides/33-lock-devices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ To control 33 Lock devices using Seam, you must prompt owners of these devices t

## Troubleshooting

For errors and warnings that are relevant to 33 Lock devices, see [Troubleshooting](../ttlock-locks.md#troubleshooting) in the TTLock device integration guide.
For errors and warnings that are relevant to 33 Lock devices, see [Troubleshooting](../ttlock-locks/#troubleshooting) in the TTLock device integration guide.

***

## Where to Order

To purchase 33 Lock devices, contact the 33 Lock sales team..

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>33 Lock Contact Page</strong></td><td></td><td><a href="https://www.33lock.com/contact">https://www.33lock.com/contact</a></td><td><a href="../../.gitbook/assets/33-lock-logo.png">33-lock-logo.png</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>33 Lock Contact Page</strong></td><td></td><td><a href="https://www.33lock.com/contact">https://www.33lock.com/contact</a></td><td><a href="../.gitbook/assets/33-lock-logo.png">33-lock-logo.png</a></td></tr></tbody></table>
Original file line number Diff line number Diff line change
Expand Up @@ -1418,4 +1418,4 @@ If you have any questions or want to report an issue, email us at [support@seam.

## Quick links

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Get an API Key</strong> (free)</td><td>Sign up for the Seam Console and get your API keys. →</td><td></td><td><a href="../../.gitbook/assets/seam-api-key.png">seam-api-key.png</a></td><td><a href="https://console.seam.co/">https://console.seam.co/</a></td></tr><tr><td><strong>Contact Sales</strong></td><td>Got a project or a specific question? Contact our team to get answers. →</td><td></td><td><a href="../../.gitbook/assets/seam-contact-us-light.png">seam-contact-us-light.png</a></td><td><a href="https://www.seam.co/contact-us">https://www.seam.co/contact-us</a></td></tr></tbody></table>
<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Get an API Key</strong> (free)</td><td>Sign up for the Seam Console and get your API keys. →</td><td></td><td><a href="../../guides/.gitbook/assets/seam-api-key.png">seam-api-key.png</a></td><td><a href="https://console.seam.co/">https://console.seam.co/</a></td></tr><tr><td><strong>Contact Sales</strong></td><td>Got a project or a specific question? Contact our team to get answers. →</td><td></td><td><a href="../.gitbook/assets/seam-contact-us-light.png">seam-contact-us-light.png</a></td><td><a href="https://www.seam.co/contact-us">https://www.seam.co/contact-us</a></td></tr></tbody></table>
2 changes: 1 addition & 1 deletion docs/brand-guides/4suites-locks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ To control 4SUITES devices using Seam, you must prompt owners of these devices t

To purchase 4SUITES devices, request a quote using the 4SUITES **Contact Us Form**.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>4SUITES Contact Us Form</strong></td><td></td><td><a href="https://www.4suiteshq.com/contact-us/">https://www.4suiteshq.com/contact-us/</a></td><td><a href="../../.gitbook/assets/4suites-logo.png">4suites-logo.png</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>4SUITES Contact Us Form</strong></td><td></td><td><a href="https://www.4suiteshq.com/contact-us/">https://www.4suiteshq.com/contact-us/</a></td><td><a href="../.gitbook/assets/4suites-logo.png">4suites-logo.png</a></td></tr></tbody></table>

***
Original file line number Diff line number Diff line change
Expand Up @@ -1036,4 +1036,4 @@ If you have any questions or want to report an issue, email us at [support@seam.

## Quick links

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Get an API Key</strong> (free)</td><td>Sign up for the Seam Console and get your API keys. →</td><td></td><td><a href="../../.gitbook/assets/seam-api-key.png">seam-api-key.png</a></td><td><a href="https://console.seam.co/">https://console.seam.co/</a></td></tr><tr><td><strong>Contact Sales</strong></td><td>Got a project or a specific question? Contact our team to get answers. →</td><td></td><td><a href="../../.gitbook/assets/seam-contact-us-light.png">seam-contact-us-light.png</a></td><td><a href="https://www.seam.co/contact-us">https://www.seam.co/contact-us</a></td></tr></tbody></table>
<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Get an API Key</strong> (free)</td><td>Sign up for the Seam Console and get your API keys. →</td><td></td><td><a href="../../guides/.gitbook/assets/seam-api-key.png">seam-api-key.png</a></td><td><a href="https://console.seam.co/">https://console.seam.co/</a></td></tr><tr><td><strong>Contact Sales</strong></td><td>Got a project or a specific question? Contact our team to get answers. →</td><td></td><td><a href="../.gitbook/assets/seam-contact-us-light.png">seam-contact-us-light.png</a></td><td><a href="https://www.seam.co/contact-us">https://www.seam.co/contact-us</a></td></tr></tbody></table>
Loading
Loading