human (Oct 27, 2024, 08:57 PM)
Write an artifact - no React - that uses fetch() against the GitHub Gist API to create a Gist containing JSON from a textarea on the page
assistant (Oct 27, 2024, 08:57 PM)
I'll help create a simple HTML/JavaScript interface for creating GitHub Gists.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Gist Creator</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
max-width: 800px;
margin: 2rem auto;
padding: 0 1rem;
}
.container {
background-color: #f8f9fa;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
textarea {
width: 100%;
min-height: 200px;
margin: 1rem 0;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
}
input[type="text"] {
width: 100%;
padding: 0.5rem;
margin: 0.5rem 0;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: #2ea44f;
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
}
button:disabled {
background-color: #94d3a2;
cursor: not-allowed;
}
.error {
color: #dc3545;
margin-top: 1rem;
}
.success {
color: #28a745;
margin-top: 1rem;
}
#result {
margin-top: 1rem;
word-break: break-all;
}
</style>
</head>
<body>
<div class="container">
<h1>GitHub Gist Creator</h1>
<div>
<label for="token">GitHub Personal Access Token:</label>
<input type="text" id="token" placeholder="ghp_your_token_here" />
<small>Need a token? <a href="https://github.com/settings/tokens" target="_blank">Create one here</a> with gist scope.</small>
</div>
<div>
<label for="filename">Filename (including .json extension):</label>
<input type="text" id="filename" placeholder="example.json" value="gist.json" />
</div>
<div>
<label for="description">Gist Description:</label>
<input type="text" id="description" placeholder="My JSON Gist" />
</div>
<div>
<label for="content">JSON Content:</label>
<textarea id="content" placeholder='{"example": "Enter your JSON here"}'></textarea>
</div>
<button onclick="createGist()" id="submit-btn">Create Gist</button>
<div id="result"></div>
</div>
<script>
async function createGist() {
const token = document.getElementById('token').value.trim();
const filename = document.getElementById('filename').value.trim();
const description = document.getElementById('description').value.trim();
let content = document.getElementById('content').value.trim();
const resultDiv = document.getElementById('result');
const submitBtn = document.getElementById('submit-btn');
// Basic validation
if (!token) {
resultDiv.innerHTML = '<div class="error">Please enter a GitHub token</div>';
return;
}
if (!filename) {
resultDiv.innerHTML = '<div class="error">Please enter a filename</div>';
return;
}
if (!content) {
resultDiv.innerHTML = '<div class="error">Please enter some JSON content</div>';
return;
}
// Validate JSON
try {
// Try to parse and then stringify to ensure proper formatting
content = JSON.stringify(JSON.parse(content), null, 2);
} catch (e) {
resultDiv.innerHTML = '<div class="error">Invalid JSON: ' + e.message + '</div>';
return;
}
// Prepare the request
const gistData = {
description: description,
public: true,
files: {
[filename]: {
content: content
}
}
};
// Disable button during request
submitBtn.disabled = true;
resultDiv.innerHTML = 'Creating gist...';
try {
const response = await fetch('https://api.github.com/gists', {
method: 'POST',
headers: {
'Accept': 'application/vnd.github.v3+json',
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(gistData)
});
const data = await response.json();
if (response.ok) {
resultDiv.innerHTML = `
<div class="success">
Gist created successfully!<br>
<a href="${data.html_url}" target="_blank">View your gist</a><br>
Raw URL: <a href="${data.files[filename].raw_url}" target="_blank">${data.files[filename].raw_url}</a>
</div>
`;
} else {
throw new Error(data.message || 'Failed to create gist');
}
} catch (error) {
resultDiv.innerHTML = `<div class="error">Error: ${error.message}</div>`;
} finally {
submitBtn.disabled = false;
}
}
// Add example JSON to textarea on page load
document.getElementById('content').value = JSON.stringify({
"example": "value",
"numbers": [1, 2, 3],
"nested": {
"key": "value"
}
}, null, 2);
</script>
</body>
</html>
I've created a standalone HTML page that provides a simple interface for creating GitHub Gists containing JSON content. Here are the key features:
-
Input fields for:
- GitHub Personal Access Token (required for authentication)
- Filename (defaults to gist.json)
- Gist description (optional)
- JSON content (with a pre-filled example)
-
Functionality:
- JSON validation before submission
- Pretty-printing of JSON input
- Error handling for invalid JSON and API errors
- Success feedback with links to both the Gist and raw JSON
- Disabled button state during API calls
-
Security considerations:
- The token is never stored
- Uses the GitHub API v3
- Uses Bearer token authentication
To use this, you'll need to:
- Create a GitHub Personal Access Token with the
gist
scope at https://github.com/settings/tokens - Enter your token in the input field
- Modify the JSON content as needed
- Click "Create Gist"
The page includes some basic styling and error handling to make it user-friendly. Would you like me to explain any particular part of the implementation or make any modifications?
human (Oct 27, 2024, 09:07 PM)
Use public: false and turn this into an async function which accepts the description and an object of {filename: content} and a PAT and returns the object from the response
assistant (Oct 27, 2024, 09:07 PM)
I'll modify the code to create a reusable async function for creating private Gists.
/**
* Creates a private GitHub Gist
* @param {string} description - Gist description
* @param {Object.<string, string>} files - Object with filenames as keys and content as values
* @param {string} token - GitHub Personal Access Token with gist scope
* @returns {Promise<Object>} - GitHub Gist API response object
* @throws {Error} - If the API request fails
*/
async function createPrivateGist(description, files, token) {
if (!token) {
throw new Error('GitHub token is required');
}
if (!files || Object.keys(files).length === 0) {
throw new Error('At least one file is required');
}
// Transform the files object into the format expected by GitHub's API
const gistFiles = Object.entries(files).reduce((acc, [filename, content]) => {
acc[filename] = { content };
return acc;
}, {});
const gistData = {
description: description || '',
public: false,
files: gistFiles
};
const response = await fetch('https://api.github.com/gists', {
method: 'POST',
headers: {
'Accept': 'application/vnd.github.v3+json',
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(gistData)
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || `Failed to create gist: ${response.status}`);
}
return data;
}
// Example usage:
/*
const files = {
'example.json': JSON.stringify({ key: 'value' }, null, 2),
'data.json': JSON.stringify({ numbers: [1, 2, 3] }, null, 2)
};
try {
const gist = await createPrivateGist(
'My private gist description',
files,
'ghp_your_token_here'
);
console.log('Gist URL:', gist.html_url);
console.log('Raw URLs:', Object.entries(gist.files).reduce((acc, [filename, file]) => {
acc[filename] = file.raw_url;
return acc;
}, {}));
} catch (error) {
console.error('Error creating gist:', error.message);
}
*/
I've created a reusable async function that:
-
Takes three parameters:
description
(string) - The Gist descriptionfiles
(object) - Key-value pairs of filename to contenttoken
(string) - GitHub Personal Access Token
-
Returns:
- The complete Gist object from GitHub's API response
- Contains URLs, file info, and other metadata
-
Includes:
- Input validation
- Error handling
- TypeScript-style JSDoc comments
- Example usage commented out at the bottom
You can use it like this:
const result = await createPrivateGist(
'My API Data',
{
'data.json': JSON.stringify({ hello: 'world' }, null, 2)
},
'your_github_token'
);
console.log(result.html_url); // https://gist.github.com/...
console.log(result.files['data.json'].raw_url); // Raw file URL
The function will throw an error if:
- No token is provided
- No files are provided
- The API request fails
Would you like me to modify anything about the implementation?
Here's the UI it made me: https://gistpreview.github.io/?310c557dbb664a7a5cdf3593fd4d7256