Skip to content
Open
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
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
# Site dependencies — opens a PR when a new pagi-help (or vitepress) version is published.
- package-ecosystem: npm
directory: /site
schedule:
interval: daily
open-pull-requests-limit: 5
60 changes: 60 additions & 0 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Deploy Site

on:
push:
branches: [master]
paths:
- "site/**"
- ".github/workflows/deploy-site.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: site
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: site/package-lock.json

- name: Install dependencies
run: npm ci

- name: Build site
run: npm run docs:build

- name: Configure Pages
uses: actions/configure-pages@v5

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: site/docs/.vitepress/dist

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 6 additions & 0 deletions site/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
docs/.vitepress/cache/
docs/.vitepress/dist/
docs/public/pagihelp.global.js
*.log
.DS_Store
19 changes: 19 additions & 0 deletions site/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# PagiHelp Documentation Site

The documentation website for [`pagi-help`](https://github.com/Codebucket-Solutions/PagiHelp), built with [VitePress](https://vitepress.dev) — live at **https://codebucket-solutions.github.io/PagiHelp/**.

This folder is self-contained and is **not** published to npm with the library.

## Local development

```bash
cd site
npm install
npm run docs:dev # start local dev server
npm run docs:build # production build -> docs/.vitepress/dist
npm run docs:preview # preview the production build
```

## Deployment

Pushing changes under `site/` to `master` triggers [`deploy-site.yml`](../.github/workflows/deploy-site.yml), which builds and publishes the site to GitHub Pages. The demo/playground bundle the published `pagi-help` npm package — Dependabot opens a PR when a new version is released, and merging it updates the live site.
177 changes: 177 additions & 0 deletions site/docs/.vitepress/config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { defineConfig } from "vitepress";
import { readFileSync } from "node:fs";

const REPO = "https://github.com/Codebucket-Solutions/PagiHelp";

// GitHub Pages serves under /PagiHelp/; override with DOCS_BASE (e.g. "/") for a domain root.
const base = process.env.DOCS_BASE || "/PagiHelp/";

// Version badge: live from the npm registry at build time, package.json as offline fallback.
const pkg = JSON.parse(
readFileSync(new URL("../../../package.json", import.meta.url), "utf8")
);
async function libVersion() {
try {
const res = await fetch("https://registry.npmjs.org/pagi-help/latest", {
signal: AbortSignal.timeout(5000),
});
if (res.ok) return (await res.json()).version;
} catch {}
return pkg.version;
}
const version = await libVersion();

export default defineConfig({
base,
title: "PagiHelp",
description:
"Pagination query builder for MySQL and PostgreSQL — filters, search, sorting, unions, and cursor pagination.",
lang: "en-US",
cleanUrls: true,
lastUpdated: true,
ignoreDeadLinks: false,

// Dark-first identity; the appearance toggle still offers light mode.
appearance: "dark",

markdown: {
theme: { light: "github-light", dark: "tokyo-night" },
},

head: [
["link", { rel: "icon", href: `${base}favicon.svg`, type: "image/svg+xml" }],
["meta", { name: "theme-color", content: "#7c5cff" }],
["meta", { property: "og:title", content: "PagiHelp" }],
[
"meta",
{
property: "og:description",
content:
"Pagination that compiles to SQL — for MySQL and PostgreSQL.",
},
],
],

themeConfig: {
logo: "/logo.svg",

nav: [
{ text: "Guide", link: "/guide/getting-started", activeMatch: "/guide/" },
{ text: "API", link: "/v2/overview", activeMatch: "/v2/" },
{ text: "Dialects", link: "/dialects/mysql", activeMatch: "/dialects/" },
{
text: "Examples",
link: "/examples/filtering",
activeMatch: "/examples/",
},
{ text: "Demo", link: "/examples/sample-data" },
{ text: "Playground", link: "/playground" },
{ text: "Reference", link: "/api/reference" },
{
text: "v" + version,
items: [
{ text: "npm", link: "https://www.npmjs.com/package/pagi-help" },
{ text: "Migrating to v2", link: "/guide/migration" },
],
},
],

sidebar: {
"/guide/": [
{
text: "Introduction",
items: [
{ text: "Getting Started", link: "/guide/getting-started" },
{ text: "Installation", link: "/guide/installation" },
],
},
{
text: "Migration",
items: [
{ text: "Migrating to v2", link: "/guide/migration" },
],
},
],
"/v2/": [
{
text: "API",
items: [
{ text: "Overview", link: "/v2/overview" },
{ text: "Constructor", link: "/v2/constructor" },
{ text: "paginate()", link: "/v2/paginate" },
{ text: "Cursor Pagination", link: "/v2/cursor-pagination" },
{
text: "Filters & Operators",
link: "/v2/filters-and-operators",
},
{ text: "Sorting", link: "/v2/sorting" },
{ text: "Search", link: "/v2/search" },
{ text: "Return Shape", link: "/v2/return-shape" },
],
},
],
"/dialects/": [
{
text: "Dialects",
items: [
{ text: "MySQL", link: "/dialects/mysql" },
{ text: "PostgreSQL", link: "/dialects/postgres" },
],
},
],
"/examples/": [
{
text: "By Feature",
items: [
{ text: "Filtering", link: "/examples/filtering" },
{ text: "Searching", link: "/examples/searching" },
{ text: "Sorting", link: "/examples/sorting" },
{ text: "Pagination", link: "/examples/pagination" },
],
},
{
text: "By Query Shape",
items: [
{ text: "Single Table", link: "/examples/single-table" },
{ text: "Joined Table", link: "/examples/joined-table" },
{ text: "Multi-Table Union", link: "/examples/multi-table-union" },
{ text: "Cursor Pagination", link: "/examples/cursor" },
],
},
{
text: "Interactive",
items: [
{ text: "Interactive Demo", link: "/examples/sample-data" },
{ text: "Playground", link: "/playground" },
],
},
],
"/api/": [
{
text: "Reference",
items: [{ text: "API Reference", link: "/api/reference" }],
},
],
},

socialLinks: [
{ icon: "github", link: REPO, ariaLabel: "GitHub repository" },
{
icon: {
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>npm</title><path d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z"/></svg>',
},
link: "https://www.npmjs.com/package/pagi-help",
ariaLabel: "npm package",
},
],

search: {
provider: "local",
},

footer: {
message: "Released under the MIT License.",
copyright: "Copyright © Codebucket Solutions · Author: Abhinav Gautam",
},
},
});
35 changes: 35 additions & 0 deletions site/docs/.vitepress/shims/crypto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Minimal browser shim for Node's `crypto` — enough for cursor fingerprints.
// paginate() (search/sort/filter/pagination) never calls this.

function fnv1aHex(input) {
// 128-bit-ish hex by hashing the string four times with different seeds.
const seeds = [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x85ebca6b];
return seeds
.map((seed) => {
let h = seed >>> 0;
for (let i = 0; i < input.length; i++) {
h ^= input.codePointAt(i);
h = Math.imul(h, 0x01000193) >>> 0;
}
return ("00000000" + h.toString(16)).slice(-8);
})
.join("");
}

function createHash() {
let buffer = "";
return {
update(value) {
buffer += String(value);
return this;
},
digest() {
return fnv1aHex(buffer);
},
};
}

const cryptoShim = { createHash };

export { createHash };
export default cryptoShim;
Loading