mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-07-31 09:17:11 -04:00
137 lines
4.3 KiB
JavaScript
137 lines
4.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Generates password-generator defaults constants for all cross-platform clients.
|
|
*
|
|
* Input: core/models/src/defaults/PasswordGeneratorDefaults.ts
|
|
* Outputs:
|
|
* - core/rust/src/password_generator/defaults.rs (Rust)
|
|
* - apps/server/Databases/AliasClientDb/Models/PasswordGeneratorDefaults.cs (C#)
|
|
*
|
|
* Note: Typescript clients can import the constants directly from the distributed `@/utils/dist/core/models/vault`.
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const REPO_ROOT = path.join(__dirname, '../../..');
|
|
const TS_SOURCE = path.join(REPO_ROOT, 'core/models/src/defaults/PasswordGeneratorDefaults.ts');
|
|
const TS_SOURCE_REL = 'core/models/src/defaults/PasswordGeneratorDefaults.ts';
|
|
|
|
const RUST_OUTPUT = path.join(REPO_ROOT, 'core/rust/src/password_generator/defaults.rs');
|
|
const CS_OUTPUT = path.join(REPO_ROOT, 'apps/server/Databases/AliasClientDb/Models/PasswordGeneratorDefaults.cs');
|
|
|
|
/**
|
|
* Parse the `export const NAME = VALUE;` lines (each with its leading single-line
|
|
* JSDoc comment) out of the TypeScript source, preserving order.
|
|
*/
|
|
function parseConstants(source) {
|
|
const constants = [];
|
|
const lines = source.split('\n');
|
|
let pendingDoc = null;
|
|
|
|
for (const line of lines) {
|
|
const trimmed = line.trim();
|
|
|
|
// Single-line JSDoc comment: /** ... */
|
|
if (trimmed.startsWith('/**') && trimmed.endsWith('*/')) {
|
|
pendingDoc = trimmed.slice(3, -2).trim();
|
|
continue;
|
|
}
|
|
|
|
const constMatch = line.match(/^\s*export const ([A-Z0-9_]+)\s*=\s*(\d+)\s*;/);
|
|
if (constMatch) {
|
|
constants.push({
|
|
name: constMatch[1],
|
|
value: Number(constMatch[2]),
|
|
doc: pendingDoc || `${constMatch[1]}.`,
|
|
});
|
|
pendingDoc = null;
|
|
continue;
|
|
}
|
|
|
|
// Any other non-blank line resets a dangling doc comment.
|
|
if (line.trim() !== '') {
|
|
pendingDoc = null;
|
|
}
|
|
}
|
|
|
|
if (constants.length === 0) {
|
|
throw new Error(`No 'export const ... = <number>;' constants found in ${TS_SOURCE_REL}`);
|
|
}
|
|
return constants;
|
|
}
|
|
|
|
/** SCREAMING_SNAKE_CASE -> PascalCase (DEFAULT_PASSWORD_LENGTH -> DefaultPasswordLength). */
|
|
function toPascalCase(name) {
|
|
return name
|
|
.toLowerCase()
|
|
.split('_')
|
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
.join('');
|
|
}
|
|
|
|
function generateRust(constants) {
|
|
const header = `//! Client-facing defaults for the password/passphrase generator.
|
|
//!
|
|
//! @generated — do NOT edit this file directly. It is generated from
|
|
//! ${TS_SOURCE_REL} by core/models/scripts/generate-password-defaults.cjs.
|
|
//! Edit the TypeScript source and run 'core/models/build.sh' to regenerate.
|
|
`;
|
|
|
|
const body = constants
|
|
.map((c) => `/// ${c.doc}\npub const ${c.name}: u32 = ${c.value};`)
|
|
.join('\n\n');
|
|
|
|
return `${header}\n${body}\n`;
|
|
}
|
|
|
|
function generateCSharp(constants) {
|
|
const header = `// <auto-generated />
|
|
// This file is auto-generated from ${TS_SOURCE_REL}
|
|
// Do not edit this file directly. Run 'core/models/build.sh' (or
|
|
// 'node core/models/scripts/generate-password-defaults.cjs') to regenerate.
|
|
|
|
#nullable enable
|
|
|
|
namespace AliasClientDb.Models;
|
|
|
|
/// <summary>
|
|
/// Password generator defaults shared across all AliasVault clients.
|
|
/// </summary>
|
|
public static class PasswordGeneratorDefaults
|
|
{`;
|
|
|
|
const body = constants
|
|
.map((c) => {
|
|
const csName = toPascalCase(c.name);
|
|
return ` /// <summary>\n /// ${c.doc}\n /// </summary>\n public const int ${csName} = ${c.value};`;
|
|
})
|
|
.join('\n\n');
|
|
|
|
return `${header}\n${body}\n}\n`;
|
|
}
|
|
|
|
function writeIfChanged(filePath, contents) {
|
|
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null;
|
|
if (existing === contents) {
|
|
console.log(` ✓ up to date: ${path.relative(REPO_ROOT, filePath)}`);
|
|
return;
|
|
}
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
fs.writeFileSync(filePath, contents);
|
|
console.log(` ✎ wrote: ${path.relative(REPO_ROOT, filePath)}`);
|
|
}
|
|
|
|
function main() {
|
|
const source = fs.readFileSync(TS_SOURCE, 'utf8');
|
|
const constants = parseConstants(source);
|
|
|
|
console.log(`Generating password-generator defaults from ${TS_SOURCE_REL}:`);
|
|
console.log(` ${constants.map((c) => `${c.name}=${c.value}`).join(', ')}`);
|
|
|
|
writeIfChanged(RUST_OUTPUT, generateRust(constants));
|
|
writeIfChanged(CS_OUTPUT, generateCSharp(constants));
|
|
}
|
|
|
|
main();
|