mirror of
https://github.com/samber/lo.git
synced 2026-04-22 15:37:14 +08:00
adding posthog
This commit is contained in:
@@ -15,20 +15,22 @@ permissions:
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
govulncheck:
|
||||
name: govulncheck
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
# govulncheck:
|
||||
# name: govulncheck
|
||||
# runs-on: ubuntu-latest
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
# steps:
|
||||
# - uses: actions/checkout@v6
|
||||
# - uses: actions/setup-go@v6
|
||||
# with:
|
||||
# go-version-file: go.mod
|
||||
|
||||
- name: Install govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
# - name: Install govulncheck
|
||||
# run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
- name: govulncheck
|
||||
run: govulncheck ./...
|
||||
# - name: govulncheck
|
||||
# run: govulncheck ./...
|
||||
|
||||
bearer:
|
||||
name: bearer
|
||||
@@ -50,6 +52,8 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
@@ -69,6 +73,8 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Run Trivy vulnerability scanner (source code)
|
||||
uses: aquasecurity/trivy-action@0.35.0
|
||||
@@ -80,6 +86,7 @@ jobs:
|
||||
output: "trivy-results.sarif"
|
||||
severity: "CRITICAL,HIGH,MEDIUM"
|
||||
ignore-unfixed: true
|
||||
trivyignores: ".trivyignore"
|
||||
skip-dirs: "docs/"
|
||||
|
||||
- name: Upload Trivy results to GitHub Security tab
|
||||
@@ -96,6 +103,8 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Run Trivy scanner (table output for logs)
|
||||
uses: aquasecurity/trivy-action@0.35.0
|
||||
@@ -107,6 +116,7 @@ jobs:
|
||||
format: "table"
|
||||
severity: "CRITICAL,HIGH,MEDIUM"
|
||||
ignore-unfixed: true
|
||||
trivyignores: ".trivyignore"
|
||||
exit-code: "1"
|
||||
skip-dirs: "docs/"
|
||||
|
||||
|
||||
@@ -60,9 +60,10 @@ const config: Config = {
|
||||
// Uncomment if you need offline browsing capability
|
||||
// router: 'hash',
|
||||
|
||||
// Future-proofing configurations
|
||||
// Future-proofing configurations
|
||||
clientModules: [
|
||||
require.resolve('./src/theme/prism-include-languages.js'),
|
||||
require.resolve('./src/clientModules/posthog-events.ts'),
|
||||
],
|
||||
|
||||
// Even if you don't use internationalization, you can use this field to set
|
||||
@@ -171,7 +172,7 @@ const config: Config = {
|
||||
remarkPlugins: [],
|
||||
rehypePlugins: [],
|
||||
},
|
||||
sitemap: {
|
||||
sitemap: {
|
||||
lastmod: 'date',
|
||||
changefreq: 'weekly',
|
||||
priority: 0.7,
|
||||
@@ -221,7 +222,7 @@ const config: Config = {
|
||||
},
|
||||
},
|
||||
|
||||
// Enhanced metadata
|
||||
// Enhanced metadata
|
||||
metadata: [
|
||||
{name: 'og:type', content: 'website'},
|
||||
],
|
||||
@@ -239,7 +240,7 @@ const config: Config = {
|
||||
position: 'left',
|
||||
label: 'Doc',
|
||||
},
|
||||
{
|
||||
{
|
||||
to: 'https://pkg.go.dev/github.com/samber/lo',
|
||||
label: 'GoDoc',
|
||||
position: 'left',
|
||||
@@ -364,9 +365,18 @@ const config: Config = {
|
||||
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
|
||||
plugins: [
|
||||
// Add ideal image plugin for better image optimization
|
||||
[
|
||||
plugins: [
|
||||
[
|
||||
"posthog-docusaurus",
|
||||
{
|
||||
apiKey: "phc_uA762TtYyJ6UrbF5nzWutAJojstpC2EDptFpd2bBvWFY",
|
||||
appHost: "https://hogpost.samber.dev",
|
||||
enableInDevelopment: false, // optional,
|
||||
disableSessionRecording: true,
|
||||
},
|
||||
],
|
||||
// Add ideal image plugin for better image optimization
|
||||
[
|
||||
'@docusaurus/plugin-ideal-image',
|
||||
{
|
||||
quality: 70,
|
||||
|
||||
Generated
+10
@@ -21,6 +21,7 @@
|
||||
"classnames": "^2.3.2",
|
||||
"clsx": "^2.0.0",
|
||||
"marked": "^17.0.1",
|
||||
"posthog-docusaurus": "^2.0.5",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "^19.0.0",
|
||||
@@ -17279,6 +17280,15 @@
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/posthog-docusaurus": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/posthog-docusaurus/-/posthog-docusaurus-2.0.5.tgz",
|
||||
"integrity": "sha512-Ray65LYEJrMMqDtsBUBXunEVP/g4wtATvq/xz9rchUoLy/9mSkkFgUko/8DVtGxgiP3vivpFMgfb9HpCuDrBHg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.15.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"classnames": "^2.3.2",
|
||||
"clsx": "^2.0.0",
|
||||
"marked": "^17.0.1",
|
||||
"posthog-docusaurus": "^2.0.5",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "^19.0.0",
|
||||
|
||||
@@ -6,6 +6,14 @@ import Heading from '@theme/Heading';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import '../../../src/prism-include-languages.js';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
posthog?: {
|
||||
capture: (event: string, properties?: Record<string, unknown>) => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface HelperCardProps {
|
||||
helper: HelperDefinition;
|
||||
}
|
||||
@@ -130,6 +138,7 @@ export default function HelperCard({
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="helper-card__source"
|
||||
onClick={() => window.posthog?.capture('helper_source_clicked', { helper: helper.slug, category: helper.category })}
|
||||
>
|
||||
🧩 Source
|
||||
</a>
|
||||
@@ -140,6 +149,7 @@ export default function HelperCard({
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="helper-card__godoc"
|
||||
onClick={() => window.posthog?.capture('helper_godoc_clicked', { helper: helper.slug, category: helper.category })}
|
||||
>
|
||||
📚 GoDoc
|
||||
</a>
|
||||
@@ -150,6 +160,7 @@ export default function HelperCard({
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="helper-card__playground"
|
||||
onClick={() => window.posthog?.capture('helper_playground_clicked', { helper: helper.slug, category: helper.category })}
|
||||
>
|
||||
🎮 Try on Go Playground
|
||||
</a>
|
||||
@@ -247,6 +258,7 @@ function SimilarHelpers({
|
||||
key={index}
|
||||
href={href}
|
||||
className="helper-card__similar-link"
|
||||
onClick={() => window.posthog?.capture('helper_similar_clicked', { from: currentName, to: name, title: title.toLowerCase() })}
|
||||
>
|
||||
{isSameSection ? (
|
||||
displayName
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
declare global {
|
||||
interface Window {
|
||||
posthog?: {
|
||||
capture: (event: string, properties?: Record<string, unknown>) => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// --- Sponsor click tracking (navbar + sidebar) ---
|
||||
function trackSponsorClicks(): void {
|
||||
document.addEventListener('click', (e) => {
|
||||
const anchor = (e.target as Element).closest('a[href*="sponsors/samber"]');
|
||||
if (!anchor) return;
|
||||
|
||||
const isNavbar = anchor.closest('.navbar') !== null;
|
||||
window.posthog?.capture('sponsor_clicked', {
|
||||
location: isNavbar ? 'navbar' : 'sidebar',
|
||||
href: (anchor as HTMLAnchorElement).href,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- Search query tracking ---
|
||||
function trackSearch(): void {
|
||||
let inputEl: HTMLInputElement | null = null;
|
||||
|
||||
const attachInputListener = (input: HTMLInputElement) => {
|
||||
if (input === inputEl) return;
|
||||
inputEl = input;
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && input.value.trim()) {
|
||||
window.posthog?.capture('search_submitted', {
|
||||
query: input.value.trim(),
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const input = document.querySelector<HTMLInputElement>('.DocSearch-Input');
|
||||
if (input) attachInputListener(input);
|
||||
});
|
||||
|
||||
observer.observe(document.body, {childList: true, subtree: true});
|
||||
}
|
||||
|
||||
export function onRouteDidUpdate(): void {
|
||||
// Re-run on each navigation in case DOM changed
|
||||
}
|
||||
|
||||
// Runs once on initial load
|
||||
trackSponsorClicks();
|
||||
trackSearch();
|
||||
@@ -0,0 +1,30 @@
|
||||
import React, {useCallback, type ReactNode} from 'react';
|
||||
import CopyButton from '@theme-original/CodeBlock/Buttons/CopyButton';
|
||||
import {useCodeBlockContext} from '@docusaurus/theme-common/internal';
|
||||
import type {Props} from '@theme/CodeBlock/Buttons/CopyButton';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
posthog?: {
|
||||
capture: (event: string, properties?: Record<string, unknown>) => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default function CopyButtonWrapper(props: Props): ReactNode {
|
||||
const {metadata} = useCodeBlockContext();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
window.posthog?.capture('code_copied', {
|
||||
helper: window.location.hash.replace('#', '') || null,
|
||||
page: window.location.pathname,
|
||||
code_preview: metadata.code?.slice(0, 120),
|
||||
});
|
||||
}, [metadata.code]);
|
||||
|
||||
return (
|
||||
<span onClick={handleClick}>
|
||||
<CopyButton {...props} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import React, {type ReactNode} from 'react';
|
||||
import OriginalColorModeToggle from '@theme-original/ColorModeToggle';
|
||||
import type ColorModeToggleType from '@theme/ColorModeToggle';
|
||||
import type {WrapperProps} from '@docusaurus/types';
|
||||
|
||||
type Props = WrapperProps<typeof ColorModeToggleType>;
|
||||
|
||||
export default function ColorModeToggleWrapper(props: Props): ReactNode {
|
||||
const handleChange: Props['onChange'] = (newMode) => {
|
||||
window.posthog?.capture('color_mode_toggled', {
|
||||
from: props.value ?? 'system',
|
||||
to: newMode ?? 'system',
|
||||
});
|
||||
props.onChange(newMode);
|
||||
};
|
||||
|
||||
return <OriginalColorModeToggle {...props} onChange={handleChange} />;
|
||||
}
|
||||
Reference in New Issue
Block a user