This commit is contained in:
commit
854da073d4
15 files changed
+2885
No files matched your search
@@ -0,0 +1,100 @@
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
import path from 'node:path';
|
||||
|
||||
const dataDirectory = path.join(process.cwd(), 'data');
|
||||
const configPath = path.join(dataDirectory, 'config.json');
|
||||
|
||||
const defaultConfig = () => ({
|
||||
adminToken: randomBytes(24).toString('base64url'),
|
||||
settings: {
|
||||
corsOrigins: [],
|
||||
trustedProxyHops: 0
|
||||
},
|
||||
credentials: [],
|
||||
documents: [],
|
||||
publications: []
|
||||
});
|
||||
|
||||
function migrateConfig(config) {
|
||||
if (config.credentials) {
|
||||
return {
|
||||
...config,
|
||||
settings: {
|
||||
...config.settings,
|
||||
corsOrigins: config.settings?.corsOrigins || [],
|
||||
trustedProxyHops: Number(config.settings?.trustedProxyHops) || 0
|
||||
}
|
||||
};
|
||||
}
|
||||
const legacyCredential = config.google?.apiKey || config.google?.serviceAccountJson ? {
|
||||
id: crypto.randomUUID(),
|
||||
name: 'Imported Google connection',
|
||||
mode: config.google.mode,
|
||||
apiKey: config.google.apiKey,
|
||||
serviceAccountJson: config.google.serviceAccountJson,
|
||||
requestsPerMinute: config.google.requestsPerMinute || 45
|
||||
} : null;
|
||||
const documents = (config.publications || []).map((publication) => ({
|
||||
id: crypto.randomUUID(),
|
||||
name: publication.name,
|
||||
spreadsheetId: publication.spreadsheetId,
|
||||
credentialId: legacyCredential?.id || '',
|
||||
sheets: publication.sheets || []
|
||||
}));
|
||||
return {
|
||||
adminToken: config.adminToken,
|
||||
settings: { corsOrigins: [], trustedProxyHops: 0 },
|
||||
credentials: legacyCredential ? [legacyCredential] : [],
|
||||
documents,
|
||||
publications: (config.publications || []).map((publication, index) => ({
|
||||
id: publication.id,
|
||||
name: publication.name,
|
||||
documentId: documents[index].id,
|
||||
sheets: publication.sheets || [],
|
||||
apiToken: publication.apiToken,
|
||||
cacheSeconds: config.google?.cacheSeconds || 30
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
export async function loadConfig() {
|
||||
try {
|
||||
const config = migrateConfig(JSON.parse(await readFile(configPath, 'utf8')));
|
||||
await saveConfig(config);
|
||||
return config;
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') throw error;
|
||||
const config = defaultConfig();
|
||||
await saveConfig(config);
|
||||
console.log(`Created admin token: ${config.adminToken}`);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveConfig(config) {
|
||||
await mkdir(dataDirectory, { recursive: true });
|
||||
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
|
||||
}
|
||||
|
||||
export function publicConfig(config) {
|
||||
return {
|
||||
settings: config.settings,
|
||||
credentials: config.credentials.map(({ apiKey, serviceAccountJson, ...credential }) => ({
|
||||
...credential,
|
||||
configured: credential.mode === 'apiKey' ? Boolean(apiKey) : Boolean(serviceAccountJson)
|
||||
})),
|
||||
documents: config.documents,
|
||||
publications: config.publications.map(({ apiToken, ...publication }) => ({
|
||||
...publication,
|
||||
dataFormat: publication.dataFormat || 'rows',
|
||||
range: publication.range || '',
|
||||
omitBlankRows: Boolean(publication.omitBlankRows),
|
||||
maxRows: Math.max(1, Math.min(100_000, Number(publication.maxRows) || 10_000)),
|
||||
consumerRequestsPerMinute: Math.max(1, Number(publication.consumerRequestsPerMinute) || 120),
|
||||
scheduledRefresh: Boolean(publication.scheduledRefresh),
|
||||
enabled: publication.enabled !== false,
|
||||
tokenConfigured: Boolean(apiToken)
|
||||
}))
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user