@rocicorp/zero 0.25.0-canary.12 → 0.25.0-canary.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/zero/package.json.js +1 -1
- package/out/zero/src/pg.js +4 -2
- package/out/zero/src/server.js +4 -2
- package/out/zero-cache/src/config/zero-config.d.ts +0 -4
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +5 -15
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +2 -8
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/otel-diag-logger.js +1 -0
- package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +62 -42
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/control.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/control.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/control.js +5 -1
- package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +2 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/json.d.ts +8 -0
- package/out/zero-cache/src/services/change-source/protocol/current/json.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/json.js +19 -0
- package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +3 -0
- package/out/zero-cache/src/services/change-source/protocol/current.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +0 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +0 -5
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +8 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +2 -3
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +0 -1
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +0 -4
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +2 -0
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +14 -1
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +3 -3
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +8 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +4 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/error.d.ts +6 -1
- package/out/zero-client/src/client/error.d.ts.map +1 -1
- package/out/zero-client/src/client/error.js +2 -2
- package/out/zero-client/src/client/error.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +6 -9
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js +3 -8
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts +3 -2
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +15 -3
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +8 -8
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-events/src/status.d.ts +1 -1
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-schema/src/permissions.d.ts +3 -0
- package/out/zero-schema/src/permissions.d.ts.map +1 -1
- package/out/zero-schema/src/permissions.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +1 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +10 -6
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +9 -18
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +10 -8
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +14 -2
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +18 -15
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +0 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/data.js +0 -11
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +2 -2
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +34 -20
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +1 -1
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +4 -2
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +1 -1
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +9 -3
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +4 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +14 -27
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +1 -1
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +4 -2
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +0 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +0 -2
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +2 -15
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +33 -96
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +4 -3
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +24 -23
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +0 -12
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +0 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +3 -11
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts +0 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +0 -17
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +0 -3
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +0 -3
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +1 -2
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +2 -2
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/query/create-builder.d.ts +2 -2
- package/out/zql/src/query/create-builder.d.ts.map +1 -1
- package/out/zql/src/query/create-builder.js +12 -3
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +0 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +0 -3
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query.d.ts +18 -5
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +6 -10
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../../zero-schema/src/permissions.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../../zero-schema/src/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sources":["../../../../zero-schema/src/permissions.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {\n mapCondition,\n toStaticParam,\n type Condition,\n type Parameter,\n} from '../../zero-protocol/src/ast.ts';\nimport {defaultFormat} from '../../zero-types/src/format.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport type {Query} from '../../zql/src/query/query.ts';\nimport {StaticQuery} from '../../zql/src/query/static-query.ts';\nimport type {\n AssetPermissions as CompiledAssetPermissions,\n PermissionsConfig as CompiledPermissionsConfig,\n} from './compiled-permissions.ts';\nimport type {NameMapper} from './name-mapper.ts';\nimport {clientToServer} from './name-mapper.ts';\n\nexport const ANYONE_CAN = [\n (_: unknown, eb: ExpressionBuilder<never, Schema>) => eb.and(),\n];\n\n/**\n * @deprecated Use {@link ANYONE_CAN} instead.\n */\nexport const ANYONE_CAN_DO_ANYTHING = {\n row: {\n select: ANYONE_CAN,\n insert: ANYONE_CAN,\n update: {\n preMutation: ANYONE_CAN,\n postMutation: ANYONE_CAN,\n },\n delete: ANYONE_CAN,\n },\n};\n\nexport const NOBODY_CAN = [];\n\nexport type Anchor = 'authData' | 'preMutationRow';\n\nexport type Queries<TSchema extends Schema> = {\n [K in keyof TSchema['tables']]: Query<K & string, TSchema>;\n};\n\nexport type PermissionRule<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = (\n authData: TAuthDataShape,\n eb: ExpressionBuilder<TTable, TSchema>,\n) => Condition;\n\nexport type AssetPermissions<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = {\n // Why an array of rules?: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n select?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n delete?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n};\n\nexport type PermissionsConfig<TAuthDataShape, TSchema extends Schema> = {\n [K in keyof TSchema['tables']]?: {\n row?: AssetPermissions<TAuthDataShape, TSchema, K & string> | undefined;\n cell?:\n | {\n [C in keyof TSchema['tables'][K]['columns']]?: Omit<\n AssetPermissions<TAuthDataShape, TSchema, K & string>,\n 'cell'\n >;\n }\n | undefined;\n };\n};\n\nexport async function definePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n definer: () =>\n | Promise<PermissionsConfig<TAuthDataShape, TSchema>>\n | PermissionsConfig<TAuthDataShape, TSchema>,\n): Promise<CompiledPermissionsConfig | undefined> {\n const expressionBuilders = {} as Record<\n string,\n ExpressionBuilder<string, Schema>\n >;\n for (const name of Object.keys(schema.tables)) {\n expressionBuilders[name] = new StaticQuery(\n schema,\n name,\n {table: name},\n defaultFormat,\n ).expressionBuilder();\n }\n\n const config = await definer();\n return compilePermissions(schema, config, expressionBuilders);\n}\n\nfunction compilePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n authz: PermissionsConfig<TAuthDataShape, TSchema> | undefined,\n expressionBuilders: Record<string, ExpressionBuilder<string, Schema>>,\n): CompiledPermissionsConfig | undefined {\n if (!authz) {\n return undefined;\n }\n const nameMapper = clientToServer(schema.tables);\n const ret: CompiledPermissionsConfig = {tables: {}};\n for (const [tableName, tableConfig] of Object.entries(authz)) {\n const serverName = schema.tables[tableName].serverName ?? tableName;\n ret.tables[serverName] = {\n row: compileRowConfig(\n nameMapper,\n tableName,\n tableConfig.row,\n expressionBuilders[tableName],\n ),\n cell: compileCellConfig(\n nameMapper,\n tableName,\n tableConfig.cell,\n expressionBuilders[tableName],\n ),\n };\n }\n\n return ret;\n}\n\nfunction compileRowConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rowRules: AssetPermissions<TAuthDataShape, TSchema, TTable> | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): CompiledAssetPermissions | undefined {\n if (!rowRules) {\n return undefined;\n }\n return {\n select: compileRules(\n clientToServer,\n tableName,\n rowRules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rowRules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rowRules.delete,\n expressionBuilder,\n ),\n };\n}\n\n/**\n * What is this \"allow\" and why are permissions policies an array of rules?\n *\n * Please read: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n */\nfunction compileRules<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rules: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): ['allow', Condition][] | undefined {\n if (!rules) {\n return undefined;\n }\n\n return rules.map(rule => {\n const cond = rule(authDataRef as TAuthDataShape, expressionBuilder);\n return ['allow', mapCondition(cond, tableName, clientToServer)] as const;\n });\n}\n\nfunction compileCellConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n cellRules:\n | Record<string, AssetPermissions<TAuthDataShape, TSchema, TTable>>\n | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): Record<string, CompiledAssetPermissions> | undefined {\n if (!cellRules) {\n return undefined;\n }\n const ret: Record<string, CompiledAssetPermissions> = {};\n for (const [columnName, rules] of Object.entries(cellRules)) {\n ret[columnName] = {\n select: compileRules(\n clientToServer,\n tableName,\n rules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rules.delete,\n expressionBuilder,\n ),\n };\n }\n return ret;\n}\n\nclass CallTracker {\n readonly #anchor: Anchor;\n readonly #path: string[];\n constructor(anchor: Anchor, path: string[]) {\n this.#anchor = anchor;\n this.#path = path;\n }\n\n get(target: {[toStaticParam]: () => Parameter}, prop: string | symbol) {\n if (prop === toStaticParam) {\n return target[toStaticParam];\n }\n assert(typeof prop === 'string');\n const path = [...this.#path, prop];\n return new Proxy(\n {\n [toStaticParam]: () => staticParam(this.#anchor, path),\n },\n new CallTracker(this.#anchor, path),\n );\n }\n}\n\nfunction baseTracker(anchor: Anchor) {\n return new Proxy(\n {\n [toStaticParam]: () => {\n throw new Error('no JWT field specified');\n },\n },\n new CallTracker(anchor, []),\n );\n}\n\nexport const authDataRef = baseTracker('authData');\nexport const preMutationRowRef = baseTracker('preMutationRow');\nexport function staticParam(\n anchorClass: 'authData' | 'preMutationRow',\n field: string | string[],\n): Parameter {\n return {\n type: 'static',\n anchor: anchorClass,\n // for backwards compatibility\n field: field.length === 1 ? field[0] : field,\n };\n}\n"],"names":["clientToServer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permissions.js","sources":["../../../../zero-schema/src/permissions.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {\n mapCondition,\n toStaticParam,\n type Condition,\n type Parameter,\n} from '../../zero-protocol/src/ast.ts';\nimport {defaultFormat} from '../../zero-types/src/format.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport type {Query} from '../../zql/src/query/query.ts';\nimport {StaticQuery} from '../../zql/src/query/static-query.ts';\nimport type {\n AssetPermissions as CompiledAssetPermissions,\n PermissionsConfig as CompiledPermissionsConfig,\n} from './compiled-permissions.ts';\nimport type {NameMapper} from './name-mapper.ts';\nimport {clientToServer} from './name-mapper.ts';\n\nexport const ANYONE_CAN = [\n (_: unknown, eb: ExpressionBuilder<never, Schema>) => eb.and(),\n];\n\n/**\n * @deprecated Use {@link ANYONE_CAN} instead.\n */\nexport const ANYONE_CAN_DO_ANYTHING = {\n row: {\n select: ANYONE_CAN,\n insert: ANYONE_CAN,\n update: {\n preMutation: ANYONE_CAN,\n postMutation: ANYONE_CAN,\n },\n delete: ANYONE_CAN,\n },\n};\n\nexport const NOBODY_CAN = [];\n\nexport type Anchor = 'authData' | 'preMutationRow';\n\nexport type Queries<TSchema extends Schema> = {\n [K in keyof TSchema['tables']]: Query<K & string, TSchema>;\n};\n\nexport type PermissionRule<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = (\n authData: TAuthDataShape,\n eb: ExpressionBuilder<TTable, TSchema>,\n) => Condition;\n\nexport type AssetPermissions<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = {\n // Why an array of rules?: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n select?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n delete?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n};\n\nexport type PermissionsConfig<TAuthDataShape, TSchema extends Schema> = {\n [K in keyof TSchema['tables']]?: {\n row?: AssetPermissions<TAuthDataShape, TSchema, K & string> | undefined;\n cell?:\n | {\n [C in keyof TSchema['tables'][K]['columns']]?: Omit<\n AssetPermissions<TAuthDataShape, TSchema, K & string>,\n 'cell'\n >;\n }\n | undefined;\n };\n};\n\n/**\n * @deprecated Use {@link defineMutators} and {@link defineQueries} instead.\n */\nexport async function definePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n definer: () =>\n | Promise<PermissionsConfig<TAuthDataShape, TSchema>>\n | PermissionsConfig<TAuthDataShape, TSchema>,\n): Promise<CompiledPermissionsConfig | undefined> {\n const expressionBuilders = {} as Record<\n string,\n ExpressionBuilder<string, Schema>\n >;\n for (const name of Object.keys(schema.tables)) {\n expressionBuilders[name] = new StaticQuery(\n schema,\n name,\n {table: name},\n defaultFormat,\n ).expressionBuilder();\n }\n\n const config = await definer();\n return compilePermissions(schema, config, expressionBuilders);\n}\n\nfunction compilePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n authz: PermissionsConfig<TAuthDataShape, TSchema> | undefined,\n expressionBuilders: Record<string, ExpressionBuilder<string, Schema>>,\n): CompiledPermissionsConfig | undefined {\n if (!authz) {\n return undefined;\n }\n const nameMapper = clientToServer(schema.tables);\n const ret: CompiledPermissionsConfig = {tables: {}};\n for (const [tableName, tableConfig] of Object.entries(authz)) {\n const serverName = schema.tables[tableName].serverName ?? tableName;\n ret.tables[serverName] = {\n row: compileRowConfig(\n nameMapper,\n tableName,\n tableConfig.row,\n expressionBuilders[tableName],\n ),\n cell: compileCellConfig(\n nameMapper,\n tableName,\n tableConfig.cell,\n expressionBuilders[tableName],\n ),\n };\n }\n\n return ret;\n}\n\nfunction compileRowConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rowRules: AssetPermissions<TAuthDataShape, TSchema, TTable> | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): CompiledAssetPermissions | undefined {\n if (!rowRules) {\n return undefined;\n }\n return {\n select: compileRules(\n clientToServer,\n tableName,\n rowRules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rowRules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rowRules.delete,\n expressionBuilder,\n ),\n };\n}\n\n/**\n * What is this \"allow\" and why are permissions policies an array of rules?\n *\n * Please read: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n */\nfunction compileRules<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rules: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): ['allow', Condition][] | undefined {\n if (!rules) {\n return undefined;\n }\n\n return rules.map(rule => {\n const cond = rule(authDataRef as TAuthDataShape, expressionBuilder);\n return ['allow', mapCondition(cond, tableName, clientToServer)] as const;\n });\n}\n\nfunction compileCellConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n cellRules:\n | Record<string, AssetPermissions<TAuthDataShape, TSchema, TTable>>\n | undefined,\n expressionBuilder: ExpressionBuilder<TTable, TSchema>,\n): Record<string, CompiledAssetPermissions> | undefined {\n if (!cellRules) {\n return undefined;\n }\n const ret: Record<string, CompiledAssetPermissions> = {};\n for (const [columnName, rules] of Object.entries(cellRules)) {\n ret[columnName] = {\n select: compileRules(\n clientToServer,\n tableName,\n rules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rules.delete,\n expressionBuilder,\n ),\n };\n }\n return ret;\n}\n\nclass CallTracker {\n readonly #anchor: Anchor;\n readonly #path: string[];\n constructor(anchor: Anchor, path: string[]) {\n this.#anchor = anchor;\n this.#path = path;\n }\n\n get(target: {[toStaticParam]: () => Parameter}, prop: string | symbol) {\n if (prop === toStaticParam) {\n return target[toStaticParam];\n }\n assert(typeof prop === 'string');\n const path = [...this.#path, prop];\n return new Proxy(\n {\n [toStaticParam]: () => staticParam(this.#anchor, path),\n },\n new CallTracker(this.#anchor, path),\n );\n }\n}\n\nfunction baseTracker(anchor: Anchor) {\n return new Proxy(\n {\n [toStaticParam]: () => {\n throw new Error('no JWT field specified');\n },\n },\n new CallTracker(anchor, []),\n );\n}\n\nexport const authDataRef = baseTracker('authData');\nexport const preMutationRowRef = baseTracker('preMutationRow');\nexport function staticParam(\n anchorClass: 'authData' | 'preMutationRow',\n field: string | string[],\n): Parameter {\n return {\n type: 'static',\n anchor: anchorClass,\n // for backwards compatibility\n field: field.length === 1 ? field[0] : field,\n };\n}\n"],"names":["clientToServer"],"mappings":";;;;;AAmBO,MAAM,aAAa;AAAA,EACxB,CAAC,GAAY,OAAyC,GAAG,IAAA;AAC3D;AAKO,MAAM,yBAAyB;AAAA,EACpC,KAAK;AAAA,IACH,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,MACN,aAAa;AAAA,MACb,cAAc;AAAA,IAAA;AAAA,IAEhB,QAAQ;AAAA,EAAA;AAEZ;AAEO,MAAM,aAAa,CAAA;AA+D1B,eAAsB,kBACpB,QACA,SAGgD;AAChD,QAAM,qBAAqB,CAAA;AAI3B,aAAW,QAAQ,OAAO,KAAK,OAAO,MAAM,GAAG;AAC7C,uBAAmB,IAAI,IAAI,IAAI;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,EAAC,OAAO,KAAA;AAAA,MACR;AAAA,IAAA,EACA,kBAAA;AAAA,EACJ;AAEA,QAAM,SAAS,MAAM,QAAA;AACrB,SAAO,mBAAmB,QAAQ,QAAQ,kBAAkB;AAC9D;AAEA,SAAS,mBACP,QACA,OACA,oBACuC;AACvC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,aAAa,eAAe,OAAO,MAAM;AAC/C,QAAM,MAAiC,EAAC,QAAQ,GAAC;AACjD,aAAW,CAAC,WAAW,WAAW,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC5D,UAAM,aAAa,OAAO,OAAO,SAAS,EAAE,cAAc;AAC1D,QAAI,OAAO,UAAU,IAAI;AAAA,MACvB,KAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,mBAAmB,SAAS;AAAA,MAAA;AAAA,MAE9B,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,mBAAmB,SAAS;AAAA,MAAA;AAAA,IAC9B;AAAA,EAEJ;AAEA,SAAO;AACT;AAEA,SAAS,iBAKPA,iBACA,WACA,UACA,mBACsC;AACtC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,MACNA;AAAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,QAAQ;AAAA,MACNA;AAAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,QAAQ;AAAA,MACN,aAAa;AAAA,QACXA;AAAAA,QACA;AAAA,QACA,SAAS,QAAQ;AAAA,QACjB;AAAA,MAAA;AAAA,MAEF,cAAc;AAAA,QACZA;AAAAA,QACA;AAAA,QACA,SAAS,QAAQ;AAAA,QACjB;AAAA,MAAA;AAAA,IACF;AAAA,IAEF,QAAQ;AAAA,MACNA;AAAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IAAA;AAAA,EACF;AAEJ;AAOA,SAAS,aAKPA,iBACA,WACA,OACA,mBACoC;AACpC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,IAAI,CAAA,SAAQ;AACvB,UAAM,OAAO,KAAK,aAA+B,iBAAiB;AAClE,WAAO,CAAC,SAAS,aAAa,MAAM,WAAWA,eAAc,CAAC;AAAA,EAChE,CAAC;AACH;AAEA,SAAS,kBAKPA,iBACA,WACA,WAGA,mBACsD;AACtD,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AACA,QAAM,MAAgD,CAAA;AACtD,aAAW,CAAC,YAAY,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC3D,QAAI,UAAU,IAAI;AAAA,MAChB,QAAQ;AAAA,QACNA;AAAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,MAEF,QAAQ;AAAA,QACNA;AAAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,MAEF,QAAQ;AAAA,QACN,aAAa;AAAA,UACXA;AAAAA,UACA;AAAA,UACA,MAAM,QAAQ;AAAA,UACd;AAAA,QAAA;AAAA,QAEF,cAAc;AAAA,UACZA;AAAAA,UACA;AAAA,UACA,MAAM,QAAQ;AAAA,UACd;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,QAAQ;AAAA,QACNA;AAAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AACA,SAAO;AACT;AAEA,MAAM,YAAY;AAAA,EACP;AAAA,EACA;AAAA,EACT,YAAY,QAAgB,MAAgB;AAC1C,SAAK,UAAU;AACf,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,IAAI,QAA4C,MAAuB;AACrE,QAAI,SAAS,eAAe;AAC1B,aAAO,OAAO,aAAa;AAAA,IAC7B;AACA,WAAO,OAAO,SAAS,QAAQ;AAC/B,UAAM,OAAO,CAAC,GAAG,KAAK,OAAO,IAAI;AACjC,WAAO,IAAI;AAAA,MACT;AAAA,QACE,CAAC,aAAa,GAAG,MAAM,YAAY,KAAK,SAAS,IAAI;AAAA,MAAA;AAAA,MAEvD,IAAI,YAAY,KAAK,SAAS,IAAI;AAAA,IAAA;AAAA,EAEtC;AACF;AAEA,SAAS,YAAY,QAAgB;AACnC,SAAO,IAAI;AAAA,IACT;AAAA,MACE,CAAC,aAAa,GAAG,MAAM;AACrB,cAAM,IAAI,MAAM,wBAAwB;AAAA,MAC1C;AAAA,IAAA;AAAA,IAEF,IAAI,YAAY,QAAQ,CAAA,CAAE;AAAA,EAAA;AAE9B;AAEO,MAAM,cAAc,YAAY,UAAU;AAChB,YAAY,gBAAgB;AACtD,SAAS,YACd,aACA,OACW;AACX,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA,IAER,OAAO,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;AAAA,EAAA;AAE3C;"}
|
|
@@ -4,6 +4,6 @@ export * from './custom.ts';
|
|
|
4
4
|
export * from './process-mutations.ts';
|
|
5
5
|
export * from './push-processor.ts';
|
|
6
6
|
export * from './queries/process-queries.ts';
|
|
7
|
-
export { handleTransformRequest, type TransformQueryFunction, } from './queries/process-queries.ts';
|
|
7
|
+
export { handleQueryRequest, handleTransformRequest, handleGetQueriesRequest, type TransformQueryFunction, } from './queries/process-queries.ts';
|
|
8
8
|
export * from './zql-database.ts';
|
|
9
9
|
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,GAC5B,MAAM,8BAA8B,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,8BAA8B,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
|
@@ -26,14 +26,18 @@ export interface Database<T> {
|
|
|
26
26
|
}
|
|
27
27
|
export type ExtractTransactionType<D> = D extends Database<infer T> ? T : never;
|
|
28
28
|
export type Params = v.Infer<typeof pushParamsSchema>;
|
|
29
|
-
export type TransactFn<D extends Database<ExtractTransactionType<D
|
|
30
|
-
export type TransactFnCallback<D extends Database<ExtractTransactionType<D
|
|
31
|
-
export type Parsed<D extends Database<ExtractTransactionType<D
|
|
32
|
-
transact: TransactFn<D
|
|
29
|
+
export type TransactFn<D extends Database<ExtractTransactionType<D>>> = (cb: TransactFnCallback<D>) => Promise<MutationResponse>;
|
|
30
|
+
export type TransactFnCallback<D extends Database<ExtractTransactionType<D>>> = (tx: ExtractTransactionType<D>, mutatorName: string, mutatorArgs: ReadonlyJSONValue | undefined) => Promise<void>;
|
|
31
|
+
export type Parsed<D extends Database<ExtractTransactionType<D>>> = {
|
|
32
|
+
transact: TransactFn<D>;
|
|
33
33
|
mutations: CustomMutation[];
|
|
34
34
|
};
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated Use {@linkcode handleMutateRequest} instead.
|
|
37
|
+
*/
|
|
38
|
+
export declare const handleMutationRequest: typeof handleMutateRequest;
|
|
39
|
+
export declare function handleMutateRequest<D extends Database<ExtractTransactionType<D>>>(dbProvider: D, cb: (transact: TransactFn<D>, mutation: CustomMutation) => Promise<MutationResponse>, queryString: URLSearchParams | Record<string, string>, body: ReadonlyJSONValue, logLevel?: LogLevel): Promise<PushResponse>;
|
|
40
|
+
export declare function handleMutateRequest<D extends Database<ExtractTransactionType<D>>>(dbProvider: D, cb: (transact: TransactFn<D>, mutation: CustomMutation) => Promise<MutationResponse>, request: Request, logLevel?: LogLevel): Promise<PushResponse>;
|
|
37
41
|
export declare class OutOfOrderMutation extends Error {
|
|
38
42
|
constructor(clientID: string, receivedMutationID: number, lastMutationID: number | bigint);
|
|
39
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-mutations.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/process-mutations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAG3D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,CAAC,MAAM,4BAA4B,CAAC;AAWhD,OAAO,EAEL,gBAAgB,EAChB,KAAK,cAAc,EAGnB,KAAK,gBAAgB,EAErB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAEjF,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAGtE,MAAM,WAAW,wBAAwB;IACvC,sBAAsB,EAAE,MAAM,OAAO,CAAC;QAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC,CAAC;IACzE,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,WAAW,EAAE,CAAC,CAAC,EACb,QAAQ,EAAE,CACR,EAAE,EAAE,CAAC,EACL,gBAAgB,EAAE,wBAAwB,KACvC,YAAY,CAAC,CAAC,CAAC,EACpB,gBAAgB,CAAC,EAAE,wBAAwB,KACxC,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAChF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEtD,MAAM,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"process-mutations.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/process-mutations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAG3D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,CAAC,MAAM,4BAA4B,CAAC;AAWhD,OAAO,EAEL,gBAAgB,EAChB,KAAK,cAAc,EAGnB,KAAK,gBAAgB,EAErB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAEjF,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAGtE,MAAM,WAAW,wBAAwB;IACvC,sBAAsB,EAAE,MAAM,OAAO,CAAC;QAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC,CAAC;IACzE,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,WAAW,EAAE,CAAC,CAAC,EACb,QAAQ,EAAE,CACR,EAAE,EAAE,CAAC,EACL,gBAAgB,EAAE,wBAAwB,KACvC,YAAY,CAAC,CAAC,CAAC,EACpB,gBAAgB,CAAC,EAAE,wBAAwB,KACxC,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAChF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEtD,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI,CACtE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,KACtB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAC1E,CACE,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAAC,EAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,iBAAiB,GAAG,SAAS,KACvC,OAAO,CAAC,IAAI,CAAC,CAAC;AAErB,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI;IAClE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;AAqBF;;GAEG;AACH,eAAO,MAAM,qBAAqB,4BAAsB,CAAC;AAEzD,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAE7C,UAAU,EAAE,CAAC,EACb,EAAE,EAAE,CACF,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,gBAAgB,CAAC,EAC9B,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrD,IAAI,EAAE,iBAAiB,EACvB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;AAEzB,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAE7C,UAAU,EAAE,CAAC,EACb,EAAE,EAAE,CACF,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,gBAAgB,CAAC,EAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;AAsXzB,qBAAa,kBAAmB,SAAQ,KAAK;gBAEzC,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,MAAM,EAC1B,cAAc,EAAE,MAAM,GAAG,MAAM;CAMlC;AAmBD,yCAAyC;AACzC,wBAAgB,WAAW,CAEzB,QAAQ,EAAE,kBAAkB,GAAG,iBAAiB,CAAC,GAAG,CAAC,EACrD,IAAI,EAAE,MAAM,GAEX,iBAAiB,CAAC,GAAG,CAAC,CAaxB"}
|
|
@@ -20,17 +20,16 @@ const applicationErrorWrapper = async (fn) => {
|
|
|
20
20
|
throw wrapWithApplicationError(error);
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
const handleMutationRequest = handleMutateRequest;
|
|
24
|
+
async function handleMutateRequest(dbProvider, cb, queryStringOrRequest, bodyOrLogLevel, logLevel) {
|
|
24
25
|
const isRequestOverload = queryStringOrRequest instanceof Request;
|
|
25
26
|
let request;
|
|
26
27
|
let queryString;
|
|
27
28
|
let jsonBody;
|
|
28
|
-
let context;
|
|
29
29
|
let lc;
|
|
30
30
|
if (isRequestOverload) {
|
|
31
31
|
request = queryStringOrRequest;
|
|
32
|
-
|
|
33
|
-
const level = contextOrLogLevel ?? "info";
|
|
32
|
+
const level = bodyOrLogLevel ?? "info";
|
|
34
33
|
lc = createLogContext(level).withContext("PushProcessor");
|
|
35
34
|
const url = new URL(request.url);
|
|
36
35
|
queryString = url.searchParams;
|
|
@@ -51,8 +50,7 @@ async function handleMutationRequest(dbProvider, cb, queryStringOrRequest, bodyO
|
|
|
51
50
|
}
|
|
52
51
|
} else {
|
|
53
52
|
queryString = queryStringOrRequest;
|
|
54
|
-
jsonBody =
|
|
55
|
-
context = contextOrLogLevel;
|
|
53
|
+
jsonBody = bodyOrLogLevel;
|
|
56
54
|
const level = logLevel ?? "info";
|
|
57
55
|
lc = createLogContext(level).withContext("PushProcessor");
|
|
58
56
|
}
|
|
@@ -107,13 +105,7 @@ async function handleMutationRequest(dbProvider, cb, queryStringOrRequest, bodyO
|
|
|
107
105
|
const responses = [];
|
|
108
106
|
let processedCount = 0;
|
|
109
107
|
try {
|
|
110
|
-
const transactor = new Transactor(
|
|
111
|
-
dbProvider,
|
|
112
|
-
pushBody,
|
|
113
|
-
queryParams,
|
|
114
|
-
lc,
|
|
115
|
-
context
|
|
116
|
-
);
|
|
108
|
+
const transactor = new Transactor(dbProvider, pushBody, queryParams, lc);
|
|
117
109
|
for (const m of pushBody.mutations) {
|
|
118
110
|
assert(m.type === "custom", "Expected custom mutation");
|
|
119
111
|
lc.debug?.(
|
|
@@ -125,7 +117,7 @@ async function handleMutationRequest(dbProvider, cb, queryStringOrRequest, bodyO
|
|
|
125
117
|
mutationPhase = "transactionPending";
|
|
126
118
|
const result = await transactor.transact(
|
|
127
119
|
m,
|
|
128
|
-
(tx, name, args) => applicationErrorWrapper(() => innerCb(tx, name, args
|
|
120
|
+
(tx, name, args) => applicationErrorWrapper(() => innerCb(tx, name, args))
|
|
129
121
|
);
|
|
130
122
|
mutationPhase = "postCommit";
|
|
131
123
|
return result;
|
|
@@ -178,13 +170,11 @@ class Transactor {
|
|
|
178
170
|
#req;
|
|
179
171
|
#params;
|
|
180
172
|
#lc;
|
|
181
|
-
|
|
182
|
-
constructor(dbProvider, req, params, lc, context) {
|
|
173
|
+
constructor(dbProvider, req, params, lc) {
|
|
183
174
|
this.#dbProvider = dbProvider;
|
|
184
175
|
this.#req = req;
|
|
185
176
|
this.#params = params;
|
|
186
177
|
this.#lc = lc;
|
|
187
|
-
this.#context = context;
|
|
188
178
|
}
|
|
189
179
|
transact = async (mutation, cb) => {
|
|
190
180
|
let appError = void 0;
|
|
@@ -258,7 +248,7 @@ class Transactor {
|
|
|
258
248
|
`Executing mutator '${mutation.name}' (id=${mutation.id})`
|
|
259
249
|
);
|
|
260
250
|
try {
|
|
261
|
-
await cb(dbTx, mutation.name, mutation.args[0]
|
|
251
|
+
await cb(dbTx, mutation.name, mutation.args[0]);
|
|
262
252
|
} catch (appError2) {
|
|
263
253
|
throw wrapWithApplicationError(appError2);
|
|
264
254
|
}
|
|
@@ -360,6 +350,7 @@ class DatabaseTransactionError extends Error {
|
|
|
360
350
|
export {
|
|
361
351
|
OutOfOrderMutation,
|
|
362
352
|
getMutation,
|
|
353
|
+
handleMutateRequest,
|
|
363
354
|
handleMutationRequest
|
|
364
355
|
};
|
|
365
356
|
//# sourceMappingURL=process-mutations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-mutations.js","sources":["../../../../zero-server/src/process-mutations.ts"],"sourcesContent":["import type {LogContext, LogLevel} from '@rocicorp/logger';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {getErrorDetails, getErrorMessage} from '../../shared/src/error.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {promiseVoid} from '../../shared/src/resolved-promises.ts';\nimport type {MaybePromise} from '../../shared/src/types.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {MutationAlreadyProcessedError} from '../../zero-cache/src/services/mutagen/error.ts';\nimport type {ApplicationError} from '../../zero-protocol/src/application-error.ts';\nimport {\n isApplicationError,\n wrapWithApplicationError,\n} from '../../zero-protocol/src/application-error.ts';\nimport {ErrorKind} from '../../zero-protocol/src/error-kind.ts';\nimport {ErrorOrigin} from '../../zero-protocol/src/error-origin.ts';\nimport {ErrorReason} from '../../zero-protocol/src/error-reason.ts';\nimport type {PushFailedBody} from '../../zero-protocol/src/error.ts';\nimport {\n pushBodySchema,\n pushParamsSchema,\n type CustomMutation,\n type Mutation,\n type MutationID,\n type MutationResponse,\n type PushBody,\n type PushResponse,\n} from '../../zero-protocol/src/push.ts';\nimport type {AnyMutatorRegistry} from '../../zql/src/mutate/mutator-registry.ts';\nimport {isMutator} from '../../zql/src/mutate/mutator.ts';\nimport type {CustomMutatorDefs, CustomMutatorImpl} from './custom.ts';\nimport {createLogContext} from './logging.ts';\n\nexport interface TransactionProviderHooks {\n updateClientMutationID: () => Promise<{lastMutationID: number | bigint}>;\n writeMutationResult: (result: MutationResponse) => Promise<void>;\n}\n\nexport interface TransactionProviderInput {\n upstreamSchema: string;\n clientGroupID: string;\n clientID: string;\n mutationID: number;\n}\n\n/**\n * Defines the abstract interface for a database that PushProcessor can execute\n * transactions against.\n */\nexport interface Database<T> {\n transaction: <R>(\n callback: (\n tx: T,\n transactionHooks: TransactionProviderHooks,\n ) => MaybePromise<R>,\n transactionInput?: TransactionProviderInput,\n ) => Promise<R>;\n}\n\nexport type ExtractTransactionType<D> = D extends Database<infer T> ? T : never;\nexport type Params = v.Infer<typeof pushParamsSchema>;\n\nexport type TransactFn<\n D extends Database<ExtractTransactionType<D>>,\n Context,\n> = (cb: TransactFnCallback<D, Context>) => Promise<MutationResponse>;\n\nexport type TransactFnCallback<\n D extends Database<ExtractTransactionType<D>>,\n Context,\n> = (\n tx: ExtractTransactionType<D>,\n mutatorName: string,\n mutatorArgs: ReadonlyJSONValue | undefined,\n ctx: Context,\n) => Promise<void>;\n\nexport type Parsed<D extends Database<ExtractTransactionType<D>>, Context> = {\n transact: TransactFn<D, Context>;\n mutations: CustomMutation[];\n};\n\ntype MutationPhase = 'preTransaction' | 'transactionPending' | 'postCommit';\n\nconst applicationErrorWrapper = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn();\n } catch (error) {\n if (\n error instanceof DatabaseTransactionError ||\n error instanceof OutOfOrderMutation ||\n error instanceof MutationAlreadyProcessedError ||\n isApplicationError(error)\n ) {\n throw error;\n }\n\n throw wrapWithApplicationError(error);\n }\n};\n\nexport function handleMutationRequest<\n D extends Database<ExtractTransactionType<D>>,\n C = undefined,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D, C>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n queryString: URLSearchParams | Record<string, string>,\n body: ReadonlyJSONValue,\n context?: C,\n logLevel?: LogLevel,\n): Promise<PushResponse>;\n\nexport function handleMutationRequest<\n D extends Database<ExtractTransactionType<D>>,\n C = undefined,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D, C>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n request: Request,\n context?: C,\n logLevel?: LogLevel,\n): Promise<PushResponse>;\n\nexport async function handleMutationRequest<\n D extends Database<ExtractTransactionType<D>>,\n C,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D, C>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n queryStringOrRequest: Request | URLSearchParams | Record<string, string>,\n bodyOrContext: ReadonlyJSONValue | C,\n contextOrLogLevel?: C | LogLevel,\n logLevel?: LogLevel,\n): Promise<PushResponse> {\n // Parse overload arguments\n const isRequestOverload = queryStringOrRequest instanceof Request;\n\n let request: Request | undefined;\n let queryString: URLSearchParams | Record<string, string>;\n let jsonBody: unknown;\n let context: C;\n let lc: LogContext;\n\n if (isRequestOverload) {\n request = queryStringOrRequest;\n context = bodyOrContext as C;\n const level = (contextOrLogLevel as LogLevel | undefined) ?? 'info';\n\n // Create log context early, before extracting JSON from Request\n lc = createLogContext(level).withContext('PushProcessor');\n\n const url = new URL(request.url);\n queryString = url.searchParams;\n\n try {\n jsonBody = await request.json();\n } catch (error) {\n lc.error?.('Failed to parse push body', error);\n const message = `Failed to parse push body: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs: [],\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n } else {\n queryString = queryStringOrRequest;\n jsonBody = bodyOrContext;\n context = contextOrLogLevel as C;\n const level = logLevel ?? 'info';\n lc = createLogContext(level).withContext('PushProcessor');\n }\n\n let mutationIDs: MutationID[] = [];\n\n let pushBody: PushBody;\n try {\n pushBody = v.parse(jsonBody, pushBodySchema);\n mutationIDs = pushBody.mutations.map(m => ({\n id: m.id,\n clientID: m.clientID,\n }));\n } catch (error) {\n lc.error?.('Failed to parse push body', error);\n const message = `Failed to parse push body: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs,\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n\n let queryParams: Params;\n try {\n const queryStringObj =\n queryString instanceof URLSearchParams\n ? Object.fromEntries(queryString)\n : queryString;\n queryParams = v.parse(queryStringObj, pushParamsSchema, 'passthrough');\n } catch (error) {\n lc.error?.('Failed to parse push query parameters', error);\n const message = `Failed to parse push query parameters: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs,\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n\n if (pushBody.pushVersion !== 1) {\n const response = {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.UnsupportedPushVersion,\n mutationIDs,\n message: `Unsupported push version: ${pushBody.pushVersion}`,\n } as const satisfies PushFailedBody;\n return response;\n }\n\n const responses: MutationResponse[] = [];\n let processedCount = 0;\n\n try {\n const transactor = new Transactor(\n dbProvider,\n pushBody,\n queryParams,\n lc,\n context,\n );\n\n // Each mutation goes through three phases:\n // 1. Pre-transaction: user logic that runs before `transact` is called. If\n // this throws we still advance LMID and persist the failure result.\n // 2. Transaction: the callback passed to `transact`, which can be retried\n // if it fails with an ApplicationError.\n // 3. Post-commit: any logic that runs after `transact` resolves. Failures\n // here are logged but the mutation remains committed.\n for (const m of pushBody.mutations) {\n assert(m.type === 'custom', 'Expected custom mutation');\n lc.debug?.(\n `Processing mutation '${m.name}' (id=${m.id}, clientID=${m.clientID})`,\n m.args,\n );\n\n let mutationPhase: MutationPhase = 'preTransaction';\n\n const transactProxy: TransactFn<D, C> = async innerCb => {\n mutationPhase = 'transactionPending';\n const result = await transactor.transact(m, (tx, name, args) =>\n applicationErrorWrapper(() => innerCb(tx, name, args, context)),\n );\n mutationPhase = 'postCommit';\n return result;\n };\n\n try {\n const res = await applicationErrorWrapper(() => cb(transactProxy, m));\n responses.push(res);\n lc.debug?.(`Mutation '${m.name}' (id=${m.id}) completed successfully`);\n\n processedCount++;\n } catch (error) {\n if (!isApplicationError(error)) {\n throw error;\n }\n\n if (mutationPhase === 'preTransaction') {\n // Pre-transaction\n await transactor.persistPreTransactionFailure(m, error);\n } else if (mutationPhase === 'postCommit') {\n // Post-commit\n lc.error?.(\n `Post-commit mutation handler failed for mutation ${m.id} for client ${m.clientID}`,\n error,\n );\n }\n\n lc.warn?.(\n `Application error processing mutation ${m.id} for client ${m.clientID}`,\n error,\n );\n responses.push(makeAppErrorResponse(m, error));\n\n processedCount++;\n }\n }\n\n return {\n mutations: responses,\n };\n } catch (error) {\n lc.error?.('Failed to process push request', error);\n // only include mutationIDs for mutations that were not processed\n const unprocessedMutationIDs = mutationIDs.slice(processedCount);\n\n const message = getErrorMessage(error);\n const details = getErrorDetails(error);\n\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason:\n error instanceof OutOfOrderMutation\n ? ErrorReason.OutOfOrderMutation\n : error instanceof DatabaseTransactionError\n ? ErrorReason.Database\n : ErrorReason.Internal,\n message,\n mutationIDs: unprocessedMutationIDs,\n ...(details ? {details} : {}),\n };\n }\n}\n\nclass Transactor<D extends Database<ExtractTransactionType<D>>, Context> {\n readonly #dbProvider: D;\n readonly #req: PushBody;\n readonly #params: Params;\n readonly #lc: LogContext;\n readonly #context: Context;\n\n constructor(\n dbProvider: D,\n req: PushBody,\n params: Params,\n lc: LogContext,\n context: Context,\n ) {\n this.#dbProvider = dbProvider;\n this.#req = req;\n this.#params = params;\n this.#lc = lc;\n this.#context = context;\n }\n\n transact = async (\n mutation: CustomMutation,\n cb: TransactFnCallback<D, Context>,\n ): Promise<MutationResponse> => {\n let appError: ApplicationError | undefined = undefined;\n for (;;) {\n try {\n const ret = await this.#transactImpl(mutation, cb, appError);\n if (appError !== undefined) {\n this.#lc.warn?.(\n `Mutation ${mutation.id} for client ${mutation.clientID} was retried after an error`,\n appError,\n );\n return makeAppErrorResponse(mutation, appError);\n }\n\n return ret;\n } catch (error) {\n if (error instanceof OutOfOrderMutation) {\n this.#lc.error?.(error);\n throw error;\n }\n\n if (error instanceof MutationAlreadyProcessedError) {\n this.#lc.warn?.(error);\n return {\n id: {\n clientID: mutation.clientID,\n id: mutation.id,\n },\n result: {\n error: 'alreadyProcessed',\n details: error.message,\n },\n };\n }\n\n if (isApplicationError(error)) {\n appError = error;\n this.#lc.warn?.(\n `Application error processing mutation ${mutation.id} for client ${mutation.clientID}`,\n appError,\n );\n continue;\n }\n\n this.#lc.error?.(\n `Unexpected error processing mutation ${mutation.id} for client ${mutation.clientID}`,\n error,\n );\n\n throw error;\n }\n }\n };\n\n async persistPreTransactionFailure(\n mutation: CustomMutation,\n appError: ApplicationError<ReadonlyJSONValue | undefined>,\n ): Promise<MutationResponse> {\n // User-land code threw before calling `transact`. We still need to bump the\n // LMID for this mutation and persist the error so that the client knows it failed.\n const ret = await this.#transactImpl(\n mutation,\n // noop callback since there's no transaction to execute\n () => promiseVoid,\n appError,\n );\n return ret;\n }\n\n async #transactImpl(\n mutation: CustomMutation,\n cb: TransactFnCallback<D, Context>,\n appError: ApplicationError | undefined,\n ): Promise<MutationResponse> {\n let transactionPhase: DatabaseTransactionPhase = 'open';\n\n try {\n const ret = await this.#dbProvider.transaction(\n async (dbTx, transactionHooks) => {\n // update the transaction phase to 'execute' after the transaction is opened\n transactionPhase = 'execute';\n\n await this.#checkAndIncrementLastMutationID(\n transactionHooks,\n mutation.clientID,\n mutation.id,\n );\n\n if (appError === undefined) {\n this.#lc.debug?.(\n `Executing mutator '${mutation.name}' (id=${mutation.id})`,\n );\n try {\n await cb(dbTx, mutation.name, mutation.args[0], this.#context);\n } catch (appError) {\n throw wrapWithApplicationError(appError);\n }\n } else {\n const mutationResult = makeAppErrorResponse(mutation, appError);\n await transactionHooks.writeMutationResult(mutationResult);\n }\n\n return {\n id: {\n clientID: mutation.clientID,\n id: mutation.id,\n },\n result: {},\n };\n },\n this.#getTransactionInput(mutation),\n );\n\n return ret;\n } catch (error) {\n if (\n isApplicationError(error) ||\n error instanceof OutOfOrderMutation ||\n error instanceof MutationAlreadyProcessedError\n ) {\n throw error;\n }\n\n throw new DatabaseTransactionError(transactionPhase, {cause: error});\n }\n }\n\n #getTransactionInput(mutation: CustomMutation): TransactionProviderInput {\n return {\n upstreamSchema: this.#params.schema,\n clientGroupID: this.#req.clientGroupID,\n clientID: mutation.clientID,\n mutationID: mutation.id,\n };\n }\n\n async #checkAndIncrementLastMutationID(\n transactionHooks: TransactionProviderHooks,\n clientID: string,\n receivedMutationID: number,\n ) {\n const {lastMutationID} = await transactionHooks.updateClientMutationID();\n\n if (receivedMutationID < lastMutationID) {\n throw new MutationAlreadyProcessedError(\n clientID,\n receivedMutationID,\n lastMutationID,\n );\n } else if (receivedMutationID > lastMutationID) {\n throw new OutOfOrderMutation(\n clientID,\n receivedMutationID,\n lastMutationID,\n );\n }\n }\n}\n\nexport class OutOfOrderMutation extends Error {\n constructor(\n clientID: string,\n receivedMutationID: number,\n lastMutationID: number | bigint,\n ) {\n super(\n `Client ${clientID} sent mutation ID ${receivedMutationID} but expected ${lastMutationID}`,\n );\n }\n}\n\nfunction makeAppErrorResponse(\n m: Mutation,\n error: ApplicationError<ReadonlyJSONValue | undefined>,\n): MutationResponse {\n return {\n id: {\n clientID: m.clientID,\n id: m.id,\n },\n result: {\n error: 'app',\n message: error.message,\n ...(error.details ? {details: error.details} : {}),\n },\n };\n}\n\n/** @deprecated Use getMutator instead */\nexport function getMutation(\n // oxlint-disable-next-line no-explicit-any\n mutators: AnyMutatorRegistry | CustomMutatorDefs<any>,\n name: string,\n // oxlint-disable-next-line no-explicit-any\n): CustomMutatorImpl<any> {\n const path = name.split(/\\.|\\|/);\n const mutator = getObjectAtPath(mutators, path);\n assert(typeof mutator === 'function', `could not find mutator ${name}`);\n\n if (isMutator(mutator)) {\n // mutator needs to be called with {tx, args, ctx}\n // CustomMutatorImpl is called with (tx, args, ctx)\n return (tx, args, ctx) => mutator.fn({args, ctx, tx});\n }\n\n // oxlint-disable-next-line no-explicit-any\n return mutator as CustomMutatorImpl<any>;\n}\n\nfunction getObjectAtPath(\n obj: Record<string, unknown>,\n path: string[],\n): unknown {\n let current: unknown = obj;\n for (const part of path) {\n if (typeof current !== 'object' || current === null || !(part in current)) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\ntype DatabaseTransactionPhase = 'open' | 'execute';\nclass DatabaseTransactionError extends Error {\n constructor(phase: DatabaseTransactionPhase, options?: ErrorOptions) {\n super(\n phase === 'open'\n ? `Failed to open database transaction: ${getErrorMessage(options?.cause)}`\n : `Database transaction failed after opening: ${getErrorMessage(options?.cause)}`,\n options,\n );\n this.name = 'DatabaseTransactionError';\n }\n}\n"],"names":["ErrorKind.PushFailed","ErrorOrigin.Server","ErrorReason.Parse","v.parse","ErrorReason.UnsupportedPushVersion","ErrorReason.OutOfOrderMutation","ErrorReason.Database","ErrorReason.Internal","appError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"process-mutations.js","sources":["../../../../zero-server/src/process-mutations.ts"],"sourcesContent":["import type {LogContext, LogLevel} from '@rocicorp/logger';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {getErrorDetails, getErrorMessage} from '../../shared/src/error.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {promiseVoid} from '../../shared/src/resolved-promises.ts';\nimport type {MaybePromise} from '../../shared/src/types.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {MutationAlreadyProcessedError} from '../../zero-cache/src/services/mutagen/error.ts';\nimport type {ApplicationError} from '../../zero-protocol/src/application-error.ts';\nimport {\n isApplicationError,\n wrapWithApplicationError,\n} from '../../zero-protocol/src/application-error.ts';\nimport {ErrorKind} from '../../zero-protocol/src/error-kind.ts';\nimport {ErrorOrigin} from '../../zero-protocol/src/error-origin.ts';\nimport {ErrorReason} from '../../zero-protocol/src/error-reason.ts';\nimport type {PushFailedBody} from '../../zero-protocol/src/error.ts';\nimport {\n pushBodySchema,\n pushParamsSchema,\n type CustomMutation,\n type Mutation,\n type MutationID,\n type MutationResponse,\n type PushBody,\n type PushResponse,\n} from '../../zero-protocol/src/push.ts';\nimport type {AnyMutatorRegistry} from '../../zql/src/mutate/mutator-registry.ts';\nimport {isMutator} from '../../zql/src/mutate/mutator.ts';\nimport type {CustomMutatorDefs, CustomMutatorImpl} from './custom.ts';\nimport {createLogContext} from './logging.ts';\n\nexport interface TransactionProviderHooks {\n updateClientMutationID: () => Promise<{lastMutationID: number | bigint}>;\n writeMutationResult: (result: MutationResponse) => Promise<void>;\n}\n\nexport interface TransactionProviderInput {\n upstreamSchema: string;\n clientGroupID: string;\n clientID: string;\n mutationID: number;\n}\n\n/**\n * Defines the abstract interface for a database that PushProcessor can execute\n * transactions against.\n */\nexport interface Database<T> {\n transaction: <R>(\n callback: (\n tx: T,\n transactionHooks: TransactionProviderHooks,\n ) => MaybePromise<R>,\n transactionInput?: TransactionProviderInput,\n ) => Promise<R>;\n}\n\nexport type ExtractTransactionType<D> = D extends Database<infer T> ? T : never;\nexport type Params = v.Infer<typeof pushParamsSchema>;\n\nexport type TransactFn<D extends Database<ExtractTransactionType<D>>> = (\n cb: TransactFnCallback<D>,\n) => Promise<MutationResponse>;\n\nexport type TransactFnCallback<D extends Database<ExtractTransactionType<D>>> =\n (\n tx: ExtractTransactionType<D>,\n mutatorName: string,\n mutatorArgs: ReadonlyJSONValue | undefined,\n ) => Promise<void>;\n\nexport type Parsed<D extends Database<ExtractTransactionType<D>>> = {\n transact: TransactFn<D>;\n mutations: CustomMutation[];\n};\n\ntype MutationPhase = 'preTransaction' | 'transactionPending' | 'postCommit';\n\nconst applicationErrorWrapper = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn();\n } catch (error) {\n if (\n error instanceof DatabaseTransactionError ||\n error instanceof OutOfOrderMutation ||\n error instanceof MutationAlreadyProcessedError ||\n isApplicationError(error)\n ) {\n throw error;\n }\n\n throw wrapWithApplicationError(error);\n }\n};\n\n/**\n * @deprecated Use {@linkcode handleMutateRequest} instead.\n */\nexport const handleMutationRequest = handleMutateRequest;\n\nexport function handleMutateRequest<\n D extends Database<ExtractTransactionType<D>>,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n queryString: URLSearchParams | Record<string, string>,\n body: ReadonlyJSONValue,\n logLevel?: LogLevel,\n): Promise<PushResponse>;\n\nexport function handleMutateRequest<\n D extends Database<ExtractTransactionType<D>>,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n request: Request,\n logLevel?: LogLevel,\n): Promise<PushResponse>;\n\nexport async function handleMutateRequest<\n D extends Database<ExtractTransactionType<D>>,\n>(\n dbProvider: D,\n cb: (\n transact: TransactFn<D>,\n mutation: CustomMutation,\n ) => Promise<MutationResponse>,\n queryStringOrRequest: Request | URLSearchParams | Record<string, string>,\n bodyOrLogLevel?: ReadonlyJSONValue | LogLevel,\n logLevel?: LogLevel,\n): Promise<PushResponse> {\n // Parse overload arguments\n const isRequestOverload = queryStringOrRequest instanceof Request;\n\n let request: Request | undefined;\n let queryString: URLSearchParams | Record<string, string>;\n let jsonBody: unknown;\n\n let lc: LogContext;\n\n if (isRequestOverload) {\n request = queryStringOrRequest;\n const level = (bodyOrLogLevel as LogLevel | undefined) ?? 'info';\n\n // Create log context early, before extracting JSON from Request\n lc = createLogContext(level).withContext('PushProcessor');\n\n const url = new URL(request.url);\n queryString = url.searchParams;\n\n try {\n jsonBody = await request.json();\n } catch (error) {\n lc.error?.('Failed to parse push body', error);\n const message = `Failed to parse push body: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs: [],\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n } else {\n queryString = queryStringOrRequest;\n jsonBody = bodyOrLogLevel;\n const level = logLevel ?? 'info';\n lc = createLogContext(level).withContext('PushProcessor');\n }\n\n let mutationIDs: MutationID[] = [];\n\n let pushBody: PushBody;\n try {\n pushBody = v.parse(jsonBody, pushBodySchema);\n mutationIDs = pushBody.mutations.map(m => ({\n id: m.id,\n clientID: m.clientID,\n }));\n } catch (error) {\n lc.error?.('Failed to parse push body', error);\n const message = `Failed to parse push body: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs,\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n\n let queryParams: Params;\n try {\n const queryStringObj =\n queryString instanceof URLSearchParams\n ? Object.fromEntries(queryString)\n : queryString;\n queryParams = v.parse(queryStringObj, pushParamsSchema, 'passthrough');\n } catch (error) {\n lc.error?.('Failed to parse push query parameters', error);\n const message = `Failed to parse push query parameters: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n mutationIDs,\n ...(details ? {details} : {}),\n } as const satisfies PushFailedBody;\n }\n\n if (pushBody.pushVersion !== 1) {\n const response = {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.UnsupportedPushVersion,\n mutationIDs,\n message: `Unsupported push version: ${pushBody.pushVersion}`,\n } as const satisfies PushFailedBody;\n return response;\n }\n\n const responses: MutationResponse[] = [];\n let processedCount = 0;\n\n try {\n const transactor = new Transactor(dbProvider, pushBody, queryParams, lc);\n\n // Each mutation goes through three phases:\n // 1. Pre-transaction: user logic that runs before `transact` is called. If\n // this throws we still advance LMID and persist the failure result.\n // 2. Transaction: the callback passed to `transact`, which can be retried\n // if it fails with an ApplicationError.\n // 3. Post-commit: any logic that runs after `transact` resolves. Failures\n // here are logged but the mutation remains committed.\n for (const m of pushBody.mutations) {\n assert(m.type === 'custom', 'Expected custom mutation');\n lc.debug?.(\n `Processing mutation '${m.name}' (id=${m.id}, clientID=${m.clientID})`,\n m.args,\n );\n\n let mutationPhase: MutationPhase = 'preTransaction';\n\n const transactProxy: TransactFn<D> = async innerCb => {\n mutationPhase = 'transactionPending';\n const result = await transactor.transact(m, (tx, name, args) =>\n applicationErrorWrapper(() => innerCb(tx, name, args)),\n );\n mutationPhase = 'postCommit';\n return result;\n };\n\n try {\n const res = await applicationErrorWrapper(() => cb(transactProxy, m));\n responses.push(res);\n lc.debug?.(`Mutation '${m.name}' (id=${m.id}) completed successfully`);\n\n processedCount++;\n } catch (error) {\n if (!isApplicationError(error)) {\n throw error;\n }\n\n if (mutationPhase === 'preTransaction') {\n // Pre-transaction\n await transactor.persistPreTransactionFailure(m, error);\n } else if (mutationPhase === 'postCommit') {\n // Post-commit\n lc.error?.(\n `Post-commit mutation handler failed for mutation ${m.id} for client ${m.clientID}`,\n error,\n );\n }\n\n lc.warn?.(\n `Application error processing mutation ${m.id} for client ${m.clientID}`,\n error,\n );\n responses.push(makeAppErrorResponse(m, error));\n\n processedCount++;\n }\n }\n\n return {\n mutations: responses,\n };\n } catch (error) {\n lc.error?.('Failed to process push request', error);\n // only include mutationIDs for mutations that were not processed\n const unprocessedMutationIDs = mutationIDs.slice(processedCount);\n\n const message = getErrorMessage(error);\n const details = getErrorDetails(error);\n\n return {\n kind: ErrorKind.PushFailed,\n origin: ErrorOrigin.Server,\n reason:\n error instanceof OutOfOrderMutation\n ? ErrorReason.OutOfOrderMutation\n : error instanceof DatabaseTransactionError\n ? ErrorReason.Database\n : ErrorReason.Internal,\n message,\n mutationIDs: unprocessedMutationIDs,\n ...(details ? {details} : {}),\n };\n }\n}\n\nclass Transactor<D extends Database<ExtractTransactionType<D>>> {\n readonly #dbProvider: D;\n readonly #req: PushBody;\n readonly #params: Params;\n readonly #lc: LogContext;\n\n constructor(dbProvider: D, req: PushBody, params: Params, lc: LogContext) {\n this.#dbProvider = dbProvider;\n this.#req = req;\n this.#params = params;\n this.#lc = lc;\n }\n\n transact = async (\n mutation: CustomMutation,\n cb: TransactFnCallback<D>,\n ): Promise<MutationResponse> => {\n let appError: ApplicationError | undefined = undefined;\n for (;;) {\n try {\n const ret = await this.#transactImpl(mutation, cb, appError);\n if (appError !== undefined) {\n this.#lc.warn?.(\n `Mutation ${mutation.id} for client ${mutation.clientID} was retried after an error`,\n appError,\n );\n return makeAppErrorResponse(mutation, appError);\n }\n\n return ret;\n } catch (error) {\n if (error instanceof OutOfOrderMutation) {\n this.#lc.error?.(error);\n throw error;\n }\n\n if (error instanceof MutationAlreadyProcessedError) {\n this.#lc.warn?.(error);\n return {\n id: {\n clientID: mutation.clientID,\n id: mutation.id,\n },\n result: {\n error: 'alreadyProcessed',\n details: error.message,\n },\n };\n }\n\n if (isApplicationError(error)) {\n appError = error;\n this.#lc.warn?.(\n `Application error processing mutation ${mutation.id} for client ${mutation.clientID}`,\n appError,\n );\n continue;\n }\n\n this.#lc.error?.(\n `Unexpected error processing mutation ${mutation.id} for client ${mutation.clientID}`,\n error,\n );\n\n throw error;\n }\n }\n };\n\n async persistPreTransactionFailure(\n mutation: CustomMutation,\n appError: ApplicationError<ReadonlyJSONValue | undefined>,\n ): Promise<MutationResponse> {\n // User-land code threw before calling `transact`. We still need to bump the\n // LMID for this mutation and persist the error so that the client knows it failed.\n const ret = await this.#transactImpl(\n mutation,\n // noop callback since there's no transaction to execute\n () => promiseVoid,\n appError,\n );\n return ret;\n }\n\n async #transactImpl(\n mutation: CustomMutation,\n cb: TransactFnCallback<D>,\n appError: ApplicationError | undefined,\n ): Promise<MutationResponse> {\n let transactionPhase: DatabaseTransactionPhase = 'open';\n\n try {\n const ret = await this.#dbProvider.transaction(\n async (dbTx, transactionHooks) => {\n // update the transaction phase to 'execute' after the transaction is opened\n transactionPhase = 'execute';\n\n await this.#checkAndIncrementLastMutationID(\n transactionHooks,\n mutation.clientID,\n mutation.id,\n );\n\n if (appError === undefined) {\n this.#lc.debug?.(\n `Executing mutator '${mutation.name}' (id=${mutation.id})`,\n );\n try {\n await cb(dbTx, mutation.name, mutation.args[0]);\n } catch (appError) {\n throw wrapWithApplicationError(appError);\n }\n } else {\n const mutationResult = makeAppErrorResponse(mutation, appError);\n await transactionHooks.writeMutationResult(mutationResult);\n }\n\n return {\n id: {\n clientID: mutation.clientID,\n id: mutation.id,\n },\n result: {},\n };\n },\n this.#getTransactionInput(mutation),\n );\n\n return ret;\n } catch (error) {\n if (\n isApplicationError(error) ||\n error instanceof OutOfOrderMutation ||\n error instanceof MutationAlreadyProcessedError\n ) {\n throw error;\n }\n\n throw new DatabaseTransactionError(transactionPhase, {cause: error});\n }\n }\n\n #getTransactionInput(mutation: CustomMutation): TransactionProviderInput {\n return {\n upstreamSchema: this.#params.schema,\n clientGroupID: this.#req.clientGroupID,\n clientID: mutation.clientID,\n mutationID: mutation.id,\n };\n }\n\n async #checkAndIncrementLastMutationID(\n transactionHooks: TransactionProviderHooks,\n clientID: string,\n receivedMutationID: number,\n ) {\n const {lastMutationID} = await transactionHooks.updateClientMutationID();\n\n if (receivedMutationID < lastMutationID) {\n throw new MutationAlreadyProcessedError(\n clientID,\n receivedMutationID,\n lastMutationID,\n );\n } else if (receivedMutationID > lastMutationID) {\n throw new OutOfOrderMutation(\n clientID,\n receivedMutationID,\n lastMutationID,\n );\n }\n }\n}\n\nexport class OutOfOrderMutation extends Error {\n constructor(\n clientID: string,\n receivedMutationID: number,\n lastMutationID: number | bigint,\n ) {\n super(\n `Client ${clientID} sent mutation ID ${receivedMutationID} but expected ${lastMutationID}`,\n );\n }\n}\n\nfunction makeAppErrorResponse(\n m: Mutation,\n error: ApplicationError<ReadonlyJSONValue | undefined>,\n): MutationResponse {\n return {\n id: {\n clientID: m.clientID,\n id: m.id,\n },\n result: {\n error: 'app',\n message: error.message,\n ...(error.details ? {details: error.details} : {}),\n },\n };\n}\n\n/** @deprecated Use getMutator instead */\nexport function getMutation(\n // oxlint-disable-next-line no-explicit-any\n mutators: AnyMutatorRegistry | CustomMutatorDefs<any>,\n name: string,\n // oxlint-disable-next-line no-explicit-any\n): CustomMutatorImpl<any> {\n const path = name.split(/\\.|\\|/);\n const mutator = getObjectAtPath(mutators, path);\n assert(typeof mutator === 'function', `could not find mutator ${name}`);\n\n if (isMutator(mutator)) {\n // mutator needs to be called with {tx, args, ctx}\n // CustomMutatorImpl is called with (tx, args, ctx)\n return (tx, args, ctx) => mutator.fn({args, ctx, tx});\n }\n\n // oxlint-disable-next-line no-explicit-any\n return mutator as CustomMutatorImpl<any>;\n}\n\nfunction getObjectAtPath(\n obj: Record<string, unknown>,\n path: string[],\n): unknown {\n let current: unknown = obj;\n for (const part of path) {\n if (typeof current !== 'object' || current === null || !(part in current)) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\ntype DatabaseTransactionPhase = 'open' | 'execute';\nclass DatabaseTransactionError extends Error {\n constructor(phase: DatabaseTransactionPhase, options?: ErrorOptions) {\n super(\n phase === 'open'\n ? `Failed to open database transaction: ${getErrorMessage(options?.cause)}`\n : `Database transaction failed after opening: ${getErrorMessage(options?.cause)}`,\n options,\n );\n this.name = 'DatabaseTransactionError';\n }\n}\n"],"names":["ErrorKind.PushFailed","ErrorOrigin.Server","ErrorReason.Parse","v.parse","ErrorReason.UnsupportedPushVersion","ErrorReason.OutOfOrderMutation","ErrorReason.Database","ErrorReason.Internal","appError"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-processor.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/push-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAG5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAE3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAEjF,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAEnD,qBAAa,aAAa,CACxB,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC7C,EAAE,SAAS,kBAAkB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5E,CAAC,GAAG,SAAS;;gBAMD,UAAU,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAE,QAAiB;IAMnE;;;;;;;;;;OAUG;IACH,OAAO,CACL,QAAQ,EAAE,EAAE,EACZ,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,YAAY,CAAC;IAExB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"push-processor.d.ts","sourceRoot":"","sources":["../../../../zero-server/src/push-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAG5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAE3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAEjF,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAEnD,qBAAa,aAAa,CACxB,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC7C,EAAE,SAAS,kBAAkB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5E,CAAC,GAAG,SAAS;;gBAMD,UAAU,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAE,QAAiB;IAMnE;;;;;;;;;;OAUG;IACH,OAAO,CACL,QAAQ,EAAE,EAAE,EACZ,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,YAAY,CAAC;IAExB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;CAqD/D"}
|
|
@@ -3,7 +3,7 @@ import { assert } from "../../shared/src/asserts.js";
|
|
|
3
3
|
import { must } from "../../shared/src/must.js";
|
|
4
4
|
import { getValueAtPath } from "../../shared/src/object-traversal.js";
|
|
5
5
|
import "../../zero-protocol/src/push.js";
|
|
6
|
-
import {
|
|
6
|
+
import { handleMutateRequest } from "./process-mutations.js";
|
|
7
7
|
import { isMutator } from "../../zql/src/mutate/mutator.js";
|
|
8
8
|
class PushProcessor {
|
|
9
9
|
#dbProvider;
|
|
@@ -16,33 +16,35 @@ class PushProcessor {
|
|
|
16
16
|
}
|
|
17
17
|
process(mutators, queryOrQueryString, body) {
|
|
18
18
|
if (queryOrQueryString instanceof Request) {
|
|
19
|
-
return
|
|
19
|
+
return handleMutateRequest(
|
|
20
20
|
this.#dbProvider,
|
|
21
21
|
(transact, mutation) => this.#processMutation(mutators, transact, mutation),
|
|
22
22
|
queryOrQueryString,
|
|
23
|
-
this.#context,
|
|
24
23
|
this.#logLevel
|
|
25
24
|
);
|
|
26
25
|
}
|
|
27
|
-
return
|
|
26
|
+
return handleMutateRequest(
|
|
28
27
|
this.#dbProvider,
|
|
29
28
|
(transact, mutation) => this.#processMutation(mutators, transact, mutation),
|
|
30
29
|
queryOrQueryString,
|
|
31
30
|
must(body),
|
|
32
|
-
this.#context,
|
|
33
31
|
this.#logLevel
|
|
34
32
|
);
|
|
35
33
|
}
|
|
36
34
|
#processMutation(mutators, transact, _mutation) {
|
|
37
35
|
return transact(
|
|
38
|
-
(tx, name, args
|
|
36
|
+
(tx, name, args) => this.#dispatchMutation(mutators, tx, name, args)
|
|
39
37
|
);
|
|
40
38
|
}
|
|
41
|
-
#dispatchMutation(mutators, dbTx, key, args
|
|
39
|
+
#dispatchMutation(mutators, dbTx, key, args) {
|
|
42
40
|
const mutator = getValueAtPath(mutators, key, /\.|\|/);
|
|
43
41
|
assert(typeof mutator === "function", `could not find mutator ${key}`);
|
|
44
42
|
if (isMutator(mutator)) {
|
|
45
|
-
return mutator.fn({
|
|
43
|
+
return mutator.fn({
|
|
44
|
+
args,
|
|
45
|
+
ctx: this.#context,
|
|
46
|
+
tx: dbTx
|
|
47
|
+
});
|
|
46
48
|
}
|
|
47
49
|
return mutator(dbTx, args);
|
|
48
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-processor.js","sources":["../../../../zero-server/src/push-processor.ts"],"sourcesContent":["import {type LogLevel} from '@rocicorp/logger';\nimport {assert} from '../../shared/src/asserts.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport {getValueAtPath} from '../../shared/src/object-traversal.ts';\nimport {\n type CustomMutation,\n type MutationResponse,\n type PushResponse,\n} from '../../zero-protocol/src/push.ts';\nimport {\n type Database,\n type ExtractTransactionType,\n
|
|
1
|
+
{"version":3,"file":"push-processor.js","sources":["../../../../zero-server/src/push-processor.ts"],"sourcesContent":["import {type LogLevel} from '@rocicorp/logger';\nimport {assert} from '../../shared/src/asserts.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport {getValueAtPath} from '../../shared/src/object-traversal.ts';\nimport {\n type CustomMutation,\n type MutationResponse,\n type PushResponse,\n} from '../../zero-protocol/src/push.ts';\nimport {\n type Database,\n type ExtractTransactionType,\n handleMutateRequest,\n type TransactFn,\n} from '../../zero-server/src/process-mutations.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {Transaction} from '../../zql/src/mutate/custom.ts';\nimport type {AnyMutatorRegistry} from '../../zql/src/mutate/mutator-registry.ts';\nimport {isMutator} from '../../zql/src/mutate/mutator.ts';\nimport type {CustomMutatorDefs} from './custom.ts';\n\nexport class PushProcessor<\n _S extends Schema,\n D extends Database<ExtractTransactionType<D>>,\n MD extends AnyMutatorRegistry | CustomMutatorDefs<ExtractTransactionType<D>>,\n C = undefined,\n> {\n readonly #dbProvider: D;\n readonly #logLevel: LogLevel;\n readonly #context: C;\n\n constructor(dbProvider: D, context?: C, logLevel: LogLevel = 'info') {\n this.#dbProvider = dbProvider;\n this.#context = context as C;\n this.#logLevel = logLevel;\n }\n\n /**\n * Processes a push request from zero-cache.\n * This function will parse the request, check the protocol version, and process each mutation in the request.\n * - If a mutation is out of order: processing will stop and an error will be returned. The zero client will retry the mutation.\n * - If a mutation has already been processed: it will be skipped and the processing will continue.\n * - If a mutation receives an application error: it will be skipped, the error will be returned to the client, and processing will continue.\n *\n * @param mutators the custom mutators for the application\n * @param queryString the query string from the request sent by zero-cache. This will include zero's postgres schema name and appID.\n * @param body the body of the request sent by zero-cache as a JSON object.\n */\n process(\n mutators: MD,\n queryString: URLSearchParams | Record<string, string>,\n body: ReadonlyJSONValue,\n ): Promise<PushResponse>;\n\n /**\n * This override gets the query string and the body from a Request object.\n *\n * @param mutators the custom mutators for the application\n * @param request A `Request` object.\n */\n process(mutators: MD, request: Request): Promise<PushResponse>;\n process(\n mutators: MD,\n queryOrQueryString: Request | URLSearchParams | Record<string, string>,\n body?: ReadonlyJSONValue,\n ): Promise<PushResponse> {\n if (queryOrQueryString instanceof Request) {\n return handleMutateRequest(\n this.#dbProvider,\n (transact, mutation) =>\n this.#processMutation(mutators, transact, mutation),\n queryOrQueryString,\n this.#logLevel,\n );\n }\n return handleMutateRequest(\n this.#dbProvider,\n (transact, mutation) =>\n this.#processMutation(mutators, transact, mutation),\n queryOrQueryString,\n must(body),\n this.#logLevel,\n );\n }\n\n #processMutation(\n mutators: MD,\n transact: TransactFn<D>,\n _mutation: CustomMutation,\n ): Promise<MutationResponse> {\n return transact((tx, name, args) =>\n this.#dispatchMutation(mutators, tx, name, args),\n );\n }\n\n #dispatchMutation(\n mutators: MD,\n dbTx: ExtractTransactionType<D>,\n key: string,\n args: ReadonlyJSONValue | undefined,\n ): Promise<void> {\n // Legacy mutators used | as a separator, new mutators use .\n const mutator = getValueAtPath(mutators, key, /\\.|\\|/);\n assert(typeof mutator === 'function', `could not find mutator ${key}`);\n if (isMutator(mutator)) {\n return mutator.fn({\n args,\n ctx: this.#context,\n tx: dbTx as Transaction<Schema, unknown>,\n });\n }\n return mutator(dbTx, args);\n }\n}\n"],"names":[],"mappings":";;;;;;;AAsBO,MAAM,cAKX;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,YAAe,SAAa,WAAqB,QAAQ;AACnE,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,YAAY;AAAA,EACnB;AAAA,EA0BA,QACE,UACA,oBACA,MACuB;AACvB,QAAI,8BAA8B,SAAS;AACzC,aAAO;AAAA,QACL,KAAK;AAAA,QACL,CAAC,UAAU,aACT,KAAK,iBAAiB,UAAU,UAAU,QAAQ;AAAA,QACpD;AAAA,QACA,KAAK;AAAA,MAAA;AAAA,IAET;AACA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,CAAC,UAAU,aACT,KAAK,iBAAiB,UAAU,UAAU,QAAQ;AAAA,MACpD;AAAA,MACA,KAAK,IAAI;AAAA,MACT,KAAK;AAAA,IAAA;AAAA,EAET;AAAA,EAEA,iBACE,UACA,UACA,WAC2B;AAC3B,WAAO;AAAA,MAAS,CAAC,IAAI,MAAM,SACzB,KAAK,kBAAkB,UAAU,IAAI,MAAM,IAAI;AAAA,IAAA;AAAA,EAEnD;AAAA,EAEA,kBACE,UACA,MACA,KACA,MACe;AAEf,UAAM,UAAU,eAAe,UAAU,KAAK,OAAO;AACrD,WAAO,OAAO,YAAY,YAAY,0BAA0B,GAAG,EAAE;AACrE,QAAI,UAAU,OAAO,GAAG;AACtB,aAAO,QAAQ,GAAG;AAAA,QAChB;AAAA,QACA,KAAK,KAAK;AAAA,QACV,IAAI;AAAA,MAAA,CACL;AAAA,IACH;AACA,WAAO,QAAQ,MAAM,IAAI;AAAA,EAC3B;AACF;"}
|
|
@@ -11,11 +11,23 @@ import type { AnyQuery } from '../../../zql/src/query/query.ts';
|
|
|
11
11
|
* This function will call `cb` in parallel for each query found in the request.
|
|
12
12
|
*
|
|
13
13
|
* If you need to limit concurrency, you can use a library like `p-limit` to wrap the `cb` function.
|
|
14
|
-
* @deprecated Use {@linkcode
|
|
14
|
+
* @deprecated Use {@linkcode handleQueryRequest} instead.
|
|
15
15
|
*/
|
|
16
16
|
export declare function handleGetQueriesRequest<S extends Schema>(cb: (name: string, args: readonly ReadonlyJSONValue[]) => MaybePromise<{
|
|
17
17
|
query: AnyQuery;
|
|
18
18
|
} | AnyQuery>, schema: S, requestOrJsonBody: Request | ReadonlyJSONValue, logLevel?: LogLevel): Promise<TransformResponseMessage>;
|
|
19
|
+
/**
|
|
20
|
+
* Invokes the callback `cb` for each query in the request or JSON body.
|
|
21
|
+
* The callback should return a Query or Promise<Query> that is the transformed result.
|
|
22
|
+
*
|
|
23
|
+
* This function will call `cb` in parallel for each query found in the request.
|
|
24
|
+
*
|
|
25
|
+
* If you need to limit concurrency, you can use a library like `p-limit` to wrap the `cb` function.
|
|
26
|
+
* @deprecated Use {@linkcode handleQueryRequest} instead.
|
|
27
|
+
*/
|
|
28
|
+
export declare function handleTransformRequest<S extends Schema>(cb: (name: string, args: readonly ReadonlyJSONValue[]) => MaybePromise<{
|
|
29
|
+
query: AnyQuery;
|
|
30
|
+
} | AnyQuery>, schema: S, requestOrJsonBody: Request | ReadonlyJSONValue, logLevel?: LogLevel): Promise<TransformResponseMessage>;
|
|
19
31
|
/**
|
|
20
32
|
* Processes a transform request by invoking the provided callback for each query.
|
|
21
33
|
* The callback should return a Query that is the transformed result.
|
|
@@ -28,7 +40,7 @@ export declare function handleGetQueriesRequest<S extends Schema>(cb: (name: str
|
|
|
28
40
|
* @param logLevel - Logging level (defaults to 'info')
|
|
29
41
|
* @returns A Promise that resolves to a TransformResponseMessage
|
|
30
42
|
*/
|
|
31
|
-
export declare function
|
|
43
|
+
export declare function handleQueryRequest<S extends Schema>(transformQuery: TransformQueryFunction, schema: S, requestOrJsonBody: Request | ReadonlyJSONValue, logLevel?: LogLevel): Promise<["transformed", ({
|
|
32
44
|
message?: string | undefined;
|
|
33
45
|
details?: ReadonlyJSONValue | undefined;
|
|
34
46
|
error: "app";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-queries.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/queries/process-queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"process-queries.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/queries/process-queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,8CAA8C,CAAC;AAKtD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAG9D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,iCAAiC,CAAC;AAG9D;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EACtD,EAAE,EAAE,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,iBAAiB,EAAE,KAC/B,YAAY,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAC,GAAG,QAAQ,CAAC,EAC/C,MAAM,EAAE,CAAC,EACT,iBAAiB,EAAE,OAAO,GAAG,iBAAiB,EAC9C,QAAQ,GAAE,QAAiB,GAC1B,OAAO,CAAC,wBAAwB,CAAC,CAEnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EACrD,EAAE,EAAE,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,iBAAiB,EAAE,KAC/B,YAAY,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAC,GAAG,QAAQ,CAAC,EAC/C,MAAM,EAAE,CAAC,EACT,iBAAiB,EAAE,OAAO,GAAG,iBAAiB,EAC9C,QAAQ,GAAE,QAAiB,GAC1B,OAAO,CAAC,wBAAwB,CAAC,CAEnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,cAAc,EAAE,sBAAsB,EACtC,MAAM,EAAE,CAAC,EACT,iBAAiB,EAAE,OAAO,GAAG,iBAAiB,EAC9C,QAAQ,GAAE,QAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAS5B;AAsGD;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,iBAAiB,GAAG,SAAS,KAChC,QAAQ,CAAC"}
|
|
@@ -10,10 +10,22 @@ import { QueryParseError } from "../../../zql/src/query/error.js";
|
|
|
10
10
|
import { asQueryInternals } from "../../../zql/src/query/query-internals.js";
|
|
11
11
|
import { createLogContext } from "../logging.js";
|
|
12
12
|
function handleGetQueriesRequest(cb, schema, requestOrJsonBody, logLevel = "info") {
|
|
13
|
-
|
|
14
|
-
return transform(cb, schema, requestOrJsonBody, lc, "get");
|
|
13
|
+
return transform(cb, schema, requestOrJsonBody, "getQueries", logLevel);
|
|
15
14
|
}
|
|
16
|
-
|
|
15
|
+
function handleTransformRequest(cb, schema, requestOrJsonBody, logLevel = "info") {
|
|
16
|
+
return transform(cb, schema, requestOrJsonBody, "transform", logLevel);
|
|
17
|
+
}
|
|
18
|
+
function handleQueryRequest(transformQuery, schema, requestOrJsonBody, logLevel = "info") {
|
|
19
|
+
return transform(
|
|
20
|
+
(name, argsArray) => transformQuery(name, argsArray[0]),
|
|
21
|
+
schema,
|
|
22
|
+
requestOrJsonBody,
|
|
23
|
+
"query",
|
|
24
|
+
logLevel
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
async function transform(cb, schema, requestOrJsonBody, apiName, logLevel = "info") {
|
|
28
|
+
const lc = createLogContext(logLevel).withContext("TransformRequest");
|
|
17
29
|
let parsed;
|
|
18
30
|
let queryIDs = [];
|
|
19
31
|
try {
|
|
@@ -26,8 +38,8 @@ async function transform(cb, schema, requestOrJsonBody, lc, apiName) {
|
|
|
26
38
|
parsed = parse(body, transformRequestMessageSchema);
|
|
27
39
|
queryIDs = parsed[1].map((r) => r.id);
|
|
28
40
|
} catch (error) {
|
|
29
|
-
lc.error?.(`Failed to parse ${apiName}
|
|
30
|
-
const message = `Failed to parse ${apiName}
|
|
41
|
+
lc.error?.(`Failed to parse ${apiName} request`, error);
|
|
42
|
+
const message = `Failed to parse ${apiName} request: ${getErrorMessage(error)}`;
|
|
31
43
|
const details = getErrorDetails(error);
|
|
32
44
|
return [
|
|
33
45
|
"transformFailed",
|
|
@@ -91,18 +103,9 @@ async function transform(cb, schema, requestOrJsonBody, lc, apiName) {
|
|
|
91
103
|
];
|
|
92
104
|
}
|
|
93
105
|
}
|
|
94
|
-
function handleTransformRequest(transformQuery, schema, requestOrJsonBody, logLevel = "info") {
|
|
95
|
-
const lc = createLogContext(logLevel).withContext("TransformRequest");
|
|
96
|
-
return transform(
|
|
97
|
-
(name, argsArray) => transformQuery(name, argsArray[0]),
|
|
98
|
-
schema,
|
|
99
|
-
requestOrJsonBody,
|
|
100
|
-
lc,
|
|
101
|
-
"transform"
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
106
|
export {
|
|
105
107
|
handleGetQueriesRequest,
|
|
108
|
+
handleQueryRequest,
|
|
106
109
|
handleTransformRequest
|
|
107
110
|
};
|
|
108
111
|
//# sourceMappingURL=process-queries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-queries.js","sources":["../../../../../zero-server/src/queries/process-queries.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"process-queries.js","sources":["../../../../../zero-server/src/queries/process-queries.ts"],"sourcesContent":["import type {LogLevel} from '@rocicorp/logger';\nimport {getErrorDetails, getErrorMessage} from '../../../shared/src/error.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport type {MaybePromise} from '../../../shared/src/types.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport {mapAST} from '../../../zero-protocol/src/ast.ts';\nimport {\n transformRequestMessageSchema,\n type TransformRequestMessage,\n type TransformResponseBody,\n type TransformResponseMessage,\n} from '../../../zero-protocol/src/custom-queries.ts';\nimport {ErrorKind} from '../../../zero-protocol/src/error-kind.ts';\nimport {ErrorOrigin} from '../../../zero-protocol/src/error-origin.ts';\nimport {ErrorReason} from '../../../zero-protocol/src/error-reason.ts';\nimport {clientToServer} from '../../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {QueryParseError} from '../../../zql/src/query/error.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {AnyQuery} from '../../../zql/src/query/query.ts';\nimport {createLogContext} from '../logging.ts';\n\n/**\n * Invokes the callback `cb` for each query in the request or JSON body.\n * The callback should return a Query or Promise<Query> that is the transformed result.\n *\n * This function will call `cb` in parallel for each query found in the request.\n *\n * If you need to limit concurrency, you can use a library like `p-limit` to wrap the `cb` function.\n * @deprecated Use {@linkcode handleQueryRequest} instead.\n */\nexport function handleGetQueriesRequest<S extends Schema>(\n cb: (\n name: string,\n args: readonly ReadonlyJSONValue[],\n ) => MaybePromise<{query: AnyQuery} | AnyQuery>,\n schema: S,\n requestOrJsonBody: Request | ReadonlyJSONValue,\n logLevel: LogLevel = 'info',\n): Promise<TransformResponseMessage> {\n return transform(cb, schema, requestOrJsonBody, 'getQueries', logLevel);\n}\n\n/**\n * Invokes the callback `cb` for each query in the request or JSON body.\n * The callback should return a Query or Promise<Query> that is the transformed result.\n *\n * This function will call `cb` in parallel for each query found in the request.\n *\n * If you need to limit concurrency, you can use a library like `p-limit` to wrap the `cb` function.\n * @deprecated Use {@linkcode handleQueryRequest} instead.\n */\nexport function handleTransformRequest<S extends Schema>(\n cb: (\n name: string,\n args: readonly ReadonlyJSONValue[],\n ) => MaybePromise<{query: AnyQuery} | AnyQuery>,\n schema: S,\n requestOrJsonBody: Request | ReadonlyJSONValue,\n logLevel: LogLevel = 'info',\n): Promise<TransformResponseMessage> {\n return transform(cb, schema, requestOrJsonBody, 'transform', logLevel);\n}\n\n/**\n * Processes a transform request by invoking the provided callback for each query.\n * The callback should return a Query that is the transformed result.\n *\n * This function will call `transformQuery` in parallel for each query found in the request.\n *\n * @param transformQuery - Callback function that takes a query name and args, and returns a Query\n * @param schema - The Zero schema\n * @param requestOrJsonBody - Either a Request object or the JSON body directly\n * @param logLevel - Logging level (defaults to 'info')\n * @returns A Promise that resolves to a TransformResponseMessage\n */\nexport function handleQueryRequest<S extends Schema>(\n transformQuery: TransformQueryFunction,\n schema: S,\n requestOrJsonBody: Request | ReadonlyJSONValue,\n logLevel: LogLevel = 'info',\n) {\n return transform(\n (name, argsArray) => transformQuery(name, argsArray[0]),\n schema,\n requestOrJsonBody,\n 'query',\n logLevel,\n );\n}\n\nasync function transform<S extends Schema>(\n cb: (\n name: string,\n args: readonly ReadonlyJSONValue[],\n ) => MaybePromise<{query: AnyQuery} | AnyQuery>,\n schema: S,\n requestOrJsonBody: Request | ReadonlyJSONValue,\n apiName: 'query' | 'getQueries' | 'transform',\n logLevel: LogLevel = 'info',\n): Promise<TransformResponseMessage> {\n const lc = createLogContext(logLevel).withContext('TransformRequest');\n let parsed: TransformRequestMessage;\n let queryIDs: string[] = [];\n try {\n let body: ReadonlyJSONValue;\n if (requestOrJsonBody instanceof Request) {\n body = await requestOrJsonBody.json();\n } else {\n body = requestOrJsonBody;\n }\n\n parsed = v.parse(body, transformRequestMessageSchema);\n\n queryIDs = parsed[1].map(r => r.id);\n } catch (error) {\n lc.error?.(`Failed to parse ${apiName} request`, error);\n\n const message = `Failed to parse ${apiName} request: ${getErrorMessage(error)}`;\n const details = getErrorDetails(error);\n\n return [\n 'transformFailed',\n {\n kind: ErrorKind.TransformFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Parse,\n message,\n queryIDs,\n ...(details ? {details} : {}),\n },\n ];\n }\n\n try {\n const nameMapper = clientToServer(schema.tables);\n\n const responses: TransformResponseBody = await Promise.all(\n parsed[1].map(async req => {\n let finalQuery: AnyQuery;\n try {\n const result = await cb(req.name, req.args);\n finalQuery = 'query' in result ? result.query : result;\n } catch (error) {\n const message = getErrorMessage(error);\n const details = getErrorDetails(error);\n\n return {\n error: error instanceof QueryParseError ? 'parse' : 'app',\n id: req.id,\n name: req.name,\n message,\n ...(details ? {details} : {}),\n };\n }\n\n try {\n const q = asQueryInternals(finalQuery);\n const ast = mapAST(q.ast, nameMapper);\n\n return {\n id: req.id,\n name: req.name,\n ast,\n };\n } catch (error) {\n lc.error?.('Failed to map AST', error);\n throw error;\n }\n }),\n );\n\n return ['transformed', responses];\n } catch (e) {\n const message = getErrorMessage(e);\n const details = getErrorDetails(e);\n\n return [\n 'transformFailed',\n {\n kind: ErrorKind.TransformFailed,\n origin: ErrorOrigin.Server,\n reason: ErrorReason.Internal,\n message,\n queryIDs,\n ...(details ? {details} : {}),\n },\n ];\n }\n}\n\n/**\n * A function that transforms a query by name and arguments into a Query object.\n *\n * @param name - The name of the query (can be dot-separated for nested queries)\n * @param args - The arguments to pass to the query (can be undefined)\n * @returns A Query object\n */\nexport type TransformQueryFunction = (\n name: string,\n args: ReadonlyJSONValue | undefined,\n) => AnyQuery;\n"],"names":["v.parse","ErrorKind.TransformFailed","ErrorOrigin.Server","ErrorReason.Parse","ErrorReason.Internal"],"mappings":";;;;;;;;;;;AA+BO,SAAS,wBACd,IAIA,QACA,mBACA,WAAqB,QACc;AACnC,SAAO,UAAU,IAAI,QAAQ,mBAAmB,cAAc,QAAQ;AACxE;AAWO,SAAS,uBACd,IAIA,QACA,mBACA,WAAqB,QACc;AACnC,SAAO,UAAU,IAAI,QAAQ,mBAAmB,aAAa,QAAQ;AACvE;AAcO,SAAS,mBACd,gBACA,QACA,mBACA,WAAqB,QACrB;AACA,SAAO;AAAA,IACL,CAAC,MAAM,cAAc,eAAe,MAAM,UAAU,CAAC,CAAC;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,eAAe,UACb,IAIA,QACA,mBACA,SACA,WAAqB,QACc;AACnC,QAAM,KAAK,iBAAiB,QAAQ,EAAE,YAAY,kBAAkB;AACpE,MAAI;AACJ,MAAI,WAAqB,CAAA;AACzB,MAAI;AACF,QAAI;AACJ,QAAI,6BAA6B,SAAS;AACxC,aAAO,MAAM,kBAAkB,KAAA;AAAA,IACjC,OAAO;AACL,aAAO;AAAA,IACT;AAEA,aAASA,MAAQ,MAAM,6BAA6B;AAEpD,eAAW,OAAO,CAAC,EAAE,IAAI,CAAA,MAAK,EAAE,EAAE;AAAA,EACpC,SAAS,OAAO;AACd,OAAG,QAAQ,mBAAmB,OAAO,YAAY,KAAK;AAEtD,UAAM,UAAU,mBAAmB,OAAO,aAAa,gBAAgB,KAAK,CAAC;AAC7E,UAAM,UAAU,gBAAgB,KAAK;AAErC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,MAAMC;AAAAA,QACN,QAAQC;AAAAA,QACR,QAAQC;AAAAA,QACR;AAAA,QACA;AAAA,QACA,GAAI,UAAU,EAAC,YAAW,CAAA;AAAA,MAAC;AAAA,IAC7B;AAAA,EAEJ;AAEA,MAAI;AACF,UAAM,aAAa,eAAe,OAAO,MAAM;AAE/C,UAAM,YAAmC,MAAM,QAAQ;AAAA,MACrD,OAAO,CAAC,EAAE,IAAI,OAAM,QAAO;AACzB,YAAI;AACJ,YAAI;AACF,gBAAM,SAAS,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI;AAC1C,uBAAa,WAAW,SAAS,OAAO,QAAQ;AAAA,QAClD,SAAS,OAAO;AACd,gBAAM,UAAU,gBAAgB,KAAK;AACrC,gBAAM,UAAU,gBAAgB,KAAK;AAErC,iBAAO;AAAA,YACL,OAAO,iBAAiB,kBAAkB,UAAU;AAAA,YACpD,IAAI,IAAI;AAAA,YACR,MAAM,IAAI;AAAA,YACV;AAAA,YACA,GAAI,UAAU,EAAC,YAAW,CAAA;AAAA,UAAC;AAAA,QAE/B;AAEA,YAAI;AACF,gBAAM,IAAI,iBAAiB,UAAU;AACrC,gBAAM,MAAM,OAAO,EAAE,KAAK,UAAU;AAEpC,iBAAO;AAAA,YACL,IAAI,IAAI;AAAA,YACR,MAAM,IAAI;AAAA,YACV;AAAA,UAAA;AAAA,QAEJ,SAAS,OAAO;AACd,aAAG,QAAQ,qBAAqB,KAAK;AACrC,gBAAM;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IAAA;AAGH,WAAO,CAAC,eAAe,SAAS;AAAA,EAClC,SAAS,GAAG;AACV,UAAM,UAAU,gBAAgB,CAAC;AACjC,UAAM,UAAU,gBAAgB,CAAC;AAEjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,MAAMF;AAAAA,QACN,QAAQC;AAAAA,QACR,QAAQE;AAAAA,QACR;AAAA,QACA;AAAA,QACA,GAAI,UAAU,EAAC,YAAW,CAAA;AAAA,MAAC;AAAA,IAC7B;AAAA,EAEJ;AACF;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../../zql/src/builder/builder.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../../zql/src/builder/builder.ts"],"names":[],"mappings":"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"}
|