1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { ValTownAPI } from 'https://esm.town/v/iamseeley/ValTownAPI';
import { GitHubAPI } from 'https://esm.town/v/iamseeley/GitHubAPI';
const VAL_TOWN_API_KEY = Deno.env.get('valtown');
const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN");
const GITHUB_REPO = "iamseeley/vals-backup";
const GITHUB_BRANCH = "main";
const valTownAPI = new ValTownAPI(VAL_TOWN_API_KEY);
const gitHubAPI = new GitHubAPI(GITHUB_TOKEN);
async function fetchVals() {
const response = await valTownAPI.getAllVals();
return response.data;
}
async function getExistingFiles() {
console.log(`Fetching existing files from repo: ${GITHUB_REPO}, branch: ${GITHUB_BRANCH}`);
try {
const response = await gitHubAPI.getRepoContent(GITHUB_REPO, "", GITHUB_BRANCH);
console.log("Existing files:", response);
return response.map(file => file.path);
} catch (error) {
console.error(`Error fetching repo content: ${error.message}`);
throw error;
}
}
async function getLastBackupDates() {
const files = await getExistingFiles();
const lastModifiedDates = {};
for (const file of files) {
const commitHistory = await gitHubAPI.getCommitHistory(GITHUB_REPO, file, GITHUB_BRANCH);
lastModifiedDates[file] = new Date(commitHistory[0].commit.committer.date).getTime();
}
return lastModifiedDates;
}
async function updateOrCreateFile(filePath, fileContent, commitMessage) {
const existingFiles = await getExistingFiles();
const fileExists = existingFiles.includes(filePath);
try {
if (fileExists) {
console.log(`File exists: ${filePath}`);
const shaResponse = await gitHubAPI.getRepoContent(GITHUB_REPO, filePath, GITHUB_BRANCH);
const sha = shaResponse.sha;
console.log(`Fetched SHA for ${filePath}: ${sha}`);
if (!sha) {
throw new Error(`Failed to fetch SHA for ${filePath}`);
}
await gitHubAPI.updateFile(GITHUB_REPO, filePath, fileContent, sha, commitMessage, GITHUB_BRANCH);
console.log(`File updated: ${filePath}`);
} else {
console.log(`File does not exist: ${filePath}`);
await gitHubAPI.createFile(GITHUB_REPO, filePath, fileContent, commitMessage, GITHUB_BRANCH);
console.log(`File created: ${filePath}`);
}
} catch (error) {
console.error(`Error creating/updating file ${filePath}: ${error.message}`);
console.error(error.stack);
if (error.message.includes('Unprocessable Entity')) {
console.error(`Check if the file path or content is incorrect for ${filePath}`);
}
throw error;
}
}
async function backupVals() {
const vals = await fetchVals();
const lastBackupDates = await getLastBackupDates();
const allValsDetails = [];
for (const val of vals) {
const valDir = val.name;
const valPath = `${valDir}/${val.name}.ts`;
const readmePath = `${valDir}/README.md`;
const valModifiedDate = new Date(val.updatedAt).getTime();
if (!lastBackupDates[valPath] || valModifiedDate > lastBackupDates[valPath]) {
const valCodeContent = val.code;
const readmeContent = val.readme || '';
const valDetails = {
name: val.name,
updatedAt: val.updatedAt,
readme: val.readme,
};
allValsDetails.push(valDetails);
await updateOrCreateFile(valPath, valCodeContent, `Update val: ${val.name}`);
await updateOrCreateFile(readmePath, readmeContent, `Update README: ${val.name}`);
}
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
June 14, 2024