Skip to content

Commit 361409c

Browse files
authored
[WIP] sst stack (#39)
* sst init * hmmmm * zod schema hell * pkg fix * this works every time 25% of the time * removed rules * AAAAAA * event bus fix * fixed event / returing issue * add .sst/types * removed triple-slash
1 parent ddbeed0 commit 361409c

File tree

19 files changed

+16243
-7816
lines changed

19 files changed

+16243
-7816
lines changed

apps/extract-stack/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.sst/*
2+
!.sst/types/index.ts
3+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import "sst/node/config";
2+
declare module "sst/node/config" {
3+
export interface ConfigTypes {
4+
APP: string;
5+
STAGE: string;
6+
}
7+
}import "sst/node/event-bus";
8+
declare module "sst/node/event-bus" {
9+
export interface EventBusResources {
10+
"ExtractBus": {
11+
eventBusName: string;
12+
}
13+
}
14+
}import "sst/node/config";
15+
declare module "sst/node/config" {
16+
export interface SecretResources {
17+
"DATABASE_URL": {
18+
value: string;
19+
}
20+
}
21+
}import "sst/node/config";
22+
declare module "sst/node/config" {
23+
export interface SecretResources {
24+
"DATABASE_AUTH_TOKEN": {
25+
value: string;
26+
}
27+
}
28+
}import "sst/node/config";
29+
declare module "sst/node/config" {
30+
export interface SecretResources {
31+
"GITLAB_TOKEN": {
32+
value: string;
33+
}
34+
}
35+
}import "sst/node/api";
36+
declare module "sst/node/api" {
37+
export interface ApiResources {
38+
"ExtractApi": {
39+
url: string;
40+
}
41+
}
42+
}

apps/extract-stack/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "@acme/extract-stack",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"type-check": "tsc --noEmit && echo \"✔ No TypeScript warnings or errors\"",
8+
"test": "echo \"Warning: no test specified\"",
9+
"lint": "eslint . && echo \"✔ No ESLint warnings or errors\"",
10+
"dev": "sst dev",
11+
"build": "sst build",
12+
"deploy": "sst deploy",
13+
"remove": "sst remove",
14+
"console": "sst console"
15+
},
16+
"author": "",
17+
"license": "ISC",
18+
"dependencies": {
19+
"@acme/extract-functions": "^1.0.0",
20+
"@acme/extract-schema": "^1.0.0",
21+
"@acme/source-control": "^1.0.0",
22+
"@libsql/client": "^0.3.1",
23+
"@tsconfig/node16": "^16.1.0",
24+
"aws-cdk-lib": "2.84.0",
25+
"aws-lambda": "^1.0.7",
26+
"constructs": "10.1.156",
27+
"drizzle-orm": "^0.27.2",
28+
"sst": "2.20.1",
29+
"zod": "^3.21.4"
30+
},
31+
"devDependencies": {
32+
"@types/aws-lambda": "^8.10.119"
33+
}
34+
}

apps/extract-stack/src/events.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { createEventBuilder } from "sst/node/event-bus";
2+
import { z } from "zod";
3+
import { RepositorySchema } from "@acme/extract-schema";
4+
import { NamespaceSchema } from "@acme/extract-schema/src/namespaces";
5+
6+
const eventBuilder = createEventBuilder({
7+
bus: "ExtractBus",
8+
metadata: z.object({
9+
version: z.number(),
10+
timestamp: z.number(),
11+
caller: z.string(),
12+
}).shape,
13+
});
14+
15+
const extractRepositoryEventSchema = z.object({
16+
repository: RepositorySchema,
17+
namespace: z.nullable(NamespaceSchema),
18+
});
19+
20+
export const extractRepositoryEvent = {
21+
schemaShape: extractRepositoryEventSchema.shape,
22+
source: 'extract',
23+
detailType: 'repository',
24+
};
25+
26+
export function defineEvent<EventSchemaShape extends z.ZodRawShape>(p: {
27+
source: string;
28+
detailType: string;
29+
schemaShape: EventSchemaShape;
30+
}) {
31+
return eventBuilder(`${p.source}.${p.detailType}`, p.schemaShape);
32+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { extractRepositoryEvent, defineEvent } from "./events";
2+
import { getRepository } from "@acme/extract-functions";
3+
import type { Context, GetRepositorySourceControl, GetRepositoryEntities } from "@acme/extract-functions";
4+
import { GitlabSourceControl } from "@acme/source-control";
5+
import { repositories, namespaces } from "@acme/extract-schema";
6+
import { createClient } from '@libsql/client';
7+
import { drizzle } from 'drizzle-orm/libsql';
8+
import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
9+
import { z } from "zod";
10+
import { Config } from "sst/node/config";
11+
12+
const client = createClient({ url: Config.DATABASE_URL, authToken: Config.DATABASE_AUTH_TOKEN });
13+
14+
const db = drizzle(client);
15+
16+
const event = defineEvent(extractRepositoryEvent);
17+
18+
19+
const context: Context<GetRepositorySourceControl, GetRepositoryEntities> = {
20+
entities: {
21+
repositories,
22+
namespaces,
23+
},
24+
integrations: {
25+
sourceControl: new GitlabSourceControl(Config.GITLAB_TOKEN),
26+
},
27+
db,
28+
};
29+
30+
const inputSchema = z.object({
31+
repositoryId: z.number(),
32+
repositoryName: z.string(),
33+
namespaceName: z.string(),
34+
});
35+
36+
type Input = z.infer<typeof inputSchema>;
37+
38+
export const handler: APIGatewayProxyHandlerV2 = async (apiGatewayEvent) => {
39+
40+
let input: Input;
41+
42+
try {
43+
input = inputSchema.parse(apiGatewayEvent);
44+
} catch (error) {
45+
return {
46+
statusCode: 400,
47+
body: JSON.stringify({ error: (error as Error).message }),
48+
};
49+
}
50+
51+
const { repositoryId, repositoryName, namespaceName } = input;
52+
53+
const { repository, namespace } = await getRepository({ externalRepositoryId: repositoryId, repositoryName, namespaceName }, context);
54+
55+
await event.publish({ repository, namespace }, { caller: 'extract-repository', timestamp: new Date().getTime(), version: 1 });
56+
57+
return {
58+
statusCode: 200,
59+
body: JSON.stringify({})
60+
};
61+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "../.sst/types/index.ts";

apps/extract-stack/src/stack.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Api, EventBus } from "sst/constructs";
2+
import type { StackContext } from "sst/constructs";
3+
import { Config } from "sst/constructs";
4+
5+
export function ExtractStack({ stack }: StackContext) {
6+
const bus = new EventBus(stack, "ExtractBus", {
7+
defaults: {
8+
retries: 10,
9+
},
10+
});
11+
12+
const DATABASE_URL = new Config.Secret(stack, "DATABASE_URL");
13+
const DATABASE_AUTH_TOKEN = new Config.Secret(stack, "DATABASE_AUTH_TOKEN");
14+
const GITLAB_TOKEN = new Config.Secret(stack, "GITLAB_TOKEN");
15+
16+
const api = new Api(stack, "ExtractApi", {
17+
defaults: {
18+
function: {
19+
bind: [bus, DATABASE_URL, DATABASE_AUTH_TOKEN, GITLAB_TOKEN],
20+
},
21+
},
22+
routes: {
23+
"POST /gitlab": "src/extract-repository.handler",
24+
},
25+
});
26+
27+
stack.addOutputs({
28+
ApiEndpoint: api.url,
29+
});
30+
31+
return {
32+
ExtractBus: bus,
33+
};
34+
}
35+

apps/extract-stack/sst.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { SSTConfig } from "sst";
2+
import { ExtractStack } from "./src/stack";
3+
4+
export default {
5+
config(_input) {
6+
return {
7+
name: "extract",
8+
region: "eu-central-1",
9+
};
10+
},
11+
stacks(app) {
12+
app.stack(ExtractStack);
13+
}
14+
} satisfies SSTConfig;

apps/extract-stack/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"baseUrl": ".",
5+
},
6+
"exclude": [],
7+
"include": [
8+
"sst.config.ts",
9+
"src/**/*.ts",
10+
"src/**/*.ts",
11+
"src/**/*.cjs",
12+
"src/**/*.mjs"
13+
]
14+
}

0 commit comments

Comments
 (0)