diff --git a/api/cmd/api/main.go b/api/cmd/api/main.go index 69b74e03..182b20f9 100644 --- a/api/cmd/api/main.go +++ b/api/cmd/api/main.go @@ -63,29 +63,32 @@ func main() { } else { slog.Info("defaulting to server development mode") } - var err error + + if opts.Stage == Development { + // Load .env + logger.Info("loading .env") + err := godotenv.Load(".env") + if err != nil { + logger.Error("loading env", slog.Any("error", err)) + os.Exit(1) + } + } + // Parse env into config + var err error var config Config err = env.Parse(&config) if err != nil { - slog.Error("parsing env to config", slog.Any("error", err)) + logger.Error("parsing env to config", slog.Any("error", err)) os.Exit(1) } logger.Info("config: ", slog.Any("config", config)) logger.Info("huma options: ", slog.Any("options", opts)) + // Create DB_URL dbURL := fmt.Sprintf("postgres://%s:%s@%s:%s/%s", config.DbUser, config.DbPass, config.DbHost, config.DbPort, config.DbName) - if opts.Stage == Development { - // Load .env - err := godotenv.Load(".env") - if err != nil { - slog.Error("loading env", slog.Any("error", err)) - os.Exit(1) - } - } - logger.Info("setting clerk secret key from environment config") clerk.SetKey(config.ClerkSecretKey) @@ -93,7 +96,7 @@ func main() { // Postgres db, err := sql.Open("pgx", dbURL) if err != nil { - slog.Error("opening database", slog.Any("error", err)) + logger.Error("opening database", slog.Any("error", err)) os.Exit(1) } logger.Info("pinging db") @@ -101,14 +104,14 @@ func main() { dbctx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() if err := db.PingContext(dbctx); err != nil { - slog.Error("pinging db", slog.Any("error", err)) + logger.Error("pinging db", slog.Any("error", err)) os.Exit(1) } logger.Info("successfully pinged db") cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { - slog.Error("loading default aws config", slog.Any("error", err)) + logger.Error("loading default aws config", slog.Any("error", err)) os.Exit(1) } @@ -130,7 +133,7 @@ func main() { logger.Info("shutting down server") os.Exit(0) } else { - slog.Error("unexpected error", slog.Any("error", err)) + logger.Error("unexpected error", slog.Any("error", err)) os.Exit(1) } } diff --git a/api/openapi.yaml b/api/openapi.yaml index 3981c26c..e52eb10f 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1,5 +1,45 @@ components: schemas: + CreateUploadURLBody: + additionalProperties: false + properties: + $schema: + description: A URL to the JSON Schema for this object. + examples: + - https://example.com/schemas/CreateUploadURLBody.json + format: uri + readOnly: true + type: string + method: + type: string + signed_headers: + additionalProperties: + type: string + type: object + upload_url: + type: string + required: + - method + - upload_url + - signed_headers + type: object + CreateUploadURLRequestBody: + additionalProperties: false + properties: + $schema: + description: A URL to the JSON Schema for this object. + examples: + - https://example.com/schemas/CreateUploadURLRequestBody.json + format: uri + readOnly: true + type: string + image_key: + examples: + - my-image.jpeg + type: string + required: + - image_key + type: object ErrorDetail: additionalProperties: false properties: @@ -83,10 +123,33 @@ components: scheme: bearer type: http info: - title: My API + title: Happened API version: 1.0.0 openapi: 3.1.0 paths: + /create-upload-url: + get: + operationId: get-create-upload-url + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CreateUploadURLRequestBody" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/CreateUploadURLBody" + description: OK + default: + content: + application/problem+json: + schema: + $ref: "#/components/schemas/ErrorModel" + description: Error + summary: Get create upload URL /greeting/protected/{name}: get: description: Protected version of greet diff --git a/client-v2/gen/openapi.ts b/client-v2/gen/openapi.ts index 7ace466e..cee0c28f 100644 --- a/client-v2/gen/openapi.ts +++ b/client-v2/gen/openapi.ts @@ -1,7 +1,7 @@ /** * Generated by orval v7.2.0 🍺 * Do not edit manually. - * My API + * Happened API * OpenAPI spec version: 1.0.0 */ import axios from 'axios' @@ -9,6 +9,33 @@ import type { AxiosRequestConfig, AxiosResponse } from 'axios' + +// https://stackoverflow.com/questions/49579094/typescript-conditional-types-filter-out-readonly-properties-pick-only-requir/49579497#49579497 +type IfEquals = (() => T extends X ? 1 : 2) extends < +T, +>() => T extends Y ? 1 : 2 +? A +: B; + +type WritableKeys = { +[P in keyof T]-?: IfEquals< + { [Q in P]: T[P] }, + { -readonly [Q in P]: T[P] }, + P +>; +}[keyof T]; + +type UnionToIntersection = + (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never; +type DistributeReadOnlyOverUnions = T extends any ? NonReadonly : never; + +type Writable = Pick>; +type NonReadonly = [T] extends [UnionToIntersection] ? { + [P in keyof Writable]: T[P] extends object + ? NonReadonly> + : T[P]; +} : DistributeReadOnlyOverUnions; + export interface GreetingOutputBody { /** A URL to the JSON Schema for this object. */ readonly $schema?: string; @@ -47,11 +74,38 @@ export interface ErrorModel { type?: string; } +export interface CreateUploadURLRequestBody { + /** A URL to the JSON Schema for this object. */ + readonly $schema?: string; + image_key: string; +} + +export type CreateUploadURLBodySignedHeaders = {[key: string]: string}; + +export interface CreateUploadURLBody { + /** A URL to the JSON Schema for this object. */ + readonly $schema?: string; + method: string; + signed_headers: CreateUploadURLBodySignedHeaders; + upload_url: string; +} + /** + * @summary Get create upload URL + */ +export const getCreateUploadUrl = >( + createUploadURLRequestBody: NonReadonly, options?: AxiosRequestConfig + ): Promise => { + return axios.get( + `/create-upload-url`,options + ); + } + +/** * Protected version of greet * @summary Get a protected greeting */ @@ -75,5 +129,6 @@ export const getGreeting = >( ); } +export type GetCreateUploadUrlResult = AxiosResponse export type ProtectedGreetResult = AxiosResponse export type GetGreetingResult = AxiosResponse