import { DynamoDB } from "aws-sdk" import { GSI, GSIBuilder } from "./GSI" import { Model, PartitionKeyBuilder } from "./Model" import { Partition } from "./Partition" import { TaggedModel } from "./types" import { DelimiterType } from "../codegen/types"; export class Table { readonly tableName: string readonly partitionKeyName: PK readonly sortKeyName: SK readonly delimiter: DelimiterType private modelTags: string[] = [] private gsis: GSI[] = [] constructor(config: { name: string; delimiter: DelimiterType, partitionKeyName: PK; sortKeyName: SK }) { this.tableName = config.name this.partitionKeyName = config.partitionKeyName this.sortKeyName = config.sortKeyName this.delimiter = config.delimiter } model(modelType: T["model"]): PartitionKeyBuilder { this.modelTags.push(modelType) return new PartitionKeyBuilder(this, modelType) } partition, U extends Model>(models: [T, ...U[]]): Partition { return new Partition(models) } gsi(name: string): GSIBuilder { return new GSIBuilder(this, name) } registerGSI(gsi: GSI) { this.gsis.push(gsi) } getModelTags(): string[] { return this.modelTags } asCreateTableInput(billingMode: DynamoDB.Types.BillingMode): DynamoDB.Types.CreateTableInput { const attributeSet = new Set([ this.partitionKeyName, this.sortKeyName, "model", ...this.gsis.flatMap((_) => [_.partitionKeyName, _.sortKeyName]) ]) const attributeDefinitions: DynamoDB.Types.AttributeDefinitions = Array.from(attributeSet).map((attr) => ({ AttributeName: attr, AttributeType: "S" })) return { TableName: this.tableName, KeySchema: [ { AttributeName: this.partitionKeyName, KeyType: "HASH" }, { AttributeName: this.sortKeyName, KeyType: "RANGE" } ], AttributeDefinitions: attributeDefinitions, GlobalSecondaryIndexes: this.gsis.map(({ name, partitionKeyName, sortKeyName }) => ({ IndexName: name, KeySchema: [ { AttributeName: partitionKeyName, KeyType: "HASH" }, { AttributeName: sortKeyName, KeyType: "RANGE" } ], Projection: { ProjectionType: "ALL" } })), BillingMode: billingMode } } }