Phase 1: Add ESLint/Prettier config + baseline auto-fixes
This commit is contained in:
@@ -42,7 +42,7 @@ module.exports = function(ctx) {
|
||||
await ctx.docker.client.createNetwork({
|
||||
Name: networkName,
|
||||
Driver: recipe.network.driver || 'bridge',
|
||||
Labels: { 'sami.managed': 'true', 'sami.recipe': recipeId }
|
||||
Labels: { 'sami.managed': 'true', 'sami.recipe': recipeId },
|
||||
});
|
||||
ctx.log.info('recipe', 'Created Docker network', { networkName });
|
||||
} catch (e) {
|
||||
@@ -62,18 +62,18 @@ module.exports = function(ctx) {
|
||||
try {
|
||||
ctx.log.info('recipe', `Deploying component: ${component.id}`, {
|
||||
role: component.role,
|
||||
internal: component.internal || false
|
||||
internal: component.internal || false,
|
||||
});
|
||||
|
||||
const result = await deployComponent(component, recipe, config, generatedPasswords, networkName);
|
||||
deployedComponents.push(result);
|
||||
|
||||
ctx.log.info('recipe', `Component deployed: ${component.id}`, {
|
||||
containerId: result.containerId?.substring(0, 12)
|
||||
containerId: result.containerId?.substring(0, 12),
|
||||
});
|
||||
} catch (componentError) {
|
||||
ctx.log.error('recipe', `Component failed: ${component.id}`, {
|
||||
error: componentError.message
|
||||
error: componentError.message,
|
||||
});
|
||||
errors.push({ componentId: component.id, role: component.role, error: componentError.message });
|
||||
// Continue deploying other components — partial success is better than total failure
|
||||
@@ -96,7 +96,7 @@ module.exports = function(ctx) {
|
||||
recipeId: recipeId,
|
||||
recipeRole: deployed.role,
|
||||
tailscaleOnly: config.sharedConfig?.tailscaleOnly || false,
|
||||
deployedAt: new Date().toISOString()
|
||||
deployedAt: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -119,18 +119,18 @@ module.exports = function(ctx) {
|
||||
role: c.role,
|
||||
containerId: c.containerId?.substring(0, 12),
|
||||
url: c.url,
|
||||
internal: c.internal
|
||||
internal: c.internal,
|
||||
})),
|
||||
errors: errors.length > 0 ? errors : undefined,
|
||||
message: errors.length > 0
|
||||
? `${recipe.name} partially deployed (${deployedComponents.length}/${componentsToDeploy.length} components)`
|
||||
: `${recipe.name} deployed successfully!`,
|
||||
setupInstructions: recipe.setupInstructions
|
||||
setupInstructions: recipe.setupInstructions,
|
||||
};
|
||||
|
||||
ctx.notification.send('deploymentSuccess', 'Recipe Deployed',
|
||||
`**${recipe.name}** recipe deployed (${deployedComponents.length} components).`,
|
||||
'success'
|
||||
'success',
|
||||
);
|
||||
|
||||
res.json(response);
|
||||
@@ -146,7 +146,7 @@ module.exports = function(ctx) {
|
||||
}
|
||||
} catch (cleanupError) {
|
||||
ctx.log.warn('recipe', 'Cleanup failed for component', {
|
||||
componentId: deployed.id, error: cleanupError.message
|
||||
componentId: deployed.id, error: cleanupError.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ module.exports = function(ctx) {
|
||||
}
|
||||
|
||||
ctx.notification.send('deploymentFailed', 'Recipe Failed',
|
||||
`Failed to deploy **${recipe.name}**: ${error.message}`, 'error'
|
||||
`Failed to deploy **${recipe.name}**: ${error.message}`, 'error',
|
||||
);
|
||||
|
||||
ctx.errorResponse(res, 500, error.message);
|
||||
@@ -254,7 +254,7 @@ module.exports = function(ctx) {
|
||||
HostConfig: {
|
||||
PortBindings: {},
|
||||
Binds: dockerConfig.volumes || [],
|
||||
RestartPolicy: { Name: 'unless-stopped' }
|
||||
RestartPolicy: { Name: 'unless-stopped' },
|
||||
},
|
||||
Env: Object.entries(dockerConfig.environment || {}).map(([k, v]) => `${k}=${v}`),
|
||||
Labels: {
|
||||
@@ -264,8 +264,8 @@ module.exports = function(ctx) {
|
||||
'sami.recipe.component': component.id,
|
||||
'sami.recipe.role': component.role,
|
||||
'sami.subdomain': subdomain,
|
||||
'sami.deployed': new Date().toISOString()
|
||||
}
|
||||
'sami.deployed': new Date().toISOString(),
|
||||
},
|
||||
};
|
||||
|
||||
// Configure ports
|
||||
@@ -288,7 +288,7 @@ module.exports = function(ctx) {
|
||||
} catch (e) {
|
||||
ctx.log.warn('recipe', `Pull failed, checking local: ${dockerConfig.image}`);
|
||||
const images = await ctx.docker.client.listImages({
|
||||
filters: { reference: [dockerConfig.image] }
|
||||
filters: { reference: [dockerConfig.image] },
|
||||
});
|
||||
if (images.length === 0) throw new Error(`Image not found: ${dockerConfig.image}`);
|
||||
}
|
||||
@@ -324,7 +324,7 @@ module.exports = function(ctx) {
|
||||
const primaryPort = port || dockerConfig.ports[0].split(/[:/]/)[0];
|
||||
const caddyConfig = ctx.caddy.generateConfig(
|
||||
subdomain, hostIp, primaryPort,
|
||||
{ tailscaleOnly: sharedConfig.tailscaleOnly || false }
|
||||
{ tailscaleOnly: sharedConfig.tailscaleOnly || false },
|
||||
);
|
||||
try {
|
||||
const helpers = require('../apps/helpers')(ctx);
|
||||
@@ -344,7 +344,7 @@ module.exports = function(ctx) {
|
||||
internal: component.internal || false,
|
||||
templateRef: component.templateRef,
|
||||
logo,
|
||||
url
|
||||
url,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ module.exports = function(ctx) {
|
||||
required: c.required,
|
||||
internal: c.internal || false,
|
||||
templateRef: c.templateRef || null,
|
||||
note: c.note || null
|
||||
note: c.note || null,
|
||||
})),
|
||||
setupInstructions: recipe.setupInstructions
|
||||
setupInstructions: recipe.setupInstructions,
|
||||
}));
|
||||
|
||||
res.json({ success: true, templates, categories: RECIPE_CATEGORIES });
|
||||
|
||||
@@ -16,7 +16,7 @@ module.exports = function(ctx) {
|
||||
if (!recipeGroups[service.recipeId]) {
|
||||
recipeGroups[service.recipeId] = {
|
||||
recipeId: service.recipeId,
|
||||
components: []
|
||||
components: [],
|
||||
};
|
||||
}
|
||||
recipeGroups[service.recipeId].components.push({
|
||||
@@ -25,7 +25,7 @@ module.exports = function(ctx) {
|
||||
logo: service.logo,
|
||||
containerId: service.containerId,
|
||||
recipeRole: service.recipeRole,
|
||||
deployedAt: service.deployedAt
|
||||
deployedAt: service.deployedAt,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ module.exports = function(ctx) {
|
||||
|
||||
// Check if this container is already listed (by containerId)
|
||||
const existing = recipeGroups[recipeId].components.find(
|
||||
c => c.containerId === containerInfo.Id
|
||||
c => c.containerId === containerInfo.Id,
|
||||
);
|
||||
if (existing) continue;
|
||||
|
||||
@@ -59,7 +59,7 @@ module.exports = function(ctx) {
|
||||
recipeRole: labels['sami.recipe.role'] || 'Unknown',
|
||||
internal: true,
|
||||
state: containerInfo.State,
|
||||
status: containerInfo.Status
|
||||
status: containerInfo.Status,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -242,7 +242,7 @@ module.exports = function(ctx) {
|
||||
|
||||
ctx.notification.send('recipeRemoved', 'Recipe Removed',
|
||||
`Removed **${recipeId}** recipe (${results.filter(r => r.status === 'removed').length} containers).`,
|
||||
'info'
|
||||
'info',
|
||||
);
|
||||
|
||||
ctx.log.info('recipe', 'Recipe removed', { recipeId, results });
|
||||
@@ -271,7 +271,7 @@ module.exports = function(ctx) {
|
||||
Id: c.Id,
|
||||
component: c.Labels['sami.recipe.component'] || c.Names[0]?.replace('/', ''),
|
||||
role: c.Labels['sami.recipe.role'] || 'Unknown',
|
||||
state: c.State
|
||||
state: c.State,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ module.exports = function(ctx) {
|
||||
*/
|
||||
async function removeCaddyBlock(subdomain) {
|
||||
const domain = ctx.buildDomain(subdomain);
|
||||
let content = await ctx.caddy.read();
|
||||
const content = await ctx.caddy.read();
|
||||
|
||||
// Find and remove the block for this domain
|
||||
const escapedDomain = domain.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
Reference in New Issue
Block a user