@m5kdev/backend 0.8.11 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/modules/auth/auth.lib.d.cts +1 -1
- package/dist/src/modules/auth/auth.lib.d.mts +1 -1
- package/dist/src/modules/base/base.procedure.cjs +30 -0
- package/dist/src/modules/base/base.procedure.cjs.map +1 -1
- package/dist/src/modules/base/base.procedure.d.cts +14 -1
- package/dist/src/modules/base/base.procedure.d.mts +14 -1
- package/dist/src/modules/base/base.procedure.mjs +30 -0
- package/dist/src/modules/base/base.procedure.mjs.map +1 -1
- package/dist/src/modules/base/base.service.cjs.map +1 -1
- package/dist/src/modules/base/base.service.d.cts +2 -2
- package/dist/src/modules/base/base.service.d.mts +2 -2
- package/dist/src/modules/base/base.service.mjs.map +1 -1
- package/dist/src/modules/billing/billing.router.cjs +1 -1
- package/dist/src/modules/billing/billing.router.mjs +1 -1
- package/dist/src/modules/connect/connect.dto.d.cts +2 -2
- package/dist/src/modules/connect/connect.dto.d.mts +2 -2
- package/dist/src/modules/connect/connect.repository.d.cts +1 -1
- package/dist/src/modules/connect/connect.repository.d.mts +1 -1
- package/dist/src/modules/connect/connect.service.d.cts +2 -2
- package/dist/src/modules/connect/connect.service.d.mts +2 -2
- package/dist/src/modules/connect/connect.trpc.d.cts +1 -1
- package/dist/src/modules/connect/connect.trpc.d.mts +1 -1
- package/dist/src/modules/docx/docx.service.cjs +21 -0
- package/dist/src/modules/docx/docx.service.cjs.map +1 -0
- package/dist/src/modules/docx/docx.service.d.cts +10 -0
- package/dist/src/modules/docx/docx.service.d.mts +10 -0
- package/dist/src/modules/docx/docx.service.mjs +17 -0
- package/dist/src/modules/docx/docx.service.mjs.map +1 -0
- package/dist/src/modules/file/file.router.cjs +2 -2
- package/dist/src/modules/file/file.router.mjs +1 -1
- package/dist/src/modules/recurrence/recurrence.service.d.cts +2 -2
- package/dist/src/modules/recurrence/recurrence.service.d.mts +2 -2
- package/dist/src/modules/recurrence/recurrence.trpc.d.cts +3 -3
- package/dist/src/modules/recurrence/recurrence.trpc.d.mts +3 -3
- package/dist/src/modules/tag/tag.trpc.d.cts +2 -2
- package/dist/src/modules/tag/tag.trpc.d.mts +2 -2
- package/dist/src/modules/webhook/webhook.router.cjs +1 -1
- package/dist/src/modules/webhook/webhook.router.mjs +1 -1
- package/package.json +8 -5
|
@@ -4830,7 +4830,7 @@ declare function createBetterAuth<O extends Orm, S extends Schema, E extends Ema
|
|
|
4830
4830
|
} | undefined;
|
|
4831
4831
|
verification?: {
|
|
4832
4832
|
modelName?: string;
|
|
4833
|
-
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "
|
|
4833
|
+
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "value" | "identifier", string>>;
|
|
4834
4834
|
additionalFields?: {
|
|
4835
4835
|
[key: string]: _$better_auth0.DBFieldAttribute;
|
|
4836
4836
|
};
|
|
@@ -4830,7 +4830,7 @@ declare function createBetterAuth<O extends Orm, S extends Schema, E extends Ema
|
|
|
4830
4830
|
} | undefined;
|
|
4831
4831
|
verification?: {
|
|
4832
4832
|
modelName?: string;
|
|
4833
|
-
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "
|
|
4833
|
+
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "value" | "identifier", string>>;
|
|
4834
4834
|
additionalFields?: {
|
|
4835
4835
|
[key: string]: _$better_auth0.DBFieldAttribute;
|
|
4836
4836
|
};
|
|
@@ -58,6 +58,20 @@ function createUseStep(stepName, step) {
|
|
|
58
58
|
run: async (args) => normalizeProcedureResult(step(args))
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
+
const DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE = "Resource not found";
|
|
62
|
+
function createLoadResourceStep(host, stepName, step, notFoundMessage) {
|
|
63
|
+
return {
|
|
64
|
+
stage: "use",
|
|
65
|
+
stepName,
|
|
66
|
+
run: async (args) => {
|
|
67
|
+
const normalized = await normalizeProcedureResult(step(args));
|
|
68
|
+
if (normalized.isErr()) return normalized;
|
|
69
|
+
const value = normalized.value;
|
|
70
|
+
if (!value) return host.error("NOT_FOUND", notFoundMessage);
|
|
71
|
+
return (0, neverthrow.ok)(value);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
61
75
|
function createInputStep(stepName, step) {
|
|
62
76
|
return {
|
|
63
77
|
stage: "input",
|
|
@@ -183,6 +197,14 @@ function createServiceProcedureBuilder(host, config) {
|
|
|
183
197
|
steps: [...config.steps, createUseStep(stepName, step)]
|
|
184
198
|
});
|
|
185
199
|
},
|
|
200
|
+
loadResource(stepName, step, options) {
|
|
201
|
+
assertUniqueStepName(config.steps, stepName);
|
|
202
|
+
const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;
|
|
203
|
+
return createServiceProcedureBuilder(host, {
|
|
204
|
+
...config,
|
|
205
|
+
steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)]
|
|
206
|
+
});
|
|
207
|
+
},
|
|
186
208
|
mapInput(stepName, step) {
|
|
187
209
|
assertUniqueStepName(config.steps, stepName);
|
|
188
210
|
return createServiceProcedureBuilder(host, {
|
|
@@ -227,6 +249,14 @@ function createPermissionServiceProcedureBuilder(host, config) {
|
|
|
227
249
|
steps: [...config.steps, createUseStep(stepName, step)]
|
|
228
250
|
});
|
|
229
251
|
},
|
|
252
|
+
loadResource(stepName, step, options) {
|
|
253
|
+
assertUniqueStepName(config.steps, stepName);
|
|
254
|
+
const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;
|
|
255
|
+
return createPermissionServiceProcedureBuilder(host, {
|
|
256
|
+
...config,
|
|
257
|
+
steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)]
|
|
258
|
+
});
|
|
259
|
+
},
|
|
230
260
|
mapInput(stepName, step) {
|
|
231
261
|
assertUniqueStepName(config.steps, stepName);
|
|
232
262
|
return createPermissionServiceProcedureBuilder(host, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.procedure.cjs","names":["validateActor"],"sources":["../../../../src/modules/base/base.procedure.ts"],"sourcesContent":["import type { QueryInput } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { TRPC_ERROR_CODE_KEY } from \"@trpc/server\";\r\nimport { ok } from \"neverthrow\";\r\nimport type { ServerError } from \"../../utils/errors\";\r\nimport type { logger } from \"../../utils/logger\";\r\nimport type { Base } from \"./base.abstract\";\r\nimport { type Actor, type ActorScope, type AuthenticatedActor, validateActor } from \"./base.actor\";\r\nimport type { ServerResult, ServerResultAsync } from \"./base.dto\";\r\nimport type { Entity, ResourceActionGrant } from \"./base.grants\";\r\n\r\ntype ServiceLogger = ReturnType<typeof logger.child>;\r\ntype RepositoryMap = Record<string, Base>;\r\ntype ServiceMap = Record<string, Base>;\r\n\r\nexport type ServiceProcedureContext = {\r\n actor?: AuthenticatedActor | null;\r\n} & Record<string, unknown>;\r\n\r\nexport type ServiceProcedureState = Record<string, unknown>;\r\nexport type ServiceProcedureStoredValue<T> = [T] extends [undefined] ? undefined : Awaited<T>;\r\nexport type ServiceProcedureResultLike<T> = T | ServerResult<T> | Promise<T | ServerResult<T>>;\r\nexport type ServiceProcedureContextFilterScope = ActorScope;\r\nexport type ServiceProcedureContextFilteredInput<TInput> = Extract<NonNullable<TInput>, QueryInput>;\r\ntype ServiceProcedureAuthContext<Scope extends ActorScope> = {\r\n actor: Actor[Scope];\r\n};\r\ntype ServiceProcedureRequiredScopeFromFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined,\r\n> = TInclude extends readonly ServiceProcedureContextFilterScope[]\r\n ? \"team\" extends TInclude[number]\r\n ? \"team\"\r\n : \"organization\" extends TInclude[number]\r\n ? \"organization\"\r\n : \"user\"\r\n : \"user\";\r\n\r\nexport type ServiceProcedure<TInput, TCtx extends ServiceProcedureContext, TOutput> = (\r\n input: TInput,\r\n ctx: TCtx\r\n) => ServerResultAsync<TOutput>;\r\n\r\nexport type ServiceProcedureArgs<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n> = {\r\n input: TInput;\r\n ctx: TCtx;\r\n state: State;\r\n repository: Repositories;\r\n service: Services;\r\n logger: ServiceLogger;\r\n};\r\n\r\nexport type ServiceProcedureStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput = undefined,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<ServiceProcedureStoredValue<TOutput>>;\r\n\r\nexport type ServiceProcedureInputMapper<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TNextInput,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<ServiceProcedureStoredValue<TNextInput>>;\r\n\r\nexport type ServiceProcedureHandler<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<TOutput>;\r\n\r\nexport type ServiceProcedureEntityResolver<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined,\r\n> =\r\n | TEntities\r\n | ((\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n ) => ServiceProcedureResultLike<TEntities>);\r\n\r\ntype ServiceProcedureAccessBaseConfig = {\r\n action: string;\r\n grants?: ResourceActionGrant[];\r\n};\r\n\r\nexport type ServiceProcedureEntityStepName<State extends ServiceProcedureState> = Extract<\r\n {\r\n [Key in keyof State]: State[Key] extends Entity | Entity[] | undefined ? Key : never;\r\n }[keyof State],\r\n string\r\n>;\r\n\r\nexport type ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined = undefined,\r\n> = ServiceProcedureAccessBaseConfig & {\r\n entities?: ServiceProcedureEntityResolver<TInput, TCtx, Repositories, Services, State, TEntities>;\r\n entityStep?: never;\r\n};\r\n\r\nexport type ServiceProcedureAccessStateConfig<\r\n State extends ServiceProcedureState,\r\n StepName extends ServiceProcedureEntityStepName<State>,\r\n> = ServiceProcedureAccessBaseConfig & {\r\n entityStep: StepName;\r\n entities?: never;\r\n};\r\n\r\nexport type ServiceProcedureAccessConfig<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined = undefined,\r\n> =\r\n | ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State, TEntities>\r\n | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>;\r\n\r\nexport interface ServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n> {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): ServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >;\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ): ServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >;\r\n addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(\r\n include?: TInclude\r\n ): ServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >;\r\n requireAuth<Scope extends ActorScope = \"user\">(\r\n scope?: Scope\r\n ): ServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): ServiceProcedure<TInput, TCtx, TOutput>;\r\n}\r\n\r\nexport interface PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n> extends ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >;\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ): PermissionServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >;\r\n addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(\r\n include?: TInclude\r\n ): PermissionServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >;\r\n requireAuth<Scope extends ActorScope = \"user\">(\r\n scope?: Scope\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n access(\r\n config: ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n access<TEntities extends Entity | Entity[] | undefined>(\r\n config: ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n TEntities\r\n >\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: TEntities }\r\n >;\r\n access<StepName extends ServiceProcedureEntityStepName<State>>(\r\n config: ServiceProcedureAccessStateConfig<State, StepName>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: State[StepName] }\r\n >;\r\n}\r\n\r\ntype BaseServiceProcedureHost<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n repository: Repositories;\r\n service: Services;\r\n logger: ServiceLogger;\r\n addContextFilter(\r\n actor: AuthenticatedActor,\r\n include?: { user?: boolean; organization?: boolean; team?: boolean },\r\n query?: QueryInput\r\n ): QueryInput;\r\n error(\r\n code: TRPC_ERROR_CODE_KEY,\r\n message?: string,\r\n options?: { cause?: unknown; clientMessage?: string; log?: boolean }\r\n ): ServerResult<never>;\r\n throwableAsync<T>(fn: () => ServerResultAsync<T>): ServerResultAsync<T>;\r\n handleUnknownError(error: unknown): ServerError;\r\n};\r\n\r\ntype PermissionServiceProcedureHost<\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n> = BaseServiceProcedureHost<Repositories, Services> & {\r\n checkPermission<T extends Entity>(\r\n actor: AuthenticatedActor,\r\n action: string,\r\n entities?: T | T[],\r\n grants?: ResourceActionGrant[]\r\n ): boolean;\r\n checkPermissionAsync<T extends Entity>(\r\n actor: AuthenticatedActor,\r\n action: string,\r\n getEntities: () => ServerResultAsync<T | T[] | undefined>,\r\n grants?: ResourceActionGrant[]\r\n ): ServerResultAsync<boolean>;\r\n};\r\n\r\ntype ProcedureStage = \"start\" | \"auth_passed\" | \"access_passed\" | \"forbidden\" | \"success\" | \"error\";\r\n\r\ntype ProcedureRuntimeStep<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n stage: \"use\" | \"input\" | \"auth\" | \"access\";\r\n stepName: string;\r\n run: (\r\n args: ServiceProcedureArgs<\r\n unknown,\r\n ServiceProcedureContext,\r\n Repositories,\r\n Services,\r\n ServiceProcedureState\r\n >\r\n ) => Promise<ServerResult<unknown>>;\r\n};\r\n\r\ntype ProcedureBuilderConfig<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n name: string;\r\n steps: ProcedureRuntimeStep<Repositories, Services>[];\r\n};\r\n\r\nconst DEFAULT_CONTEXT_FILTER_INCLUDE = [\r\n \"user\",\r\n] as const satisfies readonly ServiceProcedureContextFilterScope[];\r\n\r\nfunction isServerResult<T>(value: unknown): value is ServerResult<T> {\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n \"isErr\" in value &&\r\n typeof (value as { isErr: unknown }).isErr === \"function\" &&\r\n \"isOk\" in value &&\r\n typeof (value as { isOk: unknown }).isOk === \"function\"\r\n );\r\n}\r\n\r\nasync function normalizeProcedureResult<T>(\r\n result: ServiceProcedureResultLike<T>\r\n): Promise<ServerResult<T>> {\r\n const resolved = await result;\r\n return isServerResult<T>(resolved) ? resolved : ok(resolved);\r\n}\r\n\r\nfunction assertUniqueStepName<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n steps: ProcedureRuntimeStep<Repositories, Services>[],\r\n stepName: string\r\n) {\r\n if (steps.some((step) => step.stepName === stepName)) {\r\n throw new Error(`Duplicate service procedure step name: ${stepName}`);\r\n }\r\n}\r\n\r\nfunction hasStepName<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n steps: ProcedureRuntimeStep<Repositories, Services>[],\r\n stepName: string\r\n) {\r\n return steps.some((step) => step.stepName === stepName);\r\n}\r\n\r\nfunction getContextFilterInclude(\r\n include: readonly ServiceProcedureContextFilterScope[] = DEFAULT_CONTEXT_FILTER_INCLUDE\r\n) {\r\n return {\r\n user: include.includes(\"user\"),\r\n organization: include.includes(\"organization\"),\r\n team: include.includes(\"team\"),\r\n };\r\n}\r\n\r\nfunction getFailureStage(code: TRPC_ERROR_CODE_KEY | undefined): ProcedureStage {\r\n return code === \"FORBIDDEN\" || code === \"UNAUTHORIZED\" ? \"forbidden\" : \"error\";\r\n}\r\n\r\nfunction logProcedureStage<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n procedureName: string,\r\n ctx: ServiceProcedureContext,\r\n stage: ProcedureStage,\r\n {\r\n stepName,\r\n durationMs,\r\n errorCode,\r\n }: {\r\n stepName?: string;\r\n durationMs?: number;\r\n errorCode?: TRPC_ERROR_CODE_KEY;\r\n } = {}\r\n) {\r\n host.logger.debug({\r\n procedureName,\r\n stage,\r\n stepName,\r\n durationMs,\r\n errorCode,\r\n hasActor: Boolean(ctx.actor),\r\n });\r\n}\r\n\r\nfunction requireProcedureActor<\r\n Scope extends ActorScope,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n ctx: ServiceProcedureContext,\r\n scope: Scope\r\n): ServerResult<Actor[Scope]> {\r\n if (!ctx.actor) {\r\n return host.error(\"UNAUTHORIZED\", \"Unauthorized\");\r\n }\r\n\r\n if (!validateActor(ctx.actor, scope)) {\r\n return host.error(\"FORBIDDEN\", \"Forbidden\");\r\n }\r\n\r\n return ok(ctx.actor as Actor[Scope]);\r\n}\r\n\r\nfunction createRequireAuthStep<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n scope: ActorScope = \"user\"\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"auth\",\r\n stepName: \"auth\",\r\n run: async ({ ctx }) => {\r\n return requireProcedureActor(host, ctx, scope);\r\n },\r\n };\r\n}\r\n\r\nfunction createUseStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n>(\r\n stepName: string,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"use\",\r\n stepName,\r\n run: async (args) =>\r\n normalizeProcedureResult(\r\n step(args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>)\r\n ),\r\n };\r\n}\r\n\r\nfunction createInputStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TNextInput,\r\n>(\r\n stepName: string,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"input\",\r\n stepName,\r\n run: async (args) =>\r\n normalizeProcedureResult(\r\n step(args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>)\r\n ),\r\n };\r\n}\r\n\r\nfunction createContextFilterStep<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n include?: readonly ServiceProcedureContextFilterScope[]\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n const contextInclude = getContextFilterInclude(include);\r\n const requiredScope: ActorScope = contextInclude.team\r\n ? \"team\"\r\n : contextInclude.organization\r\n ? \"organization\"\r\n : \"user\";\r\n\r\n return {\r\n stage: \"input\",\r\n stepName: \"contextFilter\",\r\n run: async ({ input, ctx }) => {\r\n const actor = requireProcedureActor(host, ctx, requiredScope);\r\n if (actor.isErr()) return actor;\r\n return ok(host.addContextFilter(actor.value, contextInclude, input as QueryInput));\r\n },\r\n };\r\n}\r\n\r\nfunction createAccessStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined,\r\n>(\r\n host: PermissionServiceProcedureHost<Repositories, Services>,\r\n config: ServiceProcedureAccessConfig<TInput, TCtx, Repositories, Services, State, TEntities>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"access\",\r\n stepName: \"access\",\r\n run: async (args) => {\r\n const typedArgs = args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>;\r\n const actor = requireProcedureActor(host, typedArgs.ctx, \"user\");\r\n if (actor.isErr()) return actor;\r\n\r\n if (\"entityStep\" in config && typeof config.entityStep === \"string\") {\r\n const entities = typedArgs.state[config.entityStep] as TEntities;\r\n const hasPermission = host.checkPermission(\r\n actor.value,\r\n config.action,\r\n entities as Entity | Entity[] | undefined,\r\n config.grants\r\n );\r\n\r\n if (!hasPermission) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(entities);\r\n }\r\n\r\n if (typeof config.entities === \"function\") {\r\n const resolveEntities = config.entities as (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n ) => ServiceProcedureResultLike<TEntities>;\r\n\r\n let loadedEntities: TEntities | undefined;\r\n const permission = await host.checkPermissionAsync(\r\n actor.value,\r\n config.action,\r\n async () => {\r\n const entityResult = await normalizeProcedureResult(resolveEntities(typedArgs));\r\n if (entityResult.isOk()) {\r\n loadedEntities = entityResult.value;\r\n }\r\n return entityResult;\r\n },\r\n config.grants\r\n );\r\n\r\n if (permission.isErr()) {\r\n return permission;\r\n }\r\n\r\n if (!permission.value) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(loadedEntities);\r\n }\r\n\r\n const entities = config.entities;\r\n const hasPermission = host.checkPermission(\r\n actor.value,\r\n config.action,\r\n entities,\r\n config.grants\r\n );\r\n\r\n if (!hasPermission) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(entities);\r\n },\r\n };\r\n}\r\n\r\nfunction createProcedureHandler<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>,\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n): ServiceProcedure<TInput, TCtx, TOutput> {\r\n return async (input, ctx) =>\r\n host.throwableAsync(async () => {\r\n const state: ServiceProcedureState = {};\r\n const startTime = Date.now();\r\n const typedCtx = ctx as ServiceProcedureContext;\r\n let currentInput: unknown = input;\r\n\r\n logProcedureStage(host, config.name, typedCtx, \"start\");\r\n\r\n try {\r\n for (const step of config.steps) {\r\n const stepResult = await step.run({\r\n input: currentInput,\r\n ctx: typedCtx,\r\n state,\r\n repository: host.repository,\r\n service: host.service,\r\n logger: host.logger,\r\n });\r\n\r\n if (stepResult.isErr()) {\r\n logProcedureStage(host, config.name, typedCtx, getFailureStage(stepResult.error.code), {\r\n stepName: step.stepName,\r\n durationMs: Date.now() - startTime,\r\n errorCode: stepResult.error.code,\r\n });\r\n return stepResult as ServerResult<TOutput>;\r\n }\r\n\r\n state[step.stepName] = stepResult.value;\r\n\r\n if (step.stage === \"input\") {\r\n currentInput = stepResult.value;\r\n }\r\n\r\n if (step.stage === \"auth\") {\r\n logProcedureStage(host, config.name, typedCtx, \"auth_passed\", {\r\n stepName: step.stepName,\r\n });\r\n }\r\n\r\n if (step.stage === \"access\") {\r\n logProcedureStage(host, config.name, typedCtx, \"access_passed\", {\r\n stepName: step.stepName,\r\n });\r\n }\r\n }\r\n\r\n const handlerResult = await normalizeProcedureResult(\r\n handler({\r\n input: currentInput as TInput,\r\n ctx: ctx as TCtx,\r\n state: state as State,\r\n repository: host.repository,\r\n service: host.service,\r\n logger: host.logger,\r\n })\r\n );\r\n\r\n if (handlerResult.isErr()) {\r\n logProcedureStage(\r\n host,\r\n config.name,\r\n typedCtx,\r\n getFailureStage(handlerResult.error.code),\r\n {\r\n durationMs: Date.now() - startTime,\r\n errorCode: handlerResult.error.code,\r\n }\r\n );\r\n return handlerResult;\r\n }\r\n\r\n logProcedureStage(host, config.name, typedCtx, \"success\", {\r\n durationMs: Date.now() - startTime,\r\n });\r\n return handlerResult;\r\n } catch (error) {\r\n const serverError = host.handleUnknownError(error);\r\n logProcedureStage(host, config.name, typedCtx, getFailureStage(serverError.code), {\r\n durationMs: Date.now() - startTime,\r\n errorCode: serverError.code,\r\n });\r\n throw error;\r\n }\r\n });\r\n}\r\n\r\nexport function createServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>\r\n): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n function addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(include?: TInclude) {\r\n const steps = hasStepName(config.steps, \"auth\")\r\n ? config.steps\r\n : [...config.steps, createRequireAuthStep(host, \"user\")];\r\n\r\n assertUniqueStepName(steps, \"contextFilter\");\r\n\r\n return createServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >(host, {\r\n ...config,\r\n steps: [...steps, createContextFilterStep(host, include)],\r\n });\r\n }\r\n\r\n const builder: ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> = {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createUseStep(stepName, step)],\r\n });\r\n },\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createInputStep(stepName, step)],\r\n });\r\n },\r\n addContextFilter,\r\n requireAuth<Scope extends ActorScope = \"user\">(scope?: Scope) {\r\n assertUniqueStepName(config.steps, \"auth\");\r\n return createServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createRequireAuthStep(host, scope ?? \"user\")],\r\n });\r\n },\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n return createProcedureHandler(host, config, handler);\r\n },\r\n };\r\n\r\n return builder;\r\n}\r\n\r\nexport function createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n>(\r\n host: PermissionServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>\r\n): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n function addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(include?: TInclude) {\r\n const steps = hasStepName(config.steps, \"auth\")\r\n ? config.steps\r\n : [...config.steps, createRequireAuthStep(host, \"user\")];\r\n\r\n assertUniqueStepName(steps, \"contextFilter\");\r\n\r\n return createPermissionServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >(host, {\r\n ...config,\r\n steps: [...steps, createContextFilterStep(host, include)],\r\n });\r\n }\r\n\r\n function access(\r\n accessConfig: ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n function access<TEntities extends Entity | Entity[] | undefined>(\r\n accessConfig: ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n TEntities\r\n >\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: TEntities }\r\n >;\r\n function access<StepName extends ServiceProcedureEntityStepName<State>>(\r\n accessConfig: ServiceProcedureAccessStateConfig<State, StepName>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: State[StepName] }\r\n >;\r\n function access(\r\n accessConfig:\r\n | ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n Entity | Entity[] | undefined\r\n >\r\n | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>\r\n ) {\r\n assertUniqueStepName(config.steps, \"access\");\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createAccessStep(host, accessConfig)],\r\n });\r\n }\r\n\r\n const builder: PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> = {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createUseStep(stepName, step)],\r\n });\r\n },\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createPermissionServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createInputStep(stepName, step)],\r\n });\r\n },\r\n addContextFilter,\r\n requireAuth<Scope extends ActorScope = \"user\">(scope?: Scope) {\r\n assertUniqueStepName(config.steps, \"auth\");\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createRequireAuthStep(host, scope ?? \"user\")],\r\n });\r\n },\r\n access,\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n return createProcedureHandler(host, config, handler);\r\n },\r\n };\r\n\r\n return builder;\r\n}\r\n"],"mappings":";;;;;AAiVA,MAAM,iCAAiC,CACrC,OACD;AAED,SAAS,eAAkB,OAA0C;AACnE,QACE,OAAO,UAAU,YACjB,UAAU,QACV,WAAW,SACX,OAAQ,MAA6B,UAAU,cAC/C,UAAU,SACV,OAAQ,MAA4B,SAAS;;AAIjD,eAAe,yBACb,QAC0B;CAC1B,MAAM,WAAW,MAAM;AACvB,QAAO,eAAkB,SAAS,GAAG,YAAA,GAAA,WAAA,IAAc,SAAS;;AAG9D,SAAS,qBACP,OACA,UACA;AACA,KAAI,MAAM,MAAM,SAAS,KAAK,aAAa,SAAS,CAClD,OAAM,IAAI,MAAM,0CAA0C,WAAW;;AAIzE,SAAS,YACP,OACA,UACA;AACA,QAAO,MAAM,MAAM,SAAS,KAAK,aAAa,SAAS;;AAGzD,SAAS,wBACP,UAAyD,gCACzD;AACA,QAAO;EACL,MAAM,QAAQ,SAAS,OAAO;EAC9B,cAAc,QAAQ,SAAS,eAAe;EAC9C,MAAM,QAAQ,SAAS,OAAO;EAC/B;;AAGH,SAAS,gBAAgB,MAAuD;AAC9E,QAAO,SAAS,eAAe,SAAS,iBAAiB,cAAc;;AAGzE,SAAS,kBACP,MACA,eACA,KACA,OACA,EACE,UACA,YACA,cAKE,EAAE,EACN;AACA,MAAK,OAAO,MAAM;EAChB;EACA;EACA;EACA;EACA;EACA,UAAU,QAAQ,IAAI,MAAM;EAC7B,CAAC;;AAGJ,SAAS,sBAKP,MACA,KACA,OAC4B;AAC5B,KAAI,CAAC,IAAI,MACP,QAAO,KAAK,MAAM,gBAAgB,eAAe;AAGnD,KAAI,CAACA,oCAAAA,cAAc,IAAI,OAAO,MAAM,CAClC,QAAO,KAAK,MAAM,aAAa,YAAY;AAG7C,SAAA,GAAA,WAAA,IAAU,IAAI,MAAsB;;AAGtC,SAAS,sBACP,MACA,QAAoB,QAC0B;AAC9C,QAAO;EACL,OAAO;EACP,UAAU;EACV,KAAK,OAAO,EAAE,UAAU;AACtB,UAAO,sBAAsB,MAAM,KAAK,MAAM;;EAEjD;;AAGH,SAAS,cAQP,UACA,MAC8C;AAC9C,QAAO;EACL,OAAO;EACP;EACA,KAAK,OAAO,SACV,yBACE,KAAK,KAA0E,CAChF;EACJ;;AAGH,SAAS,gBAQP,UACA,MAC8C;AAC9C,QAAO;EACL,OAAO;EACP;EACA,KAAK,OAAO,SACV,yBACE,KAAK,KAA0E,CAChF;EACJ;;AAGH,SAAS,wBACP,MACA,SAC8C;CAC9C,MAAM,iBAAiB,wBAAwB,QAAQ;CACvD,MAAM,gBAA4B,eAAe,OAC7C,SACA,eAAe,eACb,iBACA;AAEN,QAAO;EACL,OAAO;EACP,UAAU;EACV,KAAK,OAAO,EAAE,OAAO,UAAU;GAC7B,MAAM,QAAQ,sBAAsB,MAAM,KAAK,cAAc;AAC7D,OAAI,MAAM,OAAO,CAAE,QAAO;AAC1B,WAAA,GAAA,WAAA,IAAU,KAAK,iBAAiB,MAAM,OAAO,gBAAgB,MAAoB,CAAC;;EAErF;;AAGH,SAAS,iBAQP,MACA,QAC8C;AAC9C,QAAO;EACL,OAAO;EACP,UAAU;EACV,KAAK,OAAO,SAAS;GACnB,MAAM,YAAY;GAClB,MAAM,QAAQ,sBAAsB,MAAM,UAAU,KAAK,OAAO;AAChE,OAAI,MAAM,OAAO,CAAE,QAAO;AAE1B,OAAI,gBAAgB,UAAU,OAAO,OAAO,eAAe,UAAU;IACnE,MAAM,WAAW,UAAU,MAAM,OAAO;AAQxC,QAAI,CAPkB,KAAK,gBACzB,MAAM,OACN,OAAO,QACP,UACA,OAAO,OACR,CAGC,QAAO,KAAK,MAAM,YAAY;AAGhC,YAAA,GAAA,WAAA,IAAU,SAAS;;AAGrB,OAAI,OAAO,OAAO,aAAa,YAAY;IACzC,MAAM,kBAAkB,OAAO;IAI/B,IAAI;IACJ,MAAM,aAAa,MAAM,KAAK,qBAC5B,MAAM,OACN,OAAO,QACP,YAAY;KACV,MAAM,eAAe,MAAM,yBAAyB,gBAAgB,UAAU,CAAC;AAC/E,SAAI,aAAa,MAAM,CACrB,kBAAiB,aAAa;AAEhC,YAAO;OAET,OAAO,OACR;AAED,QAAI,WAAW,OAAO,CACpB,QAAO;AAGT,QAAI,CAAC,WAAW,MACd,QAAO,KAAK,MAAM,YAAY;AAGhC,YAAA,GAAA,WAAA,IAAU,eAAe;;GAG3B,MAAM,WAAW,OAAO;AAQxB,OAAI,CAPkB,KAAK,gBACzB,MAAM,OACN,OAAO,QACP,UACA,OAAO,OACR,CAGC,QAAO,KAAK,MAAM,YAAY;AAGhC,WAAA,GAAA,WAAA,IAAU,SAAS;;EAEtB;;AAGH,SAAS,uBAQP,MACA,QACA,SACyC;AACzC,QAAO,OAAO,OAAO,QACnB,KAAK,eAAe,YAAY;EAC9B,MAAM,QAA+B,EAAE;EACvC,MAAM,YAAY,KAAK,KAAK;EAC5B,MAAM,WAAW;EACjB,IAAI,eAAwB;AAE5B,oBAAkB,MAAM,OAAO,MAAM,UAAU,QAAQ;AAEvD,MAAI;AACF,QAAK,MAAM,QAAQ,OAAO,OAAO;IAC/B,MAAM,aAAa,MAAM,KAAK,IAAI;KAChC,OAAO;KACP,KAAK;KACL;KACA,YAAY,KAAK;KACjB,SAAS,KAAK;KACd,QAAQ,KAAK;KACd,CAAC;AAEF,QAAI,WAAW,OAAO,EAAE;AACtB,uBAAkB,MAAM,OAAO,MAAM,UAAU,gBAAgB,WAAW,MAAM,KAAK,EAAE;MACrF,UAAU,KAAK;MACf,YAAY,KAAK,KAAK,GAAG;MACzB,WAAW,WAAW,MAAM;MAC7B,CAAC;AACF,YAAO;;AAGT,UAAM,KAAK,YAAY,WAAW;AAElC,QAAI,KAAK,UAAU,QACjB,gBAAe,WAAW;AAG5B,QAAI,KAAK,UAAU,OACjB,mBAAkB,MAAM,OAAO,MAAM,UAAU,eAAe,EAC5D,UAAU,KAAK,UAChB,CAAC;AAGJ,QAAI,KAAK,UAAU,SACjB,mBAAkB,MAAM,OAAO,MAAM,UAAU,iBAAiB,EAC9D,UAAU,KAAK,UAChB,CAAC;;GAIN,MAAM,gBAAgB,MAAM,yBAC1B,QAAQ;IACN,OAAO;IACF;IACE;IACP,YAAY,KAAK;IACjB,SAAS,KAAK;IACd,QAAQ,KAAK;IACd,CAAC,CACH;AAED,OAAI,cAAc,OAAO,EAAE;AACzB,sBACE,MACA,OAAO,MACP,UACA,gBAAgB,cAAc,MAAM,KAAK,EACzC;KACE,YAAY,KAAK,KAAK,GAAG;KACzB,WAAW,cAAc,MAAM;KAChC,CACF;AACD,WAAO;;AAGT,qBAAkB,MAAM,OAAO,MAAM,UAAU,WAAW,EACxD,YAAY,KAAK,KAAK,GAAG,WAC1B,CAAC;AACF,UAAO;WACA,OAAO;GACd,MAAM,cAAc,KAAK,mBAAmB,MAAM;AAClD,qBAAkB,MAAM,OAAO,MAAM,UAAU,gBAAgB,YAAY,KAAK,EAAE;IAChF,YAAY,KAAK,KAAK,GAAG;IACzB,WAAW,YAAY;IACxB,CAAC;AACF,SAAM;;GAER;;AAGN,SAAgB,8BAOd,MACA,QACsE;CACtE,SAAS,iBAEP,SAAoB;EACpB,MAAM,QAAQ,YAAY,OAAO,OAAO,OAAO,GAC3C,OAAO,QACP,CAAC,GAAG,OAAO,OAAO,sBAAsB,MAAM,OAAO,CAAC;AAE1D,uBAAqB,OAAO,gBAAgB;AAE5C,SAAO,8BAML,MAAM;GACN,GAAG;GACH,OAAO,CAAC,GAAG,OAAO,wBAAwB,MAAM,QAAQ,CAAC;GAC1D,CAAC;;AAyDJ,QAtDsF;EACpF,IACE,UACA,MACA;AACA,wBAAqB,OAAO,OAAO,SAAS;AAC5C,UAAO,8BAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,cAAc,UAAU,KAAK,CAAC;IACxD,CAAC;;EAEJ,SACE,UACA,MACA;AACA,wBAAqB,OAAO,OAAO,SAAS;AAC5C,UAAO,8BAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,gBAAgB,UAAU,KAAK,CAAC;IAC1D,CAAC;;EAEJ;EACA,YAA+C,OAAe;AAC5D,wBAAqB,OAAO,OAAO,OAAO;AAC1C,UAAO,8BAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,sBAAsB,MAAM,SAAS,OAAO,CAAC;IACvE,CAAC;;EAEJ,OACE,SACA;AACA,UAAO,uBAAuB,MAAM,QAAQ,QAAQ;;EAEvD;;AAKH,SAAgB,wCAOd,MACA,QACgF;CAChF,SAAS,iBAEP,SAAoB;EACpB,MAAM,QAAQ,YAAY,OAAO,OAAO,OAAO,GAC3C,OAAO,QACP,CAAC,GAAG,OAAO,OAAO,sBAAsB,MAAM,OAAO,CAAC;AAE1D,uBAAqB,OAAO,gBAAgB;AAE5C,SAAO,wCAML,MAAM;GACN,GAAG;GACH,OAAO,CAAC,GAAG,OAAO,wBAAwB,MAAM,QAAQ,CAAC;GAC1D,CAAC;;CAqCJ,SAAS,OACP,cAUA;AACA,uBAAqB,OAAO,OAAO,SAAS;AAC5C,SAAO,wCAML,MAAM;GACN,GAAG;GACH,OAAO,CAAC,GAAG,OAAO,OAAO,iBAAiB,MAAM,aAAa,CAAC;GAC/D,CAAC;;AA0DJ,QAvDgG;EAC9F,IACE,UACA,MACA;AACA,wBAAqB,OAAO,OAAO,SAAS;AAC5C,UAAO,wCAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,cAAc,UAAU,KAAK,CAAC;IACxD,CAAC;;EAEJ,SACE,UACA,MACA;AACA,wBAAqB,OAAO,OAAO,SAAS;AAC5C,UAAO,wCAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,gBAAgB,UAAU,KAAK,CAAC;IAC1D,CAAC;;EAEJ;EACA,YAA+C,OAAe;AAC5D,wBAAqB,OAAO,OAAO,OAAO;AAC1C,UAAO,wCAML,MAAM;IACN,GAAG;IACH,OAAO,CAAC,GAAG,OAAO,OAAO,sBAAsB,MAAM,SAAS,OAAO,CAAC;IACvE,CAAC;;EAEJ;EACA,OACE,SACA;AACA,UAAO,uBAAuB,MAAM,QAAQ,QAAQ;;EAEvD"}
|
|
1
|
+
{"version":3,"file":"base.procedure.cjs","names":["validateActor"],"sources":["../../../../src/modules/base/base.procedure.ts"],"sourcesContent":["import type { QueryInput } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { TRPC_ERROR_CODE_KEY } from \"@trpc/server\";\r\nimport { ok } from \"neverthrow\";\r\nimport type { ServerError } from \"../../utils/errors\";\r\nimport type { logger } from \"../../utils/logger\";\r\nimport type { Base } from \"./base.abstract\";\r\nimport { type Actor, type ActorScope, type AuthenticatedActor, validateActor } from \"./base.actor\";\r\nimport type { ServerResult, ServerResultAsync } from \"./base.dto\";\r\nimport type { Entity, ResourceActionGrant } from \"./base.grants\";\r\n\r\ntype ServiceLogger = ReturnType<typeof logger.child>;\r\ntype RepositoryMap = Record<string, Base>;\r\ntype ServiceMap = Record<string, Base>;\r\n\r\nexport type ServiceProcedureContext = {\r\n actor?: AuthenticatedActor | null;\r\n} & Record<string, unknown>;\r\n\r\nexport type ServiceProcedureState = Record<string, unknown>;\r\nexport type ServiceProcedureStoredValue<T> = [T] extends [undefined] ? undefined : Awaited<T>;\r\n/** Value stored in procedure state after `loadResource` (loader may return null/undefined; state is narrowed). */\r\nexport type ServiceProcedureLoadedResource<TOutput> = NonNullable<\r\n ServiceProcedureStoredValue<TOutput>\r\n>;\r\nexport type ServiceProcedureResultLike<T> = T | ServerResult<T> | Promise<T | ServerResult<T>>;\r\nexport type ServiceProcedureContextFilterScope = ActorScope;\r\nexport type ServiceProcedureContextFilteredInput<TInput> = Extract<NonNullable<TInput>, QueryInput>;\r\ntype ServiceProcedureAuthContext<Scope extends ActorScope> = {\r\n actor: Actor[Scope];\r\n};\r\ntype ServiceProcedureRequiredScopeFromFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined,\r\n> = TInclude extends readonly ServiceProcedureContextFilterScope[]\r\n ? \"team\" extends TInclude[number]\r\n ? \"team\"\r\n : \"organization\" extends TInclude[number]\r\n ? \"organization\"\r\n : \"user\"\r\n : \"user\";\r\n\r\nexport type ServiceProcedure<TInput, TCtx extends ServiceProcedureContext, TOutput> = (\r\n input: TInput,\r\n ctx: TCtx\r\n) => ServerResultAsync<TOutput>;\r\n\r\nexport type ServiceProcedureArgs<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n> = {\r\n input: TInput;\r\n ctx: TCtx;\r\n state: State;\r\n repository: Repositories;\r\n service: Services;\r\n logger: ServiceLogger;\r\n};\r\n\r\nexport type ServiceProcedureStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput = undefined,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<ServiceProcedureStoredValue<TOutput>>;\r\n\r\nexport type ServiceProcedureInputMapper<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TNextInput,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<ServiceProcedureStoredValue<TNextInput>>;\r\n\r\nexport type ServiceProcedureHandler<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n> = (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n) => ServiceProcedureResultLike<TOutput>;\r\n\r\nexport type ServiceProcedureEntityResolver<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined,\r\n> =\r\n | TEntities\r\n | ((\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n ) => ServiceProcedureResultLike<TEntities>);\r\n\r\ntype ServiceProcedureAccessBaseConfig = {\r\n action: string;\r\n grants?: ResourceActionGrant[];\r\n};\r\n\r\nexport type ServiceProcedureEntityStepName<State extends ServiceProcedureState> = Extract<\r\n {\r\n [Key in keyof State]: State[Key] extends Entity | Entity[] | undefined ? Key : never;\r\n }[keyof State],\r\n string\r\n>;\r\n\r\nexport type ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined = undefined,\r\n> = ServiceProcedureAccessBaseConfig & {\r\n entities?: ServiceProcedureEntityResolver<TInput, TCtx, Repositories, Services, State, TEntities>;\r\n entityStep?: never;\r\n};\r\n\r\nexport type ServiceProcedureAccessStateConfig<\r\n State extends ServiceProcedureState,\r\n StepName extends ServiceProcedureEntityStepName<State>,\r\n> = ServiceProcedureAccessBaseConfig & {\r\n entityStep: StepName;\r\n entities?: never;\r\n};\r\n\r\nexport type ServiceProcedureAccessConfig<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined = undefined,\r\n> =\r\n | ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State, TEntities>\r\n | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>;\r\n\r\nexport interface ServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n> {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): ServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >;\r\n /**\r\n * Loads a value from a `ServerResult` (or plain value) and stores it under `stepName`.\r\n * Propagates `Err`; if the resolved value is falsy, returns `NOT_FOUND`.\r\n * For valid numeric `0` or empty string, use `.use()` instead of this helper.\r\n */\r\n loadResource<StepName extends string, TOutput>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>,\r\n options?: { notFoundMessage?: string }\r\n ): ServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>\r\n >;\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ): ServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >;\r\n addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(\r\n include?: TInclude\r\n ): ServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >;\r\n requireAuth<Scope extends ActorScope = \"user\">(\r\n scope?: Scope\r\n ): ServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): ServiceProcedure<TInput, TCtx, TOutput>;\r\n}\r\n\r\nexport interface PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n> extends ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >;\r\n loadResource<StepName extends string, TOutput>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>,\r\n options?: { notFoundMessage?: string }\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>\r\n >;\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ): PermissionServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >;\r\n addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(\r\n include?: TInclude\r\n ): PermissionServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >;\r\n requireAuth<Scope extends ActorScope = \"user\">(\r\n scope?: Scope\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n access(\r\n config: ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n access<TEntities extends Entity | Entity[] | undefined>(\r\n config: ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n TEntities\r\n >\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: TEntities }\r\n >;\r\n access<StepName extends ServiceProcedureEntityStepName<State>>(\r\n config: ServiceProcedureAccessStateConfig<State, StepName>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: State[StepName] }\r\n >;\r\n}\r\n\r\ntype BaseServiceProcedureHost<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n repository: Repositories;\r\n service: Services;\r\n logger: ServiceLogger;\r\n addContextFilter(\r\n actor: AuthenticatedActor,\r\n include?: { user?: boolean; organization?: boolean; team?: boolean },\r\n query?: QueryInput\r\n ): QueryInput;\r\n error(\r\n code: TRPC_ERROR_CODE_KEY,\r\n message?: string,\r\n options?: { cause?: unknown; clientMessage?: string; log?: boolean }\r\n ): ServerResult<never>;\r\n throwableAsync<T>(fn: () => ServerResultAsync<T>): ServerResultAsync<T>;\r\n handleUnknownError(error: unknown): ServerError;\r\n};\r\n\r\ntype PermissionServiceProcedureHost<\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n> = BaseServiceProcedureHost<Repositories, Services> & {\r\n checkPermission<T extends Entity>(\r\n actor: AuthenticatedActor,\r\n action: string,\r\n entities?: T | T[],\r\n grants?: ResourceActionGrant[]\r\n ): boolean;\r\n checkPermissionAsync<T extends Entity>(\r\n actor: AuthenticatedActor,\r\n action: string,\r\n getEntities: () => ServerResultAsync<T | T[] | undefined>,\r\n grants?: ResourceActionGrant[]\r\n ): ServerResultAsync<boolean>;\r\n};\r\n\r\ntype ProcedureStage = \"start\" | \"auth_passed\" | \"access_passed\" | \"forbidden\" | \"success\" | \"error\";\r\n\r\ntype ProcedureRuntimeStep<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n stage: \"use\" | \"input\" | \"auth\" | \"access\";\r\n stepName: string;\r\n run: (\r\n args: ServiceProcedureArgs<\r\n unknown,\r\n ServiceProcedureContext,\r\n Repositories,\r\n Services,\r\n ServiceProcedureState\r\n >\r\n ) => Promise<ServerResult<unknown>>;\r\n};\r\n\r\ntype ProcedureBuilderConfig<Repositories extends RepositoryMap, Services extends ServiceMap> = {\r\n name: string;\r\n steps: ProcedureRuntimeStep<Repositories, Services>[];\r\n};\r\n\r\nconst DEFAULT_CONTEXT_FILTER_INCLUDE = [\r\n \"user\",\r\n] as const satisfies readonly ServiceProcedureContextFilterScope[];\r\n\r\nfunction isServerResult<T>(value: unknown): value is ServerResult<T> {\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n \"isErr\" in value &&\r\n typeof (value as { isErr: unknown }).isErr === \"function\" &&\r\n \"isOk\" in value &&\r\n typeof (value as { isOk: unknown }).isOk === \"function\"\r\n );\r\n}\r\n\r\nasync function normalizeProcedureResult<T>(\r\n result: ServiceProcedureResultLike<T>\r\n): Promise<ServerResult<T>> {\r\n const resolved = await result;\r\n return isServerResult<T>(resolved) ? resolved : ok(resolved);\r\n}\r\n\r\nfunction assertUniqueStepName<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n steps: ProcedureRuntimeStep<Repositories, Services>[],\r\n stepName: string\r\n) {\r\n if (steps.some((step) => step.stepName === stepName)) {\r\n throw new Error(`Duplicate service procedure step name: ${stepName}`);\r\n }\r\n}\r\n\r\nfunction hasStepName<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n steps: ProcedureRuntimeStep<Repositories, Services>[],\r\n stepName: string\r\n) {\r\n return steps.some((step) => step.stepName === stepName);\r\n}\r\n\r\nfunction getContextFilterInclude(\r\n include: readonly ServiceProcedureContextFilterScope[] = DEFAULT_CONTEXT_FILTER_INCLUDE\r\n) {\r\n return {\r\n user: include.includes(\"user\"),\r\n organization: include.includes(\"organization\"),\r\n team: include.includes(\"team\"),\r\n };\r\n}\r\n\r\nfunction getFailureStage(code: TRPC_ERROR_CODE_KEY | undefined): ProcedureStage {\r\n return code === \"FORBIDDEN\" || code === \"UNAUTHORIZED\" ? \"forbidden\" : \"error\";\r\n}\r\n\r\nfunction logProcedureStage<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n procedureName: string,\r\n ctx: ServiceProcedureContext,\r\n stage: ProcedureStage,\r\n {\r\n stepName,\r\n durationMs,\r\n errorCode,\r\n }: {\r\n stepName?: string;\r\n durationMs?: number;\r\n errorCode?: TRPC_ERROR_CODE_KEY;\r\n } = {}\r\n) {\r\n host.logger.debug({\r\n procedureName,\r\n stage,\r\n stepName,\r\n durationMs,\r\n errorCode,\r\n hasActor: Boolean(ctx.actor),\r\n });\r\n}\r\n\r\nfunction requireProcedureActor<\r\n Scope extends ActorScope,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n ctx: ServiceProcedureContext,\r\n scope: Scope\r\n): ServerResult<Actor[Scope]> {\r\n if (!ctx.actor) {\r\n return host.error(\"UNAUTHORIZED\", \"Unauthorized\");\r\n }\r\n\r\n if (!validateActor(ctx.actor, scope)) {\r\n return host.error(\"FORBIDDEN\", \"Forbidden\");\r\n }\r\n\r\n return ok(ctx.actor as Actor[Scope]);\r\n}\r\n\r\nfunction createRequireAuthStep<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n scope: ActorScope = \"user\"\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"auth\",\r\n stepName: \"auth\",\r\n run: async ({ ctx }) => {\r\n return requireProcedureActor(host, ctx, scope);\r\n },\r\n };\r\n}\r\n\r\nfunction createUseStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n>(\r\n stepName: string,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"use\",\r\n stepName,\r\n run: async (args) =>\r\n normalizeProcedureResult(\r\n step(args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>)\r\n ),\r\n };\r\n}\r\n\r\nconst DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE = \"Resource not found\";\r\n\r\nfunction createLoadResourceStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n stepName: string,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>,\r\n notFoundMessage: string\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"use\",\r\n stepName,\r\n run: async (args) => {\r\n const normalized = await normalizeProcedureResult(\r\n step(args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>)\r\n );\r\n if (normalized.isErr()) {\r\n return normalized;\r\n }\r\n const value = normalized.value;\r\n if (!value) {\r\n return host.error(\"NOT_FOUND\", notFoundMessage);\r\n }\r\n return ok(value as ServiceProcedureLoadedResource<TOutput>);\r\n },\r\n };\r\n}\r\n\r\nfunction createInputStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TNextInput,\r\n>(\r\n stepName: string,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"input\",\r\n stepName,\r\n run: async (args) =>\r\n normalizeProcedureResult(\r\n step(args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>)\r\n ),\r\n };\r\n}\r\n\r\nfunction createContextFilterStep<Repositories extends RepositoryMap, Services extends ServiceMap>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n include?: readonly ServiceProcedureContextFilterScope[]\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n const contextInclude = getContextFilterInclude(include);\r\n const requiredScope: ActorScope = contextInclude.team\r\n ? \"team\"\r\n : contextInclude.organization\r\n ? \"organization\"\r\n : \"user\";\r\n\r\n return {\r\n stage: \"input\",\r\n stepName: \"contextFilter\",\r\n run: async ({ input, ctx }) => {\r\n const actor = requireProcedureActor(host, ctx, requiredScope);\r\n if (actor.isErr()) return actor;\r\n return ok(host.addContextFilter(actor.value, contextInclude, input as QueryInput));\r\n },\r\n };\r\n}\r\n\r\nfunction createAccessStep<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TEntities extends Entity | Entity[] | undefined,\r\n>(\r\n host: PermissionServiceProcedureHost<Repositories, Services>,\r\n config: ServiceProcedureAccessConfig<TInput, TCtx, Repositories, Services, State, TEntities>\r\n): ProcedureRuntimeStep<Repositories, Services> {\r\n return {\r\n stage: \"access\",\r\n stepName: \"access\",\r\n run: async (args) => {\r\n const typedArgs = args as ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>;\r\n const actor = requireProcedureActor(host, typedArgs.ctx, \"user\");\r\n if (actor.isErr()) return actor;\r\n\r\n if (\"entityStep\" in config && typeof config.entityStep === \"string\") {\r\n const entities = typedArgs.state[config.entityStep] as TEntities;\r\n const hasPermission = host.checkPermission(\r\n actor.value,\r\n config.action,\r\n entities as Entity | Entity[] | undefined,\r\n config.grants\r\n );\r\n\r\n if (!hasPermission) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(entities);\r\n }\r\n\r\n if (typeof config.entities === \"function\") {\r\n const resolveEntities = config.entities as (\r\n args: ServiceProcedureArgs<TInput, TCtx, Repositories, Services, State>\r\n ) => ServiceProcedureResultLike<TEntities>;\r\n\r\n let loadedEntities: TEntities | undefined;\r\n const permission = await host.checkPermissionAsync(\r\n actor.value,\r\n config.action,\r\n async () => {\r\n const entityResult = await normalizeProcedureResult(resolveEntities(typedArgs));\r\n if (entityResult.isOk()) {\r\n loadedEntities = entityResult.value;\r\n }\r\n return entityResult;\r\n },\r\n config.grants\r\n );\r\n\r\n if (permission.isErr()) {\r\n return permission;\r\n }\r\n\r\n if (!permission.value) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(loadedEntities);\r\n }\r\n\r\n const entities = config.entities;\r\n const hasPermission = host.checkPermission(\r\n actor.value,\r\n config.action,\r\n entities,\r\n config.grants\r\n );\r\n\r\n if (!hasPermission) {\r\n return host.error(\"FORBIDDEN\");\r\n }\r\n\r\n return ok(entities);\r\n },\r\n };\r\n}\r\n\r\nfunction createProcedureHandler<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState,\r\n TOutput,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>,\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n): ServiceProcedure<TInput, TCtx, TOutput> {\r\n return async (input, ctx) =>\r\n host.throwableAsync(async () => {\r\n const state: ServiceProcedureState = {};\r\n const startTime = Date.now();\r\n const typedCtx = ctx as ServiceProcedureContext;\r\n let currentInput: unknown = input;\r\n\r\n logProcedureStage(host, config.name, typedCtx, \"start\");\r\n\r\n try {\r\n for (const step of config.steps) {\r\n const stepResult = await step.run({\r\n input: currentInput,\r\n ctx: typedCtx,\r\n state,\r\n repository: host.repository,\r\n service: host.service,\r\n logger: host.logger,\r\n });\r\n\r\n if (stepResult.isErr()) {\r\n logProcedureStage(host, config.name, typedCtx, getFailureStage(stepResult.error.code), {\r\n stepName: step.stepName,\r\n durationMs: Date.now() - startTime,\r\n errorCode: stepResult.error.code,\r\n });\r\n return stepResult as ServerResult<TOutput>;\r\n }\r\n\r\n state[step.stepName] = stepResult.value;\r\n\r\n if (step.stage === \"input\") {\r\n currentInput = stepResult.value;\r\n }\r\n\r\n if (step.stage === \"auth\") {\r\n logProcedureStage(host, config.name, typedCtx, \"auth_passed\", {\r\n stepName: step.stepName,\r\n });\r\n }\r\n\r\n if (step.stage === \"access\") {\r\n logProcedureStage(host, config.name, typedCtx, \"access_passed\", {\r\n stepName: step.stepName,\r\n });\r\n }\r\n }\r\n\r\n const handlerResult = await normalizeProcedureResult(\r\n handler({\r\n input: currentInput as TInput,\r\n ctx: ctx as TCtx,\r\n state: state as State,\r\n repository: host.repository,\r\n service: host.service,\r\n logger: host.logger,\r\n })\r\n );\r\n\r\n if (handlerResult.isErr()) {\r\n logProcedureStage(\r\n host,\r\n config.name,\r\n typedCtx,\r\n getFailureStage(handlerResult.error.code),\r\n {\r\n durationMs: Date.now() - startTime,\r\n errorCode: handlerResult.error.code,\r\n }\r\n );\r\n return handlerResult;\r\n }\r\n\r\n logProcedureStage(host, config.name, typedCtx, \"success\", {\r\n durationMs: Date.now() - startTime,\r\n });\r\n return handlerResult;\r\n } catch (error) {\r\n const serverError = host.handleUnknownError(error);\r\n logProcedureStage(host, config.name, typedCtx, getFailureStage(serverError.code), {\r\n durationMs: Date.now() - startTime,\r\n errorCode: serverError.code,\r\n });\r\n throw error;\r\n }\r\n });\r\n}\r\n\r\nexport function createServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n>(\r\n host: BaseServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>\r\n): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n function addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(include?: TInclude) {\r\n const steps = hasStepName(config.steps, \"auth\")\r\n ? config.steps\r\n : [...config.steps, createRequireAuthStep(host, \"user\")];\r\n\r\n assertUniqueStepName(steps, \"contextFilter\");\r\n\r\n return createServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >(host, {\r\n ...config,\r\n steps: [...steps, createContextFilterStep(host, include)],\r\n });\r\n }\r\n\r\n const builder: ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> = {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createUseStep(stepName, step)],\r\n });\r\n },\r\n loadResource<StepName extends string, TOutput>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>,\r\n options?: { notFoundMessage?: string }\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;\r\n return createServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)],\r\n });\r\n },\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createInputStep(stepName, step)],\r\n });\r\n },\r\n addContextFilter,\r\n requireAuth<Scope extends ActorScope = \"user\">(scope?: Scope) {\r\n assertUniqueStepName(config.steps, \"auth\");\r\n return createServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createRequireAuthStep(host, scope ?? \"user\")],\r\n });\r\n },\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n return createProcedureHandler(host, config, handler);\r\n },\r\n };\r\n\r\n return builder;\r\n}\r\n\r\nexport function createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx extends ServiceProcedureContext,\r\n Repositories extends RepositoryMap,\r\n Services extends ServiceMap,\r\n State extends ServiceProcedureState = Record<string, never>,\r\n>(\r\n host: PermissionServiceProcedureHost<Repositories, Services>,\r\n config: ProcedureBuilderConfig<Repositories, Services>\r\n): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {\r\n function addContextFilter<\r\n TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined,\r\n >(include?: TInclude) {\r\n const steps = hasStepName(config.steps, \"auth\")\r\n ? config.steps\r\n : [...config.steps, createRequireAuthStep(host, \"user\")];\r\n\r\n assertUniqueStepName(steps, \"contextFilter\");\r\n\r\n return createPermissionServiceProcedureBuilder<\r\n ServiceProcedureContextFilteredInput<TInput>,\r\n TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>,\r\n Repositories,\r\n Services,\r\n State & { contextFilter: ServiceProcedureContextFilteredInput<TInput> }\r\n >(host, {\r\n ...config,\r\n steps: [...steps, createContextFilterStep(host, include)],\r\n });\r\n }\r\n\r\n function access(\r\n accessConfig: ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >;\r\n function access<TEntities extends Entity | Entity[] | undefined>(\r\n accessConfig: ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n TEntities\r\n >\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: TEntities }\r\n >;\r\n function access<StepName extends ServiceProcedureEntityStepName<State>>(\r\n accessConfig: ServiceProcedureAccessStateConfig<State, StepName>\r\n ): PermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State & { access: State[StepName] }\r\n >;\r\n function access(\r\n accessConfig:\r\n | ServiceProcedureAccessEntitiesConfig<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State,\r\n Entity | Entity[] | undefined\r\n >\r\n | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>\r\n ) {\r\n assertUniqueStepName(config.steps, \"access\");\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<\"user\">,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createAccessStep(host, accessConfig)],\r\n });\r\n }\r\n\r\n const builder: PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> = {\r\n use<StepName extends string, TOutput = void>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createUseStep(stepName, step)],\r\n });\r\n },\r\n loadResource<StepName extends string, TOutput>(\r\n stepName: StepName,\r\n step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>,\r\n options?: { notFoundMessage?: string }\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)],\r\n });\r\n },\r\n mapInput<StepName extends string, TNextInput>(\r\n stepName: StepName,\r\n step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>\r\n ) {\r\n assertUniqueStepName(config.steps, stepName);\r\n return createPermissionServiceProcedureBuilder<\r\n ServiceProcedureStoredValue<TNextInput>,\r\n TCtx,\r\n Repositories,\r\n Services,\r\n State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createInputStep(stepName, step)],\r\n });\r\n },\r\n addContextFilter,\r\n requireAuth<Scope extends ActorScope = \"user\">(scope?: Scope) {\r\n assertUniqueStepName(config.steps, \"auth\");\r\n return createPermissionServiceProcedureBuilder<\r\n TInput,\r\n TCtx & ServiceProcedureAuthContext<Scope>,\r\n Repositories,\r\n Services,\r\n State\r\n >(host, {\r\n ...config,\r\n steps: [...config.steps, createRequireAuthStep(host, scope ?? \"user\")],\r\n });\r\n },\r\n access,\r\n handle<TOutput>(\r\n handler: ServiceProcedureHandler<TInput, TCtx, Repositories, Services, State, TOutput>\r\n ) {\r\n return createProcedureHandler(host, config, handler);\r\n },\r\n };\r\n\r\n return builder;\r\n}\r\n"],"mappings":"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"}
|
|
@@ -16,6 +16,8 @@ type ServiceProcedureContext = {
|
|
|
16
16
|
} & Record<string, unknown>;
|
|
17
17
|
type ServiceProcedureState = Record<string, unknown>;
|
|
18
18
|
type ServiceProcedureStoredValue<T> = [T] extends [undefined] ? undefined : Awaited<T>;
|
|
19
|
+
/** Value stored in procedure state after `loadResource` (loader may return null/undefined; state is narrowed). */
|
|
20
|
+
type ServiceProcedureLoadedResource<TOutput> = NonNullable<ServiceProcedureStoredValue<TOutput>>;
|
|
19
21
|
type ServiceProcedureResultLike<T> = T | ServerResult<T> | Promise<T | ServerResult<T>>;
|
|
20
22
|
type ServiceProcedureContextFilterScope = ActorScope;
|
|
21
23
|
type ServiceProcedureContextFilteredInput<TInput> = Extract<NonNullable<TInput>, QueryInput>;
|
|
@@ -52,6 +54,14 @@ type ServiceProcedureAccessStateConfig<State extends ServiceProcedureState, Step
|
|
|
52
54
|
type ServiceProcedureAccessConfig<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState, TEntities extends Entity | Entity[] | undefined = undefined> = ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State, TEntities> | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>;
|
|
53
55
|
interface ServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>> {
|
|
54
56
|
use<StepName extends string, TOutput = void>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TOutput>>>;
|
|
57
|
+
/**
|
|
58
|
+
* Loads a value from a `ServerResult` (or plain value) and stores it under `stepName`.
|
|
59
|
+
* Propagates `Err`; if the resolved value is falsy, returns `NOT_FOUND`.
|
|
60
|
+
* For valid numeric `0` or empty string, use `.use()` instead of this helper.
|
|
61
|
+
*/
|
|
62
|
+
loadResource<StepName extends string, TOutput>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>, options?: {
|
|
63
|
+
notFoundMessage?: string;
|
|
64
|
+
}): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>>;
|
|
55
65
|
mapInput<StepName extends string, TNextInput>(stepName: StepName, step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>): ServiceProcedureBuilder<ServiceProcedureStoredValue<TNextInput>, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>>;
|
|
56
66
|
addContextFilter<TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined>(include?: TInclude): ServiceProcedureBuilder<ServiceProcedureContextFilteredInput<TInput>, TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>, Repositories, Services, State & {
|
|
57
67
|
contextFilter: ServiceProcedureContextFilteredInput<TInput>;
|
|
@@ -61,6 +71,9 @@ interface ServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext,
|
|
|
61
71
|
}
|
|
62
72
|
interface PermissionServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>> extends ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {
|
|
63
73
|
use<StepName extends string, TOutput = void>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TOutput>>>;
|
|
74
|
+
loadResource<StepName extends string, TOutput>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>, options?: {
|
|
75
|
+
notFoundMessage?: string;
|
|
76
|
+
}): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>>;
|
|
64
77
|
mapInput<StepName extends string, TNextInput>(stepName: StepName, step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>): PermissionServiceProcedureBuilder<ServiceProcedureStoredValue<TNextInput>, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>>;
|
|
65
78
|
addContextFilter<TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined>(include?: TInclude): PermissionServiceProcedureBuilder<ServiceProcedureContextFilteredInput<TInput>, TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>, Repositories, Services, State & {
|
|
66
79
|
contextFilter: ServiceProcedureContextFilteredInput<TInput>;
|
|
@@ -107,5 +120,5 @@ type ProcedureBuilderConfig<Repositories extends RepositoryMap, Services extends
|
|
|
107
120
|
declare function createServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>>(host: BaseServiceProcedureHost<Repositories, Services>, config: ProcedureBuilderConfig<Repositories, Services>): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State>;
|
|
108
121
|
declare function createPermissionServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>>(host: PermissionServiceProcedureHost<Repositories, Services>, config: ProcedureBuilderConfig<Repositories, Services>): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State>;
|
|
109
122
|
//#endregion
|
|
110
|
-
export { PermissionServiceProcedureBuilder, ServiceProcedure, ServiceProcedureAccessConfig, ServiceProcedureAccessEntitiesConfig, ServiceProcedureAccessStateConfig, ServiceProcedureArgs, ServiceProcedureBuilder, ServiceProcedureContext, ServiceProcedureContextFilterScope, ServiceProcedureContextFilteredInput, ServiceProcedureEntityResolver, ServiceProcedureEntityStepName, ServiceProcedureHandler, ServiceProcedureInputMapper, ServiceProcedureResultLike, ServiceProcedureState, ServiceProcedureStep, ServiceProcedureStoredValue, createPermissionServiceProcedureBuilder, createServiceProcedureBuilder };
|
|
123
|
+
export { PermissionServiceProcedureBuilder, ServiceProcedure, ServiceProcedureAccessConfig, ServiceProcedureAccessEntitiesConfig, ServiceProcedureAccessStateConfig, ServiceProcedureArgs, ServiceProcedureBuilder, ServiceProcedureContext, ServiceProcedureContextFilterScope, ServiceProcedureContextFilteredInput, ServiceProcedureEntityResolver, ServiceProcedureEntityStepName, ServiceProcedureHandler, ServiceProcedureInputMapper, ServiceProcedureLoadedResource, ServiceProcedureResultLike, ServiceProcedureState, ServiceProcedureStep, ServiceProcedureStoredValue, createPermissionServiceProcedureBuilder, createServiceProcedureBuilder };
|
|
111
124
|
//# sourceMappingURL=base.procedure.d.cts.map
|
|
@@ -16,6 +16,8 @@ type ServiceProcedureContext = {
|
|
|
16
16
|
} & Record<string, unknown>;
|
|
17
17
|
type ServiceProcedureState = Record<string, unknown>;
|
|
18
18
|
type ServiceProcedureStoredValue<T> = [T] extends [undefined] ? undefined : Awaited<T>;
|
|
19
|
+
/** Value stored in procedure state after `loadResource` (loader may return null/undefined; state is narrowed). */
|
|
20
|
+
type ServiceProcedureLoadedResource<TOutput> = NonNullable<ServiceProcedureStoredValue<TOutput>>;
|
|
19
21
|
type ServiceProcedureResultLike<T> = T | ServerResult<T> | Promise<T | ServerResult<T>>;
|
|
20
22
|
type ServiceProcedureContextFilterScope = ActorScope;
|
|
21
23
|
type ServiceProcedureContextFilteredInput<TInput> = Extract<NonNullable<TInput>, QueryInput>;
|
|
@@ -52,6 +54,14 @@ type ServiceProcedureAccessStateConfig<State extends ServiceProcedureState, Step
|
|
|
52
54
|
type ServiceProcedureAccessConfig<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState, TEntities extends Entity | Entity[] | undefined = undefined> = ServiceProcedureAccessEntitiesConfig<TInput, TCtx, Repositories, Services, State, TEntities> | ServiceProcedureAccessStateConfig<State, ServiceProcedureEntityStepName<State>>;
|
|
53
55
|
interface ServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>> {
|
|
54
56
|
use<StepName extends string, TOutput = void>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TOutput>>>;
|
|
57
|
+
/**
|
|
58
|
+
* Loads a value from a `ServerResult` (or plain value) and stores it under `stepName`.
|
|
59
|
+
* Propagates `Err`; if the resolved value is falsy, returns `NOT_FOUND`.
|
|
60
|
+
* For valid numeric `0` or empty string, use `.use()` instead of this helper.
|
|
61
|
+
*/
|
|
62
|
+
loadResource<StepName extends string, TOutput>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>, options?: {
|
|
63
|
+
notFoundMessage?: string;
|
|
64
|
+
}): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>>;
|
|
55
65
|
mapInput<StepName extends string, TNextInput>(stepName: StepName, step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>): ServiceProcedureBuilder<ServiceProcedureStoredValue<TNextInput>, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>>;
|
|
56
66
|
addContextFilter<TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined>(include?: TInclude): ServiceProcedureBuilder<ServiceProcedureContextFilteredInput<TInput>, TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>, Repositories, Services, State & {
|
|
57
67
|
contextFilter: ServiceProcedureContextFilteredInput<TInput>;
|
|
@@ -61,6 +71,9 @@ interface ServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext,
|
|
|
61
71
|
}
|
|
62
72
|
interface PermissionServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>> extends ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State> {
|
|
63
73
|
use<StepName extends string, TOutput = void>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TOutput>>>;
|
|
74
|
+
loadResource<StepName extends string, TOutput>(stepName: StepName, step: ServiceProcedureStep<TInput, TCtx, Repositories, Services, State, TOutput>, options?: {
|
|
75
|
+
notFoundMessage?: string;
|
|
76
|
+
}): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureLoadedResource<TOutput>>>;
|
|
64
77
|
mapInput<StepName extends string, TNextInput>(stepName: StepName, step: ServiceProcedureInputMapper<TInput, TCtx, Repositories, Services, State, TNextInput>): PermissionServiceProcedureBuilder<ServiceProcedureStoredValue<TNextInput>, TCtx, Repositories, Services, State & Record<StepName, ServiceProcedureStoredValue<TNextInput>>>;
|
|
65
78
|
addContextFilter<TInclude extends readonly ServiceProcedureContextFilterScope[] | undefined = undefined>(include?: TInclude): PermissionServiceProcedureBuilder<ServiceProcedureContextFilteredInput<TInput>, TCtx & ServiceProcedureAuthContext<ServiceProcedureRequiredScopeFromFilter<TInclude>>, Repositories, Services, State & {
|
|
66
79
|
contextFilter: ServiceProcedureContextFilteredInput<TInput>;
|
|
@@ -107,5 +120,5 @@ type ProcedureBuilderConfig<Repositories extends RepositoryMap, Services extends
|
|
|
107
120
|
declare function createServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>>(host: BaseServiceProcedureHost<Repositories, Services>, config: ProcedureBuilderConfig<Repositories, Services>): ServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State>;
|
|
108
121
|
declare function createPermissionServiceProcedureBuilder<TInput, TCtx extends ServiceProcedureContext, Repositories extends RepositoryMap, Services extends ServiceMap, State extends ServiceProcedureState = Record<string, never>>(host: PermissionServiceProcedureHost<Repositories, Services>, config: ProcedureBuilderConfig<Repositories, Services>): PermissionServiceProcedureBuilder<TInput, TCtx, Repositories, Services, State>;
|
|
109
122
|
//#endregion
|
|
110
|
-
export { PermissionServiceProcedureBuilder, ServiceProcedure, ServiceProcedureAccessConfig, ServiceProcedureAccessEntitiesConfig, ServiceProcedureAccessStateConfig, ServiceProcedureArgs, ServiceProcedureBuilder, ServiceProcedureContext, ServiceProcedureContextFilterScope, ServiceProcedureContextFilteredInput, ServiceProcedureEntityResolver, ServiceProcedureEntityStepName, ServiceProcedureHandler, ServiceProcedureInputMapper, ServiceProcedureResultLike, ServiceProcedureState, ServiceProcedureStep, ServiceProcedureStoredValue, createPermissionServiceProcedureBuilder, createServiceProcedureBuilder };
|
|
123
|
+
export { PermissionServiceProcedureBuilder, ServiceProcedure, ServiceProcedureAccessConfig, ServiceProcedureAccessEntitiesConfig, ServiceProcedureAccessStateConfig, ServiceProcedureArgs, ServiceProcedureBuilder, ServiceProcedureContext, ServiceProcedureContextFilterScope, ServiceProcedureContextFilteredInput, ServiceProcedureEntityResolver, ServiceProcedureEntityStepName, ServiceProcedureHandler, ServiceProcedureInputMapper, ServiceProcedureLoadedResource, ServiceProcedureResultLike, ServiceProcedureState, ServiceProcedureStep, ServiceProcedureStoredValue, createPermissionServiceProcedureBuilder, createServiceProcedureBuilder };
|
|
111
124
|
//# sourceMappingURL=base.procedure.d.mts.map
|
|
@@ -56,6 +56,20 @@ function createUseStep(stepName, step) {
|
|
|
56
56
|
run: async (args) => normalizeProcedureResult(step(args))
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
const DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE = "Resource not found";
|
|
60
|
+
function createLoadResourceStep(host, stepName, step, notFoundMessage) {
|
|
61
|
+
return {
|
|
62
|
+
stage: "use",
|
|
63
|
+
stepName,
|
|
64
|
+
run: async (args) => {
|
|
65
|
+
const normalized = await normalizeProcedureResult(step(args));
|
|
66
|
+
if (normalized.isErr()) return normalized;
|
|
67
|
+
const value = normalized.value;
|
|
68
|
+
if (!value) return host.error("NOT_FOUND", notFoundMessage);
|
|
69
|
+
return ok(value);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
59
73
|
function createInputStep(stepName, step) {
|
|
60
74
|
return {
|
|
61
75
|
stage: "input",
|
|
@@ -181,6 +195,14 @@ function createServiceProcedureBuilder(host, config) {
|
|
|
181
195
|
steps: [...config.steps, createUseStep(stepName, step)]
|
|
182
196
|
});
|
|
183
197
|
},
|
|
198
|
+
loadResource(stepName, step, options) {
|
|
199
|
+
assertUniqueStepName(config.steps, stepName);
|
|
200
|
+
const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;
|
|
201
|
+
return createServiceProcedureBuilder(host, {
|
|
202
|
+
...config,
|
|
203
|
+
steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)]
|
|
204
|
+
});
|
|
205
|
+
},
|
|
184
206
|
mapInput(stepName, step) {
|
|
185
207
|
assertUniqueStepName(config.steps, stepName);
|
|
186
208
|
return createServiceProcedureBuilder(host, {
|
|
@@ -225,6 +247,14 @@ function createPermissionServiceProcedureBuilder(host, config) {
|
|
|
225
247
|
steps: [...config.steps, createUseStep(stepName, step)]
|
|
226
248
|
});
|
|
227
249
|
},
|
|
250
|
+
loadResource(stepName, step, options) {
|
|
251
|
+
assertUniqueStepName(config.steps, stepName);
|
|
252
|
+
const notFoundMessage = options?.notFoundMessage ?? DEFAULT_LOAD_RESOURCE_NOT_FOUND_MESSAGE;
|
|
253
|
+
return createPermissionServiceProcedureBuilder(host, {
|
|
254
|
+
...config,
|
|
255
|
+
steps: [...config.steps, createLoadResourceStep(host, stepName, step, notFoundMessage)]
|
|
256
|
+
});
|
|
257
|
+
},
|
|
228
258
|
mapInput(stepName, step) {
|
|
229
259
|
assertUniqueStepName(config.steps, stepName);
|
|
230
260
|
return createPermissionServiceProcedureBuilder(host, {
|