initial transfer
This commit is contained in:
Vendored
+166
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Session management for saving and replaying deployments
|
||||
* @module nopy.session
|
||||
*/
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
/**
|
||||
* Saves a session to a JSON file
|
||||
*
|
||||
* @param session - The session to save
|
||||
* @param filePath - Path to save the session file
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* saveSession(session, './my-deployment.nopysession.json');
|
||||
* ```
|
||||
*/
|
||||
export function saveSession(session, filePath) {
|
||||
const sessionToSave = {
|
||||
...session,
|
||||
};
|
||||
const dir = path.dirname(filePath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(filePath, JSON.stringify(sessionToSave, null, 2), 'utf-8');
|
||||
}
|
||||
/**
|
||||
* Loads a session from an MJS file
|
||||
*
|
||||
* @param filePath - Path to the MJS session file
|
||||
* @returns The loaded session
|
||||
*/
|
||||
async function loadSessionFromMJS(filePath) {
|
||||
const absolutePath = path.resolve(filePath);
|
||||
const fileUrl = `file://${absolutePath}`;
|
||||
try {
|
||||
const module = (await import(fileUrl));
|
||||
const session = module.default;
|
||||
if (!session) {
|
||||
throw new Error('MJS file must export a default object');
|
||||
}
|
||||
return session;
|
||||
}
|
||||
catch (error) {
|
||||
throw new Error(`Failed to load MJS session: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Loads a session from a JSON file
|
||||
*
|
||||
* @param filePath - Path to the JSON session file
|
||||
* @returns The loaded session
|
||||
*/
|
||||
function loadSessionFromJSON(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
return JSON.parse(content);
|
||||
}
|
||||
/**
|
||||
* Loads a session from a JSON or MJS file
|
||||
*
|
||||
* @param filePath - Path to the session file (.json or .mjs)
|
||||
* @returns The loaded session
|
||||
* @throws Error if file not found or invalid format
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const session = await loadSession('./deployment.nopysession.json');
|
||||
* ```
|
||||
*/
|
||||
export async function loadSession(filePath) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`Session file not found: ${filePath}`);
|
||||
}
|
||||
const ext = path.extname(filePath);
|
||||
let session;
|
||||
if (ext === '.mjs') {
|
||||
session = await loadSessionFromMJS(filePath);
|
||||
}
|
||||
else if (ext === '.json') {
|
||||
session = loadSessionFromJSON(filePath);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unsupported session file format: ${ext}. Use .json or .mjs`);
|
||||
}
|
||||
// Validate required fields
|
||||
if (!session.cubes || !Array.isArray(session.cubes)) {
|
||||
throw new Error('Invalid session format: missing or invalid "cubes" field');
|
||||
}
|
||||
if (session.hosts && !Array.isArray(session.hosts)) {
|
||||
throw new Error('Invalid session format: invalid "hosts" field');
|
||||
}
|
||||
if (!session.auth) {
|
||||
throw new Error('Invalid session format: missing "auth" field');
|
||||
}
|
||||
return session;
|
||||
}
|
||||
/**
|
||||
* Lists all session files in a directory
|
||||
*
|
||||
* @param dirPath - Directory to search for session files
|
||||
* @returns Array of session file paths
|
||||
*/
|
||||
export function listSessions(dirPath = process.cwd()) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
return [];
|
||||
}
|
||||
const files = fs.readdirSync(dirPath);
|
||||
return files
|
||||
.filter((file) => file.endsWith('.session.json') || file.endsWith('.session.mjs'))
|
||||
.map((file) => path.join(dirPath, file));
|
||||
}
|
||||
/**
|
||||
* Creates a session object from runtime data
|
||||
*
|
||||
* @param params - Session parameters
|
||||
* @returns A NopySession object
|
||||
*/
|
||||
export function createSession(params) {
|
||||
return {
|
||||
name: params.name,
|
||||
cubes: params.cubes,
|
||||
hosts: params.hosts,
|
||||
auth: params.auth,
|
||||
env: params.env,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Filters out internal variables from cube variables
|
||||
*
|
||||
* Internal variables are those used by the prompts system
|
||||
* and should not be saved in session files.
|
||||
*
|
||||
* @param variables - Variables object
|
||||
* @returns Filtered variables without internal keys
|
||||
*/
|
||||
export function filterInternalVariables(variables) {
|
||||
const internalKeys = ['customize'];
|
||||
const filtered = {};
|
||||
for (const [key, value] of Object.entries(variables)) {
|
||||
if (!internalKeys.includes(key)) {
|
||||
filtered[key] = value;
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
/**
|
||||
* Separates environment variables from cube-specific variables
|
||||
*
|
||||
* @param allVariables - All variables including env and cube-specific
|
||||
* @param envVariables - Known environment variables from config
|
||||
* @returns Object with separate env and cube variables
|
||||
*/
|
||||
export function separateEnvAndCubeVariables(allVariables, envVariables) {
|
||||
const env = {};
|
||||
const cubeVars = {};
|
||||
for (const [key, value] of Object.entries(allVariables)) {
|
||||
if (key in envVariables) {
|
||||
env[key] = value;
|
||||
}
|
||||
else {
|
||||
cubeVars[key] = value;
|
||||
}
|
||||
}
|
||||
return { env, cubeVars };
|
||||
}
|
||||
Reference in New Issue
Block a user