@kirschbaum-development/sst-laravel 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile.web +1 -1
- package/dist/bin/cli.js +13 -696
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/commands/deploy.d.ts +2 -0
- package/dist/bin/commands/deploy.js +32 -0
- package/dist/bin/commands/deploy.js.map +1 -0
- package/dist/bin/commands/github-iam.d.ts +2 -0
- package/dist/bin/commands/github-iam.js +100 -0
- package/dist/bin/commands/github-iam.js.map +1 -0
- package/dist/bin/commands/init.d.ts +2 -0
- package/dist/bin/commands/init.js +123 -0
- package/dist/bin/commands/init.js.map +1 -0
- package/dist/bin/commands/install.d.ts +2 -0
- package/dist/bin/commands/install.js +64 -0
- package/dist/bin/commands/install.js.map +1 -0
- package/dist/bin/commands/logs.d.ts +2 -0
- package/dist/bin/commands/logs.js +70 -0
- package/dist/bin/commands/logs.js.map +1 -0
- package/dist/bin/commands/ssh.d.ts +2 -0
- package/dist/bin/commands/ssh.js +46 -0
- package/dist/bin/commands/ssh.js.map +1 -0
- package/dist/bin/utils/ecs.d.ts +7 -0
- package/dist/bin/utils/ecs.js +108 -0
- package/dist/bin/utils/ecs.js.map +1 -0
- package/dist/bin/utils/git.d.ts +1 -0
- package/dist/bin/utils/git.js +19 -0
- package/dist/bin/utils/git.js.map +1 -0
- package/dist/bin/utils/iam.d.ts +4 -0
- package/dist/bin/utils/iam.js +60 -0
- package/dist/bin/utils/iam.js.map +1 -0
- package/dist/bin/utils/sst-config.d.ts +5 -0
- package/dist/bin/utils/sst-config.js +74 -0
- package/dist/bin/utils/sst-config.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ListTasksCommand, DescribeTasksCommand, ListClustersCommand } from '@aws-sdk/client-ecs';
|
|
2
|
+
import { select } from '@inquirer/prompts';
|
|
3
|
+
import { findSstConfig, extractLaravelComponents } from './sst-config.js';
|
|
4
|
+
export async function findClusterArn(ecsClient, stage, clusterOption) {
|
|
5
|
+
if (clusterOption) {
|
|
6
|
+
return clusterOption;
|
|
7
|
+
}
|
|
8
|
+
const configPath = findSstConfig();
|
|
9
|
+
if (!configPath) {
|
|
10
|
+
console.error('Error: Could not find sst.config.ts or sst.config.js in current directory.');
|
|
11
|
+
console.error('Please use --cluster flag to specify cluster ARN manually.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const components = extractLaravelComponents(configPath);
|
|
15
|
+
if (components.length === 0) {
|
|
16
|
+
console.error('Error: No Laravel components found in SST config.');
|
|
17
|
+
console.error('Please use --cluster flag to specify cluster ARN manually.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
if (components.length > 1) {
|
|
21
|
+
console.error('Error: Multiple Laravel components found in SST config.');
|
|
22
|
+
console.error(`Found: ${components.join(', ')}`);
|
|
23
|
+
console.error('Please use --cluster flag to specify which cluster to connect to.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const componentName = components[0].replace(/-/g, '');
|
|
27
|
+
const clusterPattern = `${stage}-${componentName}Cluster`;
|
|
28
|
+
console.log(`Looking for cluster matching pattern: *${clusterPattern}`);
|
|
29
|
+
const listClustersCommand = new ListClustersCommand({});
|
|
30
|
+
const listClustersResponse = await ecsClient.send(listClustersCommand);
|
|
31
|
+
if (!listClustersResponse.clusterArns || listClustersResponse.clusterArns.length === 0) {
|
|
32
|
+
console.error('Error: No ECS clusters found in this region.');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const matchingCluster = listClustersResponse.clusterArns.find(arn => {
|
|
36
|
+
const clusterName = arn.split('/').pop();
|
|
37
|
+
return clusterName?.includes(stage) && clusterName?.includes(componentName);
|
|
38
|
+
});
|
|
39
|
+
if (!matchingCluster) {
|
|
40
|
+
console.error(`Error: No cluster found matching stage "${stage}" and component "${components[0]}".`);
|
|
41
|
+
console.error('Available clusters:');
|
|
42
|
+
listClustersResponse.clusterArns.forEach(arn => {
|
|
43
|
+
console.error(` - ${arn.split('/').pop()}`);
|
|
44
|
+
});
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
console.log(`Auto-detected cluster: ${matchingCluster.split('/').pop()}`);
|
|
48
|
+
return matchingCluster;
|
|
49
|
+
}
|
|
50
|
+
export async function findTask(ecsClient, clusterArn, service, selectPrompt = 'Select a task to connect to:') {
|
|
51
|
+
const listTasksCommand = new ListTasksCommand({
|
|
52
|
+
cluster: clusterArn,
|
|
53
|
+
desiredStatus: 'RUNNING'
|
|
54
|
+
});
|
|
55
|
+
const listTasksResponse = await ecsClient.send(listTasksCommand);
|
|
56
|
+
if (!listTasksResponse.taskArns || listTasksResponse.taskArns.length === 0) {
|
|
57
|
+
console.error('No running tasks found in cluster');
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const describeTasksCommand = new DescribeTasksCommand({
|
|
61
|
+
cluster: clusterArn,
|
|
62
|
+
tasks: listTasksResponse.taskArns
|
|
63
|
+
});
|
|
64
|
+
const describeTasksResponse = await ecsClient.send(describeTasksCommand);
|
|
65
|
+
let matchingTask;
|
|
66
|
+
if (service) {
|
|
67
|
+
let servicePrefix;
|
|
68
|
+
if (service === 'web') {
|
|
69
|
+
servicePrefix = '-web';
|
|
70
|
+
}
|
|
71
|
+
else if (service === 'worker') {
|
|
72
|
+
servicePrefix = '-worker';
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
servicePrefix = `-${service}`;
|
|
76
|
+
}
|
|
77
|
+
matchingTask = describeTasksResponse.tasks?.find(task => {
|
|
78
|
+
const containerName = task.containers?.[0]?.name || '';
|
|
79
|
+
return containerName.toLowerCase().includes(servicePrefix.toLowerCase());
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (!matchingTask) {
|
|
83
|
+
if (service) {
|
|
84
|
+
console.log(`\nNo running task found matching service: ${service}`);
|
|
85
|
+
}
|
|
86
|
+
console.log('Available tasks in cluster:\n');
|
|
87
|
+
const choices = describeTasksResponse.tasks?.map(task => {
|
|
88
|
+
const taskId = task.taskArn?.split('/').pop() || '';
|
|
89
|
+
const containerName = task.containers?.[0]?.name || 'unknown';
|
|
90
|
+
const status = task.lastStatus || 'unknown';
|
|
91
|
+
return {
|
|
92
|
+
name: `${containerName} (${taskId.substring(0, 8)}...) - ${status}`,
|
|
93
|
+
value: task,
|
|
94
|
+
description: `Task: ${taskId}`
|
|
95
|
+
};
|
|
96
|
+
}) || [];
|
|
97
|
+
if (choices.length === 0) {
|
|
98
|
+
console.error('No tasks available to select from.');
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
matchingTask = await select({
|
|
102
|
+
message: selectPrompt,
|
|
103
|
+
choices
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return matchingTask;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=ecs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecs.js","sourceRoot":"","sources":["../../../bin/utils/ecs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function detectGitHubRepo(): string | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
export function detectGitHubRepo() {
|
|
3
|
+
try {
|
|
4
|
+
const remoteUrl = execSync('git remote get-url origin', { encoding: 'utf-8' }).trim();
|
|
5
|
+
const sshMatch = remoteUrl.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
6
|
+
if (sshMatch) {
|
|
7
|
+
return `${sshMatch[1]}/${sshMatch[2].replace(/\.git$/, '')}`;
|
|
8
|
+
}
|
|
9
|
+
const httpsMatch = remoteUrl.match(/https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/);
|
|
10
|
+
if (httpsMatch) {
|
|
11
|
+
return `${httpsMatch[1]}/${httpsMatch[2].replace(/\.git$/, '')}`;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../bin/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,QAAQ,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAEtF,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC9E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;QAC/D,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACvF,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;QACnE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IAMClient } from '@aws-sdk/client-iam';
|
|
2
|
+
export declare function getAwsAccountId(iamClient: IAMClient): Promise<string>;
|
|
3
|
+
export declare function ensureGithubOidcProvider(iamClient: IAMClient, githubOidcUrl: string): Promise<string>;
|
|
4
|
+
export declare function buildTrustPolicy(oidcProviderArn: string, owner: string, repo: string, branch: string): object;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CreateOpenIDConnectProviderCommand, ListOpenIDConnectProvidersCommand, GetOpenIDConnectProviderCommand, AddClientIDToOpenIDConnectProviderCommand, } from '@aws-sdk/client-iam';
|
|
2
|
+
export async function getAwsAccountId(iamClient) {
|
|
3
|
+
const { STSClient, GetCallerIdentityCommand } = await import('@aws-sdk/client-sts');
|
|
4
|
+
const stsClient = new STSClient({ region: await iamClient.config.region() });
|
|
5
|
+
const response = await stsClient.send(new GetCallerIdentityCommand({}));
|
|
6
|
+
return response.Account;
|
|
7
|
+
}
|
|
8
|
+
export async function ensureGithubOidcProvider(iamClient, githubOidcUrl) {
|
|
9
|
+
const requiredAudience = 'sts.amazonaws.com';
|
|
10
|
+
const listResponse = await iamClient.send(new ListOpenIDConnectProvidersCommand({}));
|
|
11
|
+
const existingProvider = listResponse.OpenIDConnectProviderList?.find(provider => provider.Arn?.includes('token.actions.githubusercontent.com'));
|
|
12
|
+
if (existingProvider) {
|
|
13
|
+
const providerDetails = await iamClient.send(new GetOpenIDConnectProviderCommand({
|
|
14
|
+
OpenIDConnectProviderArn: existingProvider.Arn
|
|
15
|
+
}));
|
|
16
|
+
const hasRequiredAudience = providerDetails.ClientIDList?.includes(requiredAudience);
|
|
17
|
+
if (!hasRequiredAudience) {
|
|
18
|
+
console.log(`OIDC provider exists but missing "${requiredAudience}" audience. Adding it...`);
|
|
19
|
+
await iamClient.send(new AddClientIDToOpenIDConnectProviderCommand({
|
|
20
|
+
OpenIDConnectProviderArn: existingProvider.Arn,
|
|
21
|
+
ClientID: requiredAudience
|
|
22
|
+
}));
|
|
23
|
+
console.log(`Added "${requiredAudience}" audience to OIDC provider`);
|
|
24
|
+
}
|
|
25
|
+
return existingProvider.Arn;
|
|
26
|
+
}
|
|
27
|
+
const thumbprint = '6938fd4d98bab03faadb97b34396831e3780aea1';
|
|
28
|
+
const createResponse = await iamClient.send(new CreateOpenIDConnectProviderCommand({
|
|
29
|
+
Url: githubOidcUrl,
|
|
30
|
+
ClientIDList: [requiredAudience],
|
|
31
|
+
ThumbprintList: [thumbprint]
|
|
32
|
+
}));
|
|
33
|
+
return createResponse.OpenIDConnectProviderArn;
|
|
34
|
+
}
|
|
35
|
+
export function buildTrustPolicy(oidcProviderArn, owner, repo, branch) {
|
|
36
|
+
const condition = branch === '*'
|
|
37
|
+
? `repo:${owner}/${repo}:*`
|
|
38
|
+
: `repo:${owner}/${repo}:ref:refs/heads/${branch}`;
|
|
39
|
+
return {
|
|
40
|
+
Version: '2012-10-17',
|
|
41
|
+
Statement: [
|
|
42
|
+
{
|
|
43
|
+
Effect: 'Allow',
|
|
44
|
+
Principal: {
|
|
45
|
+
Federated: oidcProviderArn
|
|
46
|
+
},
|
|
47
|
+
Action: 'sts:AssumeRoleWithWebIdentity',
|
|
48
|
+
Condition: {
|
|
49
|
+
StringEquals: {
|
|
50
|
+
'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com'
|
|
51
|
+
},
|
|
52
|
+
StringLike: {
|
|
53
|
+
'token.actions.githubusercontent.com:sub': condition
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=iam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iam.js","sourceRoot":"","sources":["../../../bin/utils/iam.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kCAAkC,EAClC,iCAAiC,EACjC,+BAA+B,EAC/B,yCAAyC,GAC1C,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAoB;IACxD,MAAM,EAAE,SAAS,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC;IACxE,OAAO,QAAQ,CAAC,OAAQ,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,SAAoB,EAAE,aAAqB;IACxF,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,iCAAiC,CAAC,EAAE,CAAC,CAAC,CAAC;IAErF,MAAM,gBAAgB,GAAG,YAAY,CAAC,yBAAyB,EAAE,IAAI,CACnE,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,qCAAqC,CAAC,CAC1E,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,eAAe,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,+BAA+B,CAAC;YAC/E,wBAAwB,EAAE,gBAAgB,CAAC,GAAG;SAC/C,CAAC,CAAC,CAAC;QAEJ,MAAM,mBAAmB,GAAG,eAAe,CAAC,YAAY,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAErF,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,qCAAqC,gBAAgB,0BAA0B,CAAC,CAAC;YAC7F,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,yCAAyC,CAAC;gBACjE,wBAAwB,EAAE,gBAAgB,CAAC,GAAG;gBAC9C,QAAQ,EAAE,gBAAgB;aAC3B,CAAC,CAAC,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,UAAU,gBAAgB,6BAA6B,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,gBAAgB,CAAC,GAAI,CAAC;IAC/B,CAAC;IAED,MAAM,UAAU,GAAG,0CAA0C,CAAC;IAE9D,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,kCAAkC,CAAC;QACjF,GAAG,EAAE,aAAa;QAClB,YAAY,EAAE,CAAC,gBAAgB,CAAC;QAChC,cAAc,EAAE,CAAC,UAAU,CAAC;KAC7B,CAAC,CAAC,CAAC;IAEJ,OAAO,cAAc,CAAC,wBAAyB,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,eAAuB,EAAE,KAAa,EAAE,IAAY,EAAE,MAAc;IACnG,MAAM,SAAS,GAAG,MAAM,KAAK,GAAG;QAC9B,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI;QAC3B,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,mBAAmB,MAAM,EAAE,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,YAAY;QACrB,SAAS,EAAE;YACT;gBACE,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE;oBACT,SAAS,EAAE,eAAe;iBAC3B;gBACD,MAAM,EAAE,+BAA+B;gBACvC,SAAS,EAAE;oBACT,YAAY,EAAE;wBACZ,yCAAyC,EAAE,mBAAmB;qBAC/D;oBACD,UAAU,EAAE;wBACV,yCAAyC,EAAE,SAAS;qBACrD;iBACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function findSstConfig(): string | null;
|
|
2
|
+
export declare function extractSstProjectName(configPath: string): string | null;
|
|
3
|
+
export declare function extractLaravelComponents(configPath: string): string[];
|
|
4
|
+
export declare function extractEnvironmentFile(configPath: string, stage: string): string | null;
|
|
5
|
+
export declare function validateDeployment(stage: string): void;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
export function findSstConfig() {
|
|
4
|
+
const cwd = process.cwd();
|
|
5
|
+
const possiblePaths = [
|
|
6
|
+
path.join(cwd, 'sst.config.ts'),
|
|
7
|
+
path.join(cwd, 'sst.config.js'),
|
|
8
|
+
];
|
|
9
|
+
for (const configPath of possiblePaths) {
|
|
10
|
+
if (fs.existsSync(configPath)) {
|
|
11
|
+
return configPath;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
export function extractSstProjectName(configPath) {
|
|
17
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
18
|
+
const match = content.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
19
|
+
return match ? match[1] : null;
|
|
20
|
+
}
|
|
21
|
+
export function extractLaravelComponents(configPath) {
|
|
22
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
23
|
+
const regex = /new\s+LaravelService\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
24
|
+
const components = [];
|
|
25
|
+
let match;
|
|
26
|
+
while ((match = regex.exec(content)) !== null) {
|
|
27
|
+
components.push(match[1]);
|
|
28
|
+
}
|
|
29
|
+
return components;
|
|
30
|
+
}
|
|
31
|
+
export function extractEnvironmentFile(configPath, stage) {
|
|
32
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
33
|
+
// Find the start of environment block
|
|
34
|
+
const envMatch = content.match(/\benvironment\s*:\s*\{/);
|
|
35
|
+
if (!envMatch || envMatch.index === undefined) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
// Extract the environment block by counting braces
|
|
39
|
+
const startIndex = envMatch.index + envMatch[0].length;
|
|
40
|
+
let braceCount = 1;
|
|
41
|
+
let endIndex = startIndex;
|
|
42
|
+
for (let i = startIndex; i < content.length && braceCount > 0; i++) {
|
|
43
|
+
if (content[i] === '{')
|
|
44
|
+
braceCount++;
|
|
45
|
+
if (content[i] === '}')
|
|
46
|
+
braceCount--;
|
|
47
|
+
endIndex = i;
|
|
48
|
+
}
|
|
49
|
+
const envBlock = content.substring(startIndex, endIndex);
|
|
50
|
+
// Now find the file property within the environment block
|
|
51
|
+
const fileMatch = envBlock.match(/\bfile\s*:\s*[`'"]([^`'"]+)[`'"]/);
|
|
52
|
+
if (!fileMatch) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
let envFile = fileMatch[1];
|
|
56
|
+
// Replace ${$app.stage} with actual stage value
|
|
57
|
+
envFile = envFile.replace(/\$\{?\$app\.stage\}?/g, stage);
|
|
58
|
+
return envFile;
|
|
59
|
+
}
|
|
60
|
+
export function validateDeployment(stage) {
|
|
61
|
+
const configPath = findSstConfig();
|
|
62
|
+
if (!configPath) {
|
|
63
|
+
throw new Error('Could not find sst.config.ts or sst.config.js in current directory.');
|
|
64
|
+
}
|
|
65
|
+
const envFile = extractEnvironmentFile(configPath, stage);
|
|
66
|
+
if (envFile) {
|
|
67
|
+
const cwd = process.cwd();
|
|
68
|
+
const envFilePath = path.join(cwd, envFile);
|
|
69
|
+
if (!fs.existsSync(envFilePath)) {
|
|
70
|
+
throw new Error(`Environment file "${envFile}" not found. Please create the file or update your sst.config.ts configuration.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=sst-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sst-config.js","sourceRoot":"","sources":["../../../bin/utils/sst-config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kirschbaum-development/sst-laravel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An unofficial extension of SST to deploy containerized Laravel applications to AWS Fargate.",
|
|
6
6
|
"main": "laravel-sst.ts",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"@inquirer/prompts": "^7.0.0",
|
|
57
57
|
"@pulumi/aws": "^7.8.0",
|
|
58
58
|
"@pulumi/pulumi": "^3.203.0",
|
|
59
|
-
"commander": "^12.0.0"
|
|
59
|
+
"commander": "^12.0.0",
|
|
60
|
+
"sst": "^3.17.25"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@types/node": "^20.0.0",
|