@teamkeel/functions-runtime 0.426.0 → 0.427.0

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.
@@ -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/parsing.js","../src/applyWhereConditions.js","../src/casing.js","../src/TimePeriod.js","../src/applyAdditionalQueryConstraints.js","../src/applyJoins.js","../src/QueryContext.js","../src/errors.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/ui/elements/display/keyValue.ts","../src/flows/ui/elements/select/table.ts","../src/flows/ui/elements/input/dataGrid.ts","../src/flows/ui/elements/input/datePicker.ts","../src/flows/ui/elements/input/file.ts","../src/flows/ui/elements/iterator.ts","../src/flows/ui/elements/interactive/print.ts","../src/flows/ui/elements/interactive/pickList.ts","../src/flows/errors.ts","../src/flows/ui/elements/input/scan.ts","../src/flows/ui/elements/display/file.ts","../src/flows/index.ts","../src/flows/ui/complete.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, KEEL_INTERNAL_ATTR } 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 span.setAttribute(KEEL_INTERNAL_ATTR, true);\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 span.setAttribute(KEEL_INTERNAL_ATTR, true);\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 if (err instanceof Error) {\n // record any errors\n span.recordException(err);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: err.message,\n });\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\n// This attribute marks just this current span as internal; if the value\nconst KEEL_INTERNAL_ATTR = \"keel_internal\";\n\n// This value, when set on an KEEL_INTERNAL_ATTR marks that all children spans are also internal\nconst KEEL_INTERNAL_CHILDREN = \"includeChildrenSpans\";\n\nexport {\n getTracer,\n withSpan,\n init,\n forceFlush,\n spanNameForModelAPI,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n};\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.KEEL_S3_ENDPOINT;\n if (endpoint) {\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: {\n accessKeyId: \"keelstorage\",\n secretAccessKey: \"keelstorage\",\n },\n endpoint: endpoint,\n });\n }\n\n const testEndpoint = process.env.TEST_AWS_ENDPOINT;\n if (testEndpoint) {\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(testEndpoint),\n };\n },\n });\n }\n\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: fromEnv(),\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 mimeType = info.split(\";\")[0];\n const name = info.split(\";\")[1].split(\"=\")[1] || \"file\";\n const buffer = Buffer.from(data, \"base64\");\n const file = new InlineFile({ filename: name, contentType: mimeType });\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 throw new Error(\"S3 client is required\");\n }\n\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 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 throw new Error(\"S3 client is required\");\n }\n\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 }\n\n // Generates a presigned upload URL. If the file doesn't have a key, a new one will be generated\n async getPresignedUploadUrl(): Promise<URL> {\n if (!s3Client) {\n throw new Error(\"S3 client is required\");\n }\n\n if (!this.key) {\n this._key = KSUID.randomSync().string;\n }\n\n const command = new PutObjectCommand({\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n });\n\n const url = await getSignedUrl(s3Client, command, { expiresIn: 60 * 60 });\n\n return new URL(url);\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 throw new Error(\"S3 client is required\");\n }\n\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}\n\nexport type FileWriteTypes = InlineFile | File;\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 { 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 { 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 (!functions[request.method]) {\n const message = `function '${request.method}' does not exist or has not been implemented`;\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 const store = permissionsApiInstance.getStore();\n if (store) {\n store.permitted = true;\n }\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 const store = permissionsApiInstance.getStore();\n if (store) {\n store.permitted = false;\n }\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 (!jobs[request.method]) {\n const message = `job '${request.method}' does not exist or has not been implemented`;\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 (!subscribers[request.method]) {\n const message = `subscriber '${request.method}' does not exist or has not been implemented`;\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 (!functions[request.method]) {\n const message = `route function '${request.method}' does not exist or has not been implemented`;\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 {\n withSpan,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n} from \"./tracing\";\nimport { tryExecuteFlow } from \"./tryExecuteFlow\";\nimport { parseInputs } from \"./parsing\";\nimport { createFlowContext, FlowConfig, STEP_STATUS, STEP_TYPE } from \"./flows\";\nimport {\n CompleteOptions,\n UiCompleteApiResponse,\n complete,\n} from \"./flows/ui/complete\";\n\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n CallbackDisrupt,\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: opentelemetry.Span) => {\n span.setAttribute(KEEL_INTERNAL_ATTR, true);\n\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, createFlowContextAPI } = config;\n\n if (!flows[request.method]) {\n const message = `flow '${request.method}' does not exist or has not been implemented`;\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 ctx = createFlowContext(\n request.meta.runId,\n request.meta.data,\n request.meta.action,\n request.meta.callback,\n request.meta.element,\n span.spanContext().spanId,\n createFlowContextAPI({\n meta: request.meta,\n })\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(request.meta?.inputs);\n\n let response: CompleteOptions<FlowConfig, unknown> | any | void =\n undefined;\n\n try {\n response = await tryExecuteFlow(db, request, 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 // the step was just created, so this span should be internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: false,\n config: flowConfig,\n executeAfter: e.executeAfter,\n });\n }\n\n // The flow is disrupted as it has just executed a UI callback.\n if (e instanceof CallbackDisrupt) {\n if (e.error) {\n return createJSONRPCErrorResponse(request.id, 500, e.response);\n }\n return createJSONRPCSuccessResponse(request.id, e.response);\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 if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e instanceof Error ? e.message : \"unknown error\",\n });\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 let ui: UiCompleteApiResponse | null = null;\n let data: any = null;\n\n // TODO: this is not a thorough enough check for the response type\n if (\n response &&\n typeof response == \"object\" &&\n \"__type\" in response &&\n response.__type === \"ui.complete\"\n ) {\n ui = await complete(response);\n\n const completeStep = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"type\", \"=\", STEP_TYPE.COMPLETE)\n .selectAll()\n .executeTakeFirst();\n\n if (!completeStep) {\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: \"\",\n stage: response.stage,\n status: STEP_STATUS.COMPLETED,\n type: STEP_TYPE.COMPLETE,\n startTime: new Date(),\n endTime: new Date(),\n ui: JSON.stringify(ui),\n })\n .returningAll()\n .executeTakeFirst();\n }\n\n data = response.data;\n } else if (response) {\n data = response;\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 data: data,\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\";\nimport { withAuditContext } from \"./auditing\";\n\nfunction tryExecuteFlow(db, request, cb) {\n return withDatabase(db, false, async () => {\n return withAuditContext(request, async () => {\n return cb();\n });\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n placeholder: options?.placeholder,\n multiline: options?.multiline,\n maxLength: options?.maxLength,\n minLength: options?.minLength,\n } satisfies UiElementInputTextApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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?: string;\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?: string;\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n placeholder: options?.placeholder,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputNumberApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n mode: options?.mode || \"checkbox\",\n } satisfies UiElementInputBooleanApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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\nexport type 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\nexport type TableColumn = {\n name: string;\n index: number;\n};\n\n// The shape of the response over the API\nexport interface UiElementTableApiResponse\n extends BaseUiDisplayResponse<\"ui.display.table\"> {\n data: any[];\n columns: TableColumn[];\n}\n\nexport const table: DisplayElementImplementation<\n UiElementTable,\n UiElementTableApiResponse\n> = (options) => {\n const { data, columns } = processTableData(options.data, options.columns);\n\n return {\n uiConfig: {\n __type: \"ui.display.table\",\n data: data || [],\n columns: columns || [],\n } satisfies UiElementTableApiResponse,\n };\n};\n\n// Only send data for columns we need\nexport const processTableData = (data: any[], columnsConfig?: string[]) => {\n const filteredData = columnsConfig\n ? data.map((item) => {\n return Object.fromEntries(\n Object.entries(item).filter(\n ([key]) => columnsConfig?.includes(key as any)\n )\n );\n })\n : data;\n\n const cols = Object.keys(filteredData[0] || {});\n const columns: TableColumn[] = cols.map((column, index) => ({\n name: column,\n index,\n }));\n\n return { data: filteredData, columns };\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 O extends boolean = false,\n>(\n name: N,\n options?: BaseInputConfig<TValue, O> & {\n options: (\n | {\n label: string;\n value: TValue;\n }\n | TValue\n )[];\n }\n) => InputElementResponse<N, O extends true ? TValue | undefined : 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 || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\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 InputElementImplementationResponse,\n InputElementResponse,\n IteratorElementImplementationResponse,\n UiElementApiResponse,\n UiElementApiResponses,\n UIElements,\n ValidateFn,\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?: ValidateFn<ExtractFormData<T>>;\n actions?: A;\n // When true, let the use go back a step if there is a previous step\n allowBack?: boolean;\n fullWidth?: boolean;\n};\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) => Promise<\n A[\"length\"] extends 0\n ? ExtractFormData<T>\n : { data: ExtractFormData<T>; action: ActionValue<A[number]> }\n>;\n\ntype PageActions = string | PageActionConfig;\ntype PageActionConfig = {\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?: PageActionConfig[];\n content: UiElementApiResponses;\n hasValidationErrors: boolean;\n validationError?: string;\n allowBack?: boolean;\n fullWidth?: boolean;\n}\n\nexport async function callbackFn<T extends UIElements>(\n elements: T,\n elementName: string,\n callbackName: string,\n data: any\n): Promise<any> {\n // Find the element by name\n const element = elements.find(\n (el) => (el as any).uiConfig && (el as any).uiConfig.name === elementName\n );\n\n if (!element) {\n throw new Error(`Element with name ${elementName} not found`);\n }\n\n // Check if the callback exists on the element\n const cb = (element as any)[callbackName];\n if (typeof cb !== \"function\") {\n throw new Error(\n `Callback ${callbackName} not found on element ${elementName}`\n );\n }\n\n // Call the callback with provided arguments\n return await cb(data);\n}\n\nexport async function page<\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n>(\n options: PageOptions<C, A, T>,\n data: any,\n action: string | null\n): Promise<{ page: UiPageApiResponse; hasValidationErrors: boolean }> {\n // Turn these back into the actual response types\n const content = options.content as unknown as ImplementationResponse<\n any,\n any\n >[];\n let hasValidationErrors = false;\n let validationError: string | undefined;\n\n // Validate actions - all action validation errors are thrown as bad requests\n if (options.actions && options.actions.length > 0) {\n // Actions are defined on the page\n // Normalize action - convert \"undefined\" string or undefined value to null\n const normalizedAction =\n action === \"undefined\" || action === undefined ? null : action;\n\n // Only validate action when data is being submitted (data is not null)\n if (data !== null) {\n if (normalizedAction === null) {\n // No action provided when actions are required during submission\n const validValues = options.actions\n .map((a) => {\n if (typeof a === \"string\") return a;\n return a && typeof a === \"object\" && \"value\" in a ? a.value : \"\";\n })\n .filter(Boolean);\n throw new Error(\n `action is required. Valid actions are: ${validValues.join(\", \")}`\n );\n }\n\n // Action provided, check if it's valid\n const isValidAction = options.actions.some((a) => {\n if (typeof a === \"string\") return a === normalizedAction;\n return (\n a &&\n typeof a === \"object\" &&\n \"value\" in a &&\n a.value === normalizedAction\n );\n });\n\n if (!isValidAction) {\n // Build list of valid action values\n const validValues = options.actions\n .map((a) => {\n if (typeof a === \"string\") return a;\n return a && typeof a === \"object\" && \"value\" in a ? a.value : \"\";\n })\n .filter(Boolean);\n\n throw new Error(\n `invalid action \"${normalizedAction}\". Valid actions are: ${validValues.join(\n \", \"\n )}`\n );\n }\n }\n } else if (\n action !== null &&\n action !== undefined &&\n action !== \"undefined\"\n ) {\n // No actions defined but a real action value was provided - this is a bad request\n throw new Error(\n `invalid action \"${action}\". No actions are defined for this page`\n );\n }\n\n const contentUiConfig = await Promise.all(\n content.map(async (c) => {\n const resolvedC = await c;\n\n const elementData =\n data && typeof data === \"object\" && resolvedC.uiConfig.name in data\n ? data[resolvedC.uiConfig.name]\n : undefined;\n\n const { uiConfig, validationErrors } = await recursivelyProcessElement(\n c,\n elementData,\n options.actions && options.actions.length > 0 ? action : null\n );\n\n if (validationErrors) hasValidationErrors = true;\n\n return uiConfig;\n })\n );\n\n // If there is page level validation, validate the data\n if (data && options.validate) {\n const validationResult =\n options.actions && action !== null\n ? await (options.validate as any)(data, action)\n : await (options.validate as any)(data);\n if (typeof validationResult === \"string\") {\n hasValidationErrors = true;\n validationError = validationResult;\n }\n }\n\n return {\n page: {\n __type: \"ui.page\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig,\n actions: options.actions?.map((a) => {\n if (typeof a === \"string\") {\n return { label: a, value: a, mode: \"primary\" };\n } else if (typeof a === \"object\") {\n a.mode = a.mode || \"primary\";\n }\n return a;\n }),\n hasValidationErrors,\n validationError,\n allowBack: options.allowBack,\n fullWidth: options.fullWidth,\n },\n hasValidationErrors,\n };\n}\n\nconst recursivelyProcessElement = async (\n c: ImplementationResponse<any, any>,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const resolvedC = await c;\n const elementType = \"__type\" in resolvedC ? resolvedC.__type : null;\n\n switch (elementType) {\n case \"input\":\n return processInputElement(\n resolvedC as InputElementImplementationResponse<any, any>,\n data,\n action\n );\n case \"iterator\":\n return processIteratorElement(\n resolvedC as IteratorElementImplementationResponse<any, any>,\n data,\n action\n );\n default:\n return {\n uiConfig: { ...resolvedC.uiConfig },\n validationErrors: false,\n };\n }\n};\n\nconst processInputElement = async (\n element: InputElementImplementationResponse<any, any>,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const hasData = data !== undefined && data !== null;\n\n if (!hasData || !element.validate) {\n return {\n uiConfig: { ...element.uiConfig },\n validationErrors: false,\n };\n }\n\n const validationError =\n action !== null\n ? await (element.validate as any)(data, action)\n : await (element.validate as any)(data);\n const hasValidationErrors = typeof validationError === \"string\";\n\n return {\n uiConfig: {\n ...element.uiConfig,\n validationError: hasValidationErrors ? validationError : undefined,\n },\n validationErrors: hasValidationErrors,\n };\n};\n\nconst processIteratorElement = async (\n element: any,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const elements = element.uiConfig.content as ImplementationResponse<\n any,\n any\n >[];\n const dataArr = data as any[] | undefined;\n\n // Process the UI config content\n const ui: UiElementApiResponse[] = [];\n for (const el of elements) {\n const result = await recursivelyProcessElement(el, undefined, action);\n ui.push(result.uiConfig);\n }\n\n // Check for validation errors if we have data\n const validationErrors = await validateIteratorData(\n elements,\n dataArr,\n action\n );\n let hasValidationErrors = validationErrors.length > 0;\n\n let validationError: string | undefined = undefined;\n if (dataArr && element.validate) {\n const v =\n action !== null\n ? await (element.validate as any)(dataArr, action)\n : await (element.validate as any)(dataArr);\n if (typeof v === \"string\") {\n hasValidationErrors = true;\n validationError = v;\n }\n }\n\n return {\n uiConfig: {\n ...element.uiConfig,\n content: ui,\n validationError: validationError,\n contentValidationErrors: hasValidationErrors\n ? validationErrors\n : undefined,\n },\n validationErrors: hasValidationErrors,\n };\n};\n\nconst validateIteratorData = async (\n elements: ImplementationResponse<any, any>[],\n dataArr: any[] | undefined,\n action: string | null\n): Promise<Array<{ index: number; name: string; validationError: string }>> => {\n const validationErrors: Array<{\n index: number;\n name: string;\n validationError: string;\n }> = [];\n\n if (!dataArr || dataArr.length === 0) {\n return validationErrors;\n }\n\n for (let i = 0; i < dataArr.length; i++) {\n const rowData = dataArr[i];\n\n for (const el of elements) {\n const resolvedEl = await el;\n\n if (\n \"__type\" in resolvedEl &&\n resolvedEl.__type === \"input\" &&\n \"validate\" in resolvedEl &&\n resolvedEl.validate &&\n typeof resolvedEl.validate === \"function\"\n ) {\n const fieldName = resolvedEl.uiConfig.name;\n\n if (rowData && typeof rowData === \"object\" && fieldName in rowData) {\n const validationError =\n action !== null\n ? await (resolvedEl as any).validate(rowData[fieldName], action)\n : await (resolvedEl as any).validate(rowData[fieldName]);\n\n if (typeof validationError === \"string\") {\n validationErrors.push({\n index: i,\n name: fieldName,\n validationError: validationError,\n });\n }\n }\n }\n }\n }\n\n return validationErrors;\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\nexport type ExtractFormData<T extends UIElements> = {\n [K in Extract<T[number], InputElementResponse<string, any>>[\"name\"]]: Extract<\n T[number],\n InputElementResponse<K, any>\n >[\"returnType\"];\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(public readonly executeAfter?: Date) {\n super();\n }\n}\n\nexport class ExhuastedRetriesDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n\nexport class CallbackDisrupt extends FlowDisrupt {\n constructor(\n public readonly response: any,\n public readonly error: boolean\n ) {\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 caption?: 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 caption?: 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 caption: options?.caption,\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 \"../..\";\nimport { ImageConfig } from \"../common\";\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 /**\n * The visual level of the header.\n *\n * @default 2\n */\n level?: 1 | 2 | 3;\n /**\n * The title of the header.\n */\n title?: string;\n /**\n * The description of the header.\n */\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 || 2,\n title: options?.title || \"\",\n description: options?.description || \"\",\n } satisfies UiElementHeaderApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\ntype KeyValueMode = \"list\" | \"grid\" | \"card\";\n\ntype KeyValueData = {\n key: string;\n value: string | number | Date | boolean; // TODO: support for an object with richer type info / linking\n};\n\n// The types the user experiences\nexport type UiElementKeyValue = DisplayElement<{\n data: KeyValueData[];\n mode?: KeyValueMode;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementKeyValueApiResponse\n extends BaseUiDisplayResponse<\"ui.display.keyValue\"> {\n data: KeyValueData[];\n mode: KeyValueMode;\n}\n\n// The implementation\nexport const keyValue: DisplayElementImplementation<\n UiElementKeyValue,\n UiElementKeyValueApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.keyValue\",\n data: options?.data || [],\n mode: options?.mode || \"list\",\n } satisfies UiElementKeyValueApiResponse,\n };\n};\n","import {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\nimport { processTableData, TableColumn, TableData } from \"../display/table\";\n\nexport type SelectMode = \"single\" | \"multi\";\n\n// 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 UiElementSelectTable = <\n const T extends Record<string, any>,\n N extends string,\n const M extends SelectMode = \"multi\",\n const O extends boolean = false,\n>(\n name: N,\n options: TableOptions<T, O, M>\n) => InputElementResponse<\n N,\n M extends \"single\" ? (O extends true ? T | undefined : T) : T[]\n>;\n\nexport type TableOptions<\n T extends Record<string, any>,\n O extends boolean,\n M extends SelectMode,\n> = Omit<\n BaseInputConfig<\n M extends \"single\" ? (O extends true ? T | undefined : T) : T[],\n O\n >,\n \"defaultValue\" | \"label\"\n> &\n TableData<T> &\n (\n | {\n mode?: M;\n }\n | {\n mode: \"multi\";\n max?: number;\n min?: number;\n }\n );\n\n// The shape of the response over the API\nexport interface UiElementSelectTableApiResponse\n extends Omit<\n BaseUiInputResponse<\"ui.select.table\", any>,\n \"defaultValue\" | \"label\"\n > {\n data: Record<string, any>[];\n columns: TableColumn[];\n mode: SelectMode;\n}\n\nexport const selectTable: InputElementImplementation<\n any,\n UiElementSelectTable,\n UiElementSelectTableApiResponse\n> = (name, options) => {\n const { data, columns } = processTableData(options.data, options.columns);\n\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.select.table\",\n name,\n data,\n columns,\n mode: options?.mode || \"multi\",\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n } satisfies UiElementSelectTableApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import { sentenceCase } from \"change-case\";\nimport {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\nimport { processTableData } from \"../display/table\";\n\n// 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 UiElementInputDataGrid = <\n N extends string,\n T extends Record<string, any>,\n const Cols extends Extract<keyof T, string>[],\n C extends ColumnConfig<Cols>[] | undefined = undefined,\n>(\n name: N,\n options: DataGridOptions<T, C>\n) => InputElementResponse<\n N,\n C extends ColumnConfig<Cols>[]\n ? {\n // If the column has a type then we need to cast the value to the type of the column\n // Otherwise we just use the type of the value\n [K in C[number] as K[\"key\"]]: MapDataType<K[\"type\"], T[K[\"key\"]]>;\n }[]\n : T[]\n>;\n\ntype MapDataType<U, Fallback> = U extends \"text\"\n ? string\n : U extends \"number\"\n ? number\n : U extends \"boolean\"\n ? boolean\n : U extends \"id\"\n ? string\n : U extends \"hidden\"\n ? Fallback\n : Fallback;\n\ntype ColumnConfig<Cols extends string[]> = {\n key: Cols[number];\n label?: string;\n type?: DataGridDataTypes;\n editable?: boolean;\n};\n\nexport type DataGridOptions<T extends Record<string, any>, C> = Omit<\n BaseInputConfig<T[]>,\n \"defaultValue\" | \"label\" | \"optional\" | \"disabled\"\n> & {\n data: T[];\n columns?: C;\n allowAddRows?: boolean;\n allowDeleteRows?: boolean;\n};\n\n// The shape of the response over the API\nexport interface UiElementInputDataGridApiResponse\n extends Omit<\n BaseUiInputResponse<\"ui.input.dataGrid\", any>,\n \"defaultValue\" | \"label\" | \"optional\" | \"disabled\"\n > {\n data: any[];\n columns: DataGridColumn[];\n allowAddRows: boolean;\n allowDeleteRows: boolean;\n}\n\ntype DataGridDataTypes = \"text\" | \"number\" | \"boolean\" | \"id\" | \"hidden\";\n\nexport type DataGridColumn = {\n key: string;\n label: string;\n index: number;\n type: DataGridDataTypes;\n editable: boolean;\n};\n\nexport const dataGridInput: InputElementImplementation<\n any,\n UiElementInputDataGrid,\n UiElementInputDataGridApiResponse\n> = (name, options) => {\n const { data } = processTableData(\n options.data,\n options.columns?.map((c) => c.key)\n );\n\n const inferType = (key: string) => {\n const inferredTypeRaw = typeof data[0][key];\n const inferredTypeMap: Record<typeof inferredTypeRaw, DataGridDataTypes> = {\n string: \"text\",\n number: \"number\",\n boolean: \"boolean\",\n bigint: \"number\",\n symbol: \"text\",\n undefined: \"text\",\n object: \"text\",\n function: \"text\",\n };\n return inferredTypeMap[inferredTypeRaw] ?? \"text\";\n };\n\n const columns = options.columns\n ? options.columns?.map((column, idx) => ({\n key: column.key,\n label: column.label || column.key,\n index: idx,\n type: column.type || inferType(column.key),\n editable:\n column.editable === undefined\n ? column.type === \"id\"\n ? false\n : true\n : column.editable,\n }))\n : Object.keys(data[0]).map((key, idx) => {\n return {\n index: idx,\n key,\n label: sentenceCase(key),\n type: inferType(key),\n editable: true,\n };\n });\n\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.dataGrid\",\n name,\n data,\n columns,\n helpText: options?.helpText,\n allowAddRows: options?.allowAddRows ?? false,\n allowDeleteRows: options?.allowDeleteRows ?? false,\n } satisfies UiElementInputDataGridApiResponse,\n validate: options?.validate, // TODO have some built in validation that checks the types of the response\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = string;\n\n/**\n * Defines what type of datepicker should we use.\n * @default \"dateTime\"\n */\ntype DatePickerMode =\n /** Pick both a date and a time */\n | \"dateTime\"\n /** Pick only a date */\n | \"date\";\n\nexport type UiElementInputDatePicker = InputElement<\n ElementDataType,\n {\n mode?: DatePickerMode;\n /** Allows selecting only dates/datetimes past this given date. */\n min?: string;\n /** Allows selecting only dates/datetimes before this given date. */\n max?: string;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputDatePickerApiResponse\n extends BaseUiInputResponse<\"ui.input.datePicker\", ElementDataType> {\n mode?: DatePickerMode;\n min?: string;\n max?: string;\n}\n\nexport const datePickerInput: InputElementImplementation<\n ElementDataType,\n UiElementInputDatePicker,\n UiElementInputDatePickerApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.datePicker\",\n name,\n label: options?.label || name,\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n mode: options?.mode,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputDatePickerApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\n getData: (x: ElementDataType) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n CallbackFn,\n} from \"../..\";\n\nimport { File, FileDbRecord } from \"../../../../File\";\n\ntype ElementDataType = Partial<FileDbRecord>;\n\nexport type UiElementInputFile = InputElement<ElementDataType, {}, File>;\n\n/**\n * key: string;\n * filename: string;\n * contentType: string;\n */\ntype PresignedUrlCallbackInput = Partial<FileDbRecord>;\ntype PresignedUrlCallbackResponse = {\n key: string;\n url: string;\n};\n\n// The shape of the response over the API\nexport interface UiElementInputFileApiResponse\n extends BaseUiInputResponse<\"ui.input.file\", ElementDataType> {}\n\nexport const fileInput: InputElementImplementation<\n ElementDataType,\n UiElementInputFile,\n UiElementInputFileApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.file\",\n name,\n label: options?.label || name,\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n } satisfies UiElementInputFileApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n getPresignedUploadURL: (async (input: PresignedUrlCallbackInput) => {\n const file = new File(input);\n const url = await file.getPresignedUploadUrl();\n return {\n url: url.toString(),\n key: file.key,\n };\n }) as CallbackFn<PresignedUrlCallbackInput, PresignedUrlCallbackResponse>,\n };\n};\n","import {\n BaseUiDisplayResponse,\n ImplementationResponse,\n IteratorElementImplementation,\n IteratorElementResponse,\n UiElementApiResponses,\n UIElements,\n ValidateFn,\n} from \"..\";\nimport { ExtractFormData } from \"../page\";\n\nexport type UiElementIterator = <N extends string, T extends UIElements>(\n name: N,\n options: {\n content: T;\n validate?: ValidateFn<ExtractFormData<T>[]>;\n max?: number;\n min?: number;\n }\n) => IteratorElementResponse<N, T>;\n\n// The shape of the response over the API\nexport interface UiElementIteratorApiResponse\n extends BaseUiDisplayResponse<\"ui.iterator\"> {\n name: string;\n content: UiElementApiResponses;\n max?: number;\n min?: number;\n validationError?: string;\n contentValidationErrors?: Array<{\n index: number;\n name: string;\n validationError: string;\n }>;\n}\n\nexport const iterator: IteratorElementImplementation<\n any,\n UiElementIterator,\n UiElementIteratorApiResponse\n> = (name, options) => {\n return {\n __type: \"iterator\",\n uiConfig: {\n __type: \"ui.iterator\",\n name,\n content: options.content as unknown as UiElementApiResponses,\n max: options.max,\n min: options.min,\n } satisfies UiElementIteratorApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementWithRequiredConfig,\n} from \"../..\";\nimport { Hardware, NullableHardware } from \"../../../index\";\n\nexport type UiElementPrint<H extends NullableHardware> =\n DisplayElementWithRequiredConfig<{\n jobs: PrintData<H>[] | PrintData<H>;\n title?: string;\n description?: string;\n /** If true, the jobs will be automatically printed. */\n autoPrint?: boolean;\n /** If true, the step will continue after the jobs are complete (pending validation). */\n autoContinue?: boolean;\n }>;\n\ntype PrintData<H extends NullableHardware> = {\n /** The name of the print job. */\n name?: string;\n /** The printer to use for the print job. Printers are defined in keelconfig.yaml. */\n printer?: H extends Hardware ? H[\"printers\"][number][\"name\"] : never;\n} & (PrintDataZpl | PrintDataRawPdf);\n\ntype PrintDataZpl = {\n type: \"zpl\";\n} & (\n | {\n data: string | string[];\n url?: never;\n }\n | {\n data?: never;\n url: string;\n }\n);\n\ntype PrintDataRawPdf = {\n type: \"rawPdf\";\n url: string;\n data?: never;\n /** The DPI of the PDF\n * @default 300\n */\n dpi?: number;\n /** The width of the page in dots.\n * e.g. 4\" at 300 dpi is 1200 dots.\n * @default 1200\n */\n pageWidth?: number;\n /** The height of the page in dots.\n * e.g. 6\" at 300 dpi is 1800 dots.\n * @default 1800\n */\n pageHeight?: number;\n};\n\n// The shape of the response over the API\nexport interface UiElementPrintApiResponse<>extends BaseUiDisplayResponse<\"ui.interactive.print\"> {\n title?: string;\n description?: string;\n data: {\n type: \"zpl\" | \"rawPdf\";\n name?: string;\n data?: string[];\n url?: string;\n printer?: string;\n dpi?: number;\n pageWidth?: number;\n pageHeight?: number;\n }[];\n autoPrint: boolean;\n autoContinue: boolean;\n}\n\nexport const print: DisplayElementImplementation<\n UiElementPrint<NullableHardware>,\n UiElementPrintApiResponse\n> = async (options) => {\n const dataConfig = Array.isArray(options.jobs)\n ? options.jobs\n : [options.jobs];\n\n const dataPromises = dataConfig.map(async (d) => {\n // if (\"file\" in d && d.file) {\n // return {\n // type: \"url\" as const,\n // url: (await d.file.getPresignedUrl()).toString(),\n // };\n // }\n\n return {\n type: d.type,\n name: d.name,\n data:\n \"data\" in d && d.data\n ? Array.isArray(d.data)\n ? d.data\n : [d.data]\n : undefined,\n printer: d.printer,\n url: \"url\" in d && d.url ? d.url : undefined,\n ...(d.type === \"rawPdf\"\n ? {\n dpi: d.dpi,\n pageWidth: d.pageWidth,\n pageHeight: d.pageHeight,\n }\n : {}),\n } satisfies UiElementPrintApiResponse[\"data\"][number];\n });\n\n const data = (await Promise.all(dataPromises)).filter(\n (x): x is NonNullable<typeof x> => x !== null\n );\n\n return {\n uiConfig: {\n __type: \"ui.interactive.print\",\n title: options.title,\n description: options.description,\n data,\n autoPrint: options.autoPrint ?? false,\n autoContinue: options.autoContinue ?? false,\n } satisfies UiElementPrintApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n BaseUiMinimalInputResponse,\n DisplayElementImplementation,\n InputElementImplementation,\n InputElementResponse,\n ValidateFn,\n} from \"../..\";\nimport { ImageConfig } from \"../common\";\n\nexport type UiElementPickList = <\n N extends string,\n T extends Record<string, any>,\n const M extends PickListInputModes = { scanner: true; manual: true },\n>(\n name: N,\n options: PickListOptions<M, T>\n) => InputElementResponse<\n N,\n {\n items: PickListResponseItem[];\n }\n>;\n\ntype PickListResponseItem = {\n id: string;\n quantity: number;\n targetQuantity: number;\n scannedBarcodes?: string[];\n};\n\ntype PickListItem = {\n id: string;\n targetQuantity: number;\n title?: string;\n description?: string;\n image?: ImageConfig;\n barcodes?: string[];\n};\n\n/**\n * Defines how duplicate scans should be handled.\n * @default \"increaseQuantity\"\n */\ntype ScanDuplicateMode =\n /** Increase quantity when duplicates are scanned */\n | \"increaseQuantity\"\n /** Reject duplicate scans with an error message */\n | \"rejectDuplicates\";\n\n/**\n * Defines how picking items should be handled. By default, all modes are enabled.\n */\ntype PickListInputModes = {\n /** Picking items can be done by scanning barcodes */\n scanner: boolean;\n /** Picking items can be done by using the add/remove buttons */\n manual: boolean;\n};\n\ntype PickListOptions<M extends PickListInputModes, T> = {\n data: T[];\n render: (data: T) => PickListItem;\n supportedInputs?: M;\n validate?: ValidateFn<{ items: PickListResponseItem[] }>;\n duplicateHandling?: ScanDuplicateMode | undefined;\n /** If true, the step will continue after all items reach the target quantity (pending validation)\n * Only applied for scanner inputs.\n */\n autoContinue?: boolean;\n};\n\n// The shape of the response over the API\nexport interface UiElementPickListApiResponse\n extends BaseUiMinimalInputResponse<\"ui.interactive.pickList\"> {\n data: PickListItem[];\n supportedInputs: PickListInputModes;\n duplicateHandling: ScanDuplicateMode | undefined;\n autoContinue: boolean;\n}\n\nexport const pickList: InputElementImplementation<\n { items: PickListResponseItem[] },\n UiElementPickList,\n UiElementPickListApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.interactive.pickList\",\n name,\n supportedInputs: options.supportedInputs || {\n scanner: true,\n manual: true,\n },\n duplicateHandling: options.duplicateHandling,\n autoContinue: options.autoContinue ?? false,\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n id: rendered.id,\n targetQuantity: rendered.targetQuantity,\n title: rendered.title,\n description: rendered.description,\n image: rendered.image ?? undefined,\n barcodes: rendered.barcodes ?? undefined,\n } satisfies PickListItem;\n }),\n } satisfies UiElementPickListApiResponse,\n validate: async (data, action) => {\n // Ensure the response is an object with an items array\n if (!(\"items\" in data)) {\n return \"Missing items in response\";\n }\n\n if (!Array.isArray(data.items)) {\n return \"Items must be an array\";\n }\n\n if (\n data.items.some(\n (item: any) =>\n typeof item !== \"object\" ||\n typeof item.id !== \"string\" ||\n typeof item.quantity !== \"number\" ||\n typeof item.targetQuantity !== \"number\" ||\n (item.scannedBarcodes && !Array.isArray(item.scannedBarcodes))\n )\n ) {\n return \"Invalid data\";\n }\n\n return options?.validate?.(data, action) ?? true;\n },\n getData: (x: any) => x,\n };\n};\n","export class NonRetriableError extends Error {\n constructor(message?: string) {\n super(message);\n }\n}\n","import {\n BaseUiMinimalInputResponse,\n InputElementImplementation,\n InputElementResponse,\n ValidateFn,\n} from \"../..\";\n\nexport type UiElementScan = <\n N extends string,\n const M extends scanMode = \"single\",\n const D extends ScanDuplicateMode = \"none\",\n>(\n name: N,\n options?: ScanOptions<M, D>\n) => InputElementResponse<\n N,\n M extends \"single\" ? string : ScanResponseItem<D>[]\n>;\n\ntype ScanResponseItem<D> = D extends \"trackQuantity\"\n ? {\n value: string;\n quantity: number;\n }\n : string;\n\n/**\n * Defines how duplicate scans should be handled.\n * @default \"none\"\n */\ntype ScanDuplicateMode =\n /** No duplicate handling - all scans are accepted as separate entries */\n | \"none\"\n /** Track quantity when duplicates are scanned */\n | \"trackQuantity\"\n /** Reject duplicate scans with an error message */\n | \"rejectDuplicates\";\n\ntype scanMode = \"single\" | \"multi\";\n\ntype ScanOptions<M, D> = {\n /** The title of the input block\n * @default \"Scan {unit plural | 'items'}\"\n */\n title?: string;\n description?: string;\n /** The singular unit of the item being scanned. E.g. \"box\", \"bottle\", \"product\" etc */\n unit?: string;\n /** The mode of the scan input\n * @default \"single\"\n */\n mode: M | scanMode;\n\n validate?: ValidateFn<ScanResponseItem<D>>;\n} & (M extends \"multi\"\n ? {\n max?: number;\n min?: number;\n duplicateHandling?: D | ScanDuplicateMode;\n }\n : {\n /** If true, the step will continue after a scan (pending validation).\n * @default false\n */\n autoContinue?: boolean;\n });\n\n// The shape of the response over the API\nexport interface UiElementInputScanApiResponse\n extends BaseUiMinimalInputResponse<\"ui.input.scan\"> {\n mode: \"single\" | \"multi\";\n title?: string;\n description?: string;\n unit?: string;\n max?: number;\n min?: number;\n duplicateHandling: ScanDuplicateMode;\n autoContinue: boolean;\n}\n\nconst isMultiMode = (opts: any): opts is ScanOptions<\"multi\", any> =>\n opts && opts.mode === \"multi\";\nconst isSingleMode = (opts: any): opts is ScanOptions<\"single\", any> =>\n opts && opts.mode === \"single\";\n\nexport const scan: InputElementImplementation<\n any,\n UiElementScan,\n UiElementInputScanApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.scan\",\n name,\n title: options?.title ?? undefined,\n description: options?.description ?? undefined,\n unit: options?.unit ?? undefined,\n mode: options?.mode ?? \"single\",\n duplicateHandling: \"none\",\n autoContinue: false,\n ...(isMultiMode(options)\n ? {\n max: options.max ?? undefined,\n min: options.min ?? undefined,\n duplicateHandling: options.duplicateHandling ?? \"none\",\n }\n : {}),\n ...(isSingleMode(options)\n ? {\n autoContinue: options.autoContinue,\n }\n : {}),\n } satisfies UiElementInputScanApiResponse,\n validate: async (data, action) => {\n return options?.validate?.(data, action) ?? true;\n },\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementWithRequiredConfig,\n} from \"../..\";\nimport { File, FileDbRecord } from \"../../../../File\";\n\nexport type UiElementFile = DisplayElementWithRequiredConfig<{\n title?: string;\n file: File;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementFileApiResponse\n extends BaseUiDisplayResponse<\"ui.display.file\"> {\n title: string;\n file?: FileDbRecord & { url: string };\n}\n\nexport const file: DisplayElementImplementation<\n UiElementFile,\n UiElementFileApiResponse\n> = async (options) => {\n const title = options.title || options.file.filename;\n const url = await options.file.getPresignedUrl();\n const metadata = await options.file.toJSON();\n return {\n uiConfig: {\n __type: \"ui.display.file\",\n title,\n file: metadata\n ? {\n url: url?.toString() || \"\",\n ...metadata,\n }\n : undefined,\n } satisfies UiElementFileApiResponse,\n };\n};\n","import { UI } from \"./ui\";\nimport { Complete, CompleteOptions } from \"./ui/complete\";\nimport { useDatabase } from \"../database\";\nimport {\n withSpan,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n} from \"../tracing\";\nimport * as opentelemetry from \"@opentelemetry/api\";\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, callbackFn, UiPage } from \"./ui/page\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n CallbackDisrupt,\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\";\nimport { keyValue } from \"./ui/elements/display/keyValue\";\nimport { selectTable } from \"./ui/elements/select/table\";\nimport { dataGridInput } from \"./ui/elements/input/dataGrid\";\nimport { datePickerInput } from \"./ui/elements/input/datePicker\";\nimport { fileInput } from \"./ui/elements/input/file\";\nimport { iterator } from \"./ui/elements/iterator\";\nimport { print } from \"./ui/elements/interactive/print\";\nimport { pickList } from \"./ui/elements/interactive/pickList\";\nimport { NonRetriableError } from \"./errors\";\nimport { scan } from \"./ui/elements/input/scan\";\nimport { file } from \"./ui/elements/display/file\";\nimport { transformRichDataTypes } from \"../parsing\";\n\nexport const enum STEP_STATUS {\n NEW = \"NEW\",\n RUNNING = \"RUNNING\",\n PENDING = \"PENDING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n}\n\nexport const enum STEP_TYPE {\n FUNCTION = \"FUNCTION\",\n UI = \"UI\",\n DELAY = \"DELAY\",\n COMPLETE = \"COMPLETE\",\n}\n\n/** A function used to calculate the delay between attempting a retry. The returned value is the number of ms of delay. */\ntype RetryPolicyFn = (retry: number) => number;\n\n/**\n * Returns a linear backoff retry delay.\n * @param intervalS duration in seconds before the first retry. The second retry will double it, the third triple it and so on.\n */\nexport const RetryBackoffLinear = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => retry * intervalS * 1000;\n};\n\n/**\n * Retuns a constant retry delay.\n * @param intervalS duration in seconds between retries.\n */\nexport const RetryConstant = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => (retry > 0 ? intervalS * 1000 : 0);\n};\n\n/**\n * Returns an exponential backoff retry delay.\n * @param intervalS the base duration in seconds.\n */\nexport const RetryBackoffExponential = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => {\n if (retry < 1) {\n return 0;\n }\n return Math.pow(intervalS, retry) * 1000;\n };\n};\n\nconst defaultOpts = {\n retries: 4,\n timeout: 60000,\n};\n\nexport interface FlowContext<\n C extends FlowConfig,\n E,\n S,\n Id,\n I,\n H extends NullableHardware,\n> {\n // Defines a function step that will be run in the flow.\n step: Step<C>;\n // Defines a UI step that will be run in the flow.\n ui: UI<C, H>;\n complete: Complete<C, I>;\n env: E;\n now: Date;\n secrets: S;\n identity: Id;\n}\n\nexport type NullableHardware = Hardware | undefined;\n\nexport type Hardware = {\n printers: Printer[];\n};\nexport interface Printer {\n name: string;\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\ntype StepOptions<C extends FlowConfig> = {\n stage?: ExtractStageKeys<C>;\n /** Number of times to retry the step after it fails. Defaults to 4. */\n retries?: number;\n /** Function to calculate the delay before retrying this step. By default steps will be retried immediately. */\n retryPolicy?: RetryPolicyFn;\n /** Maximum time in milliseconds to wait for the step to complete. Defaults to 60000 (1 minute). */\n timeout?: number;\n /** A function to call if the step fails after it exhausts all retries. */\n onFailure?: () => Promise<void> | void;\n};\n\nexport type Step<C extends FlowConfig> = {\n <R extends JsonSerializable | void>(\n /** The unique name of this step. */\n name: string,\n /** Configuration options for the step. */\n options: StepOptions<C>,\n /** The step function to execute. */\n fn: StepFunction<C, R>\n ): Promise<R>;\n <R extends JsonSerializable | void>(\n /** The unique name of this step. */\n name: string,\n /** The step function to execute. */\n fn: StepFunction<C, R>\n ): Promise<R>;\n};\n\ntype StepArgs<C extends FlowConfig> = {\n attempt: number;\n stepOptions: StepOptions<C>;\n};\n\ntype StepFunction<C extends FlowConfig, R> = (args: StepArgs<C>) => Promise<R>;\n\nexport interface FlowConfig {\n /** The stages to organise the steps in the flow. */\n stages?: StageConfig[];\n /** The title of the flow as shown in the Console. */\n title?: string;\n /** The description of the flow as shown in the Console. */\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<\n C extends FlowConfig,\n E,\n S,\n Id,\n I = undefined,\n H extends NullableHardware = undefined,\n> = (\n ctx: FlowContext<C, E, S, Id, I, H>,\n inputs: I\n) => Promise<CompleteOptions<C, I> | any | 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 /** The unique key of the stage. */\n key: string;\n /** The name of the stage as shown in the Console. */\n name: string;\n /** The description of the stage as shown in the Console. */\n description?: string;\n /** Whether the stage is initially hidden in the Console. */\n initiallyHidden?: boolean;\n};\n\ntype StageConfig = string | StageConfigObject;\n\nexport function createFlowContext<\n C extends FlowConfig,\n E,\n S,\n Id,\n I,\n H extends NullableHardware,\n>(\n runId: string,\n data: any,\n action: string | null,\n callback: string | null,\n element: string | null,\n spanId: string,\n ctx: {\n env: E;\n now: Date;\n secrets: S;\n identity: Id;\n }\n): FlowContext<C, E, S, Id, I, H> {\n // Track step and page names to prevent duplicates\n const usedNames = new Set<string>();\n\n return {\n identity: ctx.identity,\n env: ctx.env,\n now: ctx.now,\n secrets: ctx.secrets,\n complete: (options) => {\n return {\n __type: \"ui.complete\",\n ...options,\n };\n },\n step: async (name, optionsOrFn, fn?) => {\n return withSpan(`Step - ${name}`, async (span: opentelemetry.Span) => {\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<C, any>;\n\n options.retries = options.retries ?? defaultOpts.retries;\n options.timeout = options.timeout ?? defaultOpts.timeout;\n\n const db = useDatabase();\n\n // Check for duplicate step names\n if (usedNames.has(name)) {\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.FAILED,\n type: STEP_TYPE.FUNCTION,\n error: `Duplicate step name: ${name}`,\n startTime: new Date(),\n endTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new Error(`Duplicate step name: ${name}`);\n }\n usedNames.add(name);\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 // step already executed, so this tracing span is internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\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 const stepArgs: StepArgs<C> = {\n attempt: failedSteps.length + 1,\n stepOptions: options,\n };\n\n result = await withTimeout(actualFn(stepArgs), options.timeout);\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 >= options.retries ||\n e instanceof NonRetriableError\n ) {\n if (options.onFailure) {\n await options.onFailure!();\n }\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 options.retryPolicy\n ? new Date(\n Date.now() + options.retryPolicy(failedSteps.length + 1)\n )\n : undefined\n );\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 // step was just created, so this tracing span should be internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n throw new StepCreatedDisrupt();\n });\n },\n ui: {\n page: (async (name, options) => {\n return withSpan(`Page - ${name}`, async (span: opentelemetry.Span) => {\n const db = useDatabase();\n\n const isCallback = element && callback;\n\n // Check for duplicate step names\n if (usedNames.has(name)) {\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.FAILED,\n type: STEP_TYPE.UI,\n error: `Duplicate step name: ${name}`,\n startTime: new Date(),\n endTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new Error(`Duplicate step name: ${name}`);\n }\n usedNames.add(name);\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 // page already completed, so we're marking this span as internal alongside it's children\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n\n const parsedData = transformRichDataTypes(step.value);\n\n if (step.action) {\n // When actions are present, the flow always returns { data, action }\n // so we need to maintain that structure when returning from DB\n return { data: parsedData, action: step.action };\n }\n // Without actions, just return the data directly\n return parsedData;\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 span.setAttribute(\"rendered\", true);\n\n // We now render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(\n step?.id,\n (await page(options, null, null)).page\n );\n }\n\n if (isCallback) {\n span.setAttribute(\"callback\", callback);\n\n // we now need to resolve a UI callback.\n try {\n const response = await callbackFn(\n options.content,\n element,\n callback,\n data\n );\n throw new CallbackDisrupt(response, false);\n } catch (e) {\n if (e instanceof CallbackDisrupt) {\n throw e;\n }\n\n throw new CallbackDisrupt(\n e instanceof Error ? e.message : `An error occurred`,\n true\n );\n }\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(\n step?.id,\n (await page(options, null, null)).page\n );\n }\n\n try {\n const p = await page(options, data, action);\n\n if (p.hasValidationErrors) {\n throw new UIRenderDisrupt(step?.id, p.page);\n }\n } catch (e) {\n if (e instanceof UIRenderDisrupt) {\n throw e;\n }\n\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\", \"=\", step?.id)\n .returningAll()\n .executeTakeFirst();\n\n throw e;\n }\n\n // If the data has been passed in and is valid, persist the data (and action if applicable) 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 action: action,\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", step.id)\n .returningAll()\n .executeTakeFirst();\n\n const parsedData = transformRichDataTypes(data);\n\n // Only return the { data, action } wrapper when actions are defined\n if (action) {\n return { data: parsedData, action };\n }\n return parsedData;\n });\n }) as UiPage<C>,\n inputs: {\n text: textInput as any,\n number: numberInput as any,\n boolean: booleanInput as any,\n dataGrid: dataGridInput as any,\n datePicker: datePickerInput as any,\n scan: scan as any,\n file: fileInput 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 keyValue: keyValue as any,\n file: file as any,\n },\n select: {\n one: selectOne as any,\n table: selectTable as any,\n },\n iterator: iterator as any,\n interactive: {\n print: print as any,\n pickList: pickList 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, NonRetriableError };\n","import { FlowConfig, ExtractStageKeys } from \"..\";\nimport {\n BaseUiDisplayResponse,\n ImplementationResponse,\n UiElementApiResponses,\n DisplayElementResponse,\n} from \".\";\n\ntype AllOptional<T> = {\n [K in keyof T]-?: {} extends Pick<T, K> ? never : K;\n}[keyof T] extends never\n ? true\n : false;\n\ntype RestartConfig = {\n /**\n * If auto, the flow will restart automatically with a notification instead of a completion screen.\n * If manual, a button will be shown on the completion screen.\n * Default is manual.\n * */\n mode?: \"manual\" | \"auto\";\n buttonLabel?: string;\n};\n\nexport type CompleteOptions<C extends FlowConfig, I> = {\n stage?: ExtractStageKeys<C>;\n title?: string;\n description?: string;\n\n /** Automatically close the flow once complete.\n * Title and description will be shown in a notification if provided.\n * If set, you cannot return content as this will not be shown. */\n autoClose?: boolean;\n\n fullWidth?: boolean;\n\n /** Restart the flow once complete.\n * Title and description will be shown in a notification if provided.\n * If set, the flow will be restarted with the inputs provided.\n * If set, you cannot return content as this will not be shown. */\n allowRestart?: //\n // Quite messy types but this does the following:\n // This can be false to disable.\n // True if there are no inputs.\n // Otherwise the config object.\n // If the inputs are all optional then the inputs param is optional, otherwise required.\n | false\n | ([I] extends [never]\n ? boolean | RestartConfig\n : RestartConfig &\n (AllOptional<I> extends true\n ? {\n inputs?: I;\n }\n : {\n inputs: I;\n }));\n data?: any;\n} & (\n | {\n autoClose: true;\n content?: never;\n }\n | {\n autoClose?: false;\n content?: DisplayElementResponse[];\n fullWidth?: boolean;\n }\n);\n\nexport type Complete<C extends FlowConfig, I> = (\n options: CompleteOptions<C, I>\n) => CompleteOptions<C, I> & { __type: \"ui.complete\" };\n\nexport interface UiCompleteApiResponse\n extends BaseUiDisplayResponse<\"ui.complete\"> {\n stage?: string;\n title?: string;\n description?: string;\n content: UiElementApiResponses;\n autoClose?: boolean;\n fullWidth?: boolean;\n allowRestart?: {\n inputs?: any;\n } & RestartConfig;\n}\n\nexport async function complete<C extends FlowConfig, I>(\n options: CompleteOptions<C, I>\n): Promise<UiCompleteApiResponse> {\n // Turn these back into the actual response types\n const content =\n (options.content as unknown as ImplementationResponse<any, any>[]) || [];\n const contentUiConfig = (await Promise.all(\n content.map(async (c) => {\n return (await c).uiConfig;\n })\n )) as UiElementApiResponses;\n\n return {\n __type: \"ui.complete\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig || [],\n autoClose: options.autoClose,\n fullWidth: options.fullWidth,\n allowRestart:\n typeof options.allowRestart === \"boolean\"\n ? options.allowRestart\n ? { inputs: undefined }\n : undefined\n : options.allowRestart,\n } satisfies UiCompleteApiResponse;\n}\n"],"mappings":"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","names":["KSUID","import_kysely","import_kysely","import_node_async_hooks","TraceParent","import_kysely","parseInterval","sql","pgTypes","WebSocket","file","KSUID","import_kysely","complete","sql","context","context","context","table","code","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","file","STEP_STATUS","STEP_TYPE","parsedData","import_change_case","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/parsing.js","../src/applyWhereConditions.js","../src/casing.js","../src/TimePeriod.js","../src/applyAdditionalQueryConstraints.js","../src/applyJoins.js","../src/QueryContext.js","../src/errors.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/ui/elements/display/keyValue.ts","../src/flows/ui/elements/select/table.ts","../src/flows/ui/elements/input/dataGrid.ts","../src/flows/ui/elements/input/datePicker.ts","../src/flows/ui/elements/input/file.ts","../src/flows/ui/elements/iterator.ts","../src/flows/ui/elements/interactive/print.ts","../src/flows/ui/elements/interactive/pickList.ts","../src/flows/errors.ts","../src/flows/ui/elements/input/scan.ts","../src/flows/ui/elements/display/file.ts","../src/flows/index.ts","../src/flows/ui/complete.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, KEEL_INTERNAL_ATTR } 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 span.setAttribute(KEEL_INTERNAL_ATTR, true);\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 span.setAttribute(KEEL_INTERNAL_ATTR, true);\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 if (err instanceof Error) {\n // record any errors\n span.recordException(err);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: err.message,\n });\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\n// This attribute marks just this current span as internal; if the value\nconst KEEL_INTERNAL_ATTR = \"keel_internal\";\n\n// This value, when set on an KEEL_INTERNAL_ATTR marks that all children spans are also internal\nconst KEEL_INTERNAL_CHILDREN = \"includeChildrenSpans\";\n\nexport {\n getTracer,\n withSpan,\n init,\n forceFlush,\n spanNameForModelAPI,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n};\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.KEEL_S3_ENDPOINT;\n if (endpoint) {\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: {\n accessKeyId: \"keelstorage\",\n secretAccessKey: \"keelstorage\",\n },\n endpoint: endpoint,\n });\n }\n\n const testEndpoint = process.env.TEST_AWS_ENDPOINT;\n if (testEndpoint) {\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(testEndpoint),\n };\n },\n });\n }\n\n return new S3Client({\n region: process.env.KEEL_REGION,\n credentials: fromEnv(),\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 mimeType = info.split(\";\")[0];\n const name = info.split(\";\")[1].split(\"=\")[1] || \"file\";\n const buffer = Buffer.from(data, \"base64\");\n const file = new InlineFile({ filename: name, contentType: mimeType });\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 throw new Error(\"S3 client is required\");\n }\n\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 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 throw new Error(\"S3 client is required\");\n }\n\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 }\n\n // Generates a presigned upload URL. If the file doesn't have a key, a new one will be generated\n async getPresignedUploadUrl(): Promise<URL> {\n if (!s3Client) {\n throw new Error(\"S3 client is required\");\n }\n\n if (!this.key) {\n this._key = KSUID.randomSync().string;\n }\n\n const command = new PutObjectCommand({\n Bucket: process.env.KEEL_FILES_BUCKET_NAME,\n Key: \"files/\" + this.key,\n });\n\n const url = await getSignedUrl(s3Client, command, { expiresIn: 60 * 60 });\n\n return new URL(url);\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 throw new Error(\"S3 client is required\");\n }\n\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}\n\nexport type FileWriteTypes = InlineFile | File;\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 { 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 { 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 (!functions[request.method]) {\n const message = `function '${request.method}' does not exist or has not been implemented`;\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 const store = permissionsApiInstance.getStore();\n if (store) {\n store.permitted = true;\n }\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 const store = permissionsApiInstance.getStore();\n if (store) {\n store.permitted = false;\n }\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 (!jobs[request.method]) {\n const message = `job '${request.method}' does not exist or has not been implemented`;\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 (!subscribers[request.method]) {\n const message = `subscriber '${request.method}' does not exist or has not been implemented`;\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 (!functions[request.method]) {\n const message = `route function '${request.method}' does not exist or has not been implemented`;\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 {\n withSpan,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n} from \"./tracing\";\nimport { tryExecuteFlow } from \"./tryExecuteFlow\";\nimport { parseInputs } from \"./parsing\";\nimport { createFlowContext, FlowConfig, STEP_STATUS, STEP_TYPE } from \"./flows\";\nimport {\n CompleteOptions,\n UiCompleteApiResponse,\n complete,\n} from \"./flows/ui/complete\";\n\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n CallbackDisrupt,\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: opentelemetry.Span) => {\n span.setAttribute(KEEL_INTERNAL_ATTR, true);\n\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, createFlowContextAPI } = config;\n\n if (!flows[request.method]) {\n const message = `flow '${request.method}' does not exist or has not been implemented`;\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 ctx = createFlowContext(\n request.meta.runId,\n request.meta.data,\n request.meta.action,\n request.meta.callback,\n request.meta.element,\n span.spanContext().spanId,\n createFlowContextAPI({\n meta: request.meta,\n })\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(request.meta?.inputs);\n\n let response: CompleteOptions<FlowConfig, unknown> | any | void =\n undefined;\n\n try {\n response = await tryExecuteFlow(db, request, 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 // the step was just created, so this span should be internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n\n return createJSONRPCSuccessResponse(request.id, {\n runId: runId,\n runCompleted: false,\n config: flowConfig,\n executeAfter: e.executeAfter,\n });\n }\n\n // The flow is disrupted as it has just executed a UI callback.\n if (e instanceof CallbackDisrupt) {\n if (e.error) {\n return createJSONRPCErrorResponse(request.id, 500, e.response);\n }\n return createJSONRPCSuccessResponse(request.id, e.response);\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 if (e instanceof Error) {\n span.recordException(e);\n span.setStatus({\n code: opentelemetry.SpanStatusCode.ERROR,\n message: e instanceof Error ? e.message : \"unknown error\",\n });\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 let ui: UiCompleteApiResponse | null = null;\n let data: any = null;\n\n // TODO: this is not a thorough enough check for the response type\n if (\n response &&\n typeof response == \"object\" &&\n \"__type\" in response &&\n response.__type === \"ui.complete\"\n ) {\n ui = await complete(response);\n\n const completeStep = await db\n .selectFrom(\"keel.flow_step\")\n .where(\"run_id\", \"=\", runId)\n .where(\"type\", \"=\", STEP_TYPE.COMPLETE)\n .selectAll()\n .executeTakeFirst();\n\n if (!completeStep) {\n await db\n .insertInto(\"keel.flow_step\")\n .values({\n run_id: runId,\n name: \"\",\n stage: response.stage,\n status: STEP_STATUS.COMPLETED,\n type: STEP_TYPE.COMPLETE,\n startTime: new Date(),\n endTime: new Date(),\n ui: JSON.stringify(ui),\n })\n .returningAll()\n .executeTakeFirst();\n }\n\n data = response.data;\n } else if (response) {\n data = response;\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 data: data,\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\";\nimport { withAuditContext } from \"./auditing\";\n\nfunction tryExecuteFlow(db, request, cb) {\n return withDatabase(db, false, async () => {\n return withAuditContext(request, async () => {\n return cb();\n });\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n placeholder: options?.placeholder,\n multiline: options?.multiline,\n maxLength: options?.maxLength,\n minLength: options?.minLength,\n } satisfies UiElementInputTextApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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?: string;\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?: string;\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n placeholder: options?.placeholder,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputNumberApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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 optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n mode: options?.mode || \"checkbox\",\n } satisfies UiElementInputBooleanApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\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\nexport type 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\nexport type TableColumn = {\n name: string;\n index: number;\n};\n\n// The shape of the response over the API\nexport interface UiElementTableApiResponse\n extends BaseUiDisplayResponse<\"ui.display.table\"> {\n data: any[];\n columns: TableColumn[];\n}\n\nexport const table: DisplayElementImplementation<\n UiElementTable,\n UiElementTableApiResponse\n> = (options) => {\n const { data, columns } = processTableData(options.data, options.columns);\n\n return {\n uiConfig: {\n __type: \"ui.display.table\",\n data: data || [],\n columns: columns || [],\n } satisfies UiElementTableApiResponse,\n };\n};\n\n// Only send data for columns we need\nexport const processTableData = (data: any[], columnsConfig?: string[]) => {\n const filteredData = columnsConfig\n ? data.map((item) => {\n return Object.fromEntries(\n Object.entries(item).filter(\n ([key]) => columnsConfig?.includes(key as any)\n )\n );\n })\n : data;\n\n const cols = Object.keys(filteredData[0] || {});\n const columns: TableColumn[] = cols.map((column, index) => ({\n name: column,\n index,\n }));\n\n return { data: filteredData, columns };\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 O extends boolean = false,\n>(\n name: N,\n options?: BaseInputConfig<TValue, O> & {\n options: (\n | {\n label: string;\n value: TValue;\n }\n | TValue\n )[];\n }\n) => InputElementResponse<N, O extends true ? TValue | undefined : 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 || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\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 InputElementImplementationResponse,\n InputElementResponse,\n IteratorElementImplementationResponse,\n UiElementApiResponse,\n UiElementApiResponses,\n UIElements,\n ValidateFn,\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?: ValidateFn<ExtractFormData<T>>;\n actions?: A;\n // When true, let the use go back a step if there is a previous step\n allowBack?: boolean;\n fullWidth?: boolean;\n};\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) => Promise<\n A[\"length\"] extends 0\n ? ExtractFormData<T>\n : { data: ExtractFormData<T>; action: ActionValue<A[number]> }\n>;\n\ntype PageActions = string | PageActionConfig;\ntype PageActionConfig = {\n label: string;\n value: string;\n mode?: \"primary\" | \"secondary\" | \"destructive\";\n /**\n * Keyboard shortcut for this action.\n *\n * @example\n * // Single key\n * hotkey: \"1\"\n * hotkey: \"enter\"\n * hotkey: \"space\"\n * hotkey: \"F1\"\n *\n *\n * // With modifier:\n * // shift, alt + mod (cmd on macOS, ctrl on Windows/Linux)\n *\n * hotkey: \"mod+s\" // cmd+s on macOS, ctrl+s on Windows/Linux\n * hotkey: \"mod+shift+enter\" // cmd+shift+enter on macOS, ctrl+shift+enter on Windows/Linux\n *\n * // With behavior control\n * hotkey: {\n * key: \"mod+enter\",\n * behaviour: \"includeForms\" // Trigger even when focused on form elements\n * }\n */\n hotkey?: string | HotkeyConfig;\n};\n\ntype HotkeyConfig = {\n key: string;\n /** If the hotkey should be triggered when the user is on a form element or not\n *\n * @default \"excludeForms\"\n */\n behaviour?: \"includeForms\" | \"excludeForms\";\n};\n\nexport interface UiPageApiResponse extends BaseUiDisplayResponse<\"ui.page\"> {\n stage?: string;\n title?: string;\n description?: string;\n actions?: PageActionConfig[];\n content: UiElementApiResponses;\n hasValidationErrors: boolean;\n validationError?: string;\n allowBack?: boolean;\n fullWidth?: boolean;\n}\n\nexport async function callbackFn<T extends UIElements>(\n elements: T,\n elementName: string,\n callbackName: string,\n data: any\n): Promise<any> {\n // Find the element by name\n const element = elements.find(\n (el) => (el as any).uiConfig && (el as any).uiConfig.name === elementName\n );\n\n if (!element) {\n throw new Error(`Element with name ${elementName} not found`);\n }\n\n // Check if the callback exists on the element\n const cb = (element as any)[callbackName];\n if (typeof cb !== \"function\") {\n throw new Error(\n `Callback ${callbackName} not found on element ${elementName}`\n );\n }\n\n // Call the callback with provided arguments\n return await cb(data);\n}\n\nexport async function page<\n C extends FlowConfig,\n A extends PageActions[],\n T extends UIElements,\n>(\n options: PageOptions<C, A, T>,\n data: any,\n action: string | null\n): Promise<{ page: UiPageApiResponse; hasValidationErrors: boolean }> {\n // Turn these back into the actual response types\n const content = options.content as unknown as ImplementationResponse<\n any,\n any\n >[];\n let hasValidationErrors = false;\n let validationError: string | undefined;\n\n // Validate actions - all action validation errors are thrown as bad requests\n if (options.actions && options.actions.length > 0) {\n // Actions are defined on the page\n // Normalize action - convert \"undefined\" string or undefined value to null\n const normalizedAction =\n action === \"undefined\" || action === undefined ? null : action;\n\n // Only validate action when data is being submitted (data is not null)\n if (data !== null) {\n if (normalizedAction === null) {\n // No action provided when actions are required during submission\n const validValues = options.actions\n .map((a) => {\n if (typeof a === \"string\") return a;\n return a && typeof a === \"object\" && \"value\" in a ? a.value : \"\";\n })\n .filter(Boolean);\n throw new Error(\n `action is required. Valid actions are: ${validValues.join(\", \")}`\n );\n }\n\n // Action provided, check if it's valid\n const isValidAction = options.actions.some((a) => {\n if (typeof a === \"string\") return a === normalizedAction;\n return (\n a &&\n typeof a === \"object\" &&\n \"value\" in a &&\n a.value === normalizedAction\n );\n });\n\n if (!isValidAction) {\n // Build list of valid action values\n const validValues = options.actions\n .map((a) => {\n if (typeof a === \"string\") return a;\n return a && typeof a === \"object\" && \"value\" in a ? a.value : \"\";\n })\n .filter(Boolean);\n\n throw new Error(\n `invalid action \"${normalizedAction}\". Valid actions are: ${validValues.join(\n \", \"\n )}`\n );\n }\n }\n } else if (\n action !== null &&\n action !== undefined &&\n action !== \"undefined\"\n ) {\n // No actions defined but a real action value was provided - this is a bad request\n throw new Error(\n `invalid action \"${action}\". No actions are defined for this page`\n );\n }\n\n const contentUiConfig = await Promise.all(\n content.map(async (c) => {\n const resolvedC = await c;\n\n const elementData =\n data && typeof data === \"object\" && resolvedC.uiConfig.name in data\n ? data[resolvedC.uiConfig.name]\n : undefined;\n\n const { uiConfig, validationErrors } = await recursivelyProcessElement(\n c,\n elementData,\n options.actions && options.actions.length > 0 ? action : null\n );\n\n if (validationErrors) hasValidationErrors = true;\n\n return uiConfig;\n })\n );\n\n // If there is page level validation, validate the data\n if (data && options.validate) {\n const validationResult =\n options.actions && action !== null\n ? await (options.validate as any)(data, action)\n : await (options.validate as any)(data);\n if (typeof validationResult === \"string\") {\n hasValidationErrors = true;\n validationError = validationResult;\n }\n }\n\n return {\n page: {\n __type: \"ui.page\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig,\n actions: options.actions?.map((a) => {\n if (typeof a === \"string\") {\n return { label: a, value: a, mode: \"primary\" };\n } else if (typeof a === \"object\") {\n a.mode = a.mode || \"primary\";\n }\n return a;\n }),\n hasValidationErrors,\n validationError,\n allowBack: options.allowBack,\n fullWidth: options.fullWidth,\n },\n hasValidationErrors,\n };\n}\n\nconst recursivelyProcessElement = async (\n c: ImplementationResponse<any, any>,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const resolvedC = await c;\n const elementType = \"__type\" in resolvedC ? resolvedC.__type : null;\n\n switch (elementType) {\n case \"input\":\n return processInputElement(\n resolvedC as InputElementImplementationResponse<any, any>,\n data,\n action\n );\n case \"iterator\":\n return processIteratorElement(\n resolvedC as IteratorElementImplementationResponse<any, any>,\n data,\n action\n );\n default:\n return {\n uiConfig: { ...resolvedC.uiConfig },\n validationErrors: false,\n };\n }\n};\n\nconst processInputElement = async (\n element: InputElementImplementationResponse<any, any>,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const hasData = data !== undefined && data !== null;\n\n if (!hasData || !element.validate) {\n return {\n uiConfig: { ...element.uiConfig },\n validationErrors: false,\n };\n }\n\n const validationError =\n action !== null\n ? await (element.validate as any)(data, action)\n : await (element.validate as any)(data);\n const hasValidationErrors = typeof validationError === \"string\";\n\n return {\n uiConfig: {\n ...element.uiConfig,\n validationError: hasValidationErrors ? validationError : undefined,\n },\n validationErrors: hasValidationErrors,\n };\n};\n\nconst processIteratorElement = async (\n element: any,\n data: any,\n action: string | null\n): Promise<{ uiConfig: UiElementApiResponse; validationErrors: boolean }> => {\n const elements = element.uiConfig.content as ImplementationResponse<\n any,\n any\n >[];\n const dataArr = data as any[] | undefined;\n\n // Process the UI config content\n const ui: UiElementApiResponse[] = [];\n for (const el of elements) {\n const result = await recursivelyProcessElement(el, undefined, action);\n ui.push(result.uiConfig);\n }\n\n // Check for validation errors if we have data\n const validationErrors = await validateIteratorData(\n elements,\n dataArr,\n action\n );\n let hasValidationErrors = validationErrors.length > 0;\n\n let validationError: string | undefined = undefined;\n if (dataArr && element.validate) {\n const v =\n action !== null\n ? await (element.validate as any)(dataArr, action)\n : await (element.validate as any)(dataArr);\n if (typeof v === \"string\") {\n hasValidationErrors = true;\n validationError = v;\n }\n }\n\n return {\n uiConfig: {\n ...element.uiConfig,\n content: ui,\n validationError: validationError,\n contentValidationErrors: hasValidationErrors\n ? validationErrors\n : undefined,\n },\n validationErrors: hasValidationErrors,\n };\n};\n\nconst validateIteratorData = async (\n elements: ImplementationResponse<any, any>[],\n dataArr: any[] | undefined,\n action: string | null\n): Promise<Array<{ index: number; name: string; validationError: string }>> => {\n const validationErrors: Array<{\n index: number;\n name: string;\n validationError: string;\n }> = [];\n\n if (!dataArr || dataArr.length === 0) {\n return validationErrors;\n }\n\n for (let i = 0; i < dataArr.length; i++) {\n const rowData = dataArr[i];\n\n for (const el of elements) {\n const resolvedEl = await el;\n\n if (\n \"__type\" in resolvedEl &&\n resolvedEl.__type === \"input\" &&\n \"validate\" in resolvedEl &&\n resolvedEl.validate &&\n typeof resolvedEl.validate === \"function\"\n ) {\n const fieldName = resolvedEl.uiConfig.name;\n\n if (rowData && typeof rowData === \"object\" && fieldName in rowData) {\n const validationError =\n action !== null\n ? await (resolvedEl as any).validate(rowData[fieldName], action)\n : await (resolvedEl as any).validate(rowData[fieldName]);\n\n if (typeof validationError === \"string\") {\n validationErrors.push({\n index: i,\n name: fieldName,\n validationError: validationError,\n });\n }\n }\n }\n }\n }\n\n return validationErrors;\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\nexport type ExtractFormData<T extends UIElements> = {\n [K in Extract<T[number], InputElementResponse<string, any>>[\"name\"]]: Extract<\n T[number],\n InputElementResponse<K, any>\n >[\"returnType\"];\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(public readonly executeAfter?: Date) {\n super();\n }\n}\n\nexport class ExhuastedRetriesDisrupt extends FlowDisrupt {\n constructor() {\n super();\n }\n}\n\nexport class CallbackDisrupt extends FlowDisrupt {\n constructor(\n public readonly response: any,\n public readonly error: boolean\n ) {\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 caption?: 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 caption?: 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 caption: options?.caption,\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 \"../..\";\nimport { ImageConfig } from \"../common\";\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 /**\n * The visual level of the header.\n *\n * @default 2\n */\n level?: 1 | 2 | 3;\n /**\n * The title of the header.\n */\n title?: string;\n /**\n * The description of the header.\n */\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 || 2,\n title: options?.title || \"\",\n description: options?.description || \"\",\n } satisfies UiElementHeaderApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElement,\n DisplayElementImplementation,\n} from \"../..\";\n\ntype KeyValueMode = \"list\" | \"grid\" | \"card\";\n\ntype KeyValueData = {\n key: string;\n value: string | number | Date | boolean; // TODO: support for an object with richer type info / linking\n};\n\n// The types the user experiences\nexport type UiElementKeyValue = DisplayElement<{\n data: KeyValueData[];\n mode?: KeyValueMode;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementKeyValueApiResponse\n extends BaseUiDisplayResponse<\"ui.display.keyValue\"> {\n data: KeyValueData[];\n mode: KeyValueMode;\n}\n\n// The implementation\nexport const keyValue: DisplayElementImplementation<\n UiElementKeyValue,\n UiElementKeyValueApiResponse\n> = (options) => {\n return {\n uiConfig: {\n __type: \"ui.display.keyValue\",\n data: options?.data || [],\n mode: options?.mode || \"list\",\n } satisfies UiElementKeyValueApiResponse,\n };\n};\n","import {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\nimport { processTableData, TableColumn, TableData } from \"../display/table\";\n\nexport type SelectMode = \"single\" | \"multi\";\n\n// 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 UiElementSelectTable = <\n const T extends Record<string, any>,\n N extends string,\n const M extends SelectMode = \"multi\",\n const O extends boolean = false,\n>(\n name: N,\n options: TableOptions<T, O, M>\n) => InputElementResponse<\n N,\n M extends \"single\" ? (O extends true ? T | undefined : T) : T[]\n>;\n\nexport type TableOptions<\n T extends Record<string, any>,\n O extends boolean,\n M extends SelectMode,\n> = Omit<\n BaseInputConfig<\n M extends \"single\" ? (O extends true ? T | undefined : T) : T[],\n O\n >,\n \"defaultValue\" | \"label\"\n> &\n TableData<T> &\n (\n | {\n mode?: M;\n }\n | {\n mode: \"multi\";\n max?: number;\n min?: number;\n }\n );\n\n// The shape of the response over the API\nexport interface UiElementSelectTableApiResponse\n extends Omit<\n BaseUiInputResponse<\"ui.select.table\", any>,\n \"defaultValue\" | \"label\"\n > {\n data: Record<string, any>[];\n columns: TableColumn[];\n mode: SelectMode;\n}\n\nexport const selectTable: InputElementImplementation<\n any,\n UiElementSelectTable,\n UiElementSelectTableApiResponse\n> = (name, options) => {\n const { data, columns } = processTableData(options.data, options.columns);\n\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.select.table\",\n name,\n data,\n columns,\n mode: options?.mode || \"multi\",\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n } satisfies UiElementSelectTableApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import { sentenceCase } from \"change-case\";\nimport {\n BaseInputConfig,\n BaseUiInputResponse,\n InputElementImplementation,\n InputElementResponse,\n} from \"../..\";\nimport { processTableData } from \"../display/table\";\n\n// 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 UiElementInputDataGrid = <\n N extends string,\n T extends Record<string, any>,\n const Cols extends Extract<keyof T, string>[],\n C extends ColumnConfig<Cols>[] | undefined = undefined,\n>(\n name: N,\n options: DataGridOptions<T, C>\n) => InputElementResponse<\n N,\n C extends ColumnConfig<Cols>[]\n ? {\n // If the column has a type then we need to cast the value to the type of the column\n // Otherwise we just use the type of the value\n [K in C[number] as K[\"key\"]]: MapDataType<K[\"type\"], T[K[\"key\"]]>;\n }[]\n : T[]\n>;\n\ntype MapDataType<U, Fallback> = U extends \"text\"\n ? string\n : U extends \"number\"\n ? number\n : U extends \"boolean\"\n ? boolean\n : U extends \"id\"\n ? string\n : U extends \"hidden\"\n ? Fallback\n : Fallback;\n\ntype ColumnConfig<Cols extends string[]> = {\n key: Cols[number];\n label?: string;\n type?: DataGridDataTypes;\n editable?: boolean;\n};\n\nexport type DataGridOptions<T extends Record<string, any>, C> = Omit<\n BaseInputConfig<T[]>,\n \"defaultValue\" | \"label\" | \"optional\" | \"disabled\"\n> & {\n data: T[];\n columns?: C;\n allowAddRows?: boolean;\n allowDeleteRows?: boolean;\n};\n\n// The shape of the response over the API\nexport interface UiElementInputDataGridApiResponse\n extends Omit<\n BaseUiInputResponse<\"ui.input.dataGrid\", any>,\n \"defaultValue\" | \"label\" | \"optional\" | \"disabled\"\n > {\n data: any[];\n columns: DataGridColumn[];\n allowAddRows: boolean;\n allowDeleteRows: boolean;\n}\n\ntype DataGridDataTypes = \"text\" | \"number\" | \"boolean\" | \"id\" | \"hidden\";\n\nexport type DataGridColumn = {\n key: string;\n label: string;\n index: number;\n type: DataGridDataTypes;\n editable: boolean;\n};\n\nexport const dataGridInput: InputElementImplementation<\n any,\n UiElementInputDataGrid,\n UiElementInputDataGridApiResponse\n> = (name, options) => {\n const { data } = processTableData(\n options.data,\n options.columns?.map((c) => c.key)\n );\n\n const inferType = (key: string) => {\n const inferredTypeRaw = typeof data[0][key];\n const inferredTypeMap: Record<typeof inferredTypeRaw, DataGridDataTypes> = {\n string: \"text\",\n number: \"number\",\n boolean: \"boolean\",\n bigint: \"number\",\n symbol: \"text\",\n undefined: \"text\",\n object: \"text\",\n function: \"text\",\n };\n return inferredTypeMap[inferredTypeRaw] ?? \"text\";\n };\n\n const columns = options.columns\n ? options.columns?.map((column, idx) => ({\n key: column.key,\n label: column.label || column.key,\n index: idx,\n type: column.type || inferType(column.key),\n editable:\n column.editable === undefined\n ? column.type === \"id\"\n ? false\n : true\n : column.editable,\n }))\n : Object.keys(data[0]).map((key, idx) => {\n return {\n index: idx,\n key,\n label: sentenceCase(key),\n type: inferType(key),\n editable: true,\n };\n });\n\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.dataGrid\",\n name,\n data,\n columns,\n helpText: options?.helpText,\n allowAddRows: options?.allowAddRows ?? false,\n allowDeleteRows: options?.allowDeleteRows ?? false,\n } satisfies UiElementInputDataGridApiResponse,\n validate: options?.validate, // TODO have some built in validation that checks the types of the response\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n} from \"../..\";\n\ntype ElementDataType = string;\n\n/**\n * Defines what type of datepicker should we use.\n * @default \"dateTime\"\n */\ntype DatePickerMode =\n /** Pick both a date and a time */\n | \"dateTime\"\n /** Pick only a date */\n | \"date\";\n\nexport type UiElementInputDatePicker = InputElement<\n ElementDataType,\n {\n mode?: DatePickerMode;\n /** Allows selecting only dates/datetimes past this given date. */\n min?: string;\n /** Allows selecting only dates/datetimes before this given date. */\n max?: string;\n }\n>;\n\n// The shape of the response over the API\nexport interface UiElementInputDatePickerApiResponse\n extends BaseUiInputResponse<\"ui.input.datePicker\", ElementDataType> {\n mode?: DatePickerMode;\n min?: string;\n max?: string;\n}\n\nexport const datePickerInput: InputElementImplementation<\n ElementDataType,\n UiElementInputDatePicker,\n UiElementInputDatePickerApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.datePicker\",\n name,\n label: options?.label || name,\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n defaultValue: options?.defaultValue,\n mode: options?.mode,\n min: options?.min,\n max: options?.max,\n } satisfies UiElementInputDatePickerApiResponse,\n validate: options?.validate,\n onLeave: options?.onLeave,\n getData: (x: ElementDataType) => x,\n };\n};\n","import {\n BaseUiInputResponse,\n InputElementImplementation,\n InputElement,\n CallbackFn,\n} from \"../..\";\n\nimport { File, FileDbRecord } from \"../../../../File\";\n\ntype ElementDataType = Partial<FileDbRecord>;\n\nexport type UiElementInputFile = InputElement<ElementDataType, {}, File>;\n\n/**\n * key: string;\n * filename: string;\n * contentType: string;\n */\ntype PresignedUrlCallbackInput = Partial<FileDbRecord>;\ntype PresignedUrlCallbackResponse = {\n key: string;\n url: string;\n};\n\n// The shape of the response over the API\nexport interface UiElementInputFileApiResponse\n extends BaseUiInputResponse<\"ui.input.file\", ElementDataType> {}\n\nexport const fileInput: InputElementImplementation<\n ElementDataType,\n UiElementInputFile,\n UiElementInputFileApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.file\",\n name,\n label: options?.label || name,\n optional: options?.optional || false,\n disabled: options?.disabled || false,\n helpText: options?.helpText,\n } satisfies UiElementInputFileApiResponse,\n validate: options?.validate,\n getData: (x: ElementDataType) => x,\n getPresignedUploadURL: (async (input: PresignedUrlCallbackInput) => {\n const file = new File(input);\n const url = await file.getPresignedUploadUrl();\n return {\n url: url.toString(),\n key: file.key,\n };\n }) as CallbackFn<PresignedUrlCallbackInput, PresignedUrlCallbackResponse>,\n };\n};\n","import {\n BaseUiDisplayResponse,\n ImplementationResponse,\n IteratorElementImplementation,\n IteratorElementResponse,\n UiElementApiResponses,\n UIElements,\n ValidateFn,\n} from \"..\";\nimport { ExtractFormData } from \"../page\";\n\nexport type UiElementIterator = <N extends string, T extends UIElements>(\n name: N,\n options: {\n content: T;\n validate?: ValidateFn<ExtractFormData<T>[]>;\n max?: number;\n min?: number;\n }\n) => IteratorElementResponse<N, T>;\n\n// The shape of the response over the API\nexport interface UiElementIteratorApiResponse\n extends BaseUiDisplayResponse<\"ui.iterator\"> {\n name: string;\n content: UiElementApiResponses;\n max?: number;\n min?: number;\n validationError?: string;\n contentValidationErrors?: Array<{\n index: number;\n name: string;\n validationError: string;\n }>;\n}\n\nexport const iterator: IteratorElementImplementation<\n any,\n UiElementIterator,\n UiElementIteratorApiResponse\n> = (name, options) => {\n return {\n __type: \"iterator\",\n uiConfig: {\n __type: \"ui.iterator\",\n name,\n content: options.content as unknown as UiElementApiResponses,\n max: options.max,\n min: options.min,\n } satisfies UiElementIteratorApiResponse,\n validate: options?.validate,\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementWithRequiredConfig,\n} from \"../..\";\nimport { Hardware, NullableHardware } from \"../../../index\";\n\nexport type UiElementPrint<H extends NullableHardware> =\n DisplayElementWithRequiredConfig<{\n jobs: PrintData<H>[] | PrintData<H>;\n title?: string;\n description?: string;\n /** If true, the jobs will be automatically printed. */\n autoPrint?: boolean;\n /** If true, the step will continue after the jobs are complete (pending validation). */\n autoContinue?: boolean;\n }>;\n\ntype PrintData<H extends NullableHardware> = {\n /** The name of the print job. */\n name?: string;\n /** The printer to use for the print job. Printers are defined in keelconfig.yaml. */\n printer?: H extends Hardware ? H[\"printers\"][number][\"name\"] : never;\n} & (PrintDataZpl | PrintDataRawPdf);\n\ntype PrintDataZpl = {\n type: \"zpl\";\n} & (\n | {\n data: string | string[];\n url?: never;\n }\n | {\n data?: never;\n url: string;\n }\n);\n\ntype PrintDataRawPdf = {\n type: \"rawPdf\";\n url: string;\n data?: never;\n /** The DPI of the PDF\n * @default 300\n */\n dpi?: number;\n /** The width of the page in dots.\n * e.g. 4\" at 300 dpi is 1200 dots.\n * @default 1200\n */\n pageWidth?: number;\n /** The height of the page in dots.\n * e.g. 6\" at 300 dpi is 1800 dots.\n * @default 1800\n */\n pageHeight?: number;\n};\n\n// The shape of the response over the API\nexport interface UiElementPrintApiResponse<>extends BaseUiDisplayResponse<\"ui.interactive.print\"> {\n title?: string;\n description?: string;\n data: {\n type: \"zpl\" | \"rawPdf\";\n name?: string;\n data?: string[];\n url?: string;\n printer?: string;\n dpi?: number;\n pageWidth?: number;\n pageHeight?: number;\n }[];\n autoPrint: boolean;\n autoContinue: boolean;\n}\n\nexport const print: DisplayElementImplementation<\n UiElementPrint<NullableHardware>,\n UiElementPrintApiResponse\n> = async (options) => {\n const dataConfig = Array.isArray(options.jobs)\n ? options.jobs\n : [options.jobs];\n\n const dataPromises = dataConfig.map(async (d) => {\n // if (\"file\" in d && d.file) {\n // return {\n // type: \"url\" as const,\n // url: (await d.file.getPresignedUrl()).toString(),\n // };\n // }\n\n return {\n type: d.type,\n name: d.name,\n data:\n \"data\" in d && d.data\n ? Array.isArray(d.data)\n ? d.data\n : [d.data]\n : undefined,\n printer: d.printer,\n url: \"url\" in d && d.url ? d.url : undefined,\n ...(d.type === \"rawPdf\"\n ? {\n dpi: d.dpi,\n pageWidth: d.pageWidth,\n pageHeight: d.pageHeight,\n }\n : {}),\n } satisfies UiElementPrintApiResponse[\"data\"][number];\n });\n\n const data = (await Promise.all(dataPromises)).filter(\n (x): x is NonNullable<typeof x> => x !== null\n );\n\n return {\n uiConfig: {\n __type: \"ui.interactive.print\",\n title: options.title,\n description: options.description,\n data,\n autoPrint: options.autoPrint ?? false,\n autoContinue: options.autoContinue ?? false,\n } satisfies UiElementPrintApiResponse,\n };\n};\n","import {\n BaseUiDisplayResponse,\n BaseUiMinimalInputResponse,\n DisplayElementImplementation,\n InputElementImplementation,\n InputElementResponse,\n ValidateFn,\n} from \"../..\";\nimport { ImageConfig } from \"../common\";\n\nexport type UiElementPickList = <\n N extends string,\n T extends Record<string, any>,\n const M extends PickListInputModes = { scanner: true; manual: true },\n>(\n name: N,\n options: PickListOptions<M, T>\n) => InputElementResponse<\n N,\n {\n items: PickListResponseItem[];\n }\n>;\n\ntype PickListResponseItem = {\n id: string;\n quantity: number;\n targetQuantity: number;\n scannedBarcodes?: string[];\n};\n\ntype PickListItem = {\n id: string;\n targetQuantity: number;\n title?: string;\n description?: string;\n image?: ImageConfig;\n barcodes?: string[];\n};\n\n/**\n * Defines how duplicate scans should be handled.\n * @default \"increaseQuantity\"\n */\ntype ScanDuplicateMode =\n /** Increase quantity when duplicates are scanned */\n | \"increaseQuantity\"\n /** Reject duplicate scans with an error message */\n | \"rejectDuplicates\";\n\n/**\n * Defines how picking items should be handled. By default, all modes are enabled.\n */\ntype PickListInputModes = {\n /** Picking items can be done by scanning barcodes */\n scanner: boolean;\n /** Picking items can be done by using the add/remove buttons */\n manual: boolean;\n};\n\ntype PickListOptions<M extends PickListInputModes, T> = {\n data: T[];\n render: (data: T) => PickListItem;\n supportedInputs?: M;\n validate?: ValidateFn<{ items: PickListResponseItem[] }>;\n duplicateHandling?: ScanDuplicateMode | undefined;\n /** If true, the step will continue after all items reach the target quantity (pending validation)\n * Only applied for scanner inputs.\n */\n autoContinue?: boolean;\n};\n\n// The shape of the response over the API\nexport interface UiElementPickListApiResponse\n extends BaseUiMinimalInputResponse<\"ui.interactive.pickList\"> {\n data: PickListItem[];\n supportedInputs: PickListInputModes;\n duplicateHandling: ScanDuplicateMode | undefined;\n autoContinue: boolean;\n}\n\nexport const pickList: InputElementImplementation<\n { items: PickListResponseItem[] },\n UiElementPickList,\n UiElementPickListApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.interactive.pickList\",\n name,\n supportedInputs: options.supportedInputs || {\n scanner: true,\n manual: true,\n },\n duplicateHandling: options.duplicateHandling,\n autoContinue: options.autoContinue ?? false,\n data: options.data.map((item: any) => {\n const rendered = options.render(item);\n return {\n id: rendered.id,\n targetQuantity: rendered.targetQuantity,\n title: rendered.title,\n description: rendered.description,\n image: rendered.image ?? undefined,\n barcodes: rendered.barcodes ?? undefined,\n } satisfies PickListItem;\n }),\n } satisfies UiElementPickListApiResponse,\n validate: async (data, action) => {\n // Ensure the response is an object with an items array\n if (!(\"items\" in data)) {\n return \"Missing items in response\";\n }\n\n if (!Array.isArray(data.items)) {\n return \"Items must be an array\";\n }\n\n if (\n data.items.some(\n (item: any) =>\n typeof item !== \"object\" ||\n typeof item.id !== \"string\" ||\n typeof item.quantity !== \"number\" ||\n typeof item.targetQuantity !== \"number\" ||\n (item.scannedBarcodes && !Array.isArray(item.scannedBarcodes))\n )\n ) {\n return \"Invalid data\";\n }\n\n return options?.validate?.(data, action) ?? true;\n },\n getData: (x: any) => x,\n };\n};\n","export class NonRetriableError extends Error {\n constructor(message?: string) {\n super(message);\n }\n}\n","import {\n BaseUiMinimalInputResponse,\n InputElementImplementation,\n InputElementResponse,\n ValidateFn,\n} from \"../..\";\n\nexport type UiElementScan = <\n N extends string,\n const M extends scanMode = \"single\",\n const D extends ScanDuplicateMode = \"none\",\n>(\n name: N,\n options?: ScanOptions<M, D>\n) => InputElementResponse<\n N,\n M extends \"single\" ? string : ScanResponseItem<D>[]\n>;\n\ntype ScanResponseItem<D> = D extends \"trackQuantity\"\n ? {\n value: string;\n quantity: number;\n }\n : string;\n\n/**\n * Defines how duplicate scans should be handled.\n * @default \"none\"\n */\ntype ScanDuplicateMode =\n /** No duplicate handling - all scans are accepted as separate entries */\n | \"none\"\n /** Track quantity when duplicates are scanned */\n | \"trackQuantity\"\n /** Reject duplicate scans with an error message */\n | \"rejectDuplicates\";\n\ntype scanMode = \"single\" | \"multi\";\n\ntype ScanOptions<M, D> = {\n /** The title of the input block\n * @default \"Scan {unit plural | 'items'}\"\n */\n title?: string;\n description?: string;\n /** The singular unit of the item being scanned. E.g. \"box\", \"bottle\", \"product\" etc */\n unit?: string;\n /** The mode of the scan input\n * @default \"single\"\n */\n mode: M | scanMode;\n\n validate?: ValidateFn<ScanResponseItem<D>>;\n} & (M extends \"multi\"\n ? {\n max?: number;\n min?: number;\n duplicateHandling?: D | ScanDuplicateMode;\n }\n : {\n /** If true, the step will continue after a scan (pending validation).\n * @default false\n */\n autoContinue?: boolean;\n });\n\n// The shape of the response over the API\nexport interface UiElementInputScanApiResponse\n extends BaseUiMinimalInputResponse<\"ui.input.scan\"> {\n mode: \"single\" | \"multi\";\n title?: string;\n description?: string;\n unit?: string;\n max?: number;\n min?: number;\n duplicateHandling: ScanDuplicateMode;\n autoContinue: boolean;\n}\n\nconst isMultiMode = (opts: any): opts is ScanOptions<\"multi\", any> =>\n opts && opts.mode === \"multi\";\nconst isSingleMode = (opts: any): opts is ScanOptions<\"single\", any> =>\n opts && opts.mode === \"single\";\n\nexport const scan: InputElementImplementation<\n any,\n UiElementScan,\n UiElementInputScanApiResponse\n> = (name, options) => {\n return {\n __type: \"input\",\n uiConfig: {\n __type: \"ui.input.scan\",\n name,\n title: options?.title ?? undefined,\n description: options?.description ?? undefined,\n unit: options?.unit ?? undefined,\n mode: options?.mode ?? \"single\",\n duplicateHandling: \"none\",\n autoContinue: false,\n ...(isMultiMode(options)\n ? {\n max: options.max ?? undefined,\n min: options.min ?? undefined,\n duplicateHandling: options.duplicateHandling ?? \"none\",\n }\n : {}),\n ...(isSingleMode(options)\n ? {\n autoContinue: options.autoContinue,\n }\n : {}),\n } satisfies UiElementInputScanApiResponse,\n validate: async (data, action) => {\n return options?.validate?.(data, action) ?? true;\n },\n getData: (x: any) => x,\n };\n};\n","import {\n BaseUiDisplayResponse,\n DisplayElementImplementation,\n DisplayElementWithRequiredConfig,\n} from \"../..\";\nimport { File, FileDbRecord } from \"../../../../File\";\n\nexport type UiElementFile = DisplayElementWithRequiredConfig<{\n title?: string;\n file: File;\n}>;\n\n// The shape of the response over the API\nexport interface UiElementFileApiResponse\n extends BaseUiDisplayResponse<\"ui.display.file\"> {\n title: string;\n file?: FileDbRecord & { url: string };\n}\n\nexport const file: DisplayElementImplementation<\n UiElementFile,\n UiElementFileApiResponse\n> = async (options) => {\n const title = options.title || options.file.filename;\n const url = await options.file.getPresignedUrl();\n const metadata = await options.file.toJSON();\n return {\n uiConfig: {\n __type: \"ui.display.file\",\n title,\n file: metadata\n ? {\n url: url?.toString() || \"\",\n ...metadata,\n }\n : undefined,\n } satisfies UiElementFileApiResponse,\n };\n};\n","import { UI } from \"./ui\";\nimport { Complete, CompleteOptions } from \"./ui/complete\";\nimport { useDatabase } from \"../database\";\nimport {\n withSpan,\n KEEL_INTERNAL_ATTR,\n KEEL_INTERNAL_CHILDREN,\n} from \"../tracing\";\nimport * as opentelemetry from \"@opentelemetry/api\";\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, callbackFn, UiPage } from \"./ui/page\";\nimport {\n StepCreatedDisrupt,\n UIRenderDisrupt,\n ExhuastedRetriesDisrupt,\n CallbackDisrupt,\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\";\nimport { keyValue } from \"./ui/elements/display/keyValue\";\nimport { selectTable } from \"./ui/elements/select/table\";\nimport { dataGridInput } from \"./ui/elements/input/dataGrid\";\nimport { datePickerInput } from \"./ui/elements/input/datePicker\";\nimport { fileInput } from \"./ui/elements/input/file\";\nimport { iterator } from \"./ui/elements/iterator\";\nimport { print } from \"./ui/elements/interactive/print\";\nimport { pickList } from \"./ui/elements/interactive/pickList\";\nimport { NonRetriableError } from \"./errors\";\nimport { scan } from \"./ui/elements/input/scan\";\nimport { file } from \"./ui/elements/display/file\";\nimport { transformRichDataTypes } from \"../parsing\";\n\nexport const enum STEP_STATUS {\n NEW = \"NEW\",\n RUNNING = \"RUNNING\",\n PENDING = \"PENDING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n}\n\nexport const enum STEP_TYPE {\n FUNCTION = \"FUNCTION\",\n UI = \"UI\",\n DELAY = \"DELAY\",\n COMPLETE = \"COMPLETE\",\n}\n\n/** A function used to calculate the delay between attempting a retry. The returned value is the number of ms of delay. */\ntype RetryPolicyFn = (retry: number) => number;\n\n/**\n * Returns a linear backoff retry delay.\n * @param intervalS duration in seconds before the first retry. The second retry will double it, the third triple it and so on.\n */\nexport const RetryBackoffLinear = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => retry * intervalS * 1000;\n};\n\n/**\n * Retuns a constant retry delay.\n * @param intervalS duration in seconds between retries.\n */\nexport const RetryConstant = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => (retry > 0 ? intervalS * 1000 : 0);\n};\n\n/**\n * Returns an exponential backoff retry delay.\n * @param intervalS the base duration in seconds.\n */\nexport const RetryBackoffExponential = (intervalS: number): RetryPolicyFn => {\n return (retry: number) => {\n if (retry < 1) {\n return 0;\n }\n return Math.pow(intervalS, retry) * 1000;\n };\n};\n\nconst defaultOpts = {\n retries: 4,\n timeout: 60000,\n};\n\nexport interface FlowContext<\n C extends FlowConfig,\n E,\n S,\n Id,\n I,\n H extends NullableHardware,\n> {\n // Defines a function step that will be run in the flow.\n step: Step<C>;\n // Defines a UI step that will be run in the flow.\n ui: UI<C, H>;\n complete: Complete<C, I>;\n env: E;\n now: Date;\n secrets: S;\n identity: Id;\n}\n\nexport type NullableHardware = Hardware | undefined;\n\nexport type Hardware = {\n printers: Printer[];\n};\nexport interface Printer {\n name: string;\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\ntype StepOptions<C extends FlowConfig> = {\n stage?: ExtractStageKeys<C>;\n /** Number of times to retry the step after it fails. Defaults to 4. */\n retries?: number;\n /** Function to calculate the delay before retrying this step. By default steps will be retried immediately. */\n retryPolicy?: RetryPolicyFn;\n /** Maximum time in milliseconds to wait for the step to complete. Defaults to 60000 (1 minute). */\n timeout?: number;\n /** A function to call if the step fails after it exhausts all retries. */\n onFailure?: () => Promise<void> | void;\n};\n\nexport type Step<C extends FlowConfig> = {\n <R extends JsonSerializable | void>(\n /** The unique name of this step. */\n name: string,\n /** Configuration options for the step. */\n options: StepOptions<C>,\n /** The step function to execute. */\n fn: StepFunction<C, R>\n ): Promise<R>;\n <R extends JsonSerializable | void>(\n /** The unique name of this step. */\n name: string,\n /** The step function to execute. */\n fn: StepFunction<C, R>\n ): Promise<R>;\n};\n\ntype StepArgs<C extends FlowConfig> = {\n attempt: number;\n stepOptions: StepOptions<C>;\n};\n\ntype StepFunction<C extends FlowConfig, R> = (args: StepArgs<C>) => Promise<R>;\n\nexport interface FlowConfig {\n /** The stages to organise the steps in the flow. */\n stages?: StageConfig[];\n /** The title of the flow as shown in the Console. */\n title?: string;\n /** The description of the flow as shown in the Console. */\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<\n C extends FlowConfig,\n E,\n S,\n Id,\n I = undefined,\n H extends NullableHardware = undefined,\n> = (\n ctx: FlowContext<C, E, S, Id, I, H>,\n inputs: I\n) => Promise<CompleteOptions<C, I> | any | 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 /** The unique key of the stage. */\n key: string;\n /** The name of the stage as shown in the Console. */\n name: string;\n /** The description of the stage as shown in the Console. */\n description?: string;\n /** Whether the stage is initially hidden in the Console. */\n initiallyHidden?: boolean;\n};\n\ntype StageConfig = string | StageConfigObject;\n\nexport function createFlowContext<\n C extends FlowConfig,\n E,\n S,\n Id,\n I,\n H extends NullableHardware,\n>(\n runId: string,\n data: any,\n action: string | null,\n callback: string | null,\n element: string | null,\n spanId: string,\n ctx: {\n env: E;\n now: Date;\n secrets: S;\n identity: Id;\n }\n): FlowContext<C, E, S, Id, I, H> {\n // Track step and page names to prevent duplicates\n const usedNames = new Set<string>();\n\n return {\n identity: ctx.identity,\n env: ctx.env,\n now: ctx.now,\n secrets: ctx.secrets,\n complete: (options) => {\n return {\n __type: \"ui.complete\",\n ...options,\n };\n },\n step: async (name, optionsOrFn, fn?) => {\n return withSpan(`Step - ${name}`, async (span: opentelemetry.Span) => {\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<C, any>;\n\n options.retries = options.retries ?? defaultOpts.retries;\n options.timeout = options.timeout ?? defaultOpts.timeout;\n\n const db = useDatabase();\n\n // Check for duplicate step names\n if (usedNames.has(name)) {\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.FAILED,\n type: STEP_TYPE.FUNCTION,\n error: `Duplicate step name: ${name}`,\n startTime: new Date(),\n endTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new Error(`Duplicate step name: ${name}`);\n }\n usedNames.add(name);\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 // step already executed, so this tracing span is internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\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 const stepArgs: StepArgs<C> = {\n attempt: failedSteps.length + 1,\n stepOptions: options,\n };\n\n result = await withTimeout(actualFn(stepArgs), options.timeout);\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 >= options.retries ||\n e instanceof NonRetriableError\n ) {\n if (options.onFailure) {\n await options.onFailure!();\n }\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 options.retryPolicy\n ? new Date(\n Date.now() + options.retryPolicy(failedSteps.length + 1)\n )\n : undefined\n );\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 // step was just created, so this tracing span should be internal\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n throw new StepCreatedDisrupt();\n });\n },\n ui: {\n page: (async (name, options) => {\n return withSpan(`Page - ${name}`, async (span: opentelemetry.Span) => {\n const db = useDatabase();\n\n const isCallback = element && callback;\n\n // Check for duplicate step names\n if (usedNames.has(name)) {\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.FAILED,\n type: STEP_TYPE.UI,\n error: `Duplicate step name: ${name}`,\n startTime: new Date(),\n endTime: new Date(),\n })\n .returningAll()\n .executeTakeFirst();\n\n throw new Error(`Duplicate step name: ${name}`);\n }\n usedNames.add(name);\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 // page already completed, so we're marking this span as internal alongside it's children\n span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);\n\n const parsedData = transformRichDataTypes(step.value);\n\n if (step.action) {\n // When actions are present, the flow always returns { data, action }\n // so we need to maintain that structure when returning from DB\n return { data: parsedData, action: step.action };\n }\n // Without actions, just return the data directly\n return parsedData;\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 span.setAttribute(\"rendered\", true);\n\n // We now render the UI by disrupting the step with UIRenderDisrupt.\n throw new UIRenderDisrupt(\n step?.id,\n (await page(options, null, null)).page\n );\n }\n\n if (isCallback) {\n span.setAttribute(\"callback\", callback);\n\n // we now need to resolve a UI callback.\n try {\n const response = await callbackFn(\n options.content,\n element,\n callback,\n data\n );\n throw new CallbackDisrupt(response, false);\n } catch (e) {\n if (e instanceof CallbackDisrupt) {\n throw e;\n }\n\n throw new CallbackDisrupt(\n e instanceof Error ? e.message : `An error occurred`,\n true\n );\n }\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(\n step?.id,\n (await page(options, null, null)).page\n );\n }\n\n try {\n const p = await page(options, data, action);\n\n if (p.hasValidationErrors) {\n throw new UIRenderDisrupt(step?.id, p.page);\n }\n } catch (e) {\n if (e instanceof UIRenderDisrupt) {\n throw e;\n }\n\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\", \"=\", step?.id)\n .returningAll()\n .executeTakeFirst();\n\n throw e;\n }\n\n // If the data has been passed in and is valid, persist the data (and action if applicable) 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 action: action,\n spanId: spanId,\n endTime: new Date(),\n })\n .where(\"id\", \"=\", step.id)\n .returningAll()\n .executeTakeFirst();\n\n const parsedData = transformRichDataTypes(data);\n\n // Only return the { data, action } wrapper when actions are defined\n if (action) {\n return { data: parsedData, action };\n }\n return parsedData;\n });\n }) as UiPage<C>,\n inputs: {\n text: textInput as any,\n number: numberInput as any,\n boolean: booleanInput as any,\n dataGrid: dataGridInput as any,\n datePicker: datePickerInput as any,\n scan: scan as any,\n file: fileInput 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 keyValue: keyValue as any,\n file: file as any,\n },\n select: {\n one: selectOne as any,\n table: selectTable as any,\n },\n iterator: iterator as any,\n interactive: {\n print: print as any,\n pickList: pickList 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, NonRetriableError };\n","import { FlowConfig, ExtractStageKeys } from \"..\";\nimport {\n BaseUiDisplayResponse,\n ImplementationResponse,\n UiElementApiResponses,\n DisplayElementResponse,\n} from \".\";\n\ntype AllOptional<T> = {\n [K in keyof T]-?: {} extends Pick<T, K> ? never : K;\n}[keyof T] extends never\n ? true\n : false;\n\ntype RestartConfig = {\n /**\n * If auto, the flow will restart automatically with a notification instead of a completion screen.\n * If manual, a button will be shown on the completion screen.\n * Default is manual.\n * */\n mode?: \"manual\" | \"auto\";\n buttonLabel?: string;\n};\n\nexport type CompleteOptions<C extends FlowConfig, I> = {\n stage?: ExtractStageKeys<C>;\n title?: string;\n description?: string;\n\n /** Automatically close the flow once complete.\n * Title and description will be shown in a notification if provided.\n * If set, you cannot return content as this will not be shown. */\n autoClose?: boolean;\n\n fullWidth?: boolean;\n\n /** Restart the flow once complete.\n * Title and description will be shown in a notification if provided.\n * If set, the flow will be restarted with the inputs provided.\n * If set, you cannot return content as this will not be shown. */\n allowRestart?: //\n // Quite messy types but this does the following:\n // This can be false to disable.\n // True if there are no inputs.\n // Otherwise the config object.\n // If the inputs are all optional then the inputs param is optional, otherwise required.\n | false\n | ([I] extends [never]\n ? boolean | RestartConfig\n : RestartConfig &\n (AllOptional<I> extends true\n ? {\n inputs?: I;\n }\n : {\n inputs: I;\n }));\n data?: any;\n} & (\n | {\n autoClose: true;\n content?: never;\n }\n | {\n autoClose?: false;\n content?: DisplayElementResponse[];\n fullWidth?: boolean;\n }\n);\n\nexport type Complete<C extends FlowConfig, I> = (\n options: CompleteOptions<C, I>\n) => CompleteOptions<C, I> & { __type: \"ui.complete\" };\n\nexport interface UiCompleteApiResponse\n extends BaseUiDisplayResponse<\"ui.complete\"> {\n stage?: string;\n title?: string;\n description?: string;\n content: UiElementApiResponses;\n autoClose?: boolean;\n fullWidth?: boolean;\n allowRestart?: {\n inputs?: any;\n } & RestartConfig;\n}\n\nexport async function complete<C extends FlowConfig, I>(\n options: CompleteOptions<C, I>\n): Promise<UiCompleteApiResponse> {\n // Turn these back into the actual response types\n const content =\n (options.content as unknown as ImplementationResponse<any, any>[]) || [];\n const contentUiConfig = (await Promise.all(\n content.map(async (c) => {\n return (await c).uiConfig;\n })\n )) as UiElementApiResponses;\n\n return {\n __type: \"ui.complete\",\n stage: options.stage,\n title: options.title,\n description: options.description,\n content: contentUiConfig || [],\n autoClose: options.autoClose,\n fullWidth: options.fullWidth,\n allowRestart:\n typeof options.allowRestart === \"boolean\"\n ? options.allowRestart\n ? { inputs: undefined }\n : undefined\n : options.allowRestart,\n } satisfies UiCompleteApiResponse;\n}\n"],"mappings":"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","names":["KSUID","import_kysely","import_kysely","import_node_async_hooks","TraceParent","import_kysely","parseInterval","sql","pgTypes","WebSocket","file","KSUID","import_kysely","complete","sql","context","context","context","table","code","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","file","STEP_STATUS","STEP_TYPE","parsedData","import_change_case","import_ksuid","KSUID"]}