@teamkeel/functions-runtime 0.413.3 → 0.413.4
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/dist/index.cjs +19 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +19 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/oas.ts +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/ModelAPI.js","../src/database.ts","../src/auditing.js","../src/camelCasePlugin.js","../src/Duration.ts","../src/type-utils.ts","../src/tracing.js","../src/File.ts","../src/errors.js","../src/parsing.js","../src/applyWhereConditions.js","../src/casing.js","../src/TimePeriod.js","../src/applyAdditionalQueryConstraints.js","../src/applyJoins.js","../src/QueryContext.js","../src/QueryBuilder.js","../src/RequestHeaders.ts","../src/handleRequest.js","../src/permissions.ts","../src/consts.js","../src/tryExecuteFunction.js","../src/handleJob.js","../src/tryExecuteJob.js","../src/handleSubscriber.js","../src/tryExecuteSubscriber.js","../src/handleRoute.js","../src/handleFlow.js","../src/tryExecuteFlow.js","../src/flows/ui/elements/input/text.ts","../src/flows/ui/elements/input/number.ts","../src/flows/ui/elements/display/divider.ts","../src/flows/ui/elements/input/boolean.ts","../src/flows/ui/elements/display/markdown.ts","../src/flows/ui/elements/display/table.ts","../src/flows/ui/elements/select/one.ts","../src/flows/ui/page.ts","../src/flows/disrupts.ts","../src/flows/ui/elements/display/banner.ts","../src/flows/ui/elements/display/image.ts","../src/flows/ui/elements/display/code.ts","../src/flows/ui/elements/display/grid.ts","../src/flows/ui/elements/display/list.ts","../src/flows/ui/elements/display/header.ts","../src/flows/index.ts"],"sourcesContent":["import { ModelAPI } from \"./ModelAPI\";\nimport { RequestHeaders } from \"./RequestHeaders\";\nimport { handleRequest } from \"./handleRequest\";\nimport { handleJob } from \"./handleJob\";\nimport { handleSubscriber } from \"./handleSubscriber\";\nimport { handleRoute } from \"./handleRoute\";\nimport { handleFlow } from \"./handleFlow\";\nimport KSUID from \"ksuid\";\nimport { useDatabase } from \"./database\";\nimport {\n Permissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n} from \"./permissions\";\nimport * as tracing from \"./tracing\";\nimport { InlineFile, File } from \"./File\";\nimport { Duration } from \"./Duration\";\nimport { ErrorPresets } from \"./errors\";\n\n// Export JS files\nexport {\n ModelAPI,\n handleRequest,\n handleJob,\n handleSubscriber,\n handleRoute,\n handleFlow,\n KSUID,\n Permissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n tracing,\n ErrorPresets,\n};\nexport function ksuid() {\n return KSUID.randomSync().string;\n}\n\n// Export TS files\n\nexport { RequestHeaders, Duration, useDatabase, File, InlineFile };\nexport * from \"./flows\";\nexport { type UIApiResponses } from \"./flows/ui/index\";\n\n// *****************************\n// Static Types\n// *****************************\n\nexport type IDWhereCondition = {\n equals?: string | null;\n notEquals?: string | null;\n oneOf?: string[] | null;\n};\n\nexport type StringWhereCondition = {\n startsWith?: string | null;\n endsWith?: string | null;\n oneOf?: string[] | null;\n contains?: string | null;\n equals?: string | null;\n notEquals?: string | null;\n};\n\nexport type BooleanWhereCondition = {\n equals?: boolean | null;\n notEquals?: boolean | null;\n};\n\nexport type NumberWhereCondition = {\n greaterThan?: number | null;\n greaterThanOrEquals?: number | null;\n lessThan?: number | null;\n lessThanOrEquals?: number | null;\n equals?: number | null;\n notEquals?: number | null;\n};\n\nexport type DurationWhereCondition = {\n greaterThan?: DurationString | null;\n greaterThanOrEquals?: DurationString | null;\n lessThan?: DurationString | null;\n lessThanOrEquals?: DurationString | null;\n equals?: DurationString | null;\n notEquals?: DurationString | null;\n};\n\nexport type DateWhereCondition = {\n equals?: Date | string | null;\n equalsRelative?: RelativeDateString | null;\n before?: Date | string | null;\n beforeRelative?: RelativeDateString | null;\n onOrBefore?: Date | string | null;\n after?: Date | string | null;\n afterRelative?: RelativeDateString | null;\n onOrAfter?: Date | string | null;\n};\n\nexport type DateQueryInput = {\n equals?: string | null;\n before?: string | null;\n onOrBefore?: string | null;\n after?: string | null;\n onOrAfter?: string | null;\n};\n\nexport type TimestampQueryInput = {\n before: string | null;\n after: string | null;\n equalsRelative?: RelativeDateString | null;\n beforeRelative?: RelativeDateString | null;\n afterRelative?: RelativeDateString | null;\n};\n\nexport type StringArrayWhereCondition = {\n equals?: string[] | null;\n notEquals?: string[] | null;\n any?: StringArrayQueryWhereCondition | null;\n all?: StringArrayQueryWhereCondition | null;\n};\n\nexport type StringArrayQueryWhereCondition = {\n equals?: string | null;\n notEquals?: string | null;\n};\n\nexport type NumberArrayWhereCondition = {\n equals?: number[] | null;\n notEquals?: number[] | null;\n any?: NumberArrayQueryWhereCondition | null;\n all?: NumberArrayQueryWhereCondition | null;\n};\n\nexport type NumberArrayQueryWhereCondition = {\n greaterThan?: number | null;\n greaterThanOrEquals?: number | null;\n lessThan?: number | null;\n lessThanOrEquals?: number | null;\n equals?: number | null;\n notEquals?: number | null;\n};\n\nexport type BooleanArrayWhereCondition = {\n equals?: boolean[] | null;\n notEquals?: boolean[] | null;\n any?: BooleanArrayQueryWhereCondition | null;\n all?: BooleanArrayQueryWhereCondition | null;\n};\n\nexport type BooleanArrayQueryWhereCondition = {\n equals?: boolean | null;\n notEquals?: boolean | null;\n};\n\nexport type DateArrayWhereCondition = {\n equals?: Date[] | null;\n notEquals?: Date[] | null;\n any?: DateArrayQueryWhereCondition | null;\n all?: DateArrayQueryWhereCondition | null;\n};\n\nexport type DateArrayQueryWhereCondition = {\n greaterThan?: Date | null;\n greaterThanOrEquals?: Date | null;\n lessThan?: Date | null;\n lessThanOrEquals?: number | null;\n equals?: Date | null;\n notEquals?: Date | null;\n};\n\nexport type ContextAPI = {\n headers: RequestHeaders;\n response: Response;\n isAuthenticated: boolean;\n now(): Date;\n};\n\nexport type Response = {\n headers: Headers;\n status?: number;\n};\n\nexport type PageInfo = {\n startCursor: string;\n endCursor: string;\n totalCount: number;\n hasNextPage: boolean;\n count: number;\n pageNumber?: number;\n};\n\nexport type SortDirection = \"asc\" | \"desc\" | \"ASC\" | \"DESC\";\n\ndeclare class NotFoundError extends Error {}\ndeclare class BadRequestError extends Error {}\ndeclare class UnknownError extends Error {}\n\nexport type Errors = {\n /**\n * Returns a 404 HTTP status with an optional message.\n * This error indicates that the requested resource could not be found.\n */\n NotFound: typeof NotFoundError;\n /**\n * Returns a 400 HTTP status with an optional message.\n * This error indicates that the request made by the client is invalid or malformed.\n */\n BadRequest: typeof BadRequestError;\n /**\n * Returns a 500 HTTP status with an optional message.\n * This error indicates that an unexpected condition was encountered, preventing the server from fulfilling the request.\n */\n Unknown: typeof UnknownError;\n};\n\nexport type FunctionConfig = {\n /**\n * All DB calls within the function will be executed within a transaction.\n * The transaction is rolled back if the function throws an error.\n */\n dbTransaction?: boolean;\n};\n\nexport type FuncWithConfig<T> = T & {\n config: FunctionConfig;\n};\n\ntype unit =\n | \"year\"\n | \"years\"\n | \"month\"\n | \"months\"\n | \"day\"\n | \"days\"\n | \"hour\"\n | \"hours\"\n | \"minute\"\n | \"minutes\"\n | \"second\"\n | \"seconds\";\ntype direction = \"next\" | \"last\";\ntype completed = \"complete\";\ntype value = number;\n\nexport type RelativeDateString =\n | \"now\"\n | \"today\"\n | \"tomorrow\"\n | \"yesterday\"\n | `this ${unit}`\n | `${direction} ${unit}`\n | `${direction} ${value} ${unit}`\n | `${direction} ${value} ${completed} ${unit}`;\n\ntype dateDuration =\n | `${number}Y${number}M${number}D` // Example: 1Y2M10D\n | `${number}Y${number}M` // Example: 1Y2M\n | `${number}Y${number}D` // Example: 1Y10D\n | `${number}M${number}D` // Example: 10M2D\n | `${number}Y` // Example: 1Y\n | `${number}M` // Example: 1M\n | `${number}D`; // Example: 2D\n\ntype timeDuration =\n | `${number}H${number}M${number}S` // Example: 2H30M\n | `${number}H${number}M` // Example: 2H30M\n | `${number}M${number}S` // Example: 2M30S\n | `${number}H${number}S` // Example: 2H30S\n | `${number}H` // Example: 2H\n | `${number}M` // Example: 30M\n | `${number}S`; // Example: 30S\n\nexport type DurationString =\n | `P${dateDuration}T${timeDuration}`\n | `P${dateDuration}`\n | `PT${timeDuration}`;\n","import { sql } from \"kysely\";\nimport { useDatabase } from \"./database\";\nimport { transformRichDataTypes, isReferencingExistingRecord } from \"./parsing\";\nimport { isPlainObject } from \"./type-utils\";\nimport { QueryBuilder } from \"./QueryBuilder\";\nimport { QueryContext } from \"./QueryContext\";\nimport { applyWhereConditions } from \"./applyWhereConditions\";\nimport { applyJoins } from \"./applyJoins\";\nimport { InlineFile, File } from \"./File\";\nimport { Duration } from \"./Duration\";\n\nimport {\n applyLimit,\n applyOffset,\n applyOrderBy,\n} from \"./applyAdditionalQueryConstraints\";\nimport { camelCaseObject, snakeCaseObject, upperCamelCase } from \"./casing\";\nimport * as tracing from \"./tracing\";\nimport { DatabaseError } from \"./errors\";\n\n/**\n * RelationshipConfig is a simple representation of a model field that\n * is a relationship. It is used by applyJoins and applyWhereConditions\n * to build the correct query.\n * @typedef {{\n * relationshipType: \"belongsTo\" | \"hasMany\",\n * foreignKey: string,\n * referencesTable: string,\n * }} RelationshipConfig\n *\n * TableConfig is an object where the keys are relationship field names\n * (which don't exist in the database) and the values are RelationshipConfig\n * objects describing that relationship.\n * @typedef {Object.<string, RelationshipConfig} TableConfig\n *\n * TableConfigMap is mapping of database table names to TableConfig objects\n * @typedef {Object.<string, TableConfig>} TableConfigMap\n */\n\nclass ModelAPI {\n /**\n * @param {string} tableName The name of the table this API is for\n * @param {Function} _ Used to be a function that returns the default values for a row in this table. No longer used.\n * @param {TableConfigMap} tableConfigMap\n */\n constructor(tableName, _, tableConfigMap = {}) {\n this._tableName = tableName;\n this._tableConfigMap = tableConfigMap;\n this._modelName = upperCamelCase(this._tableName);\n }\n\n async create(values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"create\");\n\n return tracing.withSpan(name, () => {\n const db = useDatabase();\n return create(\n db,\n this._tableName,\n this._tableConfigMap,\n snakeCaseObject(values)\n );\n });\n }\n\n async findOne(where = {}) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findOne\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n const row = await builder.executeTakeFirst();\n if (!row) {\n return null;\n }\n\n return transformRichDataTypes(camelCaseObject(row));\n });\n }\n\n async findMany(params) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findMany\");\n const db = useDatabase();\n const where = params?.where || {};\n\n return tracing.withSpan(name, async (span) => {\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n let builder = db\n .selectFrom((qb) => {\n // We need to wrap this query as a sub query in the selectFrom because you cannot apply a different order by column when using distinct(id)\n let builder = qb\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n builder = builder.as(this._tableName);\n\n return builder;\n })\n .selectAll();\n\n // The only constraints added to the main query are the orderBy, limit and offset as they are performed on the \"outer\" set\n if (params?.limit) {\n builder = applyLimit(context, builder, params.limit);\n }\n\n if (params?.offset) {\n builder = applyOffset(context, builder, params.offset);\n }\n\n if (\n params?.orderBy !== undefined &&\n Object.keys(params?.orderBy).length > 0\n ) {\n builder = applyOrderBy(\n context,\n builder,\n this._tableName,\n params.orderBy\n );\n } else {\n builder = builder.orderBy(`${this._tableName}.id`);\n }\n\n const query = builder;\n\n span.setAttribute(\"sql\", query.compile().sql);\n const rows = await builder.execute();\n return rows.map((x) => transformRichDataTypes(camelCaseObject(x)));\n });\n }\n\n async update(where, values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"update\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db.updateTable(this._tableName).returningAll();\n\n // process input values\n const keys = values ? Object.keys(values) : [];\n const row = {};\n\n for (const key of keys) {\n const value = values[key];\n if (Array.isArray(value)) {\n row[key] = await Promise.all(\n value.map(async (item) => {\n if (item instanceof Duration) {\n return item.toPostgres();\n }\n if (item instanceof InlineFile) {\n const storedFile = await item.store();\n return storedFile.toDbRecord();\n }\n if (item instanceof File) {\n return item.toDbRecord();\n }\n return item;\n })\n );\n } else if (value instanceof Duration) {\n row[key] = value.toPostgres();\n } else if (value instanceof InlineFile) {\n const storedFile = await value.store();\n row[key] = storedFile.toDbRecord();\n } else if (value instanceof File) {\n row[key] = value.toDbRecord();\n } else {\n row[key] = value;\n }\n }\n\n builder = builder.set(snakeCaseObject(row));\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n // TODO: support joins for update\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n\n try {\n const row = await builder.executeTakeFirstOrThrow();\n return transformRichDataTypes(camelCaseObject(row));\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async delete(where) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"delete\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db.deleteFrom(this._tableName).returning([\"id\"]);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n // TODO: support joins for delete\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n try {\n const row = await builder.executeTakeFirstOrThrow();\n return row.id;\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n where(where) {\n const db = useDatabase();\n\n let builder = db\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n return new QueryBuilder(this._tableName, context, builder);\n }\n}\n\nasync function create(conn, tableName, tableConfigs, values) {\n try {\n let query = conn.insertInto(tableName);\n\n const keys = values ? Object.keys(values) : [];\n const tableConfig = tableConfigs[tableName] || {};\n const hasManyRecords = [];\n\n if (keys.length === 0) {\n // See https://github.com/kysely-org/kysely/issues/685#issuecomment-1711240534\n query = query.expression(sql`default values`);\n } else {\n const row = {};\n for (const key of keys) {\n const value = values[key];\n const columnConfig = tableConfig[key];\n\n if (!columnConfig) {\n if (Array.isArray(value)) {\n row[key] = await Promise.all(\n value.map(async (item) => {\n if (item instanceof Duration) {\n return item.toPostgres();\n }\n if (item instanceof InlineFile) {\n const storedFile = await item.store();\n return storedFile.toDbRecord();\n }\n if (item instanceof File) {\n return item.toDbRecord();\n }\n return item;\n })\n );\n } else if (value instanceof Duration) {\n row[key] = value.toPostgres();\n } else if (value instanceof InlineFile) {\n const storedFile = await value.store();\n row[key] = storedFile.toDbRecord();\n } else if (value instanceof File) {\n row[key] = value.toDbRecord();\n } else {\n row[key] = value;\n }\n continue;\n }\n\n switch (columnConfig.relationshipType) {\n case \"belongsTo\":\n if (!isPlainObject(value)) {\n throw new Error(\n `non-object provided for field ${key} of ${tableName}`\n );\n }\n\n if (isReferencingExistingRecord(value)) {\n row[columnConfig.foreignKey] = value.id;\n break;\n }\n\n const created = await create(\n conn,\n columnConfig.referencesTable,\n tableConfigs,\n value\n );\n row[columnConfig.foreignKey] = created.id;\n break;\n\n case \"hasMany\":\n if (!Array.isArray(value)) {\n throw new Error(\n `non-array provided for has-many field ${key} of ${tableName}`\n );\n }\n for (const v of value) {\n hasManyRecords.push({\n key,\n value: v,\n columnConfig,\n });\n }\n break;\n default:\n throw new Error(\n `unsupported relationship type - ${tableName}.${key} (${columnConfig.relationshipType})`\n );\n }\n }\n\n query = query.values(row);\n }\n\n const created = await query.returningAll().executeTakeFirstOrThrow();\n\n await Promise.all(\n hasManyRecords.map(async ({ key, value, columnConfig }) => {\n if (!isPlainObject(value)) {\n throw new Error(\n `non-object provided for field ${key} of ${tableName}`\n );\n }\n\n if (isReferencingExistingRecord(value)) {\n throw new Error(\n `nested update as part of create not supported for ${key} of ${tableConfig}`\n );\n }\n\n return create(conn, columnConfig.referencesTable, tableConfigs, {\n ...value,\n [columnConfig.foreignKey]: created.id,\n });\n })\n );\n\n return transformRichDataTypes(created);\n } catch (e) {\n throw new DatabaseError(e);\n }\n}\n\nexport { ModelAPI, DatabaseError };\n","import { Kysely, PostgresDialect, KyselyConfig } from \"kysely\";\nimport * as neon from \"@neondatabase/serverless\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { AuditContextPlugin } from \"./auditing\";\nimport { KeelCamelCasePlugin } from \"./camelCasePlugin\";\nimport { Pool, Client, types as pgTypes, PoolConfig, PoolClient } from \"pg\";\nimport { withSpan } from \"./tracing\";\nimport WebSocket from \"ws\";\nimport { readFileSync } from \"node:fs\";\nimport { Duration } from \"./Duration\";\n\ninterface DatabaseContext {\n transaction?: Kysely<any>;\n sDb?: Kysely<any>;\n}\n\ninterface DatabaseClientConfig {\n connString?: string;\n}\n\nconst dbInstance = new AsyncLocalStorage<Kysely<any>>();\n\n// used to establish a singleton for our vitest environment\nlet vitestDb: Kysely<any> | null = null;\n\n// withDatabase is responsible for setting the correct database client in our AsyncLocalStorage\n// so that the the code in a custom function uses the correct client.\n// For GET and LIST action types, no transaction is used, but for\n// actions that mutate data such as CREATE, DELETE & UPDATE, all of the code inside\n// the user's custom function is wrapped in a transaction so we can rollback\n// the transaction if something goes wrong.\n// withDatabase shouldn't be exposed in the public api of the sdk\nasync function withDatabase<T>(\n db: Kysely<any>,\n requiresTransaction: boolean,\n cb: (context: DatabaseContext) => Promise<T>\n): Promise<T> {\n // db.transaction() provides a kysely instance bound to a transaction.\n if (requiresTransaction) {\n return db.transaction().execute(async (transaction) => {\n return dbInstance.run(transaction, async () => {\n return cb({ transaction });\n });\n });\n }\n\n // db.connection() provides a kysely instance bound to a single database connection.\n return db.connection().execute(async (sDb) => {\n return dbInstance.run(sDb, async () => {\n return cb({ sDb });\n });\n });\n}\n\n// useDatabase will retrieve the database client set by withDatabase from the local storage\nfunction useDatabase(): Kysely<any> {\n // retrieve the instance of the database client from the store which is aware of\n // which context the current connection to the db is running in - e.g does the context\n // require a transaction or not?\n let fromStore = dbInstance.getStore();\n if (fromStore) {\n return fromStore;\n }\n\n // if the NODE_ENV is 'test' then we know we are inside of the vitest environment\n // which covers any test files ending in *.test.ts. Custom function code runs in a different node process which will not have this environment variable. Tests written using our testing\n // framework call actions (and in turn custom function code) over http using the ActionExecutor class\n if (\"NODE_ENV\" in process.env && process.env.NODE_ENV == \"test\") {\n if (!vitestDb) {\n vitestDb = createDatabaseClient();\n }\n return vitestDb;\n }\n\n // If we've gotten to this point, then we know that we are in a custom function runtime server\n // context and we haven't been able to retrieve the in-context instance of Kysely, which means we should throw an error.\n console.trace();\n throw new Error(\"useDatabase must be called within a function\");\n}\n\n// createDatabaseClient will return a brand new instance of Kysely. Every instance of Kysely\n// represents an individual connection to the database.\n// not to be exported externally from our sdk - consumers should use useDatabase\nfunction createDatabaseClient(config: DatabaseClientConfig = {}): Kysely<any> {\n const kyseleyConfig: KyselyConfig = {\n dialect: getDialect(config.connString),\n plugins: [\n // ensures that the audit context data is written to Postgres configuration parameters\n new AuditContextPlugin(),\n // allows users to query using camelCased versions of the database column names, which\n // should match the names we use in our schema.\n // We're using an extended version of Kysely's CamelCasePlugin which avoids changing keys of objects that represent\n // rich data formats, specific to Keel (e.g. Duration)\n new KeelCamelCasePlugin(),\n ],\n log(event: any) {\n if (process.env.DEBUG) {\n if (event.level === \"query\") {\n console.log(event.query.sql);\n console.log(event.query.parameters);\n }\n }\n },\n };\n\n return new Kysely(kyseleyConfig);\n}\n\nclass InstrumentedPool extends Pool {\n connect(...args: any): Promise<PoolClient> {\n const _super = super.connect.bind(this);\n return withSpan(\"Database Connect\", function (span: any) {\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n return _super.apply(null, args);\n });\n }\n}\n\nclass InstrumentedNeonServerlessPool extends neon.Pool {\n async connect(...args: any): Promise<neon.PoolClient> {\n const _super = super.connect.bind(this);\n return withSpan(\"Database Connect\", function (span: any) {\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n return _super.apply(null, args);\n });\n }\n}\n\nconst txStatements = {\n begin: \"Transaction Begin\",\n commit: \"Transaction Commit\",\n rollback: \"Transaction Rollback\",\n};\n\nclass InstrumentedClient extends Client {\n async query(...args: any): Promise<any> {\n const _super = super.query.bind(this);\n const sql = args[0];\n\n let sqlAttribute = false;\n let spanName = txStatements[sql.toLowerCase() as keyof typeof txStatements];\n if (!spanName) {\n spanName = \"Database Query\";\n sqlAttribute = true;\n }\n\n return withSpan(spanName, function (span: any) {\n if (sqlAttribute) {\n span.setAttribute(\"sql\", args[0]);\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n }\n return _super.apply(null, args);\n });\n }\n}\n\nfunction getDialect(connString?: string): PostgresDialect {\n const dbConnType = process.env.KEEL_DB_CONN_TYPE;\n switch (dbConnType) {\n case \"pg\": {\n // Adding a custom type parser for numeric fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1700 = type for NUMERIC\n pgTypes.setTypeParser(pgTypes.builtins.NUMERIC, (val: string) =>\n parseFloat(val)\n );\n // Adding a custom type parser for interval fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1186 = type for INTERVAL\n pgTypes.setTypeParser(\n pgTypes.builtins.INTERVAL,\n (val: string) => new Duration(val)\n );\n\n const poolConfig: PoolConfig = {\n Client: InstrumentedClient,\n // Increased idle time before closing a connection in the local pool (from 10s default).\n // Establising a new connection on (almost) every functions query can be expensive, so this\n // will reduce having to open connections as regularly. https://node-postgres.com/apis/pool\n //\n // NOTE: We should consider setting this to 0 (i.e. never pool locally) and open and close\n // connections with each invocation. This is because the freeze/thaw nature of lambdas can cause problems\n // with long-lived connections - see https://github.com/brianc/node-postgres/issues/2718\n // Once we're \"fully regional\" this should not be a performance problem anymore.\n //\n // Although I doubt we will run into these freeze/thaw issues if idleTimeoutMillis is always shorter than the\n // time is takes for a lambda to freeze (which is not a constant, but could be as short as several minutes,\n // https://www.pluralsight.com/resources/blog/cloud/how-long-does-aws-lambda-keep-your-idle-functions-around-before-a-cold-start)\n idleTimeoutMillis: 50000,\n // If connString is not passed fall back to reading from env var\n connectionString: connString || process.env.KEEL_DB_CONN,\n };\n\n // Allow the setting of a cert (.pem) file. RDS requires this to enforce SSL.\n if (process.env.KEEL_DB_CERT) {\n poolConfig.ssl = { ca: readFileSync(process.env.KEEL_DB_CERT) };\n }\n\n return new PostgresDialect({\n pool: new InstrumentedPool(poolConfig),\n });\n }\n case \"neon\": {\n // Adding a custom type parser for numeric fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1700 = type for NUMERIC\n neon.types.setTypeParser(pgTypes.builtins.NUMERIC, (val: string) =>\n parseFloat(val)\n );\n\n // Adding a custom type parser for interval fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1186 = type for INTERVAL\n neon.types.setTypeParser(\n pgTypes.builtins.INTERVAL,\n (val: string) => new Duration(val)\n );\n\n neon.neonConfig.webSocketConstructor = WebSocket;\n\n const pool = new InstrumentedNeonServerlessPool({\n // If connString is not passed fall back to reading from env var\n connectionString: connString || process.env.KEEL_DB_CONN,\n });\n\n pool.on(\"connect\", (client: any) => {\n const originalQuery = client.query;\n client.query = function (...args: any[]) {\n const sql = args[0];\n\n let sqlAttribute = false;\n let spanName =\n txStatements[sql.toLowerCase() as keyof typeof txStatements];\n if (!spanName) {\n spanName = \"Database Query\";\n sqlAttribute = true;\n }\n\n return withSpan(spanName, function (span: any) {\n if (sqlAttribute) {\n span.setAttribute(\"sql\", args[0]);\n span.setAttribute(\"dialect\", dbConnType);\n }\n return originalQuery.apply(client, args);\n });\n };\n });\n\n return new PostgresDialect({\n pool: pool,\n });\n }\n default:\n throw Error(\"unexpected KEEL_DB_CONN_TYPE: \" + dbConnType);\n }\n}\n\nexport {\n createDatabaseClient,\n useDatabase,\n withDatabase,\n type DatabaseContext,\n type DatabaseClientConfig,\n};\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport TraceParent from \"traceparent\";\nimport { sql, SelectionNode } from \"kysely\";\n\nconst auditContextStorage = new AsyncLocalStorage();\n\n// withAuditContext creates the audit context from the runtime request body\n// and sets it to in AsyncLocalStorage so that this data is available to the\n// ModelAPI during the execution of actions, jobs and subscribers.\nasync function withAuditContext(request, cb) {\n let audit = {};\n\n if (request.meta?.identity) {\n audit.identityId = request.meta.identity.id;\n }\n if (request.meta?.tracing?.traceparent) {\n audit.traceId = TraceParent.fromString(\n request.meta.tracing.traceparent\n )?.traceId;\n }\n\n return await auditContextStorage.run(audit, () => {\n return cb();\n });\n}\n\n// getAuditContext retrieves the audit context from AsyncLocalStorage.\nfunction getAuditContext() {\n let auditStore = auditContextStorage.getStore();\n return {\n identityId: auditStore?.identityId,\n traceId: auditStore?.traceId,\n };\n}\n\n// AuditContextPlugin is a Kysely plugin which ensures that the audit context data\n// is written to Postgres configuration parameters in the same execution as a query.\n// It does this by calling the set_identity_id() and set_trace_id() functions as a\n// clause in the returning statement. It then subsequently drops these from the actual result.\n// This ensures that these parameters are set when the tables' AFTER trigger function executes.\nclass AuditContextPlugin {\n constructor() {\n this.identityIdAlias = \"__keel_identity_id\";\n this.traceIdAlias = \"__keel_trace_id\";\n }\n\n // Appends set_identity_id() and set_trace_id() function calls to the returning statement\n // of INSERT, UPDATE and DELETE operations.\n transformQuery(args) {\n switch (args.node.kind) {\n case \"InsertQueryNode\":\n case \"UpdateQueryNode\":\n case \"DeleteQueryNode\":\n // Represents a RETURNING clause in a SQL statement.\n const returning = {\n kind: \"ReturningNode\",\n selections: [],\n };\n\n // If the query already has a selection, then append it.\n if (args.node.returning) {\n returning.selections.push(...args.node.returning.selections);\n }\n\n // Retrieve the audit context from async storage.\n const audit = getAuditContext();\n\n if (audit.identityId) {\n const rawNode = sql`set_identity_id(${audit.identityId})`\n .as(this.identityIdAlias)\n .toOperationNode();\n\n returning.selections.push(SelectionNode.create(rawNode));\n }\n\n if (audit.traceId) {\n const rawNode = sql`set_trace_id(${audit.traceId})`\n .as(this.traceIdAlias)\n .toOperationNode();\n\n returning.selections.push(SelectionNode.create(rawNode));\n }\n\n return {\n ...args.node,\n returning: returning,\n };\n }\n\n return {\n ...args.node,\n };\n }\n\n // Drops the set_identity_id() and set_trace_id() fields from the result.\n transformResult(args) {\n if (args.result?.rows) {\n for (let i = 0; i < args.result.rows.length; i++) {\n delete args.result.rows[i][this.identityIdAlias];\n delete args.result.rows[i][this.traceIdAlias];\n }\n }\n\n return args.result;\n }\n}\n\nexport { withAuditContext, getAuditContext, AuditContextPlugin };\n","import { CamelCasePlugin } from \"kysely\";\nimport { isPlainObject, isRichType } from \"./type-utils\";\n\n// KeelCamelCasePlugin is a wrapper around kysely's CamelCasePlugin. The behaviour is the same apart from the fact that\n// nested objects that are of a rich keel data type, such as Duration, are skipped so that they continue to be\n// implementations of the rich data classes defined by Keel.\nclass KeelCamelCasePlugin {\n constructor(opt) {\n this.opt = opt;\n this.CamelCasePlugin = new CamelCasePlugin(opt);\n }\n\n transformQuery(args) {\n return this.CamelCasePlugin.transformQuery(args);\n }\n\n async transformResult(args) {\n if (args.result.rows && Array.isArray(args.result.rows)) {\n return {\n ...args.result,\n rows: args.result.rows.map((row) => this.mapRow(row)),\n };\n }\n return args.result;\n }\n mapRow(row) {\n return Object.keys(row).reduce((obj, key) => {\n // Fields using @sequence will have a corresponding __sequence field which we drop as we don't want to return it\n if (key.endsWith(\"__sequence\")) {\n return obj;\n }\n let value = row[key];\n if (Array.isArray(value)) {\n value = value.map((it) =>\n canMap(it, this.opt) ? this.mapRow(it) : it\n );\n } else if (canMap(value, this.opt)) {\n value = this.mapRow(value);\n }\n obj[this.CamelCasePlugin.camelCase(key)] = value;\n return obj;\n }, {});\n }\n}\n\nfunction canMap(obj, opt) {\n return (\n isPlainObject(obj) && !opt?.maintainNestedObjectKeys && !isRichType(obj)\n );\n}\n\nexport { KeelCamelCasePlugin };\n","import parseInterval from \"postgres-interval\";\n\nconst isoRegex =\n /^P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?$/;\n\ninterface Interval {\n years?: number;\n months?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n toISOStringShort(): string;\n toPostgres(): string;\n}\n\nexport class Duration {\n private _typename: string;\n private pgInterval: string;\n private _interval: Interval;\n\n constructor(postgresString: string) {\n this._typename = \"Duration\";\n this.pgInterval = postgresString;\n this._interval = parseInterval(postgresString);\n }\n\n static fromISOString(isoString: string): Duration {\n const match = isoString.match(isoRegex);\n if (match) {\n const d = new Duration(\"0\");\n d._interval.years = match[1] ? parseInt(match[1]) : undefined;\n d._interval.months = match[2] ? parseInt(match[2]) : undefined;\n d._interval.days = match[3] ? parseInt(match[3]) : undefined;\n d._interval.hours = match[4] ? parseInt(match[4]) : undefined;\n d._interval.minutes = match[5] ? parseInt(match[5]) : undefined;\n d._interval.seconds = match[6] ? parseInt(match[6]) : undefined;\n return d;\n }\n return new Duration(\"0\");\n }\n\n toISOString(): string {\n return this._interval.toISOStringShort();\n }\n\n toPostgres(): string {\n return this._interval.toPostgres();\n }\n}\n","import { Duration } from \"./Duration\";\n\nfunction isPlainObject(obj: unknown): boolean {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\n\nfunction isRichType(obj: unknown): boolean {\n if (!isPlainObject(obj)) {\n return false;\n }\n\n return obj instanceof Duration;\n}\n\nexport { isPlainObject, isRichType };\n","import * as opentelemetry from \"@opentelemetry/api\";\nimport { BatchSpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport { envDetectorSync } from \"@opentelemetry/resources\";\n\nasync function withSpan(name, fn) {\n return getTracer().startActiveSpan(name, async (span) => {\n try {\n // await the thing (this means we can use try/catch)\n return await fn(span);\n } catch (err) {\n // record any errors\n span.recordException(err);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: err.message,\n });\n // re-throw the error\n throw err;\n } finally {\n // make sure the span is ended\n span.end();\n }\n });\n}\n\nfunction patchFetch() {\n if (!globalThis.fetch.patched) {\n const originalFetch = globalThis.fetch;\n\n globalThis.fetch = async (...args) => {\n return withSpan(\"fetch\", async (span) => {\n const url = new URL(\n args[0] instanceof Request ? args[0].url : String(args[0])\n );\n span.setAttribute(\"http.url\", url.toString());\n const scheme = url.protocol.replace(\":\", \"\");\n span.setAttribute(\"http.scheme\", scheme);\n\n const options = args[0] instanceof Request ? args[0] : args[1] || {};\n const method = (options.method || \"GET\").toUpperCase();\n span.setAttribute(\"http.method\", method);\n\n const res = await originalFetch(...args);\n span.setAttribute(\"http.status\", res.status);\n span.setAttribute(\"http.status_text\", res.statusText);\n return res;\n });\n };\n globalThis.fetch.patched = true;\n }\n}\n\nfunction patchConsoleLog() {\n if (!console.log.patched) {\n const originalConsoleLog = console.log;\n\n console.log = (...args) => {\n const span = opentelemetry.trace.getActiveSpan();\n if (span) {\n const output = args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.stack;\n }\n if (typeof arg === \"object\") {\n try {\n return JSON.stringify(arg, getCircularReplacer());\n } catch (error) {\n return \"[Object with circular references]\";\n }\n }\n if (typeof arg === \"function\") {\n return arg() || arg.name || arg.toString();\n }\n return String(arg);\n })\n .join(\" \");\n\n span.addEvent(output);\n }\n originalConsoleLog(...args);\n };\n\n console.log.patched = true;\n }\n}\n\nfunction patchConsoleError() {\n if (!console.error.patched) {\n const originalConsoleError = console.error;\n\n console.error = (...args) => {\n const span = opentelemetry.trace.getActiveSpan();\n if (span) {\n const output = args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.stack;\n }\n if (typeof arg === \"object\") {\n try {\n return JSON.stringify(arg, getCircularReplacer());\n } catch (error) {\n return \"[Object with circular references]\";\n }\n }\n if (typeof arg === \"function\") {\n return arg() || arg.name || arg.toString();\n }\n return String(arg);\n })\n .join(\" \");\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: output,\n });\n }\n originalConsoleError(...args);\n };\n\n console.error.patched = true;\n }\n}\n\n// Utility to handle circular references in objects\nfunction getCircularReplacer() {\n const seen = new WeakSet();\n return (key, value) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n }\n return value;\n };\n}\n\nfunction init() {\n if (process.env.KEEL_TRACING_ENABLED == \"true\") {\n const exporter = new OTLPTraceExporter();\n const processor = new BatchSpanProcessor(exporter);\n\n const provider = new NodeTracerProvider({\n resource: envDetectorSync.detect(),\n spanProcessors: [processor],\n });\n\n provider.register();\n }\n\n patchFetch();\n patchConsoleLog();\n patchConsoleError();\n}\n\nasync function forceFlush() {\n // The \"delegate\" is the actual provider set by the functions-runtime package\n const provider = opentelemetry.trace.getTracerProvider().getDelegate();\n if (provider && provider.forceFlush) {\n await provider.forceFlush();\n }\n}\n\nfunction getTracer() {\n return opentelemetry.trace.getTracer(\"functions\");\n}\n\nfunction spanNameForModelAPI(modelName, action) {\n return `Database ${modelName}.${action}`;\n}\n\nexport { getTracer, withSpan, init, forceFlush, spanNameForModelAPI };\n","import {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n PutObjectCommandInput,\n} from \"@aws-sdk/client-s3\";\nimport { fromEnv } from \"@aws-sdk/credential-providers\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport { useDatabase } from \"./database\";\nimport { DatabaseError } from \"./errors\";\nimport KSUID from \"ksuid\";\n\ntype MimeType =\n | \"application/json\"\n | \"application/gzip\"\n | \"application/pdf\"\n | \"application/rtf\"\n | \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n | \"application/vnd.openxmlformats-officedocument.presentationml.presentation\"\n | \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n | \"application/vnd.ms-excel\"\n | \"application/vnd.ms-powerpoint\"\n | \"application/msword\"\n | \"application/zip\"\n | \"application/xml\"\n | \"application/x-7z-compressed\"\n | \"application/x-tar\"\n | \"image/gif\"\n | \"image/jpeg\"\n | \"image/svg+xml\"\n | \"image/png\"\n | \"text/html\"\n | \"text/csv\"\n | \"text/javascript\"\n | \"text/plain\"\n | \"text/calendar\"\n | (string & {});\n\n// Type Declarations\nexport type InlineFileConstructor = {\n filename: string;\n contentType: MimeType;\n};\n\nexport type FileDbRecord = {\n key: string;\n filename: string;\n contentType: string;\n size: number;\n};\n\n// Implementation\nconst s3Client: S3Client | null = (() => {\n if (!process.env.KEEL_FILES_BUCKET_NAME) {\n return null;\n }\n\n const endpoint = process.env.TEST_AWS_ENDPOINT;\n\n if (!endpoint) {\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: fromEnv(),\n });\n }\n\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: {\n accessKeyId: \"test\",\n secretAccessKey: \"test\",\n },\n endpointProvider: () => {\n return {\n url: new URL(endpoint),\n };\n },\n });\n})();\n\nexport class InlineFile {\n protected _filename: string;\n protected _contentType: MimeType;\n protected _contents: Blob | null;\n\n constructor(input: InlineFileConstructor) {\n this._filename = input.filename;\n this._contentType = input.contentType;\n this._contents = null;\n }\n\n static fromDataURL(dataURL: string): InlineFile {\n const info = dataURL.split(\",\")[0].split(\":\")[1];\n const data = dataURL.split(\",\")[1];\n const mime = info.split(\";\")[0];\n const name = info.split(\";\")[1].split(\"=\")[1];\n const buffer = Buffer.from(data, \"base64\");\n const file = new InlineFile({ filename: name, contentType: mime });\n file.write(buffer);\n\n return file;\n }\n\n // Gets size of the file's contents in bytes\n get size(): number {\n if (this._contents) {\n return this._contents.size;\n }\n return 0;\n }\n\n // Gets the media type of the file contents\n get contentType(): string {\n return this._contentType;\n }\n\n // Gets the name of the file\n get filename(): string {\n return this._filename;\n }\n\n // Write the files contents from a buffer\n write(buffer: Buffer): void {\n this._contents = new Blob([buffer]);\n }\n\n // Reads the contents of the file as a buffer\n async read(): Promise<Buffer> {\n if (!this._contents) {\n throw new Error(\"No contents to read\");\n }\n const arrayBuffer = await this._contents.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n // Persists the file\n async store(expires: Date | null = null): Promise<File> {\n const content = await this.read();\n const key = KSUID.randomSync().string;\n\n await storeFile(\n content,\n key,\n this._filename,\n this._contentType,\n this.size,\n expires\n );\n\n return new File({\n key: key,\n size: this.size,\n filename: this.filename,\n contentType: this.contentType,\n });\n }\n}\n\nexport class File extends InlineFile {\n private _key: string;\n private _size: number;\n\n constructor(input: Partial<FileDbRecord>) {\n super({\n filename: input.filename || \"\",\n contentType: input.contentType || \"\",\n });\n this._key = input.key || \"\";\n this._size = input.size || 0;\n }\n\n // Creates a new instance from the database record\n static fromDbRecord(input: FileDbRecord): File {\n return new File({\n key: input.key,\n filename: input.filename,\n size: input.size,\n contentType: input.contentType,\n });\n }\n\n get size(): number {\n return this._size;\n }\n\n // Gets the stored key\n get key(): string {\n return this._key;\n }\n\n get isPublic(): boolean {\n return false; // Implement as needed\n }\n\n async read(): Promise<Buffer> {\n if (this._contents) {\n const arrayBuffer = await this._contents.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n if (s3Client) {\n const params = {\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n };\n const command = new GetObjectCommand(params);\n const response = await s3Client.send(command);\n const blob = await response.Body!.transformToByteArray();\n return Buffer.from(blob);\n }\n\n const db = useDatabase();\n\n try {\n const query = db\n .selectFrom(\"keel_storage\")\n .select(\"data\")\n .where(\"id\", \"=\", this.key);\n\n const row = await query.executeTakeFirstOrThrow();\n return row.data;\n } catch (e) {\n throw new DatabaseError(e);\n }\n }\n\n async store(expires: Date | null = null): Promise<File> {\n if (this._contents) {\n const contents = await this.read();\n await storeFile(\n contents,\n this.key,\n this.filename,\n this.contentType,\n this.size,\n expires\n );\n }\n return this;\n }\n\n // Generates a presigned download URL\n async getPresignedUrl(): Promise<URL> {\n if (s3Client) {\n const command = new GetObjectCommand({\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n ResponseContentDisposition: \"inline\",\n });\n\n const url = await getSignedUrl(s3Client, command, { expiresIn: 60 * 60 });\n\n return new URL(url);\n } else {\n const contents = await this.read();\n const dataurl = `data:${this.contentType};name=${\n this.filename\n };base64,${contents.toString(\"base64\")}`;\n return new URL(dataurl);\n }\n }\n\n // Persists the file\n toDbRecord(): FileDbRecord {\n return {\n key: this.key,\n filename: this.filename,\n contentType: this.contentType,\n size: this.size,\n };\n }\n\n toJSON(): FileDbRecord {\n return this.toDbRecord();\n }\n}\n\nasync function storeFile(\n contents: Buffer,\n key: string,\n filename: string,\n contentType: string,\n size: number,\n expires: Date | null\n): Promise<void> {\n if (s3Client) {\n const params: PutObjectCommandInput = {\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + key,\n Body: contents,\n ContentType: contentType,\n ContentDisposition: `attachment; filename=\"${encodeURIComponent(\n filename\n )}\"`,\n Metadata: {\n filename: filename,\n },\n ACL: \"private\",\n };\n\n if (expires) {\n if (expires instanceof Date) {\n params.Expires = expires;\n } else {\n console.warn(\"Invalid expires value. Skipping Expires parameter.\");\n }\n }\n\n const command = new PutObjectCommand(params);\n try {\n await s3Client.send(command);\n } catch (error) {\n console.error(\"Error uploading file:\", error);\n throw error;\n }\n } else {\n const db = useDatabase();\n\n try {\n const query = db\n .insertInto(\"keel_storage\")\n .values({\n id: key,\n filename: filename,\n content_type: contentType,\n data: contents,\n })\n .onConflict((oc) =>\n oc\n .column(\"id\")\n .doUpdateSet(() => ({\n filename: filename,\n content_type: contentType,\n data: contents,\n }))\n .where(\"keel_storage.id\", \"=\", key)\n )\n .returningAll();\n\n await query.execute();\n } catch (e) {\n throw new DatabaseError(e);\n }\n }\n}\n\nexport type FileWriteTypes = InlineFile | File;\n","import { createJSONRPCErrorResponse } from \"json-rpc-2.0\";\n\nconst RuntimeErrors = {\n // Catchall error type for unhandled execution errors during custom function\n UnknownError: -32001,\n // DatabaseError represents any error at pg level that isn't handled explicitly below\n DatabaseError: -32002,\n // No result returned from custom function by user\n NoResultError: -32003,\n // When trying to delete/update a non existent record in the db\n RecordNotFoundError: -32004,\n ForeignKeyConstraintError: -32005,\n NotNullConstraintError: -32006,\n UniqueConstraintError: -32007,\n PermissionError: -32008,\n BadRequestError: -32009,\n};\n\n// Error presets\nclass PermissionError extends Error {}\n\nclass DatabaseError extends Error {\n constructor(error) {\n super(error.message);\n this.error = error;\n }\n}\n\nclass NotFoundError extends Error {\n errorCode = RuntimeErrors.RecordNotFoundError;\n constructor(message) {\n super(message); // Default message is handled by the runtime for consistency with built in actions\n }\n}\n\nclass BadRequestError extends Error {\n errorCode = RuntimeErrors.BadRequestError;\n constructor(message = \"bad request\") {\n super(message);\n }\n}\n\nclass UnknownError extends Error {\n errorCode = RuntimeErrors.UnknownError;\n constructor(message = \"unknown error\") {\n super(message);\n }\n}\n\nconst ErrorPresets = {\n NotFound: NotFoundError,\n BadRequest: BadRequestError,\n Unknown: UnknownError,\n};\n\n// errorToJSONRPCResponse transforms a JavaScript Error instance (or derivative) into a valid JSONRPC response object to pass back to the Keel runtime.\nfunction errorToJSONRPCResponse(request, e) {\n switch (e.constructor.name) {\n case \"PermissionError\":\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.PermissionError,\n e.message\n );\n // Any error thrown in the ModelAPI class is\n // wrapped in a DatabaseError in order to differentiate 'our code' vs the user's own code.\n case \"NoResultError\":\n return createJSONRPCErrorResponse(\n request.id,\n\n // to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54\n RuntimeErrors.RecordNotFoundError,\n \"\" // Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors\n );\n case \"DatabaseError\":\n let err = e;\n\n // If wrapped error then unwrap\n if (e instanceof DatabaseError) {\n err = e.error;\n }\n\n if (err.constructor.name == \"NoResultError\") {\n return createJSONRPCErrorResponse(\n request.id,\n\n // to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54\n RuntimeErrors.RecordNotFoundError,\n \"\" // Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors\n );\n }\n\n // if the error contains 'code' then assume it has other pg error message keys\n // todo: make this more ironclad.\n // when using lib-pq, should match https://github.com/brianc/node-postgres/blob/master/packages/pg-protocol/src/parser.ts#L371-L386\n if (\"code\" in err) {\n const { code, detail, table } = err;\n\n let rpcErrorCode, column, value;\n const [col, val] = parseKeyMessage(err.detail);\n column = col;\n value = val;\n\n switch (code) {\n case \"23502\":\n rpcErrorCode = RuntimeErrors.NotNullConstraintError;\n column = err.column;\n break;\n case \"23503\":\n rpcErrorCode = RuntimeErrors.ForeignKeyConstraintError;\n break;\n case \"23505\":\n rpcErrorCode = RuntimeErrors.UniqueConstraintError;\n break;\n default:\n rpcErrorCode = RuntimeErrors.DatabaseError;\n break;\n }\n\n return createJSONRPCErrorResponse(request.id, rpcErrorCode, e.message, {\n table,\n column,\n code,\n detail,\n value,\n });\n }\n\n // we don't know what it is, but it's something else\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.DatabaseError,\n e.message\n );\n default:\n // Use the errorCode in the error if we have some from a preset\n return createJSONRPCErrorResponse(\n request.id,\n e.errorCode ?? RuntimeErrors.UnknownError,\n e.message\n );\n }\n}\n\n// example data:\n// Key (author_id)=(fake) is not present in table \"author\".\nconst keyMessagePattern = /\\Key\\s[(](.*)[)][=][(](.*)[)]/;\nconst parseKeyMessage = (msg) => {\n const [, col, value] = keyMessagePattern.exec(msg) || [];\n\n return [col, value];\n};\n\nexport {\n errorToJSONRPCResponse,\n RuntimeErrors,\n DatabaseError,\n PermissionError,\n ErrorPresets,\n};\n","import { Duration } from \"./Duration\";\nimport { InlineFile, File } from \"./File\";\nimport { isPlainObject } from \"./type-utils\";\n\n// parseInputs takes a set of inputs and creates objects for the ones that are of a complex type.\n//\n// inputs that are objects and contain a \"__typename\" field are resolved to instances of the complex type\n// they represent.\nfunction parseInputs(inputs) {\n if (inputs != null && typeof inputs === \"object\") {\n for (const k of Object.keys(inputs)) {\n if (inputs[k] !== null && typeof inputs[k] === \"object\") {\n if (Array.isArray(inputs[k])) {\n inputs[k] = inputs[k].map((item) => {\n if (item && typeof item === \"object\") {\n if (\"__typename\" in item) {\n return parseComplexInputType(item);\n }\n // Recursively parse nested objects in arrays\n return parseInputs(item);\n }\n return item;\n });\n } else if (\"__typename\" in inputs[k]) {\n inputs[k] = parseComplexInputType(inputs[k]);\n } else {\n inputs[k] = parseInputs(inputs[k]);\n }\n }\n }\n }\n\n return inputs;\n}\n\n// parseComplexInputType will parse out complex types such as InlineFile and Duration\nfunction parseComplexInputType(value) {\n switch (value.__typename) {\n case \"InlineFile\":\n return InlineFile.fromDataURL(value.dataURL);\n case \"Duration\":\n return Duration.fromISOString(value.interval);\n default:\n throw new Error(\"complex type not handled: \" + value.__typename);\n }\n}\n\n// parseOutputs will take a response from the custom function and perform operations on any fields if necessary.\n//\n// For example, InlineFiles need to be stored before returning the response.\nasync function parseOutputs(outputs) {\n if (outputs != null && typeof outputs === \"object\") {\n for (const k of Object.keys(outputs)) {\n if (outputs[k] !== null && typeof outputs[k] === \"object\") {\n if (Array.isArray(outputs[k])) {\n outputs[k] = await Promise.all(\n outputs[k].map((item) => parseOutputs(item))\n );\n } else if (outputs[k] instanceof InlineFile) {\n const stored = await outputs[k].store();\n outputs[k] = stored;\n } else if (outputs[k] instanceof Duration) {\n outputs[k] = outputs[k].toISOString();\n } else {\n outputs[k] = await parseOutputs(outputs[k]);\n }\n }\n }\n }\n\n return outputs;\n}\n\n// transformRichDataTypes iterates through the given object's keys and if any of the values are a rich data type, instantiate their respective class\nfunction transformRichDataTypes(data) {\n const keys = data ? Object.keys(data) : [];\n const row = {};\n\n for (const key of keys) {\n const value = data[key];\n if (Array.isArray(value)) {\n row[key] = value.map((item) => transformRichDataTypes({ item }).item);\n } else if (isPlainObject(value)) {\n if (value._typename == \"Duration\" && value.pgInterval) {\n row[key] = new Duration(value.pgInterval);\n } else if (\n value.key &&\n value.size &&\n value.filename &&\n value.contentType\n ) {\n row[key] = File.fromDbRecord(value);\n } else {\n row[key] = value;\n }\n } else {\n row[key] = value;\n }\n }\n\n return row;\n}\n\nfunction isReferencingExistingRecord(value) {\n return Object.keys(value).length === 1 && value.id;\n}\n\nexport {\n parseInputs,\n parseOutputs,\n transformRichDataTypes,\n isReferencingExistingRecord,\n};\n","import { sql } from \"kysely\";\nimport { snakeCase } from \"./casing\";\nimport { TimePeriod } from \"./TimePeriod\";\n\nconst opMapping = {\n startsWith: { op: \"like\", value: (v) => `${v}%` },\n endsWith: { op: \"like\", value: (v) => `%${v}` },\n contains: { op: \"like\", value: (v) => `%${v}%` },\n oneOf: { op: \"=\", value: (v) => sql`ANY(${v})` },\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: sql`is not distinct from` },\n notEquals: { op: sql`is distinct from` },\n equalsRelative: {\n op: sql`BETWEEN`,\n value: (v) =>\n sql`${sql.raw(\n TimePeriod.fromExpression(v).periodStartSQL()\n )} AND ${sql.raw(TimePeriod.fromExpression(v).periodEndSQL())}`,\n },\n beforeRelative: {\n op: \"<\",\n value: (v) =>\n sql`${sql.raw(TimePeriod.fromExpression(v).periodStartSQL())}`,\n },\n afterRelative: {\n op: \">=\",\n value: (v) => sql`${sql.raw(TimePeriod.fromExpression(v).periodEndSQL())}`,\n },\n any: {\n isArrayQuery: true,\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: \"=\" },\n notEquals: { op: \"=\", value: (v) => sql`NOT ${v}` },\n },\n all: {\n isArrayQuery: true,\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: \"=\" },\n notEquals: { op: \"=\", value: (v) => sql`NOT ${v}` },\n },\n};\n\n/**\n * Applies the given where conditions to the provided Kysely\n * instance and returns the resulting new Kysely instance.\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} qb\n * @param {Object} where\n * @returns {import(\"kysely\").Kysely}\n */\nfunction applyWhereConditions(context, qb, where = {}) {\n const conf = context.tableConfig();\n for (const key of Object.keys(where)) {\n const v = where[key];\n\n // Handle nested where conditions e.g. using a join table\n if (conf && conf[snakeCase(key)]) {\n const rel = conf[snakeCase(key)];\n context.withJoin(rel.referencesTable, () => {\n qb = applyWhereConditions(context, qb, v);\n });\n continue;\n }\n\n const fieldName = `${context.tableAlias()}.${snakeCase(key)}`;\n\n if (Object.prototype.toString.call(v) !== \"[object Object]\") {\n qb = qb.where(fieldName, sql`is not distinct from`, sql`${v}`);\n continue;\n }\n\n for (const op of Object.keys(v)) {\n const mapping = opMapping[op];\n if (!mapping) {\n throw new Error(`invalid where condition: ${op}`);\n }\n\n if (mapping.isArrayQuery) {\n for (const arrayOp of Object.keys(v[op])) {\n qb = qb.where(\n mapping[arrayOp].value\n ? mapping[arrayOp].value(v[op][arrayOp])\n : sql`${v[op][arrayOp]}`,\n mapping[arrayOp].op,\n sql`${sql(op)}(${sql.ref(fieldName)})`\n );\n }\n } else {\n qb = qb.where(\n fieldName,\n mapping.op,\n mapping.value ? mapping.value(v[op]) : sql`${v[op]}`\n );\n }\n }\n }\n\n return qb;\n}\n\nexport { applyWhereConditions };\n","import { snakeCase, camelCase } from \"change-case\";\n\nfunction camelCaseObject(obj = {}) {\n const r = {};\n for (const key of Object.keys(obj)) {\n r[\n camelCase(key, {\n transform: camelCaseTransform,\n splitRegexp: [\n /([a-z0-9])([A-Z])/g,\n /([A-Z])([A-Z][a-z])/g,\n /([a-zA-Z])([0-9])/g,\n ],\n })\n ] = obj[key];\n }\n return r;\n}\n\nfunction snakeCaseObject(obj) {\n const r = {};\n for (const key of Object.keys(obj)) {\n r[\n snakeCase(key, {\n splitRegexp: [\n /([a-z0-9])([A-Z])/g,\n /([A-Z])([A-Z][a-z])/g,\n /([a-zA-Z])([0-9])/g,\n ],\n })\n ] = obj[key];\n }\n return r;\n}\n\nfunction upperCamelCase(s) {\n s = camelCase(s);\n return s[0].toUpperCase() + s.substring(1);\n}\n\nfunction camelCaseTransform(input, index) {\n if (index === 0) return input.toLowerCase();\n const firstChar = input.charAt(0);\n const lowerChars = input.substr(1).toLowerCase();\n return `${firstChar.toUpperCase()}${lowerChars}`;\n}\n\nexport {\n camelCaseObject,\n snakeCaseObject,\n snakeCase,\n camelCase,\n upperCamelCase,\n};\n","class TimePeriod {\n constructor(period = \"\", value = 0, offset = 0, complete = false) {\n this.period = period;\n this.value = value;\n this.offset = offset;\n this.complete = complete;\n }\n\n static fromExpression(expression) {\n // Regex pattern\n const pattern =\n /^(this|next|last)?\\s*(\\d+)?\\s*(complete)?\\s*(second|minute|hour|day|week|month|year|seconds|minutes|hours|days|weeks|months|years)?$/i;\n\n const shorthandPattern = /^(now|today|tomorrow|yesterday)$/i;\n\n const shorthandMatch = shorthandPattern.exec(expression.trim());\n if (shorthandMatch) {\n const shorthand = shorthandMatch[1].toLowerCase();\n switch (shorthand) {\n case \"now\":\n return new TimePeriod();\n case \"today\":\n return TimePeriod.fromExpression(\"this day\");\n case \"tomorrow\":\n return TimePeriod.fromExpression(\"next complete day\");\n case \"yesterday\":\n return TimePeriod.fromExpression(\"last complete day\");\n }\n }\n\n const match = pattern.exec(expression.trim());\n if (!match) {\n throw new Error(\"Invalid time period expression\");\n }\n\n const [, direction, rawValue, isComplete, rawPeriod] = match;\n\n let period = rawPeriod ? rawPeriod.toLowerCase().replace(/s$/, \"\") : \"\";\n let value = rawValue ? parseInt(rawValue, 10) : 1;\n let complete = Boolean(isComplete);\n let offset = 0;\n\n switch (direction?.toLowerCase()) {\n case \"this\":\n offset = 0;\n complete = true;\n break;\n case \"next\":\n offset = complete ? 1 : 0;\n break;\n case \"last\":\n offset = -value;\n break;\n default:\n throw new Error(\n \"Time period expression must start with this, next, or last\"\n );\n }\n\n return new TimePeriod(period, value, offset, complete);\n }\n\n periodStartSQL() {\n let sql = \"NOW()\";\n if (this.offset !== 0) {\n sql = `${sql} + INTERVAL '${this.offset} ${this.period}'`;\n }\n\n if (this.complete) {\n sql = `DATE_TRUNC('${this.period}', ${sql})`;\n } else {\n sql = `(${sql})`;\n }\n\n return sql;\n }\n\n periodEndSQL() {\n let sql = this.periodStartSQL();\n if (this.value != 0) {\n sql = `(${sql} + INTERVAL '${this.value} ${this.period}')`;\n }\n return sql;\n }\n}\n\nexport { TimePeriod };\n","import { snakeCase } from \"./casing\";\n\nfunction applyLimit(context, qb, limit) {\n return qb.limit(limit);\n}\n\nfunction applyOffset(context, qb, offset) {\n return qb.offset(offset);\n}\n\nfunction applyOrderBy(context, qb, tableName, orderBy = {}) {\n Object.entries(orderBy).forEach(([key, sortOrder]) => {\n qb = qb.orderBy(`${tableName}.${snakeCase(key)}`, sortOrder.toLowerCase());\n });\n return qb;\n}\n\nexport { applyLimit, applyOffset, applyOrderBy };\n","import { snakeCase } from \"./casing\";\n\n/**\n * Adds the joins required by the where conditions to the given\n * Kysely instance and returns the resulting new Kysely instance.\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} qb\n * @param {Object} where\n * @returns {import(\"kysely\").Kysely}\n */\nfunction applyJoins(context, qb, where) {\n const conf = context.tableConfig();\n if (!conf) {\n return qb;\n }\n\n const srcTable = context.tableAlias();\n\n for (const key of Object.keys(where)) {\n const rel = conf[snakeCase(key)];\n if (!rel) {\n continue;\n }\n\n const targetTable = rel.referencesTable;\n\n if (context.hasJoin(targetTable)) {\n continue;\n }\n\n context.withJoin(targetTable, () => {\n switch (rel.relationshipType) {\n case \"hasMany\":\n // For hasMany the primary key is on the source table\n // and the foreign key is on the target table\n qb = qb.innerJoin(\n `${targetTable} as ${context.tableAlias()}`,\n `${srcTable}.id`,\n `${context.tableAlias()}.${rel.foreignKey}`\n );\n break;\n\n case \"belongsTo\":\n // For belongsTo the primary key is on the target table\n // and the foreign key is on the source table\n qb = qb.innerJoin(\n `${targetTable} as ${context.tableAlias()}`,\n `${srcTable}.${rel.foreignKey}`,\n `${context.tableAlias()}.id`\n );\n break;\n default:\n throw new Error(`unknown relationshipType: ${rel.relationshipType}`);\n }\n\n // Keep traversing through the where conditions to see if\n // more joins need to be applied\n qb = applyJoins(context, qb, where[key]);\n });\n }\n\n return qb;\n}\n\nexport { applyJoins };\n","/**\n * QueryContext is used to store state about the current query, for example\n * which joins have already been applied. It is used by applyJoins and\n * applyWhereConditions to generate consistent table aliases for joins.\n *\n * This class has the concept of a \"table path\". This is just a list of tables, starting\n * with some \"root\" table and ending with the table we're currently joining to. So\n * for example if we started with a \"product\" table and joined from there to \"order_item\"\n * and then to \"order\" and then to \"customer\" the table path would be:\n * [\"product\", \"order_item\", \"order\", \"customer\"]\n * At this point the \"current\" table is \"customer\" and it's alias would be:\n * \"product$order_item$order$customer\"\n */\nclass QueryContext {\n /**\n * @param {string[]} tablePath This is the path from the \"root\" table to the \"current table\".\n * @param {import(\"./ModelAPI\").TableConfigMap} tableConfigMap\n * @param {string[]} joins\n */\n constructor(tablePath, tableConfigMap, joins = []) {\n this._tablePath = tablePath;\n this._tableConfigMap = tableConfigMap;\n this._joins = joins;\n }\n\n clone() {\n return new QueryContext([...this._tablePath], this._tableConfigMap, [\n ...this._joins,\n ]);\n }\n\n /**\n * Returns true if, given the current table path, a join to the given\n * table has already been added.\n * @param {string} table\n * @returns {boolean}\n */\n hasJoin(table) {\n const alias = joinAlias([...this._tablePath, table]);\n return this._joins.includes(alias);\n }\n\n /**\n * Adds table to the QueryContext's path and registers the join,\n * calls fn, then pops the table off the path.\n * @param {string} table\n * @param {Function} fn\n */\n withJoin(table, fn) {\n this._tablePath.push(table);\n this._joins.push(this.tableAlias());\n\n fn();\n\n // Don't change the _joins list, we want to remember those\n this._tablePath.pop();\n }\n\n /**\n * Returns the alias that will be used for the current table\n * @returns {string}\n */\n tableAlias() {\n return joinAlias(this._tablePath);\n }\n\n /**\n * Returns the current table name\n * @returns {string}\n */\n tableName() {\n return this._tablePath[this._tablePath.length - 1];\n }\n\n /**\n * Return the TableConfig for the current table\n * @returns {import(\"./ModelAPI\").TableConfig | undefined}\n */\n tableConfig() {\n return this._tableConfigMap[this.tableName()];\n }\n}\n\nfunction joinAlias(tablePath) {\n return tablePath.join(\"$\");\n}\n\nexport { QueryContext };\n","import { applyWhereConditions } from \"./applyWhereConditions\";\nimport {\n applyLimit,\n applyOffset,\n applyOrderBy,\n} from \"./applyAdditionalQueryConstraints\";\nimport { applyJoins } from \"./applyJoins\";\nimport { camelCaseObject, snakeCaseObject, upperCamelCase } from \"./casing\";\nimport { useDatabase } from \"./database\";\nimport { transformRichDataTypes } from \"./parsing\";\nimport { QueryContext } from \"./QueryContext\";\nimport * as tracing from \"./tracing\";\nimport { DatabaseError } from \"./errors\";\n\nclass QueryBuilder {\n /**\n * @param {string} tableName\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} db\n */\n constructor(tableName, context, db) {\n this._tableName = tableName;\n this._context = context;\n this._db = db;\n this._modelName = upperCamelCase(this._tableName);\n }\n\n where(where) {\n const context = this._context.clone();\n\n let builder = applyJoins(context, this._db, where);\n builder = applyWhereConditions(context, builder, where);\n\n return new QueryBuilder(this._tableName, context, builder);\n }\n\n sql() {\n return this._db.compile().sql;\n }\n\n async update(values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"update\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n // we build a sub-query to add to the WHERE id IN (XXX) containing all of the\n // wheres added in previous .where() chains.\n const sub = this._db.clearSelect().select(\"id\");\n\n const query = db\n .updateTable(this._tableName)\n .set(snakeCaseObject(values))\n .returningAll()\n .where(\"id\", \"in\", sub);\n\n try {\n const result = await query.execute();\n const numUpdatedRows = result.length;\n\n // the double (==) is important because we are comparing bigint to int\n if (numUpdatedRows == 0) {\n return null;\n }\n\n if (numUpdatedRows > 1) {\n throw new DatabaseError(\n new Error(\n \"more than one row matched update constraints - only unique fields should be used when updating.\"\n )\n );\n }\n\n return transformRichDataTypes(camelCaseObject(result[0]));\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async delete() {\n const name = tracing.spanNameForModelAPI(this._modelName, \"delete\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n // the original query selects the distinct id + the model.* so we need to clear\n const sub = this._db.clearSelect().select(\"id\");\n let builder = db.deleteFrom(this._tableName).where(\"id\", \"in\", sub);\n\n const query = builder.returning([\"id\"]);\n\n // final query looks something like:\n // delete from \"person\" where \"id\" in (select distinct on (\"person\".\"id\") \"id\" from \"person\" where \"person\".\"id\" = $1) returning \"id\"\n\n span.setAttribute(\"sql\", query.compile().sql);\n\n try {\n const row = await query.executeTakeFirstOrThrow();\n return row.id;\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async findOne() {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findOne\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db\n .selectFrom((qb) => {\n // this._db contains all of the where constraints and joins\n // we want to include that in the sub query in the same way we\n // add all of this information into the sub query in the ModelAPI's\n // implementation of findOne\n return this._db.as(this._tableName);\n })\n .selectAll();\n\n span.setAttribute(\"sql\", builder.compile().sql);\n\n const row = await builder.executeTakeFirst();\n if (!row) {\n return null;\n }\n\n return transformRichDataTypes(camelCaseObject(row));\n });\n }\n\n async findMany(params) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findMany\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n let builder = db\n .selectFrom((qb) => {\n // this._db contains all of the where constraints and joins\n // we want to include that in the sub query in the same way we\n // add all of this information into the sub query in the ModelAPI's\n // implementation of findMany\n return this._db.as(this._tableName);\n })\n .selectAll();\n\n // The only constraints added to the main query are the orderBy, limit and offset as they are performed on the \"outer\" set\n if (params?.limit) {\n builder = applyLimit(context, builder, params.limit);\n }\n\n if (params?.offset) {\n builder = applyOffset(context, builder, params.offset);\n }\n\n if (\n params?.orderBy !== undefined &&\n Object.keys(params?.orderBy).length > 0\n ) {\n builder = applyOrderBy(\n context,\n builder,\n this._tableName,\n params.orderBy\n );\n } else {\n builder = builder.orderBy(`${this._tableName}.id`);\n }\n\n const query = builder;\n\n span.setAttribute(\"sql\", query.compile().sql);\n const rows = await builder.execute();\n return rows.map((x) => transformRichDataTypes(camelCaseObject(x)));\n });\n }\n}\n\nexport { QueryBuilder };\n","interface RequestHeadersMap {\n [key: string]: string;\n}\n\nexport class RequestHeaders {\n private _headers: Headers;\n\n /**\n * @param {{Object.<string, string>}} requestHeaders Map of request headers submitted from the client\n */\n\n constructor(requestHeaders: RequestHeadersMap) {\n this._headers = new Headers(requestHeaders);\n }\n\n get: Headers[\"get\"] = (key: string) => {\n return this._headers.get(key);\n };\n\n has: Headers[\"has\"] = (key: string) => {\n return this._headers.has(key);\n };\n}\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { tryExecuteFunction } from \"./tryExecuteFunction\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { parseInputs, parseOutputs } from \"./parsing\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a custom function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleRequest(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n if (process.env.KEEL_LOG_LEVEL == \"debug\") {\n console.log(request);\n }\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createContextAPI, functions, permissionFns, actionTypes } =\n config;\n\n if (!(request.method in functions)) {\n const message = `no corresponding function found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // headers reference passed to custom function where object data can be modified\n const headers = new Headers();\n\n // The ctx argument passed into the custom function.\n const ctx = createContextAPI({\n responseHeaders: headers,\n meta: request.meta,\n });\n\n // The Go runtime does *some* permissions checks up front before the request reaches\n // this method, so we pass in a permissionState object on the request.meta object that\n // indicates whether a call to a custom function has already been authorised\n const permitted =\n request.meta && request.meta.permissionState.status === \"granted\"\n ? true\n : null;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const customFunction = functions[request.method];\n const actionType = actionTypes[request.method];\n\n const functionConfig = customFunction?.config ?? {};\n\n const result = await tryExecuteFunction(\n {\n request,\n ctx,\n permitted,\n db,\n permissionFns,\n actionType,\n functionConfig,\n },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the custom function to the containing tryExecuteFunction block\n // Once the custom function is called, tryExecuteFunction will check the schema's permission rules to see if it can continue committing\n // the transaction to the db. If a permission rule is violated, any changes made inside the transaction are rolled back.\n const result = await customFunction(ctx, inputs);\n\n return parseOutputs(result);\n }\n );\n\n if (result instanceof Error) {\n span.recordException(result);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: result.message,\n });\n return errorToJSONRPCResponse(request, result);\n }\n\n const response = createJSONRPCSuccessResponse(request.id, result);\n\n const responseHeaders = {};\n for (const pair of headers.entries()) {\n responseHeaders[pair[0]] = pair[1].split(\", \");\n }\n response.meta = {\n headers: responseHeaders,\n status: ctx.response.status,\n };\n\n return response;\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleRequest, RuntimeErrors };\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { PermissionError } from \"./errors\";\n\nexport const PERMISSION_STATE = {\n UNKNOWN: \"unknown\",\n PERMITTED: \"permitted\",\n UNPERMITTED: \"unpermitted\",\n} as const;\n\nexport type PermissionState =\n (typeof PERMISSION_STATE)[keyof typeof PERMISSION_STATE];\n\n/**\n * Permissions class for managing access control in the runtime\n */\nexport class Permissions {\n // The Go runtime performs role based permission rule checks prior to calling the functions\n // runtime, so the status could already be granted. If already granted, then we need to inherit that permission state as the state is later used to decide whether to run in process permission checks\n // TLDR if a role based permission is relevant and it is granted, then it is effectively the same as the end user calling api.permissions.allow() explicitly in terms of behaviour.\n\n /**\n * Explicitly permit access to an action\n */\n allow(): void {\n permissionsApiInstance.getStore()!.permitted = true;\n }\n\n /**\n * Explicitly deny access to an action\n */\n deny(): never {\n // if a user is explicitly calling deny() then we want to throw an error\n // so that any further execution of the custom function stops abruptly\n permissionsApiInstance.getStore()!.permitted = false;\n throw new PermissionError();\n }\n\n getState(): PermissionState {\n const permitted = permissionsApiInstance.getStore()!.permitted;\n\n switch (true) {\n case permitted === false:\n return PERMISSION_STATE.UNPERMITTED;\n case permitted === null:\n return PERMISSION_STATE.UNKNOWN;\n case permitted === true:\n return PERMISSION_STATE.PERMITTED;\n default:\n return PERMISSION_STATE.UNKNOWN;\n }\n }\n}\n\ninterface PermissionStore {\n permitted: boolean | null;\n}\n\nconst permissionsApiInstance = new AsyncLocalStorage<PermissionStore>();\n\ninterface PermissionCallback {\n getPermissionState: () => PermissionState;\n}\n\n// withPermissions sets the initial permission state from the go runtime in the AsyncLocalStorage so consumers further down the hierarchy can read or mutate the state\n// at will\nexport const withPermissions = async <T>(\n initialValue: boolean | null,\n cb: (permissions: PermissionCallback) => Promise<T>\n): Promise<T> => {\n const permissions = new Permissions();\n\n return await permissionsApiInstance.run({ permitted: initialValue }, () => {\n return cb({ getPermissionState: permissions.getState });\n });\n};\n\ninterface CheckBuiltInPermissionsParams {\n rows: any[];\n permissionFns: Array<(rows: any[], ctx: any, db: any) => Promise<boolean>>;\n ctx: any;\n db: any;\n functionName: string;\n}\n\nexport const checkBuiltInPermissions = async ({\n rows,\n permissionFns,\n ctx,\n db,\n functionName,\n}: CheckBuiltInPermissionsParams): Promise<void> => {\n for (const permissionFn of permissionFns) {\n const result = await permissionFn(rows, ctx, db);\n // if any of the permission functions return true,\n // then we return early\n if (result) {\n return;\n }\n }\n\n throw new PermissionError(`Not permitted to access ${functionName}`);\n};\n\nexport { PermissionError };\nexport { permissionsApiInstance };\n","const PROTO_ACTION_TYPES = {\n UNKNOWN: \"ACTION_TYPE_UNKNOWN\",\n CREATE: \"ACTION_TYPE_CREATE\",\n GET: \"ACTION_TYPE_GET\",\n LIST: \"ACTION_TYPE_LIST\",\n UPDATE: \"ACTION_TYPE_UPDATE\",\n DELETE: \"ACTION_TYPE_DELETE\",\n READ: \"ACTION_TYPE_READ\",\n WRITE: \"ACTION_TYPE_WRITE\",\n JOB: \"JOB_TYPE\",\n SUBSCRIBER: \"SUBSCRIBER_TYPE\",\n FLOW: \"FLOW_TYPE\",\n};\n\nexport { PROTO_ACTION_TYPES };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport {\n withPermissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n} from \"./permissions\";\nimport { PermissionError } from \"./errors\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\n\n// tryExecuteFunction will create a new database transaction around a function call\n// and handle any permissions checks. If a permission check fails, then an Error will be thrown and the catch block will be hit.\nfunction tryExecuteFunction(\n { request, db, permitted, permissionFns, actionType, ctx, functionConfig },\n cb\n) {\n return withPermissions(permitted, async ({ getPermissionState }) => {\n let requiresTransaction = true;\n switch (actionType) {\n case PROTO_ACTION_TYPES.GET:\n case PROTO_ACTION_TYPES.LIST:\n case PROTO_ACTION_TYPES.READ:\n requiresTransaction = false;\n break;\n }\n\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n\n return withDatabase(db, requiresTransaction, async ({ transaction }) => {\n const fnResult = await withAuditContext(request, async () => {\n return cb();\n });\n\n // api.permissions maintains an internal state of whether the current function has been *explicitly* permitted/denied by the user in the course of their custom function, or if execution has already been permitted by a role based permission (evaluated in the main runtime).\n // we need to check that the final state is permitted or unpermitted. if it's not, then it means that the user has taken no explicit action to permit/deny\n // and therefore we default to checking the permissions defined in the schema automatically.\n switch (getPermissionState()) {\n case PERMISSION_STATE.PERMITTED:\n return fnResult;\n case PERMISSION_STATE.UNPERMITTED:\n throw new PermissionError(\n `Not permitted to access ${request.method}`\n );\n default:\n // unknown state, proceed with checking against the built in permissions in the schema\n const relevantPermissions = permissionFns[request.method];\n\n const peakInsideTransaction =\n actionType === PROTO_ACTION_TYPES.CREATE;\n\n let rowsForPermissions = [];\n if (fnResult != null) {\n switch (actionType) {\n case PROTO_ACTION_TYPES.LIST:\n rowsForPermissions = fnResult;\n break;\n case PROTO_ACTION_TYPES.DELETE:\n rowsForPermissions = [{ id: fnResult }];\n break;\n case (PROTO_ACTION_TYPES.GET, PROTO_ACTION_TYPES.CREATE):\n rowsForPermissions = [fnResult];\n break;\n default:\n rowsForPermissions = [fnResult];\n break;\n }\n }\n\n // check will throw a PermissionError if a permission rule is invalid\n await checkBuiltInPermissions({\n rows: rowsForPermissions,\n permissionFns: relevantPermissions,\n // it is important that we pass db here as db represents the connection to the database\n // *outside* of the current transaction. Given that any changes inside of a transaction\n // are opaque to the outside, we can utilize this when running permission rules and then deciding to\n // rollback any changes if they do not pass. However, for creates we need to be able to 'peak' inside the transaction to read the created record, as this won't exist outside of the transaction.\n db: peakInsideTransaction ? transaction : db,\n ctx,\n functionName: request.method,\n });\n\n // If the built in permission check above doesn't throw, then it means that the request is permitted and we can continue returning the return value from the custom function out of the transaction\n return fnResult;\n }\n });\n });\n}\n\nexport { tryExecuteFunction };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { tryExecuteJob } from \"./tryExecuteJob\";\nimport { parseInputs } from \"./parsing\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a job function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleJob(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createJobContextAPI, jobs } = config;\n\n if (!(request.method in jobs)) {\n const message = `no corresponding job found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // The ctx argument passed into the job function.\n const ctx = createJobContextAPI({\n meta: request.meta,\n });\n\n const permitted =\n request.meta && request.meta.permissionState.status === \"granted\"\n ? true\n : null;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const jobFunction = jobs[request.method];\n const actionType = PROTO_ACTION_TYPES.JOB;\n\n const functionConfig = jobFunction?.config ?? {};\n\n await tryExecuteJob(\n { request, permitted, db, actionType, functionConfig },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the job function to the containing tryExecuteJob block\n return jobFunction(ctx, inputs);\n }\n );\n\n return createJSONRPCSuccessResponse(request.id, null);\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleJob, RuntimeErrors };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport { withPermissions, PERMISSION_STATE } from \"./permissions\";\nimport { PermissionError } from \"./errors\";\n\n// tryExecuteJob will create a new database transaction around a function call\n// and handle any permissions checks. If a permission check fails, then an Error will be thrown and the catch block will be hit.\nfunction tryExecuteJob({ db, permitted, request, functionConfig }, cb) {\n return withPermissions(permitted, async ({ getPermissionState }) => {\n let requiresTransaction = false;\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n return withDatabase(db, requiresTransaction, async () => {\n await withAuditContext(request, async () => {\n return cb();\n });\n\n // api.permissions maintains an internal state of whether the current operation has been *explicitly* permitted/denied by the user in the course of their custom function, or if execution has already been permitted by a role based permission (evaluated in the main runtime).\n // we need to check that the final state is permitted or unpermitted. if it's not, then it means that the user has taken no explicit action to permit/deny\n // and therefore we default to checking the permissions defined in the schema automatically.\n if (getPermissionState() === PERMISSION_STATE.UNPERMITTED) {\n throw new PermissionError(`Not permitted to access ${request.method}`);\n }\n });\n });\n}\n\nexport { tryExecuteJob };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\nimport { tryExecuteSubscriber } from \"./tryExecuteSubscriber\";\nimport { parseInputs } from \"./parsing\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a subscriber function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleSubscriber(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createSubscriberContextAPI, subscribers } = config;\n\n if (!(request.method in subscribers)) {\n const message = `no corresponding subscriber found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // The ctx argument passed into the subscriber function.\n const ctx = createSubscriberContextAPI({\n meta: request.meta,\n });\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const subscriberFunction = subscribers[request.method];\n const actionType = PROTO_ACTION_TYPES.SUBSCRIBER;\n\n const functionConfig = subscriberFunction?.config ?? {};\n\n await tryExecuteSubscriber(\n { request, db, actionType, functionConfig },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the subscriber function to the containing tryExecuteSubscriber block\n return subscriberFunction(ctx, inputs);\n }\n );\n\n return createJSONRPCSuccessResponse(request.id, null);\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleSubscriber, RuntimeErrors };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\n\n// tryExecuteSubscriber will create a new database connection and execute the function call.\nfunction tryExecuteSubscriber({ request, db, functionConfig }, cb) {\n let requiresTransaction = false;\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n return withDatabase(db, requiresTransaction, async () => {\n await withAuditContext(request, async () => {\n return cb();\n });\n });\n}\n\nexport { tryExecuteSubscriber };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient, withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\n\nasync function handleRoute(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createContextAPI, functions } = config;\n\n if (!(request.method in functions)) {\n const message = `no route function found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // For route functions context doesn't need request headers or the response object as this is handled by\n // params and the function response respectively\n const {\n headers,\n response: __,\n ...ctx\n } = createContextAPI({\n responseHeaders: new Headers(),\n meta: request.meta,\n });\n\n // Add request headers to params\n request.params.headers = headers;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const routeHandler = functions[request.method];\n\n const result = await withDatabase(db, false, () => {\n return withAuditContext(request, () => {\n return routeHandler(request.params, ctx);\n });\n });\n\n if (result instanceof Error) {\n span.recordException(result);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: result.message,\n });\n return errorToJSONRPCResponse(request, result);\n }\n\n const response = createJSONRPCSuccessResponse(request.id, result);\n\n return response;\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleRoute, RuntimeErrors };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { tryExecuteFlow } from \"./tryExecuteFlow\";\nimport { parseInputs } from \"./parsing\";\nimport { createFlowContext } from \"./flows\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n} from \"./flows/disrupts\";\n\nasync function handleFlow(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n let flowConfig = null;\n const runId = request.meta?.runId;\n\n try {\n if (!runId) {\n throw new Error(\"no runId provided\");\n }\n\n const { flows } = config;\n\n if (!(request.method in flows)) {\n const message = `no corresponding flow found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n\n const flowRun = await db\n .selectFrom(\"keel.flow_run\")\n .where(\"id\", \"=\", runId)\n .selectAll()\n .executeTakeFirst();\n\n if (!flowRun) {\n throw new Error(\"no flow run found\");\n }\n\n const ctx = createFlowContext(\n request.meta.runId,\n request.meta.data,\n span.spanContext().spanId\n );\n\n const flowFunction = flows[request.method].fn;\n flowConfig = flows[request.method].config;\n\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(flowRun.input);\n\n try {\n await tryExecuteFlow(db, async () => {\n return flowFunction(ctx, inputs);\n });\n } catch (e) {\n // The flow is disrupted as a new step has been created\n if (e instanceof StepCreatedDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: false,\n config: flowConfig,\n });\n }\n\n // The flow is disrupted by a pending UI step\n if (e instanceof UIRenderDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n stepId: e.stepId,\n config: flowConfig,\n ui: e.contents,\n });\n }\n\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n\n // The flow has failed due to exhausted step retries\n if (e instanceof ExhuastedRetriesDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n error: \"flow failed due to exhausted step retries\",\n config: flowConfig,\n });\n }\n\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n error: e.message,\n config: flowConfig,\n });\n }\n\n // If we reach this point, then we know the entire flow completed successfully\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n config: flowConfig,\n });\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleFlow, RuntimeErrors };\n","import { withDatabase } from \"./database\";\n\nfunction tryExecuteFlow(db, cb) {\n return withDatabase(db, false, async () => {\n return cb();\n });\n}\n\nexport { tryExecuteFlow };\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = string;\n\nexport type UiElementInputText = InputElement<\n ElementDataType,\n {\n placeholder?: string;\n multiline?: boolean;\n maxLength?: number;\n minLength?: number;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputTextApiResponse\n extends BaseUiInputResponse<\"ui.input.text\", ElementDataType> {\n placeholder?: string;\n multiline?: boolean;\n maxLength?: number;\n minLength?: number;\n}\n\nexport const textInput: InputElementImplementation<\n ElementDataType,\n UiElementInputText,\n UiElementInputTextApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.text\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n placeholder: options?.placeholder,\n multiline: options?.multiline,\n maxLength: options?.maxLength,\n minLength: options?.minLength,\n } satisfies UiElementInputTextApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = number;\n\nexport type UiElementInputNumber = InputElement<\n ElementDataType,\n {\n placeholder?: number;\n min?: number;\n max?: number;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputNumberApiResponse\n extends BaseUiInputResponse<\"ui.input.number\", ElementDataType> {\n placeholder?: number;\n min?: number;\n max?: number;\n}\n\nexport const numberInput: InputElementImplementation<\n ElementDataType,\n UiElementInputNumber,\n UiElementInputNumberApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.number\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n placeholder: options?.placeholder,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputNumberApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementDivider = DisplayElement<{}>;\n\n// The shape of the response over the API\nexport interface UiElementDividerApiResponse\n extends BaseUiDisplayResponse<\"ui.display.divider\"> {}\n\nexport const divider: DisplayElementImplementation<\n UiElementDivider,\n UiElementDividerApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.divider\",\n } satisfies UiElementDividerApiResponse,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = boolean;\n\nexport type UiElementInputBoolean = InputElement<\n ElementDataType,\n {\n mode?: \"checkbox\" | \"switch\";\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputBooleanApiResponse\n extends BaseUiInputResponse<\"ui.input.boolean\", ElementDataType> {\n mode: \"checkbox\" | \"switch\";\n}\n\nexport const booleanInput: InputElementImplementation<\n ElementDataType,\n UiElementInputBoolean,\n UiElementInputBooleanApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.boolean\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n mode: options?.mode || \"checkbox\",\n } satisfies UiElementInputBooleanApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementMarkdown = DisplayElement<{\n content: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementMarkdownApiResponse\n extends BaseUiDisplayResponse<\"ui.display.markdown\"> {\n content: string;\n}\n\nexport const markdown: DisplayElementImplementation<\n UiElementMarkdown,\n UiElementMarkdownApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.markdown\",\n content: options?.content || \"\",\n } satisfies UiElementMarkdownApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype TableData<T extends Record<string, any>> = {\n data: T[];\n columns?: Array<Extract<keyof T, string>>;\n};\n\nexport type UiElementTable = <const T extends Record<string, any>>(\n options: TableData<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementTableApiResponse\n extends BaseUiDisplayResponse<\"ui.display.table\"> {\n data: any[];\n columns?: string[]; // Todo: support for an object form with extra context on the data type\n}\n\nexport const table: DisplayElementImplementation<\n UiElementTable,\n UiElementTableApiResponse\n> = (options) => {\n // Only send data for columns we need\n const filteredData = options.columns\n ? options.data.map((item) => {\n return Object.fromEntries(\n Object.entries(item).filter(\n ([key]) => options.columns?.includes(key as any)\n )\n );\n })\n : options.data;\n\n return {\n uiConfig: {\n __type: \"ui.display.table\",\n data: filteredData || [],\n columns: options.columns,\n } satisfies UiElementTableApiResponse,\n };\n};\n","import {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\n\ntype ElementDataType = string | number | boolean | Date;\n\n// Annoyingly can't use the whole InputElement type and also use a local\n// bounded type parameter to infer the type of the value from the config options\n// So having to duplicate the types of the inputs\nexport type UiElementSelectOne = <\n const TValue extends ElementDataType,\n N extends string,\n>(\n name: N,\n options?: BaseInputConfig<TValue> & {\n options: (\n | {\n label: string;\n value: TValue;\n }\n | TValue\n )[];\n }\n) => InputElementResponse<N, TValue>;\n\n// The shape of the response over the API\nexport interface UiElementSelectOneApiResponse\n extends BaseUiInputResponse<\"ui.select.one\", ElementDataType> {\n options: (\n | {\n label: string;\n value: ElementDataType;\n }\n | ElementDataType\n )[];\n}\n\nexport const selectOne: InputElementImplementation<\n ElementDataType,\n UiElementSelectOne,\n UiElementSelectOneApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.select.one\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n options: options?.options || [],\n } satisfies UiElementSelectOneApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n };\n};\n","import { FlowConfig, ExtractStageKeys } from \"..\";\nimport {\n BaseUiDisplayResponse,\n ImplementationResponse,\n InputElementResponse,\n UiElementApiResponses,\n UIElements,\n} from \".\";\n\ntype PageOptions<\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n> = {\n stage?: ExtractStageKeys<C>;\n title?: string;\n description?: string;\n content: T;\n validate?: (data: ExtractFormData<T>) => Promise<true | string>;\n actions?: A;\n};\nexport type UiPage<C extends FlowConfig> = <\n T extends UIElements,\n const A extends PageActions[] = [],\n>(\n name: string,\n options: PageOptions<C, A, T>\n) => A[\"length\"] extends 0\n ? ExtractFormData<T>\n : { data: ExtractFormData<T>; action: ActionValue<A[number]> };\n\ntype PageActions =\n | string\n | {\n label: string;\n value: string;\n mode?: \"primary\" | \"secondary\" | \"destructive\";\n };\n\nexport interface UiPageApiResponse extends BaseUiDisplayResponse<\"ui.page\"> {\n stage?: string;\n title?: string;\n description?: string;\n actions?: PageActions[];\n content: UiElementApiResponses;\n}\n\nexport const page = <\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n>(\n options: PageOptions<C, A, T>\n): UiPageApiResponse => {\n // Turn these back into the actual response types\n const content = options.content as unknown as ImplementationResponse<\n any,\n any\n >[];\n\n // TODO Validation\n // for (const c of content) {\n // if ('__type' in c && c.__type === \"input\") {\n // c.validate()\n // }\n // }\n\n const contentUiConfig = content\n .map((c) => c.uiConfig)\n .filter(Boolean) as UiElementApiResponses;\n\n return {\n __type: \"ui.page\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig,\n actions: options.actions,\n };\n};\n\n/* ********************\n * Helper functions\n ******************* */\n\n// Extract the key from a custom action, supporting either a string or an object with a value property\ntype ActionValue<T> = T extends string\n ? T\n : T extends { value: infer V }\n ? V\n : never;\n\n// Extract the data from elements and return a key-value object based on the name of the element\ntype ExtractFormData<T extends UIElements> = {\n [K in Extract<T[number], InputElementResponse<string, any>>[\"name\"]]: Extract<\n T[number],\n InputElementResponse<K, any>\n >[\"valueType\"];\n};\n","// This is a special type that is thrown to disrupt the execution of a flow\nabstract class FlowDisrupt {\n protected constructor() {}\n}\n\nexport class UIRenderDisrupt extends FlowDisrupt {\n constructor(\n public readonly stepId: string,\n public readonly contents: any\n ) {\n super();\n }\n}\n\nexport class StepErrorDisrupt extends FlowDisrupt {\n constructor(public readonly message: string) {\n super();\n }\n}\n\nexport class StepCreatedDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n\nexport class ExhuastedRetriesDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\ntype BannerMode = \"info\" | \"warning\" | \"error\" | \"success\";\n\nexport type UiElementBanner = DisplayElement<{\n title: string;\n description: string;\n mode?: BannerMode;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementBannerApiResponse\n extends BaseUiDisplayResponse<\"ui.display.banner\"> {\n title: string;\n description: string;\n mode: BannerMode;\n}\n\nexport const banner: DisplayElementImplementation<\n UiElementBanner,\n UiElementBannerApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.banner\",\n title: options?.title || \"\",\n description: options?.description || \"\",\n mode: options?.mode || \"info\",\n } satisfies UiElementBannerApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementImage = DisplayElement<{\n url: string;\n alt?: string;\n size?: \"thumbnail\" | \"small\" | \"medium\" | \"large\" | \"full\";\n title?: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementImageApiResponse\n extends BaseUiDisplayResponse<\"ui.display.image\"> {\n url: string;\n alt?: string;\n size?: \"thumbnail\" | \"small\" | \"medium\" | \"large\" | \"full\";\n title?: string;\n}\n\nexport const image: DisplayElementImplementation<\n UiElementImage,\n UiElementImageApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.image\",\n url: options?.url || \"\",\n alt: options?.alt,\n size: options?.size,\n title: options?.title,\n } satisfies UiElementImageApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementCode = DisplayElement<{\n code: string;\n language?: string; // TODO: type the supported languages\n}>;\n\n// The shape of the response over the API\nexport interface UiElementCodeApiResponse\n extends BaseUiDisplayResponse<\"ui.display.code\"> {\n code: string;\n language?: string;\n}\n\nexport const code: DisplayElementImplementation<\n UiElementCode,\n UiElementCodeApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.code\",\n code: options?.code || \"\",\n language: options?.language,\n } satisfies UiElementCodeApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype ImageConfig = {\n url: string;\n alt?: string;\n aspectRatio?: number;\n fit?: \"cover\" | \"contain\";\n};\n\ntype GridItem = {\n title?: string;\n description?: string;\n image?: ImageConfig;\n};\n\nexport type GridOptions<T> = {\n data: T[];\n render: (data: T) => GridItem;\n};\n\n// The types the user experiences\nexport type UiElementGrid = <T extends any>(\n options: GridOptions<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementGridApiResponse\n extends BaseUiDisplayResponse<\"ui.display.grid\"> {\n data: GridItem[];\n}\n\n// The implementation\nexport const grid: DisplayElementImplementation<\n UiElementGrid,\n UiElementGridApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.grid\",\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n title: rendered.title,\n description: rendered.description,\n image: rendered.image,\n } satisfies GridItem;\n }),\n } satisfies UiElementGridApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype ImageConfig = {\n url: string;\n alt?: string;\n fit?: \"cover\" | \"contain\";\n};\n\ntype ListItem = {\n title?: string;\n description?: string;\n image?: ImageConfig;\n};\n\ntype ListOptions<T> = {\n data: T[];\n render: (data: T) => ListItem;\n};\n\n// The types the user experiences\nexport type UiElementList = <T extends any>(\n options: ListOptions<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementListApiResponse\n extends BaseUiDisplayResponse<\"ui.display.list\"> {\n data: ListItem[];\n}\n\n// The implementation\nexport const list: DisplayElementImplementation<\n UiElementList,\n UiElementListApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.list\",\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n title: rendered.title,\n description: rendered.description,\n image: rendered.image,\n } satisfies ListItem;\n }),\n } satisfies UiElementListApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementHeader = DisplayElement<{\n level: 1 | 2 | 3;\n title?: string;\n description?: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementHeaderApiResponse\n extends BaseUiDisplayResponse<\"ui.display.header\"> {\n level: number;\n title: string;\n description: string;\n}\n\nexport const header: DisplayElementImplementation<\n UiElementHeader,\n UiElementHeaderApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.header\",\n level: options?.level || 1,\n title: options?.title || \"\",\n description: options?.description || \"\",\n } satisfies UiElementHeaderApiResponse,\n };\n};\n","import { UI } from \"./ui\";\nimport { useDatabase } from \"../database\";\nimport { textInput } from \"./ui/elements/input/text\";\nimport { numberInput } from \"./ui/elements/input/number\";\nimport { divider } from \"./ui/elements/display/divider\";\nimport { booleanInput } from \"./ui/elements/input/boolean\";\nimport { markdown } from \"./ui/elements/display/markdown\";\nimport { table } from \"./ui/elements/display/table\";\nimport { selectOne } from \"./ui/elements/select/one\";\nimport { page, UiPage } from \"./ui/page\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n} from \"./disrupts\";\nimport { banner } from \"./ui/elements/display/banner\";\nimport { image } from \"./ui/elements/display/image\";\nimport { code } from \"./ui/elements/display/code\";\nimport { grid } from \"./ui/elements/display/grid\";\nimport { list } from \"./ui/elements/display/list\";\nimport { header } from \"./ui/elements/display/header\";\n\nconst enum STEP_STATUS {\n NEW = \"NEW\",\n RUNNING = \"RUNNING\",\n PENDING = \"PENDING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n}\n\nconst enum STEP_TYPE {\n FUNCTION = \"FUNCTION\",\n UI = \"UI\",\n DELAY = \"DELAY\",\n}\n\nconst defaultOpts = {\n maxRetries: 5,\n timeoutInMs: 60000,\n};\n\nexport interface FlowContext<C extends FlowConfig> {\n step: Step<C>;\n ui: UI<C>;\n}\n\n// Steps can only return values that can be serialized to JSON and then\n// deserialized back to the same object/value that represents the type.\n// i.e. the string, number and boolean primitives, and arrays of them and objects made up of them.\ntype JsonSerializable =\n | string\n | number\n | boolean\n | null\n | JsonSerializable[]\n | { [key: string]: JsonSerializable };\n\nexport type Step<C extends FlowConfig> = {\n <R extends JsonSerializable | void>(\n name: string,\n options: {\n stage?: ExtractStageKeys<C>;\n maxRetries?: number;\n timeoutInMs?: number;\n },\n fn: () => Promise<R> & {\n catch: (\n errorHandler: (err: Error) => Promise<void> | void\n ) => Promise<any>;\n }\n ): Promise<R>;\n <R extends JsonSerializable | void>(\n name: string,\n fn: () => Promise<R> & {\n catch: (\n errorHandler: (err: Error) => Promise<void> | void\n ) => Promise<any>;\n }\n ): Promise<R>;\n};\n\ntype StepFunction<R> = () => Promise<R> & {\n catch: (errorHandler: (err: Error) => Promise<void> | void) => Promise<any>;\n};\n\nexport interface FlowConfig {\n stages?: StageConfig[];\n title?: string;\n description?: string;\n}\n\nexport type FlowFunction<C extends FlowConfig, I extends any = {}> = (\n ctx: FlowContext<C>,\n inputs: I\n) => Promise<void>;\n\n// Extract the stage keys from the flow config supporting either a string or an object with a key property\nexport type ExtractStageKeys<T extends FlowConfig> = T extends {\n stages: infer S;\n}\n ? S extends ReadonlyArray<infer U>\n ? U extends string\n ? U\n : U extends { key: infer K extends string }\n ? K\n : never\n : never\n : never;\n\ntype StageConfig =\n | string\n | {\n key: string;\n name: string;\n description?: string;\n initiallyHidden?: boolean;\n };\n\nexport function createFlowContext<C extends FlowConfig>(\n runId: string,\n data: any,\n spanId: string\n): FlowContext<C> {\n return {\n step: async (name, optionsOrFn, fn?) => {\n // We need to check the type of the arguments due to the step function being overloaded\n const options = typeof optionsOrFn === \"function\" ? {} : optionsOrFn;\n const actualFn = (\n typeof optionsOrFn === \"function\" ? optionsOrFn : fn!\n ) as StepFunction<any>;\n\n const db = useDatabase();\n\n // First check if we already have a result for this step\n const past = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"name\", \"=\", name)\n .selectAll()\n .execute();\n\n const newSteps = past.filter((step) => step.status === STEP_STATUS.NEW);\n const completedSteps = past.filter(\n (step) => step.status === STEP_STATUS.COMPLETED\n );\n const failedSteps = past.filter(\n (step) => step.status === STEP_STATUS.FAILED\n );\n\n if (newSteps.length > 1) {\n throw new Error(\"Multiple NEW steps found for the same step\");\n }\n\n if (completedSteps.length > 1) {\n throw new Error(\"Multiple completed steps found for the same step\");\n }\n\n if (completedSteps.length > 1 && newSteps.length > 1) {\n throw new Error(\n \"Multiple completed and new steps found for the same step\"\n );\n }\n\n if (completedSteps.length === 1) {\n return completedSteps[0].value;\n }\n\n // Do we have a NEW step waiting to be run?\n if (newSteps.length === 1) {\n let result = null;\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n startTime: new Date(),\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n try {\n result = await withTimeout(\n actualFn(),\n options.timeoutInMs ?? defaultOpts.timeoutInMs\n );\n } catch (e) {\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.FAILED,\n spanId: spanId,\n endTime: new Date(),\n error: e instanceof Error ? e.message : \"An error occurred\",\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n if (\n failedSteps.length + 1 >=\n (options.maxRetries ?? defaultOpts.maxRetries)\n ) {\n throw new ExhuastedRetriesDisrupt();\n }\n\n // If we have retries left, create a new step\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.NEW,\n type: STEP_TYPE.FUNCTION,\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new StepCreatedDisrupt();\n }\n\n // Store the result in the database\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.COMPLETED,\n value: JSON.stringify(result),\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n return result;\n }\n\n // The step hasn't yet run successfully, so we need to create a NEW run\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.NEW,\n type: STEP_TYPE.FUNCTION,\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new StepCreatedDisrupt();\n\n // TODO: Incorporate when we have support error handling\n // const stepPromise = fn({} as any);\n // const stepWithCatch = Object.assign(stepPromise, {\n // catch: async (errorHandler: (err: Error) => Promise<void> | void) => {\n // try {\n // return await stepPromise;\n // } catch (err) {\n // await errorHandler(err as Error);\n // throw err;\n // }\n // },\n // });\n // return stepWithCatch;\n },\n ui: {\n page: (async (name, options) => {\n const db = useDatabase();\n\n // First check if this step exists\n let step = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"name\", \"=\", name)\n .selectAll()\n .executeTakeFirst();\n\n // If this step has already been completed, return the values. Steps are only ever run to completion once.\n if (step && step.status === STEP_STATUS.COMPLETED) {\n return step.value;\n }\n\n if (!step) {\n // The step hasn't yet run so we create a new the step with state PENDING.\n step = await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.PENDING,\n type: STEP_TYPE.UI,\n startTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n // If no data has been passed in, render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(step?.id, page(options));\n }\n\n if (!data) {\n // If no data has been passed in, render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(step?.id, page(options));\n }\n\n // TODO: Validate the data! If not valid, throw a UIRenderDisrupt along with the validation errors.\n\n // If the data has been passed in and is valid, persist the data and mark the step as COMPLETED, and then return the data.\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.COMPLETED,\n value: JSON.stringify(data),\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", step.id)\n .returningAll()\n .executeTakeFirst();\n\n return data;\n }) as UiPage<C>,\n inputs: {\n text: textInput as any,\n number: numberInput as any,\n boolean: booleanInput as any,\n },\n display: {\n divider: divider as any,\n markdown: markdown as any,\n table: table as any,\n header: header as any,\n banner: banner as any,\n image: image as any,\n code: code as any,\n grid: grid as any,\n list: list as any,\n },\n select: {\n one: selectOne as any,\n },\n },\n };\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nfunction withTimeout<T>(promiseFn: Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n promiseFn,\n wait(timeout).then(() => {\n throw new Error(`Step function timed out after ${timeout}ms`);\n }),\n ]);\n}\n\nexport { UI };\n"],"mappings":"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","names":["KSUID","import_kysely","import_kysely","import_node_async_hooks","TraceParent","import_kysely","parseInterval","sql","pgTypes","WebSocket","code","table","KSUID","import_kysely","sql","context","context","context","table","context","context","builder","row","created","import_json_rpc_2","opentelemetry","result","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_ksuid","KSUID"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/ModelAPI.js","../src/database.ts","../src/auditing.js","../src/camelCasePlugin.js","../src/Duration.ts","../src/type-utils.ts","../src/tracing.js","../src/File.ts","../src/errors.js","../src/parsing.js","../src/applyWhereConditions.js","../src/casing.js","../src/TimePeriod.js","../src/applyAdditionalQueryConstraints.js","../src/applyJoins.js","../src/QueryContext.js","../src/QueryBuilder.js","../src/RequestHeaders.ts","../src/handleRequest.js","../src/permissions.ts","../src/consts.js","../src/tryExecuteFunction.js","../src/handleJob.js","../src/tryExecuteJob.js","../src/handleSubscriber.js","../src/tryExecuteSubscriber.js","../src/handleRoute.js","../src/handleFlow.ts","../src/tryExecuteFlow.js","../src/flows/ui/elements/input/text.ts","../src/flows/ui/elements/input/number.ts","../src/flows/ui/elements/display/divider.ts","../src/flows/ui/elements/input/boolean.ts","../src/flows/ui/elements/display/markdown.ts","../src/flows/ui/elements/display/table.ts","../src/flows/ui/elements/select/one.ts","../src/flows/ui/page.ts","../src/flows/disrupts.ts","../src/flows/ui/elements/display/banner.ts","../src/flows/ui/elements/display/image.ts","../src/flows/ui/elements/display/code.ts","../src/flows/ui/elements/display/grid.ts","../src/flows/ui/elements/display/list.ts","../src/flows/ui/elements/display/header.ts","../src/flows/index.ts"],"sourcesContent":["import { ModelAPI } from \"./ModelAPI\";\nimport { RequestHeaders } from \"./RequestHeaders\";\nimport { handleRequest } from \"./handleRequest\";\nimport { handleJob } from \"./handleJob\";\nimport { handleSubscriber } from \"./handleSubscriber\";\nimport { handleRoute } from \"./handleRoute\";\nimport { handleFlow } from \"./handleFlow\";\nimport KSUID from \"ksuid\";\nimport { useDatabase } from \"./database\";\nimport {\n Permissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n} from \"./permissions\";\nimport * as tracing from \"./tracing\";\nimport { InlineFile, File } from \"./File\";\nimport { Duration } from \"./Duration\";\nimport { ErrorPresets } from \"./errors\";\n\n// Export JS files\nexport {\n ModelAPI,\n handleRequest,\n handleJob,\n handleSubscriber,\n handleRoute,\n KSUID,\n Permissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n tracing,\n ErrorPresets,\n};\nexport function ksuid() {\n return KSUID.randomSync().string;\n}\n\n// Export TS files\n\nexport { RequestHeaders, Duration, useDatabase, File, InlineFile, handleFlow };\nexport * from \"./flows\";\nexport { type UIApiResponses } from \"./flows/ui/index\";\n\n// *****************************\n// Static Types\n// *****************************\n\nexport type IDWhereCondition = {\n equals?: string | null;\n notEquals?: string | null;\n oneOf?: string[] | null;\n};\n\nexport type StringWhereCondition = {\n startsWith?: string | null;\n endsWith?: string | null;\n oneOf?: string[] | null;\n contains?: string | null;\n equals?: string | null;\n notEquals?: string | null;\n};\n\nexport type BooleanWhereCondition = {\n equals?: boolean | null;\n notEquals?: boolean | null;\n};\n\nexport type NumberWhereCondition = {\n greaterThan?: number | null;\n greaterThanOrEquals?: number | null;\n lessThan?: number | null;\n lessThanOrEquals?: number | null;\n equals?: number | null;\n notEquals?: number | null;\n};\n\nexport type DurationWhereCondition = {\n greaterThan?: DurationString | null;\n greaterThanOrEquals?: DurationString | null;\n lessThan?: DurationString | null;\n lessThanOrEquals?: DurationString | null;\n equals?: DurationString | null;\n notEquals?: DurationString | null;\n};\n\nexport type DateWhereCondition = {\n equals?: Date | string | null;\n equalsRelative?: RelativeDateString | null;\n before?: Date | string | null;\n beforeRelative?: RelativeDateString | null;\n onOrBefore?: Date | string | null;\n after?: Date | string | null;\n afterRelative?: RelativeDateString | null;\n onOrAfter?: Date | string | null;\n};\n\nexport type DateQueryInput = {\n equals?: string | null;\n before?: string | null;\n onOrBefore?: string | null;\n after?: string | null;\n onOrAfter?: string | null;\n};\n\nexport type TimestampQueryInput = {\n before: string | null;\n after: string | null;\n equalsRelative?: RelativeDateString | null;\n beforeRelative?: RelativeDateString | null;\n afterRelative?: RelativeDateString | null;\n};\n\nexport type StringArrayWhereCondition = {\n equals?: string[] | null;\n notEquals?: string[] | null;\n any?: StringArrayQueryWhereCondition | null;\n all?: StringArrayQueryWhereCondition | null;\n};\n\nexport type StringArrayQueryWhereCondition = {\n equals?: string | null;\n notEquals?: string | null;\n};\n\nexport type NumberArrayWhereCondition = {\n equals?: number[] | null;\n notEquals?: number[] | null;\n any?: NumberArrayQueryWhereCondition | null;\n all?: NumberArrayQueryWhereCondition | null;\n};\n\nexport type NumberArrayQueryWhereCondition = {\n greaterThan?: number | null;\n greaterThanOrEquals?: number | null;\n lessThan?: number | null;\n lessThanOrEquals?: number | null;\n equals?: number | null;\n notEquals?: number | null;\n};\n\nexport type BooleanArrayWhereCondition = {\n equals?: boolean[] | null;\n notEquals?: boolean[] | null;\n any?: BooleanArrayQueryWhereCondition | null;\n all?: BooleanArrayQueryWhereCondition | null;\n};\n\nexport type BooleanArrayQueryWhereCondition = {\n equals?: boolean | null;\n notEquals?: boolean | null;\n};\n\nexport type DateArrayWhereCondition = {\n equals?: Date[] | null;\n notEquals?: Date[] | null;\n any?: DateArrayQueryWhereCondition | null;\n all?: DateArrayQueryWhereCondition | null;\n};\n\nexport type DateArrayQueryWhereCondition = {\n greaterThan?: Date | null;\n greaterThanOrEquals?: Date | null;\n lessThan?: Date | null;\n lessThanOrEquals?: number | null;\n equals?: Date | null;\n notEquals?: Date | null;\n};\n\nexport type ContextAPI = {\n headers: RequestHeaders;\n response: Response;\n isAuthenticated: boolean;\n now(): Date;\n};\n\nexport type Response = {\n headers: Headers;\n status?: number;\n};\n\nexport type PageInfo = {\n startCursor: string;\n endCursor: string;\n totalCount: number;\n hasNextPage: boolean;\n count: number;\n pageNumber?: number;\n};\n\nexport type SortDirection = \"asc\" | \"desc\" | \"ASC\" | \"DESC\";\n\ndeclare class NotFoundError extends Error {}\ndeclare class BadRequestError extends Error {}\ndeclare class UnknownError extends Error {}\n\nexport type Errors = {\n /**\n * Returns a 404 HTTP status with an optional message.\n * This error indicates that the requested resource could not be found.\n */\n NotFound: typeof NotFoundError;\n /**\n * Returns a 400 HTTP status with an optional message.\n * This error indicates that the request made by the client is invalid or malformed.\n */\n BadRequest: typeof BadRequestError;\n /**\n * Returns a 500 HTTP status with an optional message.\n * This error indicates that an unexpected condition was encountered, preventing the server from fulfilling the request.\n */\n Unknown: typeof UnknownError;\n};\n\nexport type FunctionConfig = {\n /**\n * All DB calls within the function will be executed within a transaction.\n * The transaction is rolled back if the function throws an error.\n */\n dbTransaction?: boolean;\n};\n\nexport type FuncWithConfig<T> = T & {\n config: FunctionConfig;\n};\n\ntype unit =\n | \"year\"\n | \"years\"\n | \"month\"\n | \"months\"\n | \"day\"\n | \"days\"\n | \"hour\"\n | \"hours\"\n | \"minute\"\n | \"minutes\"\n | \"second\"\n | \"seconds\";\ntype direction = \"next\" | \"last\";\ntype completed = \"complete\";\ntype value = number;\n\nexport type RelativeDateString =\n | \"now\"\n | \"today\"\n | \"tomorrow\"\n | \"yesterday\"\n | `this ${unit}`\n | `${direction} ${unit}`\n | `${direction} ${value} ${unit}`\n | `${direction} ${value} ${completed} ${unit}`;\n\ntype dateDuration =\n | `${number}Y${number}M${number}D` // Example: 1Y2M10D\n | `${number}Y${number}M` // Example: 1Y2M\n | `${number}Y${number}D` // Example: 1Y10D\n | `${number}M${number}D` // Example: 10M2D\n | `${number}Y` // Example: 1Y\n | `${number}M` // Example: 1M\n | `${number}D`; // Example: 2D\n\ntype timeDuration =\n | `${number}H${number}M${number}S` // Example: 2H30M\n | `${number}H${number}M` // Example: 2H30M\n | `${number}M${number}S` // Example: 2M30S\n | `${number}H${number}S` // Example: 2H30S\n | `${number}H` // Example: 2H\n | `${number}M` // Example: 30M\n | `${number}S`; // Example: 30S\n\nexport type DurationString =\n | `P${dateDuration}T${timeDuration}`\n | `P${dateDuration}`\n | `PT${timeDuration}`;\n","import { sql } from \"kysely\";\nimport { useDatabase } from \"./database\";\nimport { transformRichDataTypes, isReferencingExistingRecord } from \"./parsing\";\nimport { isPlainObject } from \"./type-utils\";\nimport { QueryBuilder } from \"./QueryBuilder\";\nimport { QueryContext } from \"./QueryContext\";\nimport { applyWhereConditions } from \"./applyWhereConditions\";\nimport { applyJoins } from \"./applyJoins\";\nimport { InlineFile, File } from \"./File\";\nimport { Duration } from \"./Duration\";\n\nimport {\n applyLimit,\n applyOffset,\n applyOrderBy,\n} from \"./applyAdditionalQueryConstraints\";\nimport { camelCaseObject, snakeCaseObject, upperCamelCase } from \"./casing\";\nimport * as tracing from \"./tracing\";\nimport { DatabaseError } from \"./errors\";\n\n/**\n * RelationshipConfig is a simple representation of a model field that\n * is a relationship. It is used by applyJoins and applyWhereConditions\n * to build the correct query.\n * @typedef {{\n * relationshipType: \"belongsTo\" | \"hasMany\",\n * foreignKey: string,\n * referencesTable: string,\n * }} RelationshipConfig\n *\n * TableConfig is an object where the keys are relationship field names\n * (which don't exist in the database) and the values are RelationshipConfig\n * objects describing that relationship.\n * @typedef {Object.<string, RelationshipConfig} TableConfig\n *\n * TableConfigMap is mapping of database table names to TableConfig objects\n * @typedef {Object.<string, TableConfig>} TableConfigMap\n */\n\nclass ModelAPI {\n /**\n * @param {string} tableName The name of the table this API is for\n * @param {Function} _ Used to be a function that returns the default values for a row in this table. No longer used.\n * @param {TableConfigMap} tableConfigMap\n */\n constructor(tableName, _, tableConfigMap = {}) {\n this._tableName = tableName;\n this._tableConfigMap = tableConfigMap;\n this._modelName = upperCamelCase(this._tableName);\n }\n\n async create(values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"create\");\n\n return tracing.withSpan(name, () => {\n const db = useDatabase();\n return create(\n db,\n this._tableName,\n this._tableConfigMap,\n snakeCaseObject(values)\n );\n });\n }\n\n async findOne(where = {}) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findOne\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n const row = await builder.executeTakeFirst();\n if (!row) {\n return null;\n }\n\n return transformRichDataTypes(camelCaseObject(row));\n });\n }\n\n async findMany(params) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findMany\");\n const db = useDatabase();\n const where = params?.where || {};\n\n return tracing.withSpan(name, async (span) => {\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n let builder = db\n .selectFrom((qb) => {\n // We need to wrap this query as a sub query in the selectFrom because you cannot apply a different order by column when using distinct(id)\n let builder = qb\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n builder = builder.as(this._tableName);\n\n return builder;\n })\n .selectAll();\n\n // The only constraints added to the main query are the orderBy, limit and offset as they are performed on the \"outer\" set\n if (params?.limit) {\n builder = applyLimit(context, builder, params.limit);\n }\n\n if (params?.offset) {\n builder = applyOffset(context, builder, params.offset);\n }\n\n if (\n params?.orderBy !== undefined &&\n Object.keys(params?.orderBy).length > 0\n ) {\n builder = applyOrderBy(\n context,\n builder,\n this._tableName,\n params.orderBy\n );\n } else {\n builder = builder.orderBy(`${this._tableName}.id`);\n }\n\n const query = builder;\n\n span.setAttribute(\"sql\", query.compile().sql);\n const rows = await builder.execute();\n return rows.map((x) => transformRichDataTypes(camelCaseObject(x)));\n });\n }\n\n async update(where, values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"update\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db.updateTable(this._tableName).returningAll();\n\n // process input values\n const keys = values ? Object.keys(values) : [];\n const row = {};\n\n for (const key of keys) {\n const value = values[key];\n if (Array.isArray(value)) {\n row[key] = await Promise.all(\n value.map(async (item) => {\n if (item instanceof Duration) {\n return item.toPostgres();\n }\n if (item instanceof InlineFile) {\n const storedFile = await item.store();\n return storedFile.toDbRecord();\n }\n if (item instanceof File) {\n return item.toDbRecord();\n }\n return item;\n })\n );\n } else if (value instanceof Duration) {\n row[key] = value.toPostgres();\n } else if (value instanceof InlineFile) {\n const storedFile = await value.store();\n row[key] = storedFile.toDbRecord();\n } else if (value instanceof File) {\n row[key] = value.toDbRecord();\n } else {\n row[key] = value;\n }\n }\n\n builder = builder.set(snakeCaseObject(row));\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n // TODO: support joins for update\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n\n try {\n const row = await builder.executeTakeFirstOrThrow();\n return transformRichDataTypes(camelCaseObject(row));\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async delete(where) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"delete\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db.deleteFrom(this._tableName).returning([\"id\"]);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n // TODO: support joins for delete\n builder = applyWhereConditions(context, builder, where);\n\n span.setAttribute(\"sql\", builder.compile().sql);\n try {\n const row = await builder.executeTakeFirstOrThrow();\n return row.id;\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n where(where) {\n const db = useDatabase();\n\n let builder = db\n .selectFrom(this._tableName)\n .distinctOn(`${this._tableName}.id`)\n .selectAll(this._tableName);\n\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n builder = applyJoins(context, builder, where);\n builder = applyWhereConditions(context, builder, where);\n\n return new QueryBuilder(this._tableName, context, builder);\n }\n}\n\nasync function create(conn, tableName, tableConfigs, values) {\n try {\n let query = conn.insertInto(tableName);\n\n const keys = values ? Object.keys(values) : [];\n const tableConfig = tableConfigs[tableName] || {};\n const hasManyRecords = [];\n\n if (keys.length === 0) {\n // See https://github.com/kysely-org/kysely/issues/685#issuecomment-1711240534\n query = query.expression(sql`default values`);\n } else {\n const row = {};\n for (const key of keys) {\n const value = values[key];\n const columnConfig = tableConfig[key];\n\n if (!columnConfig) {\n if (Array.isArray(value)) {\n row[key] = await Promise.all(\n value.map(async (item) => {\n if (item instanceof Duration) {\n return item.toPostgres();\n }\n if (item instanceof InlineFile) {\n const storedFile = await item.store();\n return storedFile.toDbRecord();\n }\n if (item instanceof File) {\n return item.toDbRecord();\n }\n return item;\n })\n );\n } else if (value instanceof Duration) {\n row[key] = value.toPostgres();\n } else if (value instanceof InlineFile) {\n const storedFile = await value.store();\n row[key] = storedFile.toDbRecord();\n } else if (value instanceof File) {\n row[key] = value.toDbRecord();\n } else {\n row[key] = value;\n }\n continue;\n }\n\n switch (columnConfig.relationshipType) {\n case \"belongsTo\":\n if (!isPlainObject(value)) {\n throw new Error(\n `non-object provided for field ${key} of ${tableName}`\n );\n }\n\n if (isReferencingExistingRecord(value)) {\n row[columnConfig.foreignKey] = value.id;\n break;\n }\n\n const created = await create(\n conn,\n columnConfig.referencesTable,\n tableConfigs,\n value\n );\n row[columnConfig.foreignKey] = created.id;\n break;\n\n case \"hasMany\":\n if (!Array.isArray(value)) {\n throw new Error(\n `non-array provided for has-many field ${key} of ${tableName}`\n );\n }\n for (const v of value) {\n hasManyRecords.push({\n key,\n value: v,\n columnConfig,\n });\n }\n break;\n default:\n throw new Error(\n `unsupported relationship type - ${tableName}.${key} (${columnConfig.relationshipType})`\n );\n }\n }\n\n query = query.values(row);\n }\n\n const created = await query.returningAll().executeTakeFirstOrThrow();\n\n await Promise.all(\n hasManyRecords.map(async ({ key, value, columnConfig }) => {\n if (!isPlainObject(value)) {\n throw new Error(\n `non-object provided for field ${key} of ${tableName}`\n );\n }\n\n if (isReferencingExistingRecord(value)) {\n throw new Error(\n `nested update as part of create not supported for ${key} of ${tableConfig}`\n );\n }\n\n return create(conn, columnConfig.referencesTable, tableConfigs, {\n ...value,\n [columnConfig.foreignKey]: created.id,\n });\n })\n );\n\n return transformRichDataTypes(created);\n } catch (e) {\n throw new DatabaseError(e);\n }\n}\n\nexport { ModelAPI, DatabaseError };\n","import { Kysely, PostgresDialect, KyselyConfig } from \"kysely\";\nimport * as neon from \"@neondatabase/serverless\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { AuditContextPlugin } from \"./auditing\";\nimport { KeelCamelCasePlugin } from \"./camelCasePlugin\";\nimport { Pool, Client, types as pgTypes, PoolConfig, PoolClient } from \"pg\";\nimport { withSpan } from \"./tracing\";\nimport WebSocket from \"ws\";\nimport { readFileSync } from \"node:fs\";\nimport { Duration } from \"./Duration\";\n\ninterface DatabaseContext {\n transaction?: Kysely<any>;\n sDb?: Kysely<any>;\n}\n\ninterface DatabaseClientConfig {\n connString?: string;\n}\n\nconst dbInstance = new AsyncLocalStorage<Kysely<any>>();\n\n// used to establish a singleton for our vitest environment\nlet vitestDb: Kysely<any> | null = null;\n\n// withDatabase is responsible for setting the correct database client in our AsyncLocalStorage\n// so that the the code in a custom function uses the correct client.\n// For GET and LIST action types, no transaction is used, but for\n// actions that mutate data such as CREATE, DELETE & UPDATE, all of the code inside\n// the user's custom function is wrapped in a transaction so we can rollback\n// the transaction if something goes wrong.\n// withDatabase shouldn't be exposed in the public api of the sdk\nasync function withDatabase<T>(\n db: Kysely<any>,\n requiresTransaction: boolean,\n cb: (context: DatabaseContext) => Promise<T>\n): Promise<T> {\n // db.transaction() provides a kysely instance bound to a transaction.\n if (requiresTransaction) {\n return db.transaction().execute(async (transaction) => {\n return dbInstance.run(transaction, async () => {\n return cb({ transaction });\n });\n });\n }\n\n // db.connection() provides a kysely instance bound to a single database connection.\n return db.connection().execute(async (sDb) => {\n return dbInstance.run(sDb, async () => {\n return cb({ sDb });\n });\n });\n}\n\n// useDatabase will retrieve the database client set by withDatabase from the local storage\nfunction useDatabase(): Kysely<any> {\n // retrieve the instance of the database client from the store which is aware of\n // which context the current connection to the db is running in - e.g does the context\n // require a transaction or not?\n let fromStore = dbInstance.getStore();\n if (fromStore) {\n return fromStore;\n }\n\n // if the NODE_ENV is 'test' then we know we are inside of the vitest environment\n // which covers any test files ending in *.test.ts. Custom function code runs in a different node process which will not have this environment variable. Tests written using our testing\n // framework call actions (and in turn custom function code) over http using the ActionExecutor class\n if (\"NODE_ENV\" in process.env && process.env.NODE_ENV == \"test\") {\n if (!vitestDb) {\n vitestDb = createDatabaseClient();\n }\n return vitestDb;\n }\n\n // If we've gotten to this point, then we know that we are in a custom function runtime server\n // context and we haven't been able to retrieve the in-context instance of Kysely, which means we should throw an error.\n console.trace();\n throw new Error(\"useDatabase must be called within a function\");\n}\n\n// createDatabaseClient will return a brand new instance of Kysely. Every instance of Kysely\n// represents an individual connection to the database.\n// not to be exported externally from our sdk - consumers should use useDatabase\nfunction createDatabaseClient(config: DatabaseClientConfig = {}): Kysely<any> {\n const kyseleyConfig: KyselyConfig = {\n dialect: getDialect(config.connString),\n plugins: [\n // ensures that the audit context data is written to Postgres configuration parameters\n new AuditContextPlugin(),\n // allows users to query using camelCased versions of the database column names, which\n // should match the names we use in our schema.\n // We're using an extended version of Kysely's CamelCasePlugin which avoids changing keys of objects that represent\n // rich data formats, specific to Keel (e.g. Duration)\n new KeelCamelCasePlugin(),\n ],\n log(event: any) {\n if (process.env.DEBUG) {\n if (event.level === \"query\") {\n console.log(event.query.sql);\n console.log(event.query.parameters);\n }\n }\n },\n };\n\n return new Kysely(kyseleyConfig);\n}\n\nclass InstrumentedPool extends Pool {\n connect(...args: any): Promise<PoolClient> {\n const _super = super.connect.bind(this);\n return withSpan(\"Database Connect\", function (span: any) {\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n return _super.apply(null, args);\n });\n }\n}\n\nclass InstrumentedNeonServerlessPool extends neon.Pool {\n async connect(...args: any): Promise<neon.PoolClient> {\n const _super = super.connect.bind(this);\n return withSpan(\"Database Connect\", function (span: any) {\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n return _super.apply(null, args);\n });\n }\n}\n\nconst txStatements = {\n begin: \"Transaction Begin\",\n commit: \"Transaction Commit\",\n rollback: \"Transaction Rollback\",\n};\n\nclass InstrumentedClient extends Client {\n async query(...args: any): Promise<any> {\n const _super = super.query.bind(this);\n const sql = args[0];\n\n let sqlAttribute = false;\n let spanName = txStatements[sql.toLowerCase() as keyof typeof txStatements];\n if (!spanName) {\n spanName = \"Database Query\";\n sqlAttribute = true;\n }\n\n return withSpan(spanName, function (span: any) {\n if (sqlAttribute) {\n span.setAttribute(\"sql\", args[0]);\n span.setAttribute(\"dialect\", process.env[\"KEEL_DB_CONN_TYPE\"]);\n }\n return _super.apply(null, args);\n });\n }\n}\n\nfunction getDialect(connString?: string): PostgresDialect {\n const dbConnType = process.env.KEEL_DB_CONN_TYPE;\n switch (dbConnType) {\n case \"pg\": {\n // Adding a custom type parser for numeric fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1700 = type for NUMERIC\n pgTypes.setTypeParser(pgTypes.builtins.NUMERIC, (val: string) =>\n parseFloat(val)\n );\n // Adding a custom type parser for interval fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1186 = type for INTERVAL\n pgTypes.setTypeParser(\n pgTypes.builtins.INTERVAL,\n (val: string) => new Duration(val)\n );\n\n const poolConfig: PoolConfig = {\n Client: InstrumentedClient,\n // Increased idle time before closing a connection in the local pool (from 10s default).\n // Establising a new connection on (almost) every functions query can be expensive, so this\n // will reduce having to open connections as regularly. https://node-postgres.com/apis/pool\n //\n // NOTE: We should consider setting this to 0 (i.e. never pool locally) and open and close\n // connections with each invocation. This is because the freeze/thaw nature of lambdas can cause problems\n // with long-lived connections - see https://github.com/brianc/node-postgres/issues/2718\n // Once we're \"fully regional\" this should not be a performance problem anymore.\n //\n // Although I doubt we will run into these freeze/thaw issues if idleTimeoutMillis is always shorter than the\n // time is takes for a lambda to freeze (which is not a constant, but could be as short as several minutes,\n // https://www.pluralsight.com/resources/blog/cloud/how-long-does-aws-lambda-keep-your-idle-functions-around-before-a-cold-start)\n idleTimeoutMillis: 50000,\n // If connString is not passed fall back to reading from env var\n connectionString: connString || process.env.KEEL_DB_CONN,\n };\n\n // Allow the setting of a cert (.pem) file. RDS requires this to enforce SSL.\n if (process.env.KEEL_DB_CERT) {\n poolConfig.ssl = { ca: readFileSync(process.env.KEEL_DB_CERT) };\n }\n\n return new PostgresDialect({\n pool: new InstrumentedPool(poolConfig),\n });\n }\n case \"neon\": {\n // Adding a custom type parser for numeric fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1700 = type for NUMERIC\n neon.types.setTypeParser(pgTypes.builtins.NUMERIC, (val: string) =>\n parseFloat(val)\n );\n\n // Adding a custom type parser for interval fields: see https://kysely.dev/docs/recipes/data-types#configuring-runtime-javascript-types\n // 1186 = type for INTERVAL\n neon.types.setTypeParser(\n pgTypes.builtins.INTERVAL,\n (val: string) => new Duration(val)\n );\n\n neon.neonConfig.webSocketConstructor = WebSocket;\n\n const pool = new InstrumentedNeonServerlessPool({\n // If connString is not passed fall back to reading from env var\n connectionString: connString || process.env.KEEL_DB_CONN,\n });\n\n pool.on(\"connect\", (client: any) => {\n const originalQuery = client.query;\n client.query = function (...args: any[]) {\n const sql = args[0];\n\n let sqlAttribute = false;\n let spanName =\n txStatements[sql.toLowerCase() as keyof typeof txStatements];\n if (!spanName) {\n spanName = \"Database Query\";\n sqlAttribute = true;\n }\n\n return withSpan(spanName, function (span: any) {\n if (sqlAttribute) {\n span.setAttribute(\"sql\", args[0]);\n span.setAttribute(\"dialect\", dbConnType);\n }\n return originalQuery.apply(client, args);\n });\n };\n });\n\n return new PostgresDialect({\n pool: pool,\n });\n }\n default:\n throw Error(\"unexpected KEEL_DB_CONN_TYPE: \" + dbConnType);\n }\n}\n\nexport {\n createDatabaseClient,\n useDatabase,\n withDatabase,\n type DatabaseContext,\n type DatabaseClientConfig,\n};\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport TraceParent from \"traceparent\";\nimport { sql, SelectionNode } from \"kysely\";\n\nconst auditContextStorage = new AsyncLocalStorage();\n\n// withAuditContext creates the audit context from the runtime request body\n// and sets it to in AsyncLocalStorage so that this data is available to the\n// ModelAPI during the execution of actions, jobs and subscribers.\nasync function withAuditContext(request, cb) {\n let audit = {};\n\n if (request.meta?.identity) {\n audit.identityId = request.meta.identity.id;\n }\n if (request.meta?.tracing?.traceparent) {\n audit.traceId = TraceParent.fromString(\n request.meta.tracing.traceparent\n )?.traceId;\n }\n\n return await auditContextStorage.run(audit, () => {\n return cb();\n });\n}\n\n// getAuditContext retrieves the audit context from AsyncLocalStorage.\nfunction getAuditContext() {\n let auditStore = auditContextStorage.getStore();\n return {\n identityId: auditStore?.identityId,\n traceId: auditStore?.traceId,\n };\n}\n\n// AuditContextPlugin is a Kysely plugin which ensures that the audit context data\n// is written to Postgres configuration parameters in the same execution as a query.\n// It does this by calling the set_identity_id() and set_trace_id() functions as a\n// clause in the returning statement. It then subsequently drops these from the actual result.\n// This ensures that these parameters are set when the tables' AFTER trigger function executes.\nclass AuditContextPlugin {\n constructor() {\n this.identityIdAlias = \"__keel_identity_id\";\n this.traceIdAlias = \"__keel_trace_id\";\n }\n\n // Appends set_identity_id() and set_trace_id() function calls to the returning statement\n // of INSERT, UPDATE and DELETE operations.\n transformQuery(args) {\n switch (args.node.kind) {\n case \"InsertQueryNode\":\n case \"UpdateQueryNode\":\n case \"DeleteQueryNode\":\n // Represents a RETURNING clause in a SQL statement.\n const returning = {\n kind: \"ReturningNode\",\n selections: [],\n };\n\n // If the query already has a selection, then append it.\n if (args.node.returning) {\n returning.selections.push(...args.node.returning.selections);\n }\n\n // Retrieve the audit context from async storage.\n const audit = getAuditContext();\n\n if (audit.identityId) {\n const rawNode = sql`set_identity_id(${audit.identityId})`\n .as(this.identityIdAlias)\n .toOperationNode();\n\n returning.selections.push(SelectionNode.create(rawNode));\n }\n\n if (audit.traceId) {\n const rawNode = sql`set_trace_id(${audit.traceId})`\n .as(this.traceIdAlias)\n .toOperationNode();\n\n returning.selections.push(SelectionNode.create(rawNode));\n }\n\n return {\n ...args.node,\n returning: returning,\n };\n }\n\n return {\n ...args.node,\n };\n }\n\n // Drops the set_identity_id() and set_trace_id() fields from the result.\n transformResult(args) {\n if (args.result?.rows) {\n for (let i = 0; i < args.result.rows.length; i++) {\n delete args.result.rows[i][this.identityIdAlias];\n delete args.result.rows[i][this.traceIdAlias];\n }\n }\n\n return args.result;\n }\n}\n\nexport { withAuditContext, getAuditContext, AuditContextPlugin };\n","import { CamelCasePlugin } from \"kysely\";\nimport { isPlainObject, isRichType } from \"./type-utils\";\n\n// KeelCamelCasePlugin is a wrapper around kysely's CamelCasePlugin. The behaviour is the same apart from the fact that\n// nested objects that are of a rich keel data type, such as Duration, are skipped so that they continue to be\n// implementations of the rich data classes defined by Keel.\nclass KeelCamelCasePlugin {\n constructor(opt) {\n this.opt = opt;\n this.CamelCasePlugin = new CamelCasePlugin(opt);\n }\n\n transformQuery(args) {\n return this.CamelCasePlugin.transformQuery(args);\n }\n\n async transformResult(args) {\n if (args.result.rows && Array.isArray(args.result.rows)) {\n return {\n ...args.result,\n rows: args.result.rows.map((row) => this.mapRow(row)),\n };\n }\n return args.result;\n }\n mapRow(row) {\n return Object.keys(row).reduce((obj, key) => {\n // Fields using @sequence will have a corresponding __sequence field which we drop as we don't want to return it\n if (key.endsWith(\"__sequence\")) {\n return obj;\n }\n let value = row[key];\n if (Array.isArray(value)) {\n value = value.map((it) =>\n canMap(it, this.opt) ? this.mapRow(it) : it\n );\n } else if (canMap(value, this.opt)) {\n value = this.mapRow(value);\n }\n obj[this.CamelCasePlugin.camelCase(key)] = value;\n return obj;\n }, {});\n }\n}\n\nfunction canMap(obj, opt) {\n return (\n isPlainObject(obj) && !opt?.maintainNestedObjectKeys && !isRichType(obj)\n );\n}\n\nexport { KeelCamelCasePlugin };\n","import parseInterval from \"postgres-interval\";\n\nconst isoRegex =\n /^P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?$/;\n\ninterface Interval {\n years?: number;\n months?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n toISOStringShort(): string;\n toPostgres(): string;\n}\n\nexport class Duration {\n private _typename: string;\n private pgInterval: string;\n private _interval: Interval;\n\n constructor(postgresString: string) {\n this._typename = \"Duration\";\n this.pgInterval = postgresString;\n this._interval = parseInterval(postgresString);\n }\n\n static fromISOString(isoString: string): Duration {\n const match = isoString.match(isoRegex);\n if (match) {\n const d = new Duration(\"0\");\n d._interval.years = match[1] ? parseInt(match[1]) : undefined;\n d._interval.months = match[2] ? parseInt(match[2]) : undefined;\n d._interval.days = match[3] ? parseInt(match[3]) : undefined;\n d._interval.hours = match[4] ? parseInt(match[4]) : undefined;\n d._interval.minutes = match[5] ? parseInt(match[5]) : undefined;\n d._interval.seconds = match[6] ? parseInt(match[6]) : undefined;\n return d;\n }\n return new Duration(\"0\");\n }\n\n toISOString(): string {\n return this._interval.toISOStringShort();\n }\n\n toPostgres(): string {\n return this._interval.toPostgres();\n }\n}\n","import { Duration } from \"./Duration\";\n\nfunction isPlainObject(obj: unknown): boolean {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\n\nfunction isRichType(obj: unknown): boolean {\n if (!isPlainObject(obj)) {\n return false;\n }\n\n return obj instanceof Duration;\n}\n\nexport { isPlainObject, isRichType };\n","import * as opentelemetry from \"@opentelemetry/api\";\nimport { BatchSpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport { envDetectorSync } from \"@opentelemetry/resources\";\n\nasync function withSpan(name, fn) {\n return getTracer().startActiveSpan(name, async (span) => {\n try {\n // await the thing (this means we can use try/catch)\n return await fn(span);\n } catch (err) {\n // record any errors\n span.recordException(err);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: err.message,\n });\n // re-throw the error\n throw err;\n } finally {\n // make sure the span is ended\n span.end();\n }\n });\n}\n\nfunction patchFetch() {\n if (!globalThis.fetch.patched) {\n const originalFetch = globalThis.fetch;\n\n globalThis.fetch = async (...args) => {\n return withSpan(\"fetch\", async (span) => {\n const url = new URL(\n args[0] instanceof Request ? args[0].url : String(args[0])\n );\n span.setAttribute(\"http.url\", url.toString());\n const scheme = url.protocol.replace(\":\", \"\");\n span.setAttribute(\"http.scheme\", scheme);\n\n const options = args[0] instanceof Request ? args[0] : args[1] || {};\n const method = (options.method || \"GET\").toUpperCase();\n span.setAttribute(\"http.method\", method);\n\n const res = await originalFetch(...args);\n span.setAttribute(\"http.status\", res.status);\n span.setAttribute(\"http.status_text\", res.statusText);\n return res;\n });\n };\n globalThis.fetch.patched = true;\n }\n}\n\nfunction patchConsoleLog() {\n if (!console.log.patched) {\n const originalConsoleLog = console.log;\n\n console.log = (...args) => {\n const span = opentelemetry.trace.getActiveSpan();\n if (span) {\n const output = args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.stack;\n }\n if (typeof arg === \"object\") {\n try {\n return JSON.stringify(arg, getCircularReplacer());\n } catch (error) {\n return \"[Object with circular references]\";\n }\n }\n if (typeof arg === \"function\") {\n return arg() || arg.name || arg.toString();\n }\n return String(arg);\n })\n .join(\" \");\n\n span.addEvent(output);\n }\n originalConsoleLog(...args);\n };\n\n console.log.patched = true;\n }\n}\n\nfunction patchConsoleError() {\n if (!console.error.patched) {\n const originalConsoleError = console.error;\n\n console.error = (...args) => {\n const span = opentelemetry.trace.getActiveSpan();\n if (span) {\n const output = args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.stack;\n }\n if (typeof arg === \"object\") {\n try {\n return JSON.stringify(arg, getCircularReplacer());\n } catch (error) {\n return \"[Object with circular references]\";\n }\n }\n if (typeof arg === \"function\") {\n return arg() || arg.name || arg.toString();\n }\n return String(arg);\n })\n .join(\" \");\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: output,\n });\n }\n originalConsoleError(...args);\n };\n\n console.error.patched = true;\n }\n}\n\n// Utility to handle circular references in objects\nfunction getCircularReplacer() {\n const seen = new WeakSet();\n return (key, value) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n }\n return value;\n };\n}\n\nfunction init() {\n if (process.env.KEEL_TRACING_ENABLED == \"true\") {\n const exporter = new OTLPTraceExporter();\n const processor = new BatchSpanProcessor(exporter);\n\n const provider = new NodeTracerProvider({\n resource: envDetectorSync.detect(),\n spanProcessors: [processor],\n });\n\n provider.register();\n }\n\n patchFetch();\n patchConsoleLog();\n patchConsoleError();\n}\n\nasync function forceFlush() {\n // The \"delegate\" is the actual provider set by the functions-runtime package\n const provider = opentelemetry.trace.getTracerProvider().getDelegate();\n if (provider && provider.forceFlush) {\n await provider.forceFlush();\n }\n}\n\nfunction getTracer() {\n return opentelemetry.trace.getTracer(\"functions\");\n}\n\nfunction spanNameForModelAPI(modelName, action) {\n return `Database ${modelName}.${action}`;\n}\n\nexport { getTracer, withSpan, init, forceFlush, spanNameForModelAPI };\n","import {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n PutObjectCommandInput,\n} from \"@aws-sdk/client-s3\";\nimport { fromEnv } from \"@aws-sdk/credential-providers\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport { useDatabase } from \"./database\";\nimport { DatabaseError } from \"./errors\";\nimport KSUID from \"ksuid\";\n\ntype MimeType =\n | \"application/json\"\n | \"application/gzip\"\n | \"application/pdf\"\n | \"application/rtf\"\n | \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n | \"application/vnd.openxmlformats-officedocument.presentationml.presentation\"\n | \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n | \"application/vnd.ms-excel\"\n | \"application/vnd.ms-powerpoint\"\n | \"application/msword\"\n | \"application/zip\"\n | \"application/xml\"\n | \"application/x-7z-compressed\"\n | \"application/x-tar\"\n | \"image/gif\"\n | \"image/jpeg\"\n | \"image/svg+xml\"\n | \"image/png\"\n | \"text/html\"\n | \"text/csv\"\n | \"text/javascript\"\n | \"text/plain\"\n | \"text/calendar\"\n | (string & {});\n\n// Type Declarations\nexport type InlineFileConstructor = {\n filename: string;\n contentType: MimeType;\n};\n\nexport type FileDbRecord = {\n key: string;\n filename: string;\n contentType: string;\n size: number;\n};\n\n// Implementation\nconst s3Client: S3Client | null = (() => {\n if (!process.env.KEEL_FILES_BUCKET_NAME) {\n return null;\n }\n\n const endpoint = process.env.TEST_AWS_ENDPOINT;\n\n if (!endpoint) {\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: fromEnv(),\n });\n }\n\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: {\n accessKeyId: \"test\",\n secretAccessKey: \"test\",\n },\n endpointProvider: () => {\n return {\n url: new URL(endpoint),\n };\n },\n });\n})();\n\nexport class InlineFile {\n protected _filename: string;\n protected _contentType: MimeType;\n protected _contents: Blob | null;\n\n constructor(input: InlineFileConstructor) {\n this._filename = input.filename;\n this._contentType = input.contentType;\n this._contents = null;\n }\n\n static fromDataURL(dataURL: string): InlineFile {\n const info = dataURL.split(\",\")[0].split(\":\")[1];\n const data = dataURL.split(\",\")[1];\n const mime = info.split(\";\")[0];\n const name = info.split(\";\")[1].split(\"=\")[1];\n const buffer = Buffer.from(data, \"base64\");\n const file = new InlineFile({ filename: name, contentType: mime });\n file.write(buffer);\n\n return file;\n }\n\n // Gets size of the file's contents in bytes\n get size(): number {\n if (this._contents) {\n return this._contents.size;\n }\n return 0;\n }\n\n // Gets the media type of the file contents\n get contentType(): string {\n return this._contentType;\n }\n\n // Gets the name of the file\n get filename(): string {\n return this._filename;\n }\n\n // Write the files contents from a buffer\n write(buffer: Buffer): void {\n this._contents = new Blob([buffer]);\n }\n\n // Reads the contents of the file as a buffer\n async read(): Promise<Buffer> {\n if (!this._contents) {\n throw new Error(\"No contents to read\");\n }\n const arrayBuffer = await this._contents.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n // Persists the file\n async store(expires: Date | null = null): Promise<File> {\n const content = await this.read();\n const key = KSUID.randomSync().string;\n\n await storeFile(\n content,\n key,\n this._filename,\n this._contentType,\n this.size,\n expires\n );\n\n return new File({\n key: key,\n size: this.size,\n filename: this.filename,\n contentType: this.contentType,\n });\n }\n}\n\nexport class File extends InlineFile {\n private _key: string;\n private _size: number;\n\n constructor(input: Partial<FileDbRecord>) {\n super({\n filename: input.filename || \"\",\n contentType: input.contentType || \"\",\n });\n this._key = input.key || \"\";\n this._size = input.size || 0;\n }\n\n // Creates a new instance from the database record\n static fromDbRecord(input: FileDbRecord): File {\n return new File({\n key: input.key,\n filename: input.filename,\n size: input.size,\n contentType: input.contentType,\n });\n }\n\n get size(): number {\n return this._size;\n }\n\n // Gets the stored key\n get key(): string {\n return this._key;\n }\n\n get isPublic(): boolean {\n return false; // Implement as needed\n }\n\n async read(): Promise<Buffer> {\n if (this._contents) {\n const arrayBuffer = await this._contents.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n if (s3Client) {\n const params = {\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n };\n const command = new GetObjectCommand(params);\n const response = await s3Client.send(command);\n const blob = await response.Body!.transformToByteArray();\n return Buffer.from(blob);\n }\n\n const db = useDatabase();\n\n try {\n const query = db\n .selectFrom(\"keel_storage\")\n .select(\"data\")\n .where(\"id\", \"=\", this.key);\n\n const row = await query.executeTakeFirstOrThrow();\n return row.data;\n } catch (e) {\n throw new DatabaseError(e);\n }\n }\n\n async store(expires: Date | null = null): Promise<File> {\n if (this._contents) {\n const contents = await this.read();\n await storeFile(\n contents,\n this.key,\n this.filename,\n this.contentType,\n this.size,\n expires\n );\n }\n return this;\n }\n\n // Generates a presigned download URL\n async getPresignedUrl(): Promise<URL> {\n if (s3Client) {\n const command = new GetObjectCommand({\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n ResponseContentDisposition: \"inline\",\n });\n\n const url = await getSignedUrl(s3Client, command, { expiresIn: 60 * 60 });\n\n return new URL(url);\n } else {\n const contents = await this.read();\n const dataurl = `data:${this.contentType};name=${\n this.filename\n };base64,${contents.toString(\"base64\")}`;\n return new URL(dataurl);\n }\n }\n\n // Persists the file\n toDbRecord(): FileDbRecord {\n return {\n key: this.key,\n filename: this.filename,\n contentType: this.contentType,\n size: this.size,\n };\n }\n\n toJSON(): FileDbRecord {\n return this.toDbRecord();\n }\n}\n\nasync function storeFile(\n contents: Buffer,\n key: string,\n filename: string,\n contentType: string,\n size: number,\n expires: Date | null\n): Promise<void> {\n if (s3Client) {\n const params: PutObjectCommandInput = {\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + key,\n Body: contents,\n ContentType: contentType,\n ContentDisposition: `attachment; filename=\"${encodeURIComponent(\n filename\n )}\"`,\n Metadata: {\n filename: filename,\n },\n ACL: \"private\",\n };\n\n if (expires) {\n if (expires instanceof Date) {\n params.Expires = expires;\n } else {\n console.warn(\"Invalid expires value. Skipping Expires parameter.\");\n }\n }\n\n const command = new PutObjectCommand(params);\n try {\n await s3Client.send(command);\n } catch (error) {\n console.error(\"Error uploading file:\", error);\n throw error;\n }\n } else {\n const db = useDatabase();\n\n try {\n const query = db\n .insertInto(\"keel_storage\")\n .values({\n id: key,\n filename: filename,\n content_type: contentType,\n data: contents,\n })\n .onConflict((oc) =>\n oc\n .column(\"id\")\n .doUpdateSet(() => ({\n filename: filename,\n content_type: contentType,\n data: contents,\n }))\n .where(\"keel_storage.id\", \"=\", key)\n )\n .returningAll();\n\n await query.execute();\n } catch (e) {\n throw new DatabaseError(e);\n }\n }\n}\n\nexport type FileWriteTypes = InlineFile | File;\n","import { createJSONRPCErrorResponse } from \"json-rpc-2.0\";\n\nconst RuntimeErrors = {\n // Catchall error type for unhandled execution errors during custom function\n UnknownError: -32001,\n // DatabaseError represents any error at pg level that isn't handled explicitly below\n DatabaseError: -32002,\n // No result returned from custom function by user\n NoResultError: -32003,\n // When trying to delete/update a non existent record in the db\n RecordNotFoundError: -32004,\n ForeignKeyConstraintError: -32005,\n NotNullConstraintError: -32006,\n UniqueConstraintError: -32007,\n PermissionError: -32008,\n BadRequestError: -32009,\n};\n\n// Error presets\nclass PermissionError extends Error {}\n\nclass DatabaseError extends Error {\n constructor(error) {\n super(error.message);\n this.error = error;\n }\n}\n\nclass NotFoundError extends Error {\n errorCode = RuntimeErrors.RecordNotFoundError;\n constructor(message) {\n super(message); // Default message is handled by the runtime for consistency with built in actions\n }\n}\n\nclass BadRequestError extends Error {\n errorCode = RuntimeErrors.BadRequestError;\n constructor(message = \"bad request\") {\n super(message);\n }\n}\n\nclass UnknownError extends Error {\n errorCode = RuntimeErrors.UnknownError;\n constructor(message = \"unknown error\") {\n super(message);\n }\n}\n\nconst ErrorPresets = {\n NotFound: NotFoundError,\n BadRequest: BadRequestError,\n Unknown: UnknownError,\n};\n\n// errorToJSONRPCResponse transforms a JavaScript Error instance (or derivative) into a valid JSONRPC response object to pass back to the Keel runtime.\nfunction errorToJSONRPCResponse(request, e) {\n switch (e.constructor.name) {\n case \"PermissionError\":\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.PermissionError,\n e.message\n );\n // Any error thrown in the ModelAPI class is\n // wrapped in a DatabaseError in order to differentiate 'our code' vs the user's own code.\n case \"NoResultError\":\n return createJSONRPCErrorResponse(\n request.id,\n\n // to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54\n RuntimeErrors.RecordNotFoundError,\n \"\" // Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors\n );\n case \"DatabaseError\":\n let err = e;\n\n // If wrapped error then unwrap\n if (e instanceof DatabaseError) {\n err = e.error;\n }\n\n if (err.constructor.name == \"NoResultError\") {\n return createJSONRPCErrorResponse(\n request.id,\n\n // to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54\n RuntimeErrors.RecordNotFoundError,\n \"\" // Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors\n );\n }\n\n // if the error contains 'code' then assume it has other pg error message keys\n // todo: make this more ironclad.\n // when using lib-pq, should match https://github.com/brianc/node-postgres/blob/master/packages/pg-protocol/src/parser.ts#L371-L386\n if (\"code\" in err) {\n const { code, detail, table } = err;\n\n let rpcErrorCode, column, value;\n const [col, val] = parseKeyMessage(err.detail);\n column = col;\n value = val;\n\n switch (code) {\n case \"23502\":\n rpcErrorCode = RuntimeErrors.NotNullConstraintError;\n column = err.column;\n break;\n case \"23503\":\n rpcErrorCode = RuntimeErrors.ForeignKeyConstraintError;\n break;\n case \"23505\":\n rpcErrorCode = RuntimeErrors.UniqueConstraintError;\n break;\n default:\n rpcErrorCode = RuntimeErrors.DatabaseError;\n break;\n }\n\n return createJSONRPCErrorResponse(request.id, rpcErrorCode, e.message, {\n table,\n column,\n code,\n detail,\n value,\n });\n }\n\n // we don't know what it is, but it's something else\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.DatabaseError,\n e.message\n );\n default:\n // Use the errorCode in the error if we have some from a preset\n return createJSONRPCErrorResponse(\n request.id,\n e.errorCode ?? RuntimeErrors.UnknownError,\n e.message\n );\n }\n}\n\n// example data:\n// Key (author_id)=(fake) is not present in table \"author\".\nconst keyMessagePattern = /\\Key\\s[(](.*)[)][=][(](.*)[)]/;\nconst parseKeyMessage = (msg) => {\n const [, col, value] = keyMessagePattern.exec(msg) || [];\n\n return [col, value];\n};\n\nexport {\n errorToJSONRPCResponse,\n RuntimeErrors,\n DatabaseError,\n PermissionError,\n ErrorPresets,\n};\n","import { Duration } from \"./Duration\";\nimport { InlineFile, File } from \"./File\";\nimport { isPlainObject } from \"./type-utils\";\n\n// parseInputs takes a set of inputs and creates objects for the ones that are of a complex type.\n//\n// inputs that are objects and contain a \"__typename\" field are resolved to instances of the complex type\n// they represent.\nfunction parseInputs(inputs) {\n if (inputs != null && typeof inputs === \"object\") {\n for (const k of Object.keys(inputs)) {\n if (inputs[k] !== null && typeof inputs[k] === \"object\") {\n if (Array.isArray(inputs[k])) {\n inputs[k] = inputs[k].map((item) => {\n if (item && typeof item === \"object\") {\n if (\"__typename\" in item) {\n return parseComplexInputType(item);\n }\n // Recursively parse nested objects in arrays\n return parseInputs(item);\n }\n return item;\n });\n } else if (\"__typename\" in inputs[k]) {\n inputs[k] = parseComplexInputType(inputs[k]);\n } else {\n inputs[k] = parseInputs(inputs[k]);\n }\n }\n }\n }\n\n return inputs;\n}\n\n// parseComplexInputType will parse out complex types such as InlineFile and Duration\nfunction parseComplexInputType(value) {\n switch (value.__typename) {\n case \"InlineFile\":\n return InlineFile.fromDataURL(value.dataURL);\n case \"Duration\":\n return Duration.fromISOString(value.interval);\n default:\n throw new Error(\"complex type not handled: \" + value.__typename);\n }\n}\n\n// parseOutputs will take a response from the custom function and perform operations on any fields if necessary.\n//\n// For example, InlineFiles need to be stored before returning the response.\nasync function parseOutputs(outputs) {\n if (outputs != null && typeof outputs === \"object\") {\n for (const k of Object.keys(outputs)) {\n if (outputs[k] !== null && typeof outputs[k] === \"object\") {\n if (Array.isArray(outputs[k])) {\n outputs[k] = await Promise.all(\n outputs[k].map((item) => parseOutputs(item))\n );\n } else if (outputs[k] instanceof InlineFile) {\n const stored = await outputs[k].store();\n outputs[k] = stored;\n } else if (outputs[k] instanceof Duration) {\n outputs[k] = outputs[k].toISOString();\n } else {\n outputs[k] = await parseOutputs(outputs[k]);\n }\n }\n }\n }\n\n return outputs;\n}\n\n// transformRichDataTypes iterates through the given object's keys and if any of the values are a rich data type, instantiate their respective class\nfunction transformRichDataTypes(data) {\n const keys = data ? Object.keys(data) : [];\n const row = {};\n\n for (const key of keys) {\n const value = data[key];\n if (Array.isArray(value)) {\n row[key] = value.map((item) => transformRichDataTypes({ item }).item);\n } else if (isPlainObject(value)) {\n if (value._typename == \"Duration\" && value.pgInterval) {\n row[key] = new Duration(value.pgInterval);\n } else if (\n value.key &&\n value.size &&\n value.filename &&\n value.contentType\n ) {\n row[key] = File.fromDbRecord(value);\n } else {\n row[key] = value;\n }\n } else {\n row[key] = value;\n }\n }\n\n return row;\n}\n\nfunction isReferencingExistingRecord(value) {\n return Object.keys(value).length === 1 && value.id;\n}\n\nexport {\n parseInputs,\n parseOutputs,\n transformRichDataTypes,\n isReferencingExistingRecord,\n};\n","import { sql } from \"kysely\";\nimport { snakeCase } from \"./casing\";\nimport { TimePeriod } from \"./TimePeriod\";\n\nconst opMapping = {\n startsWith: { op: \"like\", value: (v) => `${v}%` },\n endsWith: { op: \"like\", value: (v) => `%${v}` },\n contains: { op: \"like\", value: (v) => `%${v}%` },\n oneOf: { op: \"=\", value: (v) => sql`ANY(${v})` },\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: sql`is not distinct from` },\n notEquals: { op: sql`is distinct from` },\n equalsRelative: {\n op: sql`BETWEEN`,\n value: (v) =>\n sql`${sql.raw(\n TimePeriod.fromExpression(v).periodStartSQL()\n )} AND ${sql.raw(TimePeriod.fromExpression(v).periodEndSQL())}`,\n },\n beforeRelative: {\n op: \"<\",\n value: (v) =>\n sql`${sql.raw(TimePeriod.fromExpression(v).periodStartSQL())}`,\n },\n afterRelative: {\n op: \">=\",\n value: (v) => sql`${sql.raw(TimePeriod.fromExpression(v).periodEndSQL())}`,\n },\n any: {\n isArrayQuery: true,\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: \"=\" },\n notEquals: { op: \"=\", value: (v) => sql`NOT ${v}` },\n },\n all: {\n isArrayQuery: true,\n greaterThan: { op: \">\" },\n greaterThanOrEquals: { op: \">=\" },\n lessThan: { op: \"<\" },\n lessThanOrEquals: { op: \"<=\" },\n before: { op: \"<\" },\n onOrBefore: { op: \"<=\" },\n after: { op: \">\" },\n onOrAfter: { op: \">=\" },\n equals: { op: \"=\" },\n notEquals: { op: \"=\", value: (v) => sql`NOT ${v}` },\n },\n};\n\n/**\n * Applies the given where conditions to the provided Kysely\n * instance and returns the resulting new Kysely instance.\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} qb\n * @param {Object} where\n * @returns {import(\"kysely\").Kysely}\n */\nfunction applyWhereConditions(context, qb, where = {}) {\n const conf = context.tableConfig();\n for (const key of Object.keys(where)) {\n const v = where[key];\n\n // Handle nested where conditions e.g. using a join table\n if (conf && conf[snakeCase(key)]) {\n const rel = conf[snakeCase(key)];\n context.withJoin(rel.referencesTable, () => {\n qb = applyWhereConditions(context, qb, v);\n });\n continue;\n }\n\n const fieldName = `${context.tableAlias()}.${snakeCase(key)}`;\n\n if (Object.prototype.toString.call(v) !== \"[object Object]\") {\n qb = qb.where(fieldName, sql`is not distinct from`, sql`${v}`);\n continue;\n }\n\n for (const op of Object.keys(v)) {\n const mapping = opMapping[op];\n if (!mapping) {\n throw new Error(`invalid where condition: ${op}`);\n }\n\n if (mapping.isArrayQuery) {\n for (const arrayOp of Object.keys(v[op])) {\n qb = qb.where(\n mapping[arrayOp].value\n ? mapping[arrayOp].value(v[op][arrayOp])\n : sql`${v[op][arrayOp]}`,\n mapping[arrayOp].op,\n sql`${sql(op)}(${sql.ref(fieldName)})`\n );\n }\n } else {\n qb = qb.where(\n fieldName,\n mapping.op,\n mapping.value ? mapping.value(v[op]) : sql`${v[op]}`\n );\n }\n }\n }\n\n return qb;\n}\n\nexport { applyWhereConditions };\n","import { snakeCase, camelCase } from \"change-case\";\n\nfunction camelCaseObject(obj = {}) {\n const r = {};\n for (const key of Object.keys(obj)) {\n r[\n camelCase(key, {\n transform: camelCaseTransform,\n splitRegexp: [\n /([a-z0-9])([A-Z])/g,\n /([A-Z])([A-Z][a-z])/g,\n /([a-zA-Z])([0-9])/g,\n ],\n })\n ] = obj[key];\n }\n return r;\n}\n\nfunction snakeCaseObject(obj) {\n const r = {};\n for (const key of Object.keys(obj)) {\n r[\n snakeCase(key, {\n splitRegexp: [\n /([a-z0-9])([A-Z])/g,\n /([A-Z])([A-Z][a-z])/g,\n /([a-zA-Z])([0-9])/g,\n ],\n })\n ] = obj[key];\n }\n return r;\n}\n\nfunction upperCamelCase(s) {\n s = camelCase(s);\n return s[0].toUpperCase() + s.substring(1);\n}\n\nfunction camelCaseTransform(input, index) {\n if (index === 0) return input.toLowerCase();\n const firstChar = input.charAt(0);\n const lowerChars = input.substr(1).toLowerCase();\n return `${firstChar.toUpperCase()}${lowerChars}`;\n}\n\nexport {\n camelCaseObject,\n snakeCaseObject,\n snakeCase,\n camelCase,\n upperCamelCase,\n};\n","class TimePeriod {\n constructor(period = \"\", value = 0, offset = 0, complete = false) {\n this.period = period;\n this.value = value;\n this.offset = offset;\n this.complete = complete;\n }\n\n static fromExpression(expression) {\n // Regex pattern\n const pattern =\n /^(this|next|last)?\\s*(\\d+)?\\s*(complete)?\\s*(second|minute|hour|day|week|month|year|seconds|minutes|hours|days|weeks|months|years)?$/i;\n\n const shorthandPattern = /^(now|today|tomorrow|yesterday)$/i;\n\n const shorthandMatch = shorthandPattern.exec(expression.trim());\n if (shorthandMatch) {\n const shorthand = shorthandMatch[1].toLowerCase();\n switch (shorthand) {\n case \"now\":\n return new TimePeriod();\n case \"today\":\n return TimePeriod.fromExpression(\"this day\");\n case \"tomorrow\":\n return TimePeriod.fromExpression(\"next complete day\");\n case \"yesterday\":\n return TimePeriod.fromExpression(\"last complete day\");\n }\n }\n\n const match = pattern.exec(expression.trim());\n if (!match) {\n throw new Error(\"Invalid time period expression\");\n }\n\n const [, direction, rawValue, isComplete, rawPeriod] = match;\n\n let period = rawPeriod ? rawPeriod.toLowerCase().replace(/s$/, \"\") : \"\";\n let value = rawValue ? parseInt(rawValue, 10) : 1;\n let complete = Boolean(isComplete);\n let offset = 0;\n\n switch (direction?.toLowerCase()) {\n case \"this\":\n offset = 0;\n complete = true;\n break;\n case \"next\":\n offset = complete ? 1 : 0;\n break;\n case \"last\":\n offset = -value;\n break;\n default:\n throw new Error(\n \"Time period expression must start with this, next, or last\"\n );\n }\n\n return new TimePeriod(period, value, offset, complete);\n }\n\n periodStartSQL() {\n let sql = \"NOW()\";\n if (this.offset !== 0) {\n sql = `${sql} + INTERVAL '${this.offset} ${this.period}'`;\n }\n\n if (this.complete) {\n sql = `DATE_TRUNC('${this.period}', ${sql})`;\n } else {\n sql = `(${sql})`;\n }\n\n return sql;\n }\n\n periodEndSQL() {\n let sql = this.periodStartSQL();\n if (this.value != 0) {\n sql = `(${sql} + INTERVAL '${this.value} ${this.period}')`;\n }\n return sql;\n }\n}\n\nexport { TimePeriod };\n","import { snakeCase } from \"./casing\";\n\nfunction applyLimit(context, qb, limit) {\n return qb.limit(limit);\n}\n\nfunction applyOffset(context, qb, offset) {\n return qb.offset(offset);\n}\n\nfunction applyOrderBy(context, qb, tableName, orderBy = {}) {\n Object.entries(orderBy).forEach(([key, sortOrder]) => {\n qb = qb.orderBy(`${tableName}.${snakeCase(key)}`, sortOrder.toLowerCase());\n });\n return qb;\n}\n\nexport { applyLimit, applyOffset, applyOrderBy };\n","import { snakeCase } from \"./casing\";\n\n/**\n * Adds the joins required by the where conditions to the given\n * Kysely instance and returns the resulting new Kysely instance.\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} qb\n * @param {Object} where\n * @returns {import(\"kysely\").Kysely}\n */\nfunction applyJoins(context, qb, where) {\n const conf = context.tableConfig();\n if (!conf) {\n return qb;\n }\n\n const srcTable = context.tableAlias();\n\n for (const key of Object.keys(where)) {\n const rel = conf[snakeCase(key)];\n if (!rel) {\n continue;\n }\n\n const targetTable = rel.referencesTable;\n\n if (context.hasJoin(targetTable)) {\n continue;\n }\n\n context.withJoin(targetTable, () => {\n switch (rel.relationshipType) {\n case \"hasMany\":\n // For hasMany the primary key is on the source table\n // and the foreign key is on the target table\n qb = qb.innerJoin(\n `${targetTable} as ${context.tableAlias()}`,\n `${srcTable}.id`,\n `${context.tableAlias()}.${rel.foreignKey}`\n );\n break;\n\n case \"belongsTo\":\n // For belongsTo the primary key is on the target table\n // and the foreign key is on the source table\n qb = qb.innerJoin(\n `${targetTable} as ${context.tableAlias()}`,\n `${srcTable}.${rel.foreignKey}`,\n `${context.tableAlias()}.id`\n );\n break;\n default:\n throw new Error(`unknown relationshipType: ${rel.relationshipType}`);\n }\n\n // Keep traversing through the where conditions to see if\n // more joins need to be applied\n qb = applyJoins(context, qb, where[key]);\n });\n }\n\n return qb;\n}\n\nexport { applyJoins };\n","/**\n * QueryContext is used to store state about the current query, for example\n * which joins have already been applied. It is used by applyJoins and\n * applyWhereConditions to generate consistent table aliases for joins.\n *\n * This class has the concept of a \"table path\". This is just a list of tables, starting\n * with some \"root\" table and ending with the table we're currently joining to. So\n * for example if we started with a \"product\" table and joined from there to \"order_item\"\n * and then to \"order\" and then to \"customer\" the table path would be:\n * [\"product\", \"order_item\", \"order\", \"customer\"]\n * At this point the \"current\" table is \"customer\" and it's alias would be:\n * \"product$order_item$order$customer\"\n */\nclass QueryContext {\n /**\n * @param {string[]} tablePath This is the path from the \"root\" table to the \"current table\".\n * @param {import(\"./ModelAPI\").TableConfigMap} tableConfigMap\n * @param {string[]} joins\n */\n constructor(tablePath, tableConfigMap, joins = []) {\n this._tablePath = tablePath;\n this._tableConfigMap = tableConfigMap;\n this._joins = joins;\n }\n\n clone() {\n return new QueryContext([...this._tablePath], this._tableConfigMap, [\n ...this._joins,\n ]);\n }\n\n /**\n * Returns true if, given the current table path, a join to the given\n * table has already been added.\n * @param {string} table\n * @returns {boolean}\n */\n hasJoin(table) {\n const alias = joinAlias([...this._tablePath, table]);\n return this._joins.includes(alias);\n }\n\n /**\n * Adds table to the QueryContext's path and registers the join,\n * calls fn, then pops the table off the path.\n * @param {string} table\n * @param {Function} fn\n */\n withJoin(table, fn) {\n this._tablePath.push(table);\n this._joins.push(this.tableAlias());\n\n fn();\n\n // Don't change the _joins list, we want to remember those\n this._tablePath.pop();\n }\n\n /**\n * Returns the alias that will be used for the current table\n * @returns {string}\n */\n tableAlias() {\n return joinAlias(this._tablePath);\n }\n\n /**\n * Returns the current table name\n * @returns {string}\n */\n tableName() {\n return this._tablePath[this._tablePath.length - 1];\n }\n\n /**\n * Return the TableConfig for the current table\n * @returns {import(\"./ModelAPI\").TableConfig | undefined}\n */\n tableConfig() {\n return this._tableConfigMap[this.tableName()];\n }\n}\n\nfunction joinAlias(tablePath) {\n return tablePath.join(\"$\");\n}\n\nexport { QueryContext };\n","import { applyWhereConditions } from \"./applyWhereConditions\";\nimport {\n applyLimit,\n applyOffset,\n applyOrderBy,\n} from \"./applyAdditionalQueryConstraints\";\nimport { applyJoins } from \"./applyJoins\";\nimport { camelCaseObject, snakeCaseObject, upperCamelCase } from \"./casing\";\nimport { useDatabase } from \"./database\";\nimport { transformRichDataTypes } from \"./parsing\";\nimport { QueryContext } from \"./QueryContext\";\nimport * as tracing from \"./tracing\";\nimport { DatabaseError } from \"./errors\";\n\nclass QueryBuilder {\n /**\n * @param {string} tableName\n * @param {import(\"./QueryContext\").QueryContext} context\n * @param {import(\"kysely\").Kysely} db\n */\n constructor(tableName, context, db) {\n this._tableName = tableName;\n this._context = context;\n this._db = db;\n this._modelName = upperCamelCase(this._tableName);\n }\n\n where(where) {\n const context = this._context.clone();\n\n let builder = applyJoins(context, this._db, where);\n builder = applyWhereConditions(context, builder, where);\n\n return new QueryBuilder(this._tableName, context, builder);\n }\n\n sql() {\n return this._db.compile().sql;\n }\n\n async update(values) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"update\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n // we build a sub-query to add to the WHERE id IN (XXX) containing all of the\n // wheres added in previous .where() chains.\n const sub = this._db.clearSelect().select(\"id\");\n\n const query = db\n .updateTable(this._tableName)\n .set(snakeCaseObject(values))\n .returningAll()\n .where(\"id\", \"in\", sub);\n\n try {\n const result = await query.execute();\n const numUpdatedRows = result.length;\n\n // the double (==) is important because we are comparing bigint to int\n if (numUpdatedRows == 0) {\n return null;\n }\n\n if (numUpdatedRows > 1) {\n throw new DatabaseError(\n new Error(\n \"more than one row matched update constraints - only unique fields should be used when updating.\"\n )\n );\n }\n\n return transformRichDataTypes(camelCaseObject(result[0]));\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async delete() {\n const name = tracing.spanNameForModelAPI(this._modelName, \"delete\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n // the original query selects the distinct id + the model.* so we need to clear\n const sub = this._db.clearSelect().select(\"id\");\n let builder = db.deleteFrom(this._tableName).where(\"id\", \"in\", sub);\n\n const query = builder.returning([\"id\"]);\n\n // final query looks something like:\n // delete from \"person\" where \"id\" in (select distinct on (\"person\".\"id\") \"id\" from \"person\" where \"person\".\"id\" = $1) returning \"id\"\n\n span.setAttribute(\"sql\", query.compile().sql);\n\n try {\n const row = await query.executeTakeFirstOrThrow();\n return row.id;\n } catch (e) {\n throw new DatabaseError(e);\n }\n });\n }\n\n async findOne() {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findOne\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n let builder = db\n .selectFrom((qb) => {\n // this._db contains all of the where constraints and joins\n // we want to include that in the sub query in the same way we\n // add all of this information into the sub query in the ModelAPI's\n // implementation of findOne\n return this._db.as(this._tableName);\n })\n .selectAll();\n\n span.setAttribute(\"sql\", builder.compile().sql);\n\n const row = await builder.executeTakeFirst();\n if (!row) {\n return null;\n }\n\n return transformRichDataTypes(camelCaseObject(row));\n });\n }\n\n async findMany(params) {\n const name = tracing.spanNameForModelAPI(this._modelName, \"findMany\");\n const db = useDatabase();\n\n return tracing.withSpan(name, async (span) => {\n const context = new QueryContext([this._tableName], this._tableConfigMap);\n\n let builder = db\n .selectFrom((qb) => {\n // this._db contains all of the where constraints and joins\n // we want to include that in the sub query in the same way we\n // add all of this information into the sub query in the ModelAPI's\n // implementation of findMany\n return this._db.as(this._tableName);\n })\n .selectAll();\n\n // The only constraints added to the main query are the orderBy, limit and offset as they are performed on the \"outer\" set\n if (params?.limit) {\n builder = applyLimit(context, builder, params.limit);\n }\n\n if (params?.offset) {\n builder = applyOffset(context, builder, params.offset);\n }\n\n if (\n params?.orderBy !== undefined &&\n Object.keys(params?.orderBy).length > 0\n ) {\n builder = applyOrderBy(\n context,\n builder,\n this._tableName,\n params.orderBy\n );\n } else {\n builder = builder.orderBy(`${this._tableName}.id`);\n }\n\n const query = builder;\n\n span.setAttribute(\"sql\", query.compile().sql);\n const rows = await builder.execute();\n return rows.map((x) => transformRichDataTypes(camelCaseObject(x)));\n });\n }\n}\n\nexport { QueryBuilder };\n","interface RequestHeadersMap {\n [key: string]: string;\n}\n\nexport class RequestHeaders {\n private _headers: Headers;\n\n /**\n * @param {{Object.<string, string>}} requestHeaders Map of request headers submitted from the client\n */\n\n constructor(requestHeaders: RequestHeadersMap) {\n this._headers = new Headers(requestHeaders);\n }\n\n get: Headers[\"get\"] = (key: string) => {\n return this._headers.get(key);\n };\n\n has: Headers[\"has\"] = (key: string) => {\n return this._headers.has(key);\n };\n}\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { tryExecuteFunction } from \"./tryExecuteFunction\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { parseInputs, parseOutputs } from \"./parsing\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a custom function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleRequest(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n if (process.env.KEEL_LOG_LEVEL == \"debug\") {\n console.log(request);\n }\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createContextAPI, functions, permissionFns, actionTypes } =\n config;\n\n if (!(request.method in functions)) {\n const message = `no corresponding function found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // headers reference passed to custom function where object data can be modified\n const headers = new Headers();\n\n // The ctx argument passed into the custom function.\n const ctx = createContextAPI({\n responseHeaders: headers,\n meta: request.meta,\n });\n\n // The Go runtime does *some* permissions checks up front before the request reaches\n // this method, so we pass in a permissionState object on the request.meta object that\n // indicates whether a call to a custom function has already been authorised\n const permitted =\n request.meta && request.meta.permissionState.status === \"granted\"\n ? true\n : null;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const customFunction = functions[request.method];\n const actionType = actionTypes[request.method];\n\n const functionConfig = customFunction?.config ?? {};\n\n const result = await tryExecuteFunction(\n {\n request,\n ctx,\n permitted,\n db,\n permissionFns,\n actionType,\n functionConfig,\n },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the custom function to the containing tryExecuteFunction block\n // Once the custom function is called, tryExecuteFunction will check the schema's permission rules to see if it can continue committing\n // the transaction to the db. If a permission rule is violated, any changes made inside the transaction are rolled back.\n const result = await customFunction(ctx, inputs);\n\n return parseOutputs(result);\n }\n );\n\n if (result instanceof Error) {\n span.recordException(result);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: result.message,\n });\n return errorToJSONRPCResponse(request, result);\n }\n\n const response = createJSONRPCSuccessResponse(request.id, result);\n\n const responseHeaders = {};\n for (const pair of headers.entries()) {\n responseHeaders[pair[0]] = pair[1].split(\", \");\n }\n response.meta = {\n headers: responseHeaders,\n status: ctx.response.status,\n };\n\n return response;\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleRequest, RuntimeErrors };\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { PermissionError } from \"./errors\";\n\nexport const PERMISSION_STATE = {\n UNKNOWN: \"unknown\",\n PERMITTED: \"permitted\",\n UNPERMITTED: \"unpermitted\",\n} as const;\n\nexport type PermissionState =\n (typeof PERMISSION_STATE)[keyof typeof PERMISSION_STATE];\n\n/**\n * Permissions class for managing access control in the runtime\n */\nexport class Permissions {\n // The Go runtime performs role based permission rule checks prior to calling the functions\n // runtime, so the status could already be granted. If already granted, then we need to inherit that permission state as the state is later used to decide whether to run in process permission checks\n // TLDR if a role based permission is relevant and it is granted, then it is effectively the same as the end user calling api.permissions.allow() explicitly in terms of behaviour.\n\n /**\n * Explicitly permit access to an action\n */\n allow(): void {\n permissionsApiInstance.getStore()!.permitted = true;\n }\n\n /**\n * Explicitly deny access to an action\n */\n deny(): never {\n // if a user is explicitly calling deny() then we want to throw an error\n // so that any further execution of the custom function stops abruptly\n permissionsApiInstance.getStore()!.permitted = false;\n throw new PermissionError();\n }\n\n getState(): PermissionState {\n const permitted = permissionsApiInstance.getStore()!.permitted;\n\n switch (true) {\n case permitted === false:\n return PERMISSION_STATE.UNPERMITTED;\n case permitted === null:\n return PERMISSION_STATE.UNKNOWN;\n case permitted === true:\n return PERMISSION_STATE.PERMITTED;\n default:\n return PERMISSION_STATE.UNKNOWN;\n }\n }\n}\n\ninterface PermissionStore {\n permitted: boolean | null;\n}\n\nconst permissionsApiInstance = new AsyncLocalStorage<PermissionStore>();\n\ninterface PermissionCallback {\n getPermissionState: () => PermissionState;\n}\n\n// withPermissions sets the initial permission state from the go runtime in the AsyncLocalStorage so consumers further down the hierarchy can read or mutate the state\n// at will\nexport const withPermissions = async <T>(\n initialValue: boolean | null,\n cb: (permissions: PermissionCallback) => Promise<T>\n): Promise<T> => {\n const permissions = new Permissions();\n\n return await permissionsApiInstance.run({ permitted: initialValue }, () => {\n return cb({ getPermissionState: permissions.getState });\n });\n};\n\ninterface CheckBuiltInPermissionsParams {\n rows: any[];\n permissionFns: Array<(rows: any[], ctx: any, db: any) => Promise<boolean>>;\n ctx: any;\n db: any;\n functionName: string;\n}\n\nexport const checkBuiltInPermissions = async ({\n rows,\n permissionFns,\n ctx,\n db,\n functionName,\n}: CheckBuiltInPermissionsParams): Promise<void> => {\n for (const permissionFn of permissionFns) {\n const result = await permissionFn(rows, ctx, db);\n // if any of the permission functions return true,\n // then we return early\n if (result) {\n return;\n }\n }\n\n throw new PermissionError(`Not permitted to access ${functionName}`);\n};\n\nexport { PermissionError };\nexport { permissionsApiInstance };\n","const PROTO_ACTION_TYPES = {\n UNKNOWN: \"ACTION_TYPE_UNKNOWN\",\n CREATE: \"ACTION_TYPE_CREATE\",\n GET: \"ACTION_TYPE_GET\",\n LIST: \"ACTION_TYPE_LIST\",\n UPDATE: \"ACTION_TYPE_UPDATE\",\n DELETE: \"ACTION_TYPE_DELETE\",\n READ: \"ACTION_TYPE_READ\",\n WRITE: \"ACTION_TYPE_WRITE\",\n JOB: \"JOB_TYPE\",\n SUBSCRIBER: \"SUBSCRIBER_TYPE\",\n FLOW: \"FLOW_TYPE\",\n};\n\nexport { PROTO_ACTION_TYPES };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport {\n withPermissions,\n PERMISSION_STATE,\n checkBuiltInPermissions,\n} from \"./permissions\";\nimport { PermissionError } from \"./errors\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\n\n// tryExecuteFunction will create a new database transaction around a function call\n// and handle any permissions checks. If a permission check fails, then an Error will be thrown and the catch block will be hit.\nfunction tryExecuteFunction(\n { request, db, permitted, permissionFns, actionType, ctx, functionConfig },\n cb\n) {\n return withPermissions(permitted, async ({ getPermissionState }) => {\n let requiresTransaction = true;\n switch (actionType) {\n case PROTO_ACTION_TYPES.GET:\n case PROTO_ACTION_TYPES.LIST:\n case PROTO_ACTION_TYPES.READ:\n requiresTransaction = false;\n break;\n }\n\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n\n return withDatabase(db, requiresTransaction, async ({ transaction }) => {\n const fnResult = await withAuditContext(request, async () => {\n return cb();\n });\n\n // api.permissions maintains an internal state of whether the current function has been *explicitly* permitted/denied by the user in the course of their custom function, or if execution has already been permitted by a role based permission (evaluated in the main runtime).\n // we need to check that the final state is permitted or unpermitted. if it's not, then it means that the user has taken no explicit action to permit/deny\n // and therefore we default to checking the permissions defined in the schema automatically.\n switch (getPermissionState()) {\n case PERMISSION_STATE.PERMITTED:\n return fnResult;\n case PERMISSION_STATE.UNPERMITTED:\n throw new PermissionError(\n `Not permitted to access ${request.method}`\n );\n default:\n // unknown state, proceed with checking against the built in permissions in the schema\n const relevantPermissions = permissionFns[request.method];\n\n const peakInsideTransaction =\n actionType === PROTO_ACTION_TYPES.CREATE;\n\n let rowsForPermissions = [];\n if (fnResult != null) {\n switch (actionType) {\n case PROTO_ACTION_TYPES.LIST:\n rowsForPermissions = fnResult;\n break;\n case PROTO_ACTION_TYPES.DELETE:\n rowsForPermissions = [{ id: fnResult }];\n break;\n case (PROTO_ACTION_TYPES.GET, PROTO_ACTION_TYPES.CREATE):\n rowsForPermissions = [fnResult];\n break;\n default:\n rowsForPermissions = [fnResult];\n break;\n }\n }\n\n // check will throw a PermissionError if a permission rule is invalid\n await checkBuiltInPermissions({\n rows: rowsForPermissions,\n permissionFns: relevantPermissions,\n // it is important that we pass db here as db represents the connection to the database\n // *outside* of the current transaction. Given that any changes inside of a transaction\n // are opaque to the outside, we can utilize this when running permission rules and then deciding to\n // rollback any changes if they do not pass. However, for creates we need to be able to 'peak' inside the transaction to read the created record, as this won't exist outside of the transaction.\n db: peakInsideTransaction ? transaction : db,\n ctx,\n functionName: request.method,\n });\n\n // If the built in permission check above doesn't throw, then it means that the request is permitted and we can continue returning the return value from the custom function out of the transaction\n return fnResult;\n }\n });\n });\n}\n\nexport { tryExecuteFunction };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { tryExecuteJob } from \"./tryExecuteJob\";\nimport { parseInputs } from \"./parsing\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a job function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleJob(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createJobContextAPI, jobs } = config;\n\n if (!(request.method in jobs)) {\n const message = `no corresponding job found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // The ctx argument passed into the job function.\n const ctx = createJobContextAPI({\n meta: request.meta,\n });\n\n const permitted =\n request.meta && request.meta.permissionState.status === \"granted\"\n ? true\n : null;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const jobFunction = jobs[request.method];\n const actionType = PROTO_ACTION_TYPES.JOB;\n\n const functionConfig = jobFunction?.config ?? {};\n\n await tryExecuteJob(\n { request, permitted, db, actionType, functionConfig },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the job function to the containing tryExecuteJob block\n return jobFunction(ctx, inputs);\n }\n );\n\n return createJSONRPCSuccessResponse(request.id, null);\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleJob, RuntimeErrors };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport { withPermissions, PERMISSION_STATE } from \"./permissions\";\nimport { PermissionError } from \"./errors\";\n\n// tryExecuteJob will create a new database transaction around a function call\n// and handle any permissions checks. If a permission check fails, then an Error will be thrown and the catch block will be hit.\nfunction tryExecuteJob({ db, permitted, request, functionConfig }, cb) {\n return withPermissions(permitted, async ({ getPermissionState }) => {\n let requiresTransaction = false;\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n return withDatabase(db, requiresTransaction, async () => {\n await withAuditContext(request, async () => {\n return cb();\n });\n\n // api.permissions maintains an internal state of whether the current operation has been *explicitly* permitted/denied by the user in the course of their custom function, or if execution has already been permitted by a role based permission (evaluated in the main runtime).\n // we need to check that the final state is permitted or unpermitted. if it's not, then it means that the user has taken no explicit action to permit/deny\n // and therefore we default to checking the permissions defined in the schema automatically.\n if (getPermissionState() === PERMISSION_STATE.UNPERMITTED) {\n throw new PermissionError(`Not permitted to access ${request.method}`);\n }\n });\n });\n}\n\nexport { tryExecuteJob };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { PROTO_ACTION_TYPES } from \"./consts\";\nimport { tryExecuteSubscriber } from \"./tryExecuteSubscriber\";\nimport { parseInputs } from \"./parsing\";\n\n// Generic handler function that is agnostic to runtime environment (local or lambda)\n// to execute a subscriber function based on the contents of a jsonrpc-2.0 payload object.\n// To read more about jsonrpc request and response shapes, please read https://www.jsonrpc.org/specification\nasync function handleSubscriber(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createSubscriberContextAPI, subscribers } = config;\n\n if (!(request.method in subscribers)) {\n const message = `no corresponding subscriber found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // The ctx argument passed into the subscriber function.\n const ctx = createSubscriberContextAPI({\n meta: request.meta,\n });\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const subscriberFunction = subscribers[request.method];\n const actionType = PROTO_ACTION_TYPES.SUBSCRIBER;\n\n const functionConfig = subscriberFunction?.config ?? {};\n\n await tryExecuteSubscriber(\n { request, db, actionType, functionConfig },\n async () => {\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(request.params);\n\n // Return the subscriber function to the containing tryExecuteSubscriber block\n return subscriberFunction(ctx, inputs);\n }\n );\n\n return createJSONRPCSuccessResponse(request.id, null);\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleSubscriber, RuntimeErrors };\n","import { withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\n\n// tryExecuteSubscriber will create a new database connection and execute the function call.\nfunction tryExecuteSubscriber({ request, db, functionConfig }, cb) {\n let requiresTransaction = false;\n if (functionConfig?.dbTransaction !== undefined) {\n requiresTransaction = functionConfig.dbTransaction;\n }\n return withDatabase(db, requiresTransaction, async () => {\n await withAuditContext(request, async () => {\n return cb();\n });\n });\n}\n\nexport { tryExecuteSubscriber };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient, withDatabase } from \"./database\";\nimport { withAuditContext } from \"./auditing\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\n\nasync function handleRoute(request, config) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span) => {\n let db = null;\n\n try {\n const { createContextAPI, functions } = config;\n\n if (!(request.method in functions)) {\n const message = `no route function found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n // For route functions context doesn't need request headers or the response object as this is handled by\n // params and the function response respectively\n const {\n headers,\n response: __,\n ...ctx\n } = createContextAPI({\n responseHeaders: new Headers(),\n meta: request.meta,\n });\n\n // Add request headers to params\n request.params.headers = headers;\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n const routeHandler = functions[request.method];\n\n const result = await withDatabase(db, false, () => {\n return withAuditContext(request, () => {\n return routeHandler(request.params, ctx);\n });\n });\n\n if (result instanceof Error) {\n span.recordException(result);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: result.message,\n });\n return errorToJSONRPCResponse(request, result);\n }\n\n const response = createJSONRPCSuccessResponse(request.id, result);\n\n return response;\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleRoute, RuntimeErrors };\n","import {\n createJSONRPCErrorResponse,\n createJSONRPCSuccessResponse,\n JSONRPCErrorCode,\n} from \"json-rpc-2.0\";\nimport { createDatabaseClient } from \"./database\";\nimport { errorToJSONRPCResponse, RuntimeErrors } from \"./errors\";\nimport * as opentelemetry from \"@opentelemetry/api\";\nimport { withSpan } from \"./tracing\";\nimport { tryExecuteFlow } from \"./tryExecuteFlow\";\nimport { parseInputs } from \"./parsing\";\nimport { createFlowContext, FlowConfig } from \"./flows\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n} from \"./flows/disrupts\";\nimport { sentenceCase } from \"change-case\";\n\nasync function handleFlow(request: any, config: any) {\n // Try to extract trace context from caller\n const activeContext = opentelemetry.propagation.extract(\n opentelemetry.context.active(),\n request.meta?.tracing\n );\n\n // Run the whole request with the extracted context\n return opentelemetry.context.with(activeContext, () => {\n // Wrapping span for the whole request\n return withSpan(request.method, async (span: any) => {\n let db = null;\n let flowConfig = null;\n const runId = request.meta?.runId;\n\n try {\n if (!runId) {\n throw new Error(\"no runId provided\");\n }\n\n const { flows } = config;\n\n if (!(request.method in flows)) {\n const message = `no corresponding flow found for '${request.method}'`;\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n return createJSONRPCErrorResponse(\n request.id,\n JSONRPCErrorCode.MethodNotFound,\n message\n );\n }\n\n db = createDatabaseClient({\n connString: request.meta?.secrets?.KEEL_DB_CONN,\n });\n\n const flowRun = await db\n .selectFrom(\"keel.flow_run\")\n .where(\"id\", \"=\", runId)\n .selectAll()\n .executeTakeFirst();\n\n if (!flowRun) {\n throw new Error(\"no flow run found\");\n }\n\n const ctx = createFlowContext(\n request.meta.runId,\n request.meta.data,\n span.spanContext().spanId\n );\n\n const flowFunction = flows[request.method].fn;\n\n // Normalise the flow config\n const rawFlowConfig: FlowConfig = flows[request.method].config;\n flowConfig = {\n ...rawFlowConfig,\n title: rawFlowConfig.title || sentenceCase(request.method || \"flow\"),\n stages: rawFlowConfig.stages?.map((stage) => {\n if (typeof stage === \"string\") {\n return {\n key: stage,\n name: stage,\n };\n }\n return stage;\n }),\n };\n\n // parse request params to convert objects into rich field types (e.g. InlineFile)\n const inputs = parseInputs(flowRun.input);\n\n try {\n await tryExecuteFlow(db, async () => {\n return flowFunction(ctx, inputs);\n });\n } catch (e) {\n // The flow is disrupted as a new step has been created\n if (e instanceof StepCreatedDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: false,\n config: flowConfig,\n });\n }\n\n // The flow is disrupted by a pending UI step\n if (e instanceof UIRenderDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n stepId: e.stepId,\n config: flowConfig,\n ui: e.contents,\n });\n }\n\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e instanceof Error ? e.message : \"unknown error\",\n });\n\n // The flow has failed due to exhausted step retries\n if (e instanceof ExhuastedRetriesDisrupt) {\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n error: \"flow failed due to exhausted step retries\",\n config: flowConfig,\n });\n }\n\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n error: e instanceof Error ? e.message : \"unknown error\",\n config: flowConfig,\n });\n }\n\n // If we reach this point, then we know the entire flow completed successfully\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: true,\n config: flowConfig,\n });\n } catch (e) {\n if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e.message,\n });\n return errorToJSONRPCResponse(request, e);\n }\n\n const message = JSON.stringify(e);\n\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: message,\n });\n\n return createJSONRPCErrorResponse(\n request.id,\n RuntimeErrors.UnknownError,\n message\n );\n } finally {\n if (db) {\n await db.destroy();\n }\n }\n });\n });\n}\n\nexport { handleFlow, RuntimeErrors };\n","import { withDatabase } from \"./database\";\n\nfunction tryExecuteFlow(db, cb) {\n return withDatabase(db, false, async () => {\n return cb();\n });\n}\n\nexport { tryExecuteFlow };\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = string;\n\nexport type UiElementInputText = InputElement<\n ElementDataType,\n {\n placeholder?: string;\n multiline?: boolean;\n maxLength?: number;\n minLength?: number;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputTextApiResponse\n extends BaseUiInputResponse<\"ui.input.text\", ElementDataType> {\n placeholder?: string;\n multiline?: boolean;\n maxLength?: number;\n minLength?: number;\n}\n\nexport const textInput: InputElementImplementation<\n ElementDataType,\n UiElementInputText,\n UiElementInputTextApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.text\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n placeholder: options?.placeholder,\n multiline: options?.multiline,\n maxLength: options?.maxLength,\n minLength: options?.minLength,\n } satisfies UiElementInputTextApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = number;\n\nexport type UiElementInputNumber = InputElement<\n ElementDataType,\n {\n placeholder?: number;\n min?: number;\n max?: number;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputNumberApiResponse\n extends BaseUiInputResponse<\"ui.input.number\", ElementDataType> {\n placeholder?: number;\n min?: number;\n max?: number;\n}\n\nexport const numberInput: InputElementImplementation<\n ElementDataType,\n UiElementInputNumber,\n UiElementInputNumberApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.number\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n placeholder: options?.placeholder,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputNumberApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementDivider = DisplayElement<{}>;\n\n// The shape of the response over the API\nexport interface UiElementDividerApiResponse\n extends BaseUiDisplayResponse<\"ui.display.divider\"> {}\n\nexport const divider: DisplayElementImplementation<\n UiElementDivider,\n UiElementDividerApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.divider\",\n } satisfies UiElementDividerApiResponse,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = boolean;\n\nexport type UiElementInputBoolean = InputElement<\n ElementDataType,\n {\n mode?: \"checkbox\" | \"switch\";\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputBooleanApiResponse\n extends BaseUiInputResponse<\"ui.input.boolean\", ElementDataType> {\n mode: \"checkbox\" | \"switch\";\n}\n\nexport const booleanInput: InputElementImplementation<\n ElementDataType,\n UiElementInputBoolean,\n UiElementInputBooleanApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.boolean\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n mode: options?.mode || \"checkbox\",\n } satisfies UiElementInputBooleanApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementMarkdown = DisplayElement<{\n content: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementMarkdownApiResponse\n extends BaseUiDisplayResponse<\"ui.display.markdown\"> {\n content: string;\n}\n\nexport const markdown: DisplayElementImplementation<\n UiElementMarkdown,\n UiElementMarkdownApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.markdown\",\n content: options?.content || \"\",\n } satisfies UiElementMarkdownApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype TableData<T extends Record<string, any>> = {\n data: T[];\n columns?: Array<Extract<keyof T, string>>;\n};\n\nexport type UiElementTable = <const T extends Record<string, any>>(\n options: TableData<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementTableApiResponse\n extends BaseUiDisplayResponse<\"ui.display.table\"> {\n data: any[];\n columns?: string[]; // Todo: support for an object form with extra context on the data type\n}\n\nexport const table: DisplayElementImplementation<\n UiElementTable,\n UiElementTableApiResponse\n> = (options) => {\n // Only send data for columns we need\n const filteredData = options.columns\n ? options.data.map((item) => {\n return Object.fromEntries(\n Object.entries(item).filter(\n ([key]) => options.columns?.includes(key as any)\n )\n );\n })\n : options.data;\n\n return {\n uiConfig: {\n __type: \"ui.display.table\",\n data: filteredData || [],\n columns: options.columns,\n } satisfies UiElementTableApiResponse,\n };\n};\n","import {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\n\ntype ElementDataType = string | number | boolean | Date;\n\n// Annoyingly can't use the whole InputElement type and also use a local\n// bounded type parameter to infer the type of the value from the config options\n// So having to duplicate the types of the inputs\nexport type UiElementSelectOne = <\n const TValue extends ElementDataType,\n N extends string,\n>(\n name: N,\n options?: BaseInputConfig<TValue> & {\n options: (\n | {\n label: string;\n value: TValue;\n }\n | TValue\n )[];\n }\n) => InputElementResponse<N, TValue>;\n\n// The shape of the response over the API\nexport interface UiElementSelectOneApiResponse\n extends BaseUiInputResponse<\"ui.select.one\", ElementDataType> {\n options: (\n | {\n label: string;\n value: ElementDataType;\n }\n | ElementDataType\n )[];\n}\n\nexport const selectOne: InputElementImplementation<\n ElementDataType,\n UiElementSelectOne,\n UiElementSelectOneApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.select.one\",\n name,\n label: options?.label || name,\n defaultValue: options?.defaultValue,\n optional: options?.optional,\n options: options?.options || [],\n } satisfies UiElementSelectOneApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n };\n};\n","import { FlowConfig, ExtractStageKeys } from \"..\";\nimport {\n BaseUiDisplayResponse,\n ImplementationResponse,\n InputElementResponse,\n UiElementApiResponses,\n UIElements,\n} from \".\";\n\ntype PageOptions<\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n> = {\n stage?: ExtractStageKeys<C>;\n title?: string;\n description?: string;\n content: T;\n validate?: (data: ExtractFormData<T>) => Promise<true | string>;\n actions?: A;\n};\nexport type UiPage<C extends FlowConfig> = <\n T extends UIElements,\n const A extends PageActions[] = [],\n>(\n name: string,\n options: PageOptions<C, A, T>\n) => A[\"length\"] extends 0\n ? ExtractFormData<T>\n : { data: ExtractFormData<T>; action: ActionValue<A[number]> };\n\ntype PageActions =\n | string\n | {\n label: string;\n value: string;\n mode?: \"primary\" | \"secondary\" | \"destructive\";\n };\n\nexport interface UiPageApiResponse extends BaseUiDisplayResponse<\"ui.page\"> {\n stage?: string;\n title?: string;\n description?: string;\n actions?: PageActions[];\n content: UiElementApiResponses;\n}\n\nexport const page = <\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n>(\n options: PageOptions<C, A, T>\n): UiPageApiResponse => {\n // Turn these back into the actual response types\n const content = options.content as unknown as ImplementationResponse<\n any,\n any\n >[];\n\n // TODO Validation\n // for (const c of content) {\n // if ('__type' in c && c.__type === \"input\") {\n // c.validate()\n // }\n // }\n\n const contentUiConfig = content\n .map((c) => c.uiConfig)\n .filter(Boolean) as UiElementApiResponses;\n\n return {\n __type: \"ui.page\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig,\n actions: options.actions,\n };\n};\n\n/* ********************\n * Helper functions\n ******************* */\n\n// Extract the key from a custom action, supporting either a string or an object with a value property\ntype ActionValue<T> = T extends string\n ? T\n : T extends { value: infer V }\n ? V\n : never;\n\n// Extract the data from elements and return a key-value object based on the name of the element\ntype ExtractFormData<T extends UIElements> = {\n [K in Extract<T[number], InputElementResponse<string, any>>[\"name\"]]: Extract<\n T[number],\n InputElementResponse<K, any>\n >[\"valueType\"];\n};\n","// This is a special type that is thrown to disrupt the execution of a flow\nabstract class FlowDisrupt {\n protected constructor() {}\n}\n\nexport class UIRenderDisrupt extends FlowDisrupt {\n constructor(\n public readonly stepId: string,\n public readonly contents: any\n ) {\n super();\n }\n}\n\nexport class StepErrorDisrupt extends FlowDisrupt {\n constructor(public readonly message: string) {\n super();\n }\n}\n\nexport class StepCreatedDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n\nexport class ExhuastedRetriesDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\ntype BannerMode = \"info\" | \"warning\" | \"error\" | \"success\";\n\nexport type UiElementBanner = DisplayElement<{\n title: string;\n description: string;\n mode?: BannerMode;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementBannerApiResponse\n extends BaseUiDisplayResponse<\"ui.display.banner\"> {\n title: string;\n description: string;\n mode: BannerMode;\n}\n\nexport const banner: DisplayElementImplementation<\n UiElementBanner,\n UiElementBannerApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.banner\",\n title: options?.title || \"\",\n description: options?.description || \"\",\n mode: options?.mode || \"info\",\n } satisfies UiElementBannerApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementImage = DisplayElement<{\n url: string;\n alt?: string;\n size?: \"thumbnail\" | \"small\" | \"medium\" | \"large\" | \"full\";\n title?: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementImageApiResponse\n extends BaseUiDisplayResponse<\"ui.display.image\"> {\n url: string;\n alt?: string;\n size?: \"thumbnail\" | \"small\" | \"medium\" | \"large\" | \"full\";\n title?: string;\n}\n\nexport const image: DisplayElementImplementation<\n UiElementImage,\n UiElementImageApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.image\",\n url: options?.url || \"\",\n alt: options?.alt,\n size: options?.size,\n title: options?.title,\n } satisfies UiElementImageApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementCode = DisplayElement<{\n code: string;\n language?: string; // TODO: type the supported languages\n}>;\n\n// The shape of the response over the API\nexport interface UiElementCodeApiResponse\n extends BaseUiDisplayResponse<\"ui.display.code\"> {\n code: string;\n language?: string;\n}\n\nexport const code: DisplayElementImplementation<\n UiElementCode,\n UiElementCodeApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.code\",\n code: options?.code || \"\",\n language: options?.language,\n } satisfies UiElementCodeApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype ImageConfig = {\n url: string;\n alt?: string;\n aspectRatio?: number;\n fit?: \"cover\" | \"contain\";\n};\n\ntype GridItem = {\n title?: string;\n description?: string;\n image?: ImageConfig;\n};\n\nexport type GridOptions<T> = {\n data: T[];\n render: (data: T) => GridItem;\n};\n\n// The types the user experiences\nexport type UiElementGrid = <T extends any>(\n options: GridOptions<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementGridApiResponse\n extends BaseUiDisplayResponse<\"ui.display.grid\"> {\n data: GridItem[];\n}\n\n// The implementation\nexport const grid: DisplayElementImplementation<\n UiElementGrid,\n UiElementGridApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.grid\",\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n title: rendered.title,\n description: rendered.description,\n image: rendered.image,\n } satisfies GridItem;\n }),\n } satisfies UiElementGridApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementResponse,\n} from \"../..\";\n\ntype ImageConfig = {\n url: string;\n alt?: string;\n fit?: \"cover\" | \"contain\";\n};\n\ntype ListItem = {\n title?: string;\n description?: string;\n image?: ImageConfig;\n};\n\ntype ListOptions<T> = {\n data: T[];\n render: (data: T) => ListItem;\n};\n\n// The types the user experiences\nexport type UiElementList = <T extends any>(\n options: ListOptions<T>\n) => DisplayElementResponse;\n\n// The shape of the response over the API\nexport interface UiElementListApiResponse\n extends BaseUiDisplayResponse<\"ui.display.list\"> {\n data: ListItem[];\n}\n\n// The implementation\nexport const list: DisplayElementImplementation<\n UiElementList,\n UiElementListApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.list\",\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n title: rendered.title,\n description: rendered.description,\n image: rendered.image,\n } satisfies ListItem;\n }),\n } satisfies UiElementListApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\nexport type UiElementHeader = DisplayElement<{\n level: 1 | 2 | 3;\n title?: string;\n description?: string;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementHeaderApiResponse\n extends BaseUiDisplayResponse<\"ui.display.header\"> {\n level: number;\n title: string;\n description: string;\n}\n\nexport const header: DisplayElementImplementation<\n UiElementHeader,\n UiElementHeaderApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.header\",\n level: options?.level || 1,\n title: options?.title || \"\",\n description: options?.description || \"\",\n } satisfies UiElementHeaderApiResponse,\n };\n};\n","import { UI } from \"./ui\";\nimport { useDatabase } from \"../database\";\nimport { textInput } from \"./ui/elements/input/text\";\nimport { numberInput } from \"./ui/elements/input/number\";\nimport { divider } from \"./ui/elements/display/divider\";\nimport { booleanInput } from \"./ui/elements/input/boolean\";\nimport { markdown } from \"./ui/elements/display/markdown\";\nimport { table } from \"./ui/elements/display/table\";\nimport { selectOne } from \"./ui/elements/select/one\";\nimport { page, UiPage } from \"./ui/page\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n} from \"./disrupts\";\nimport { banner } from \"./ui/elements/display/banner\";\nimport { image } from \"./ui/elements/display/image\";\nimport { code } from \"./ui/elements/display/code\";\nimport { grid } from \"./ui/elements/display/grid\";\nimport { list } from \"./ui/elements/display/list\";\nimport { header } from \"./ui/elements/display/header\";\n\nconst enum STEP_STATUS {\n NEW = \"NEW\",\n RUNNING = \"RUNNING\",\n PENDING = \"PENDING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n}\n\nconst enum STEP_TYPE {\n FUNCTION = \"FUNCTION\",\n UI = \"UI\",\n DELAY = \"DELAY\",\n}\n\nconst defaultOpts = {\n maxRetries: 5,\n timeoutInMs: 60000,\n};\n\nexport interface FlowContext<C extends FlowConfig> {\n step: Step<C>;\n ui: UI<C>;\n}\n\n// Steps can only return values that can be serialized to JSON and then\n// deserialized back to the same object/value that represents the type.\n// i.e. the string, number and boolean primitives, and arrays of them and objects made up of them.\ntype JsonSerializable =\n | string\n | number\n | boolean\n | null\n | JsonSerializable[]\n | { [key: string]: JsonSerializable };\n\nexport type Step<C extends FlowConfig> = {\n <R extends JsonSerializable | void>(\n name: string,\n options: {\n stage?: ExtractStageKeys<C>;\n maxRetries?: number;\n timeoutInMs?: number;\n },\n fn: () => Promise<R> & {\n catch: (\n errorHandler: (err: Error) => Promise<void> | void\n ) => Promise<any>;\n }\n ): Promise<R>;\n <R extends JsonSerializable | void>(\n name: string,\n fn: () => Promise<R> & {\n catch: (\n errorHandler: (err: Error) => Promise<void> | void\n ) => Promise<any>;\n }\n ): Promise<R>;\n};\n\ntype StepFunction<R> = () => Promise<R> & {\n catch: (errorHandler: (err: Error) => Promise<void> | void) => Promise<any>;\n};\n\nexport interface FlowConfig {\n stages?: StageConfig[];\n title?: string;\n description?: string;\n}\n\n// What is returned as the config to the API\nexport interface FlowConfigAPI {\n stages?: StageConfigObject[];\n title: string;\n description?: string;\n}\n\nexport type FlowFunction<C extends FlowConfig, I extends any = {}> = (\n ctx: FlowContext<C>,\n inputs: I\n) => Promise<void>;\n\n// Extract the stage keys from the flow config supporting either a string or an object with a key property\nexport type ExtractStageKeys<T extends FlowConfig> = T extends {\n stages: infer S;\n}\n ? S extends ReadonlyArray<infer U>\n ? U extends string\n ? U\n : U extends { key: infer K extends string }\n ? K\n : never\n : never\n : never;\n\ntype StageConfigObject = {\n key: string;\n name: string;\n description?: string;\n initiallyHidden?: boolean;\n};\n\ntype StageConfig = string | StageConfigObject;\n\nexport function createFlowContext<C extends FlowConfig>(\n runId: string,\n data: any,\n spanId: string\n): FlowContext<C> {\n return {\n step: async (name, optionsOrFn, fn?) => {\n // We need to check the type of the arguments due to the step function being overloaded\n const options = typeof optionsOrFn === \"function\" ? {} : optionsOrFn;\n const actualFn = (\n typeof optionsOrFn === \"function\" ? optionsOrFn : fn!\n ) as StepFunction<any>;\n\n const db = useDatabase();\n\n // First check if we already have a result for this step\n const past = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"name\", \"=\", name)\n .selectAll()\n .execute();\n\n const newSteps = past.filter((step) => step.status === STEP_STATUS.NEW);\n const completedSteps = past.filter(\n (step) => step.status === STEP_STATUS.COMPLETED\n );\n const failedSteps = past.filter(\n (step) => step.status === STEP_STATUS.FAILED\n );\n\n if (newSteps.length > 1) {\n throw new Error(\"Multiple NEW steps found for the same step\");\n }\n\n if (completedSteps.length > 1) {\n throw new Error(\"Multiple completed steps found for the same step\");\n }\n\n if (completedSteps.length > 1 && newSteps.length > 1) {\n throw new Error(\n \"Multiple completed and new steps found for the same step\"\n );\n }\n\n if (completedSteps.length === 1) {\n return completedSteps[0].value;\n }\n\n // Do we have a NEW step waiting to be run?\n if (newSteps.length === 1) {\n let result = null;\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n startTime: new Date(),\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n try {\n result = await withTimeout(\n actualFn(),\n options.timeoutInMs ?? defaultOpts.timeoutInMs\n );\n } catch (e) {\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.FAILED,\n spanId: spanId,\n endTime: new Date(),\n error: e instanceof Error ? e.message : \"An error occurred\",\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n if (\n failedSteps.length + 1 >=\n (options.maxRetries ?? defaultOpts.maxRetries)\n ) {\n throw new ExhuastedRetriesDisrupt();\n }\n\n // If we have retries left, create a new step\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.NEW,\n type: STEP_TYPE.FUNCTION,\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new StepCreatedDisrupt();\n }\n\n // Store the result in the database\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.COMPLETED,\n value: JSON.stringify(result),\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", newSteps[0].id)\n .returningAll()\n .executeTakeFirst();\n\n return result;\n }\n\n // The step hasn't yet run successfully, so we need to create a NEW run\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.NEW,\n type: STEP_TYPE.FUNCTION,\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new StepCreatedDisrupt();\n\n // TODO: Incorporate when we have support error handling\n // const stepPromise = fn({} as any);\n // const stepWithCatch = Object.assign(stepPromise, {\n // catch: async (errorHandler: (err: Error) => Promise<void> | void) => {\n // try {\n // return await stepPromise;\n // } catch (err) {\n // await errorHandler(err as Error);\n // throw err;\n // }\n // },\n // });\n // return stepWithCatch;\n },\n ui: {\n page: (async (name, options) => {\n const db = useDatabase();\n\n // First check if this step exists\n let step = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"name\", \"=\", name)\n .selectAll()\n .executeTakeFirst();\n\n // If this step has already been completed, return the values. Steps are only ever run to completion once.\n if (step && step.status === STEP_STATUS.COMPLETED) {\n return step.value;\n }\n\n if (!step) {\n // The step hasn't yet run so we create a new the step with state PENDING.\n step = await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: name,\n stage: options.stage,\n status: STEP_STATUS.PENDING,\n type: STEP_TYPE.UI,\n startTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n // If no data has been passed in, render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(step?.id, page(options));\n }\n\n if (!data) {\n // If no data has been passed in, render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(step?.id, page(options));\n }\n\n // TODO: Validate the data! If not valid, throw a UIRenderDisrupt along with the validation errors.\n\n // If the data has been passed in and is valid, persist the data and mark the step as COMPLETED, and then return the data.\n await db\n .updateTable(\"keel.flow_step\")\n .set({\n status: STEP_STATUS.COMPLETED,\n value: JSON.stringify(data),\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", step.id)\n .returningAll()\n .executeTakeFirst();\n\n return data;\n }) as UiPage<C>,\n inputs: {\n text: textInput as any,\n number: numberInput as any,\n boolean: booleanInput as any,\n },\n display: {\n divider: divider as any,\n markdown: markdown as any,\n table: table as any,\n header: header as any,\n banner: banner as any,\n image: image as any,\n code: code as any,\n grid: grid as any,\n list: list as any,\n },\n select: {\n one: selectOne as any,\n },\n },\n };\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nfunction withTimeout<T>(promiseFn: Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n promiseFn,\n wait(timeout).then(() => {\n throw new Error(`Step function timed out after ${timeout}ms`);\n }),\n ]);\n}\n\nexport { UI };\n"],"mappings":"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","names":["KSUID","import_kysely","import_kysely","import_node_async_hooks","TraceParent","import_kysely","parseInterval","sql","pgTypes","WebSocket","code","table","KSUID","import_kysely","sql","context","context","context","table","context","context","builder","row","created","import_json_rpc_2","opentelemetry","result","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_json_rpc_2","opentelemetry","import_change_case","import_ksuid","KSUID"]}
|