Skip to content

[pull] main from pages-cms:main #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 106 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
ade52dd
Adding the Resend Platform Email Configuration
putuwahyu29 Jan 30, 2025
3d89b66
Update Readme
putuwahyu29 Jan 30, 2025
2b01920
Dealing with null value in collection views
hunvreus Feb 10, 2025
75a799f
Making sure branches are encoded in URLs and API calls (#145)
hunvreus Feb 10, 2025
3b735b0
Fixing bug with githubImage service
hunvreus Feb 10, 2025
814e760
Fixing more branch URLs
hunvreus Feb 10, 2025
56c5a83
Fixing more branch URLs
hunvreus Feb 10, 2025
ee4e324
Staring work on reference and autocomplete
hunvreus Feb 12, 2025
ab6646a
Fix collection view
ryangittings Feb 21, 2025
accc740
Improve repo permissions
ryangittings Feb 21, 2025
77a607f
added custom field to auto-generate a uuid
AndrewMonty Feb 22, 2025
fe53b24
move field to core
AndrewMonty Feb 22, 2025
b0d5a02
Fixes
ryangittings Mar 4, 2025
45996ef
Fix list defaults
ryangittings Mar 4, 2025
2cbdde8
Fix
ryangittings Mar 5, 2025
4c36782
Merge pull request #186 from gittingsstudio/patch/rich-text-bug
hunvreus Mar 8, 2025
47a460f
Merge pull request #182 from gittingsstudio/patch/exclude-folder
hunvreus Mar 8, 2025
3dac3a8
New select field (WIP)
hunvreus Mar 8, 2025
a6ab647
Added options and cleaned up PR
hunvreus Mar 8, 2025
9871a92
Merge branch 'pr-167' into development
hunvreus Mar 8, 2025
189addf
Merge pull request #144 from putuwahyu29/main
hunvreus Mar 9, 2025
79161ab
Merge pull request #174 from gittingsstudio/patch/hide-hidden-collect…
hunvreus Mar 9, 2025
4ea5dd9
Merge pull request #173 from gittingsstudio/patch/repo-permissions
hunvreus Mar 9, 2025
a6c2b7c
Fixes
ryangittings Mar 10, 2025
7240685
Fixes
ryangittings Mar 10, 2025
58c61f5
Fixes
ryangittings Mar 10, 2025
0d2c996
Merge pull request #183 from gittingsstudio/patch/list-defaults
hunvreus Mar 11, 2025
600e407
Working fetch on new select field
hunvreus Mar 11, 2025
292180e
Adding templates for value and label
hunvreus Mar 11, 2025
970960f
Polished animations, fixed validation of multiple fields
hunvreus Mar 11, 2025
4ac54a7
Working proof of concept for caching and Reference field
hunvreus Mar 14, 2025
da1676b
Adding comments on API endpoints
hunvreus Mar 14, 2025
7d011ef
Updating cache on individual file operations
hunvreus Mar 14, 2025
e65f8a3
Cleaning up and testing migration
hunvreus Mar 14, 2025
028cf64
Resolving merge conflict
hunvreus Mar 14, 2025
a27934e
Fixed validation for reference
hunvreus Mar 14, 2025
877078a
Adding custm icons
hunvreus Mar 14, 2025
9e118cb
Adding contributing guidelines
hunvreus Mar 14, 2025
f50d5e8
Fixing #177
hunvreus Mar 14, 2025
ecda219
Fixing handling of frontmatter for json-frontmatter, remove Lucide ic…
hunvreus Mar 14, 2025
631f484
Adding comments
hunvreus Mar 15, 2025
13605fb
First version of the file field
hunvreus Mar 15, 2025
bb4a7b1
Removing unused RHF helpers
hunvreus Mar 15, 2025
f9f92d0
Removing unused RHF helpers
hunvreus Mar 15, 2025
350b242
Adding support for multiple media
hunvreus Mar 16, 2025
742ffe3
Refining caching
hunvreus Mar 17, 2025
9788260
Adding back media page
hunvreus Mar 17, 2025
9af99ee
Refined cache strategy
hunvreus Mar 17, 2025
12188f4
Refined cache strategy
hunvreus Mar 17, 2025
d722b29
Fixing error with githubImage
hunvreus Mar 17, 2025
0f6c575
Adding migration snapshot
hunvreus Mar 17, 2025
e247ddb
Fixing file caching
hunvreus Mar 17, 2025
1c8a106
Cleaning up drizzle migrations, updating schema for cache (naming, in…
hunvreus Mar 18, 2025
bf91084
Removing _journal.json from git
hunvreus Mar 18, 2025
d9e5325
Fixing image issues in rich-text?
hunvreus Mar 18, 2025
7f87ce9
Fixing media
hunvreus Mar 18, 2025
796ccbd
Fixing collections api
hunvreus Mar 18, 2025
076bee0
Adding back drizzle journal
hunvreus Mar 18, 2025
eccc245
Adding proper extensions logic to fiel field and media components
hunvreus Mar 18, 2025
818cd16
Adding drag and drop support for uploading files
hunvreus Mar 19, 2025
a94f1f3
Adding file extensions validation on drag and drop
hunvreus Mar 19, 2025
38352bf
Updating read/write functions to account for new media config
hunvreus Mar 19, 2025
bc8b8e6
Fixing scroll bug on media dialog
hunvreus Mar 19, 2025
d2e05fe
Cleaning up
hunvreus Mar 19, 2025
a17d44e
Cleaning up debug code
hunvreus Mar 19, 2025
77c4f0d
Quick fix for single images
hunvreus Mar 19, 2025
8425165
Fixing options
hunvreus Mar 19, 2025
ff5e2a6
Fixing folders not showing up on collections
hunvreus Mar 19, 2025
a7ee57c
Adding restriction on subfolders
hunvreus Mar 19, 2025
9c13612
Moving migrations to post build step
hunvreus Mar 20, 2025
d8cdd0d
Debugging caching in development
hunvreus Mar 20, 2025
abed723
Removing debugging code
hunvreus Mar 20, 2025
1d87730
Minor bug fixes
hunvreus Mar 20, 2025
0f2156a
Cleaning up reference search
hunvreus Mar 20, 2025
4fac287
Fixing options on text field (#202)
hunvreus Mar 20, 2025
ac3fcbd
Updating contributing guidelines
hunvreus Mar 20, 2025
331182f
Moving history tracking to client
hunvreus Mar 21, 2025
ab9a5b6
Testing forced prefetch
hunvreus Mar 21, 2025
59b4c83
Adding ALT button on images in rich-text
hunvreus Mar 21, 2025
ac9f586
Bug with overloaded date
hunvreus Mar 21, 2025
a6f9d1b
Adding prefetch
hunvreus Mar 21, 2025
6b83318
Adding prefetch
hunvreus Mar 21, 2025
b92707f
Added file AND permission cache tables, updated webhook rules for ALL…
hunvreus Mar 22, 2025
ea396e2
Adding permission cache table
hunvreus Mar 22, 2025
9a2a2ab
Adding cache access check with simple caching
hunvreus Mar 22, 2025
b1f80d4
Adding info in README
hunvreus Mar 22, 2025
6f6cd20
Adding cache expiration for content
hunvreus Mar 22, 2025
29ac0c7
Merge pull request #209 from pages-cms/feature/cache
hunvreus Mar 22, 2025
078d360
Fixing bug with case sensitivity on owner/repo in webhook and cache
hunvreus Mar 22, 2025
b93b03a
Merge pull request #210 from pages-cms/development
hunvreus Mar 26, 2025
1275162
hotfix: add detailed error logging for webhook handler
hunvreus Mar 26, 2025
eb7df94
hotfix: webhook errors
hunvreus Mar 26, 2025
ff58c6c
hotfix: webhook errors
hunvreus Mar 26, 2025
5a74917
Linking to Discord chat
hunvreus Mar 26, 2025
ced341e
Fixing RESEND env vars
hunvreus Mar 26, 2025
aff9110
Removing GitHub profile link for collaborators
hunvreus Mar 26, 2025
b0f9eb7
Removing old.select
hunvreus Mar 27, 2025
ec643a8
Fixing media prefix swap issues
hunvreus Mar 27, 2025
f6b0331
Remove debugging messages
hunvreus Mar 27, 2025
1309f0d
Add number buttons component
Meldiron Mar 28, 2025
d413313
Fix redirect URL for GitHub app management
Meldiron Mar 29, 2025
c6596fd
Remove unwanted changes
Meldiron Mar 29, 2025
26df50b
Adding default routing for media, fixing media upload bugs and fixing…
hunvreus Mar 30, 2025
67b1505
Merge pull request #220 from Meldiron/fix-manage-redirect
hunvreus Apr 15, 2025
a740658
Revert "Merge pull request #220 from Meldiron/fix-manage-redirect"
hunvreus Apr 15, 2025
ee59a71
Fix upload bug
hunvreus Apr 15, 2025
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
4 changes: 3 additions & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ xxx
GITHUB_APP_WEBHOOK_SECRET="another-random-string-of-characters"
GITHUB_APP_CLIENT_ID="your-github-app-client-id"
GITHUB_APP_CLIENT_SECRET="your-github-app-client-secret"
RESEND_DOMAIN_EMAIL ="your-domain-email"
RESEND_API_KEY="your-resend-api-key"
SQLITE_URL="file:./local.db"
# SQLITE_AUTH_TOKEN=""
# BASE_URL="https://mycustomdomain.com"
# BASE_URL="https://mycustomdomain.com"
# PERMISSION_CACHE_TTL="60"
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

# local sqlite db
# Database
local.db
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Contributing to Pages CMS

- Submit pull requests (PRs) against the `development` branch, not `main`.
- For branches, we have:
- `main` is our production and default branch. This is what we deploy to https://app.pagescms.org.
- `development` is for staging. We deploy it at https://dev.pagescms.org.
- New features are worked in `feature/name-of-the-feature` branches.
- Issues are addressed in `issue/123-main-isse` branches.
- When ready, we PR against `development`, test it and then finally merge to `main`.
- Keep changes focused: one feature or fix per PR.
- Test locally before submitting.
- Follow existing code style.

Thanks for helping!
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ It offers a user-friendly interface to edit the content of your website or app d

Go to [pagescms.org/docs](https://pagescms.org/docs).

## Community chat

[Join the Discord server](https://pagescms.org/chat) to get help with Pages CMS, share feedback, and connect with other users building with the platform.

## Built with

- [Next.js](https://nextjs.org/)
Expand Down Expand Up @@ -71,7 +75,9 @@ You will need to fill in the following information:
- Account permissions: nothing.
- **Subscribe to events**:
- Installation target
- Repository (you'll probably need to add this after creating the GitHub App)
- Repository
- Push
- Delete
- **Where can this GitHub App be installed?**: you'll want to select "Any account" unless you intend to only use Pages CMS on the account this GitHub App is created under.

### Environment variables
Expand All @@ -85,10 +91,14 @@ Variable | Comments
`GITHUB_APP_WEBHOOK_SECRET` | The secret you picked for your webhook. This is used to ensure the request is coming from GitHub.
`GITHUB_APP_CLIENT_ID` | GitHub App Client ID from your GitHub App details page.
`GITHUB_APP_CLIENT_SECRET` | GitHub App Client Secret you generate on theGitHub App details page.
`RESEND_FROM_EMAIL` | The sender for authentication emails. Must be a verified domain in your Resend account and follow the format `[email protected]` or `Name <[email protected]>`.
`RESEND_API_KEY` | You'll get that when you create a (free) [Resend](https://resend.com) account to handle emails.
`SQLITE_URL` | `file:./local.db` for development, `libsql://pages-cms-username.turso.io` for example if you use [Turso](https://turso.tech) (you should, Turso is great).
`SQLITE_AUTH_TOKEN` | Leave blank for development, otherwise use the token provided by [Turso](https://turso.tech) (if that's what you use).
`BASE_URL` | **OPTIONAL**. If you're deploying to Vercel or working locally, you won't need that. If you're deploying elsewhere, you'll need to specify the base URL for the app (e.g. `https://mycustomdomain.com`).
`FILE_CACHE_TTL` | **OPTIONAL**. Time to live (in minutes) for file cache (collections and
media folders). Defaults to 10080 (7 days). Set to "-1" to prevent the cache from ever expiring, or "0" if you want no cache.
`PERMISSION_CACHE_TTL` | **OPTIONAL**. Time to live (in minutes) for the permission cache, which controls access to file cache. Defaults to 60. Set to "0" if you want to always check permissions against the GitHub API.

### Local development

Expand Down
2 changes: 0 additions & 2 deletions app/(main)/[owner]/[repo]/[branch]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { ConfigProvider } from "@/contexts/config-context";
import { RepoLayout } from "@/components/repo/repo-layout";
import { EmptyCreate } from "@/components/empty-create";
import { Message } from "@/components/message";
import { Tracker } from "@/components/tracker";

export default async function Layout({
children,
Expand Down Expand Up @@ -107,7 +106,6 @@ export default async function Layout({

return (
<ConfigProvider value={config}>
<Tracker owner={owner} repo={repo} branch={branch} />
<RepoLayout>{errorMessage ? errorMessage : children}</RepoLayout>
</ConfigProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@
import { useSearchParams } from "next/navigation";
import { useConfig } from "@/contexts/config-context";
import { MediaView} from "@/components/media/media-view";
import { Message } from "@/components/message";

export default function Page() {
export default function Page({
params
}: {
params: {
name: string;
}
}) {
const searchParams = useSearchParams();
const path = searchParams.get("path") || "";

const { config } = useConfig();
if (!config) throw new Error(`Configuration not found.`);

return (
<div className="max-w-screen-xl mx-auto flex-1 flex flex-col h-full">
<header className="flex items-center mb-6">
<h1 className="font-semibold text-lg md:text-2xl">Media</h1>
</header>
<div className="flex flex-col relative flex-1">
<MediaView initialPath={path}/>
<MediaView initialPath={path} media={params.name} />
</div>
</div>
);
Expand Down
8 changes: 4 additions & 4 deletions app/(main)/[owner]/[repo]/[branch]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export default function Page() {

useEffect(() => {
if (config?.object.content?.[0]) {
router.replace(`/${config.owner}/${config.repo}/${config.branch}/${config.object.content[0].type}/${config.object.content[0].name}`);
router.replace(`/${config.owner}/${config.repo}/${encodeURIComponent(config.branch)}/${config.object.content[0].type}/${config.object.content[0].name}`);
} else if (config?.object.media) {
router.replace(`/${config.owner}/${config.repo}/${config.branch}/media`);
router.replace(`/${config.owner}/${config.repo}/${encodeURIComponent(config.branch)}/media/${config.object.media[0].name}`);
} else if (config?.object.settings !== false) {
router.replace(`/${config?.owner}/${config?.repo}/${config?.branch}/settings`);
router.replace(`/${config?.owner}/${config?.repo}/${encodeURIComponent(config!.branch)}/settings`);
} else {
setError(true);
}
Expand All @@ -28,7 +28,7 @@ export default function Page() {
description={<>This branch and/or repository has no configuration and settings are disabled. Edit on GitHub if you think this is a mistake.</>}
className="absolute inset-0"
cta="Edit configuration on GitHub"
href={`https://github.com/${config?.owner}/${config?.repo}/edit/${config?.branch}/.pages.yml`}
href={`https://github.com/${config?.owner}/${config?.repo}/edit/${encodeURIComponent(config!.branch)}/.pages.yml`}
/>
: null;
}
2 changes: 1 addition & 1 deletion app/(main)/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default async function Page() {
return (
<MainRootLayout>
<div className="max-w-screen-sm mx-auto p-4 md:p-6 space-y-6">
<Link className={cn(buttonVariants({ variant: "outline", size: "xs" }), "inline-flex")} href="/">
<Link className={cn(buttonVariants({ variant: "outline", size: "xs" }), "inline-flex")} href="/" prefetch={true}>
<ArrowLeft className="h-4 w-4 mr-1.5" />
Go home
</Link>
Expand Down
10 changes: 9 additions & 1 deletion app/api/[owner]/[repo]/[branch]/branches/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import { createOctokitInstance } from "@/lib/utils/octokit";
import { getAuth } from "@/lib/auth";
import { getToken } from "@/lib/token";

/**
* Creates a new branch in a GitHub repository.
*
* POST /api/[owner]/[repo]/[branch]/branches
*
* Requires authentication.
*/

export async function POST(
request: Request,
{ params }: { params: { owner: string, repo: string, branch: string } }
Expand All @@ -18,7 +26,7 @@ export async function POST(

const octokit = createOctokitInstance(token);

// Get the SHA of the branch we"re creating the new branch from
// Get the SHA of the branch we're creating the new branch from
const { data: refData } = await octokit.rest.git.getRef({
owner: params.owner,
repo: params.repo,
Expand Down
108 changes: 70 additions & 38 deletions app/api/[owner]/[repo]/[branch]/collections/[name]/route.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
export const maxDuration = 30;

import { type NextRequest } from "next/server";
import { createOctokitInstance } from "@/lib/utils/octokit"
import { readFns } from "@/fields/registry";
import { parse } from "@/lib/serialization";
import { deepMap, getDateFromFilename, getSchemaByName } from "@/lib/schema";
import { deepMap, getDateFromFilename, getSchemaByName, safeAccess } from "@/lib/schema";
import { getConfig } from "@/lib/utils/config";
import { normalizePath } from "@/lib/utils/file";
import { getAuth } from "@/lib/auth";
import { getToken } from "@/lib/token";
import { getCollectionCache, checkRepoAccess } from "@/lib/githubCache";

/**
* Fetches and parses collection contents from GitHub repositories
* (for collection views and searches)
*
* GET /api/[owner]/[repo]/[branch]/collections/[name]
*
* Requires authentication. If type is set to "search", we filter the contents
* based on the query and fields parameters.
*/

export async function GET(
request: NextRequest,
Expand All @@ -21,6 +31,11 @@ export async function GET(
const token = await getToken(user, params.owner, params.repo);
if (!token) throw new Error("Token not found");

if (user.githubId) {
const hasAccess = await checkRepoAccess(token, params.owner, params.repo, user.githubId);
if (!hasAccess) throw new Error(`No access to repository ${params.owner}/${params.repo}.`);
}

const config = await getConfig(params.owner, params.repo, params.branch);
if (!config) throw new Error(`Configuration not found for ${params.owner}/${params.repo}/${params.branch}.`);

Expand All @@ -29,48 +44,64 @@ export async function GET(

const searchParams = request.nextUrl.searchParams;
const path = searchParams.get("path") || "";
const type = searchParams.get("type");
const query = searchParams.get("query") || "";
const fields = searchParams.get("fields")?.split(",") || ["name"];

const normalizedPath = normalizePath(path);
if (!normalizedPath.startsWith(schema.path)) throw new Error(`Invalid path "${path}" for collection "${params.name}".`);

const octokit = createOctokitInstance(token);
const query = `
query ($owner: String!, $repo: String!, $expression: String!) {
repository(owner: $owner, name: $repo) {
object(expression: $expression) {
... on Tree {
entries {
name
path
type
object {
... on Blob {
text
oid
}
}
}
}
}
}
}
`;
const expression = `${params.branch}:${normalizedPath}`;
const response: any = await octokit.graphql(query, { owner: params.owner, repo: params.repo, expression });
// TODO: handle 401 / Bad credentials error

const entries = response.repository?.object?.entries;

if (entries === undefined) throw new Error("Not found");
if (schema.subfolders === false) {
if (normalizedPath !== schema.path) throw new Error(`Invalid path "${path}" for collection "${params.name}".`);
}

let entries = await getCollectionCache(params.owner, params.repo, params.branch, normalizedPath, token);

let data: {
contents: Record<string, any>[],
errors: string[]
} = {
contents: [],
errors: []
};

if (entries) {
data = parseContents(entries, schema, config);

// If this is a search request, filter the contents
if (type === "search" && query) {
const searchQuery = query.toLowerCase();
const searchFields = Array.isArray(fields) ? fields : fields ? [fields] : [];

data.contents = data.contents.filter(item => {
if (searchFields.length === 0) {
if (
(item.name && item.name.toLowerCase().includes(searchQuery)) ||
(item.path && item.path.toLowerCase().includes(searchQuery))
) {
return true;
}

if (entries) data = parseContents(entries, schema, config);
return item.content && item.content.toLowerCase().includes(searchQuery);
}

return searchFields.some(field => {
if (field === 'name' || field === 'path') {
const value = item[field];
return value && String(value).toLowerCase().includes(searchQuery);
}

if (field.startsWith('fields.')) {
const fieldPath = field.replace('fields.', '');
const value = safeAccess(item.fields, fieldPath);
return value && String(value).toLowerCase().includes(searchQuery);
}

return false;
});
});
}
}

return Response.json({
status: "success",
Expand All @@ -85,6 +116,7 @@ export async function GET(
}
}

// Parse the list of entries into objects based on the content schema.
const parseContents = (
contents: any,
schema: Record<string, any>,
Expand All @@ -101,13 +133,13 @@ const parseContents = (

parsedContents = contents.map((item: any) => {
// If it's a file and it matches the schema extension
if (item.type === "blob" && (item.path.endsWith(`.${schema.extension}`) || schema.extension === "") && !excludedFiles.includes(item.name)) {
if (item.type === "file" && (item.path.endsWith(`.${schema.extension}`) || schema.extension === "") && !excludedFiles.includes(item.name)) {
let contentObject: Record<string, any> = {};

if (serializedTypes.includes(schema.format) && schema.fields) {
// If we are dealing with a serialized format and we have fields defined
try {
contentObject = parse(item.object.text, { format: schema.format, delimiters: schema.delimiters });
contentObject = parse(item.content, { format: schema.format, delimiters: schema.delimiters });
contentObject = deepMap(contentObject, schema.fields, (value, field) => readFns[field.type] ? readFns[field.type](value, field, config) : value);
} catch (error: any) {
// TODO: send this to the client?
Expand All @@ -132,14 +164,14 @@ const parseContents = (
}
// TODO: handle proper returns
return {
sha: item.object.oid,
sha: item.sha,
name: item.name,
path: item.path,
content: item.object.text,
object: contentObject,
content: item.content,
fields: contentObject,
type: "file",
};
} else if (item.type === "tree") {
} else if (item.type === "dir" && !excludedFiles.includes(item.name) && schema.subfolders !== false) {
return {
name: item.name,
path: item.path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import { getFileExtension, normalizePath } from "@/lib/utils/file";
import { getAuth } from "@/lib/auth";
import { getToken } from "@/lib/token";

/**
* Fetches the history of a file from GitHub repositories.
*
* GET /api/[owner]/[repo]/[branch]/entries/[path]/history
*
* Requires authentication.
*/

export async function GET(
request: NextRequest,
{ params }: { params: { owner: string, repo: string, branch: string, path: string } }
Expand Down
11 changes: 11 additions & 0 deletions app/api/[owner]/[repo]/[branch]/entries/[path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import { getFileExtension, normalizePath } from "@/lib/utils/file";
import { getAuth } from "@/lib/auth";
import { getToken } from "@/lib/token";

/**
* Fetches and parses individual file contents from GitHub repositories
* (usually for editing).
*
* GET /api/[owner]/[repo]/[branch]/entries/[path]?name=[schemaName]
*
* Requires authentication. If no schema name is provided, we return the raw
* contents.
*/

export async function GET(
request: NextRequest,
{ params }: { params: { owner: string, repo: string, branch: string, path: string } }
Expand Down Expand Up @@ -80,6 +90,7 @@ export async function GET(
}
}

// Parse the entry into an object based on the content schema.
const parseContent = (
content: string,
schema: Record<string, any>,
Expand Down
Loading