every-plugin 0.8.9 → 2.2.2

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.
Files changed (182) hide show
  1. package/dist/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +15 -1
  2. package/dist/_virtual/{rolldown_runtime.mjs → _rolldown/runtime.mjs} +15 -2
  3. package/dist/build/rspack/dev-server-middleware.cjs +15 -4
  4. package/dist/build/rspack/dev-server-middleware.cjs.map +1 -1
  5. package/dist/build/rspack/dev-server-middleware.mjs +15 -4
  6. package/dist/build/rspack/dev-server-middleware.mjs.map +1 -1
  7. package/dist/build/rspack/fix-mf-data-uri-plugin.cjs +44 -0
  8. package/dist/build/rspack/fix-mf-data-uri-plugin.cjs.map +1 -0
  9. package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts +11 -0
  10. package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts.map +1 -0
  11. package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts +11 -0
  12. package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts.map +1 -0
  13. package/dist/build/rspack/fix-mf-data-uri-plugin.mjs +43 -0
  14. package/dist/build/rspack/fix-mf-data-uri-plugin.mjs.map +1 -0
  15. package/dist/build/rspack/index.cjs +8 -6
  16. package/dist/build/rspack/index.d.cts +4 -3
  17. package/dist/build/rspack/index.d.mts +4 -3
  18. package/dist/build/rspack/index.mjs +4 -3
  19. package/dist/build/rspack/module-federation.cjs +3 -3
  20. package/dist/build/rspack/module-federation.cjs.map +1 -1
  21. package/dist/build/rspack/module-federation.mjs +1 -1
  22. package/dist/build/rspack/module-federation.mjs.map +1 -1
  23. package/dist/build/rspack/plugin.cjs +83 -5
  24. package/dist/build/rspack/plugin.cjs.map +1 -1
  25. package/dist/build/rspack/plugin.d.cts +12 -1
  26. package/dist/build/rspack/plugin.d.cts.map +1 -1
  27. package/dist/build/rspack/plugin.d.mts +12 -1
  28. package/dist/build/rspack/plugin.d.mts.map +1 -1
  29. package/dist/build/rspack/plugin.mjs +80 -5
  30. package/dist/build/rspack/plugin.mjs.map +1 -1
  31. package/dist/build/rspack/utils.cjs +5 -4
  32. package/dist/build/rspack/utils.cjs.map +1 -1
  33. package/dist/build/rspack/utils.mjs +3 -2
  34. package/dist/build/rspack/utils.mjs.map +1 -1
  35. package/dist/build/shared-deps.cjs +50 -65
  36. package/dist/build/shared-deps.cjs.map +1 -1
  37. package/dist/build/shared-deps.d.cts +27 -4
  38. package/dist/build/shared-deps.d.cts.map +1 -1
  39. package/dist/build/shared-deps.d.mts +27 -4
  40. package/dist/build/shared-deps.d.mts.map +1 -1
  41. package/dist/build/shared-deps.mjs +48 -64
  42. package/dist/build/shared-deps.mjs.map +1 -1
  43. package/dist/errors.cjs +1 -0
  44. package/dist/errors.cjs.map +1 -1
  45. package/dist/errors.d.cts.map +1 -1
  46. package/dist/errors.d.mts.map +1 -1
  47. package/dist/errors.mjs.map +1 -1
  48. package/dist/index.cjs +2 -0
  49. package/dist/index.d.cts +2 -2
  50. package/dist/index.d.mts +2 -2
  51. package/dist/index.mjs +2 -2
  52. package/dist/orpc-client.cjs +17 -0
  53. package/dist/orpc-client.d.cts +2 -0
  54. package/dist/orpc-client.d.mts +2 -0
  55. package/dist/orpc-client.mjs +5 -0
  56. package/dist/orpc-openapi.cjs +17 -0
  57. package/dist/orpc-openapi.d.cts +2 -0
  58. package/dist/orpc-openapi.d.mts +2 -0
  59. package/dist/orpc-openapi.mjs +5 -0
  60. package/dist/orpc.cjs +8 -7
  61. package/dist/plugin.cjs +10 -9
  62. package/dist/plugin.cjs.map +1 -1
  63. package/dist/plugin.d.cts +28 -29
  64. package/dist/plugin.d.cts.map +1 -1
  65. package/dist/plugin.d.mts +28 -29
  66. package/dist/plugin.d.mts.map +1 -1
  67. package/dist/plugin.mjs +10 -10
  68. package/dist/plugin.mjs.map +1 -1
  69. package/dist/runtime/errors.cjs +2 -2
  70. package/dist/runtime/errors.cjs.map +1 -1
  71. package/dist/runtime/errors.d.cts +4 -4
  72. package/dist/runtime/errors.d.cts.map +1 -1
  73. package/dist/runtime/errors.d.mts +4 -4
  74. package/dist/runtime/errors.d.mts.map +1 -1
  75. package/dist/runtime/errors.mjs +1 -1
  76. package/dist/runtime/errors.mjs.map +1 -1
  77. package/dist/runtime/index.cjs +24 -20
  78. package/dist/runtime/index.cjs.map +1 -1
  79. package/dist/runtime/index.d.cts +3 -3
  80. package/dist/runtime/index.d.cts.map +1 -1
  81. package/dist/runtime/index.d.mts +3 -3
  82. package/dist/runtime/index.d.mts.map +1 -1
  83. package/dist/runtime/index.mjs +12 -9
  84. package/dist/runtime/index.mjs.map +1 -1
  85. package/dist/runtime/mf-config.cjs +33 -0
  86. package/dist/runtime/mf-config.cjs.map +1 -0
  87. package/dist/runtime/mf-config.d.cts +41 -0
  88. package/dist/runtime/mf-config.d.cts.map +1 -0
  89. package/dist/runtime/mf-config.d.mts +41 -0
  90. package/dist/runtime/mf-config.d.mts.map +1 -0
  91. package/dist/runtime/mf-config.mjs +29 -0
  92. package/dist/runtime/mf-config.mjs.map +1 -0
  93. package/dist/runtime/services/module-federation.service.cjs +19 -56
  94. package/dist/runtime/services/module-federation.service.cjs.map +1 -1
  95. package/dist/runtime/services/module-federation.service.d.cts.map +1 -1
  96. package/dist/runtime/services/module-federation.service.d.mts.map +1 -1
  97. package/dist/runtime/services/module-federation.service.mjs +18 -55
  98. package/dist/runtime/services/module-federation.service.mjs.map +1 -1
  99. package/dist/runtime/services/normalize.cjs +3 -2
  100. package/dist/runtime/services/normalize.cjs.map +1 -1
  101. package/dist/runtime/services/normalize.d.cts.map +1 -1
  102. package/dist/runtime/services/normalize.d.mts.map +1 -1
  103. package/dist/runtime/services/normalize.mjs +2 -2
  104. package/dist/runtime/services/normalize.mjs.map +1 -1
  105. package/dist/runtime/services/plugin-lifecycle.service.cjs +1 -1
  106. package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -1
  107. package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +1 -1
  108. package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +1 -1
  109. package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -1
  110. package/dist/runtime/services/plugin-loader.service.cjs +3 -3
  111. package/dist/runtime/services/plugin-loader.service.cjs.map +1 -1
  112. package/dist/runtime/services/plugin-loader.service.d.cts +1 -1
  113. package/dist/runtime/services/plugin-loader.service.d.cts.map +1 -1
  114. package/dist/runtime/services/plugin-loader.service.d.mts +1 -1
  115. package/dist/runtime/services/plugin-loader.service.d.mts.map +1 -1
  116. package/dist/runtime/services/plugin-loader.service.mjs +2 -2
  117. package/dist/runtime/services/plugin-loader.service.mjs.map +1 -1
  118. package/dist/runtime/services/plugin.service.cjs +1 -1
  119. package/dist/runtime/services/plugin.service.cjs.map +1 -1
  120. package/dist/runtime/services/plugin.service.d.cts +6 -7
  121. package/dist/runtime/services/plugin.service.d.cts.map +1 -1
  122. package/dist/runtime/services/plugin.service.d.mts +6 -7
  123. package/dist/runtime/services/plugin.service.d.mts.map +1 -1
  124. package/dist/runtime/services/plugin.service.mjs.map +1 -1
  125. package/dist/runtime/services/secrets.service.cjs +4 -4
  126. package/dist/runtime/services/secrets.service.cjs.map +1 -1
  127. package/dist/runtime/services/secrets.service.d.cts.map +1 -1
  128. package/dist/runtime/services/secrets.service.d.mts.map +1 -1
  129. package/dist/runtime/services/secrets.service.mjs +3 -3
  130. package/dist/runtime/services/secrets.service.mjs.map +1 -1
  131. package/dist/runtime/validation.cjs +1 -1
  132. package/dist/runtime/validation.cjs.map +1 -1
  133. package/dist/runtime/validation.mjs.map +1 -1
  134. package/dist/testing/index.cjs +2 -1
  135. package/dist/testing/index.cjs.map +1 -1
  136. package/dist/testing/index.d.cts +0 -2
  137. package/dist/testing/index.d.cts.map +1 -1
  138. package/dist/testing/index.d.mts +0 -2
  139. package/dist/testing/index.d.mts.map +1 -1
  140. package/dist/testing/index.mjs +1 -1
  141. package/dist/testing/index.mjs.map +1 -1
  142. package/dist/types.d.cts +22 -22
  143. package/dist/types.d.cts.map +1 -1
  144. package/dist/types.d.mts +22 -22
  145. package/dist/types.d.mts.map +1 -1
  146. package/dist/zod.cjs +4 -3
  147. package/dist/zod.mjs +2 -2
  148. package/package.json +204 -194
  149. package/src/build/rspack/dev-server-middleware.ts +233 -0
  150. package/src/build/rspack/fix-mf-data-uri-plugin.ts +49 -0
  151. package/src/build/rspack/index.ts +14 -0
  152. package/src/build/rspack/module-federation.ts +6 -0
  153. package/src/build/rspack/plugin.ts +252 -0
  154. package/src/build/rspack/utils.ts +60 -0
  155. package/src/build/shared-deps.ts +79 -0
  156. package/src/effect.ts +1 -0
  157. package/src/errors.ts +140 -0
  158. package/src/index.ts +26 -0
  159. package/src/orpc-client.ts +2 -0
  160. package/src/orpc-openapi.ts +2 -0
  161. package/src/orpc.ts +9 -0
  162. package/src/plugin.ts +220 -0
  163. package/src/runtime/errors.ts +332 -0
  164. package/src/runtime/index.ts +258 -0
  165. package/src/runtime/mf-config.ts +29 -0
  166. package/src/runtime/services/module-federation.service.ts +181 -0
  167. package/src/runtime/services/normalize.ts +18 -0
  168. package/src/runtime/services/plugin-lifecycle.service.ts +86 -0
  169. package/src/runtime/services/plugin-loader.service.ts +254 -0
  170. package/src/runtime/services/plugin.service.ts +66 -0
  171. package/src/runtime/services/secrets.service.ts +74 -0
  172. package/src/runtime/services.ts +5 -0
  173. package/src/runtime/validation.ts +23 -0
  174. package/src/testing/index.ts +87 -0
  175. package/src/testing/mocks/module-federation.service.ts +41 -0
  176. package/src/types.ts +309 -0
  177. package/src/zod-core.ts +4 -0
  178. package/src/zod.ts +1 -0
  179. package/dist/package.cjs +0 -47
  180. package/dist/package.cjs.map +0 -1
  181. package/dist/package.mjs +0 -29
  182. package/dist/package.mjs.map +0 -1
package/src/errors.ts ADDED
@@ -0,0 +1,140 @@
1
+ import { z } from "./zod";
2
+
3
+ /**
4
+ * Error pattern constants for categorizing infrastructure errors
5
+ */
6
+ export const ERROR_PATTERNS = {
7
+ CONNECTION_REFUSED: ["ECONNREFUSED"],
8
+ HOST_NOT_FOUND: ["ENOTFOUND", "EHOSTUNREACH"],
9
+ TIMEOUT: ["ETIMEDOUT", "ESOCKETTIMEDOUT", "timeout"],
10
+ CONNECTION_RESET: ["ECONNRESET", "EPIPE"],
11
+ PERMISSION: ["EACCES", "EPERM", "permission denied"],
12
+ AUTH: ["401", "unauthorized", "authentication failed"],
13
+ RATE_LIMITED: ["429", "too many requests", "rate limit"],
14
+ SERVICE_UNAVAILABLE: ["503", "service unavailable"],
15
+ } as const;
16
+
17
+ /**
18
+ * Common error schemas for plugin contracts.
19
+ * Import individually or use the grouped PluginErrors export.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { NOT_FOUND, FORBIDDEN, UNAUTHORIZED } from "every-plugin/errors";
24
+ *
25
+ * export const contract = oc.router({
26
+ * getData: oc.route(...)
27
+ * .errors({ NOT_FOUND, FORBIDDEN, UNAUTHORIZED })
28
+ * });
29
+ * ```
30
+ */
31
+
32
+ export const UNAUTHORIZED = {
33
+ status: 401,
34
+ data: z.object({
35
+ apiKeyProvided: z.boolean(),
36
+ provider: z.string().optional(),
37
+ authType: z.enum(["apiKey", "oauth", "token"]).optional(),
38
+ }),
39
+ } as const;
40
+
41
+ export const RATE_LIMITED = {
42
+ status: 429,
43
+ data: z.object({
44
+ retryAfter: z.number().int().min(1),
45
+ remainingRequests: z.number().int().min(0).optional(),
46
+ resetTime: z.string().datetime().optional(),
47
+ limitType: z.enum(["requests", "tokens", "bandwidth"]).optional(),
48
+ }),
49
+ } as const;
50
+
51
+ export const SERVICE_UNAVAILABLE = {
52
+ status: 503,
53
+ data: z.object({
54
+ retryAfter: z.number().int().optional(),
55
+ maintenanceWindow: z.boolean().default(false),
56
+ estimatedUptime: z.string().datetime().optional(),
57
+ }),
58
+ } as const;
59
+
60
+ export const BAD_REQUEST = {
61
+ status: 400,
62
+ data: z.object({
63
+ invalidFields: z.array(z.string()).optional(),
64
+ validationErrors: z
65
+ .array(
66
+ z.object({
67
+ field: z.string(),
68
+ message: z.string(),
69
+ code: z.string().optional(),
70
+ }),
71
+ )
72
+ .optional(),
73
+ }),
74
+ } as const;
75
+
76
+ export const NOT_FOUND = {
77
+ status: 404,
78
+ data: z.object({
79
+ resource: z.string().optional(),
80
+ resourceId: z.string().optional(),
81
+ }),
82
+ } as const;
83
+
84
+ export const FORBIDDEN = {
85
+ status: 403,
86
+ data: z.object({
87
+ requiredPermissions: z.array(z.string()).optional(),
88
+ action: z.string().optional(),
89
+ }),
90
+ } as const;
91
+
92
+ export const TIMEOUT = {
93
+ status: 504,
94
+ data: z.object({
95
+ timeoutMs: z.number().int().min(0).optional(),
96
+ operation: z.string().optional(),
97
+ retryable: z.boolean().default(true),
98
+ }),
99
+ } as const;
100
+
101
+ export const CONNECTION_ERROR = {
102
+ status: 502,
103
+ data: z.object({
104
+ errorCode: z.string().optional(),
105
+ host: z.string().optional(),
106
+ port: z.number().int().optional(),
107
+ suggestion: z.string().optional(),
108
+ }),
109
+ } as const;
110
+
111
+ /**
112
+ * Grouped export for all plugin errors.
113
+ * Use individual imports for cleaner code.
114
+ */
115
+ export const PluginErrors = {
116
+ UNAUTHORIZED,
117
+ RATE_LIMITED,
118
+ SERVICE_UNAVAILABLE,
119
+ BAD_REQUEST,
120
+ NOT_FOUND,
121
+ FORBIDDEN,
122
+ TIMEOUT,
123
+ CONNECTION_ERROR,
124
+ } as const;
125
+
126
+ /**
127
+ * @deprecated Use individual imports or PluginErrors instead
128
+ */
129
+ export const CommonPluginErrors = PluginErrors;
130
+
131
+ export {
132
+ extractFromFiberFailure,
133
+ formatORPCError,
134
+ isRetryableORPCCode,
135
+ ModuleFederationError,
136
+ PluginRuntimeError,
137
+ toPluginRuntimeError,
138
+ ValidationError,
139
+ wrapORPCError,
140
+ } from "./runtime/errors";
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ export * from "./errors";
2
+ export * from "./plugin";
3
+ export * from "./runtime";
4
+
5
+ // Re-export the normalize helper for build configs
6
+ export { getNormalizedRemoteName } from "./runtime/services/normalize";
7
+
8
+ export type {
9
+ AnyPlugin,
10
+ EveryPlugin,
11
+ InitializedPlugin,
12
+ LoadedPlugin,
13
+ PluginClientType,
14
+ PluginConfigInput,
15
+ PluginContext,
16
+ PluginContract,
17
+ PluginInstance,
18
+ PluginMetadata,
19
+ PluginRegistry,
20
+ PluginRouterType,
21
+ PluginRuntimeConfig,
22
+ PluginSecrets,
23
+ PluginVariables,
24
+ RegisteredPlugins,
25
+ SecretsConfig,
26
+ } from "./types";
@@ -0,0 +1,2 @@
1
+ export * from "@orpc/client";
2
+ export * from "@orpc/react-query";
@@ -0,0 +1,2 @@
1
+ export * from "@orpc/openapi";
2
+ export * from "@orpc/zod";
package/src/orpc.ts ADDED
@@ -0,0 +1,9 @@
1
+ export * from "@orpc/contract";
2
+ export * from "@orpc/experimental-publisher";
3
+ export type { IORedisPublisherOptions } from "@orpc/experimental-publisher/ioredis";
4
+ export { IORedisPublisher } from "@orpc/experimental-publisher/ioredis";
5
+ export type { MemoryPublisherOptions } from "@orpc/experimental-publisher/memory";
6
+ export { MemoryPublisher } from "@orpc/experimental-publisher/memory";
7
+ export type { UpstashRedisPublisherOptions } from "@orpc/experimental-publisher/upstash-redis";
8
+ export { UpstashRedisPublisher } from "@orpc/experimental-publisher/upstash-redis";
9
+ export * from "@orpc/server";
package/src/plugin.ts ADDED
@@ -0,0 +1,220 @@
1
+ import type { AnyContractRouter, AnySchema, InferSchemaOutput } from "@orpc/contract";
2
+ import { ORPCError } from "@orpc/contract";
3
+ import type { Context, Implementer, Router } from "@orpc/server";
4
+ import { implement, onError } from "@orpc/server";
5
+ import { Effect, type Scope } from "effect";
6
+ import { extractFromFiberFailure, formatORPCError } from "./runtime/errors";
7
+
8
+ type ContextOutput<T> = T extends AnySchema ? InferSchemaOutput<T> : Record<string, never>;
9
+
10
+ export type PluginConfigFor<
11
+ V extends AnySchema,
12
+ S extends AnySchema,
13
+ TRequestContext extends AnySchema | undefined,
14
+ > = {
15
+ variables: V;
16
+ secrets: S;
17
+ context: TRequestContext;
18
+ };
19
+
20
+ type PluginInitializeInput<V extends AnySchema, S extends AnySchema> = {
21
+ variables: InferSchemaOutput<V>;
22
+ secrets: InferSchemaOutput<S>;
23
+ };
24
+
25
+ type PluginDefinition<
26
+ V extends AnySchema,
27
+ S extends AnySchema,
28
+ TContract extends AnyContractRouter,
29
+ TRequestContext extends AnySchema | undefined,
30
+ TDeps extends Context,
31
+ P extends Record<string, unknown>,
32
+ > = {
33
+ variables: V;
34
+ secrets: S;
35
+ contract: TContract;
36
+ context?: TRequestContext;
37
+ initialize?: (
38
+ config: PluginInitializeInput<V, S>,
39
+ plugins: P,
40
+ ) => Effect.Effect<TDeps, Error, Scope.Scope>;
41
+ createRouter: (
42
+ deps: TDeps,
43
+ builder: Implementer<TContract, ContextOutput<TRequestContext>, ContextOutput<TRequestContext>>,
44
+ ) => Router<TContract, any>;
45
+ shutdown?: (deps: TDeps) => Effect.Effect<void, Error, never>;
46
+ };
47
+
48
+ /**
49
+ * Loaded plugin with static binding property
50
+ */
51
+ export interface LoadedPluginWithBinding<
52
+ TContract extends AnyContractRouter,
53
+ TVariables extends AnySchema,
54
+ TSecrets extends AnySchema,
55
+ TRequestContext extends AnySchema | undefined,
56
+ TDeps extends Context = Record<never, never>,
57
+ > {
58
+ new (): Plugin<TContract, TVariables, TSecrets, TRequestContext, TDeps>;
59
+ binding: {
60
+ contract: TContract;
61
+ variables: TVariables;
62
+ secrets: TSecrets;
63
+ context: TRequestContext;
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Plugin interface
69
+ */
70
+ export interface Plugin<
71
+ TContract extends AnyContractRouter,
72
+ TVariables extends AnySchema,
73
+ TSecrets extends AnySchema,
74
+ TRequestContext extends AnySchema | undefined,
75
+ TDeps extends Context = Record<never, never>,
76
+ > {
77
+ readonly id: string;
78
+ readonly contract: TContract;
79
+ readonly configSchema: PluginConfigFor<TVariables, TSecrets, TRequestContext>;
80
+
81
+ initialize(
82
+ config: PluginInitializeInput<TVariables, TSecrets>,
83
+ plugins: Record<string, unknown>,
84
+ ): Effect.Effect<TDeps, unknown, Scope.Scope>;
85
+
86
+ shutdown(): Effect.Effect<void, never>;
87
+
88
+ /**
89
+ * Creates the strongly-typed oRPC router for this plugin.
90
+ * The router's procedure types are inferred directly from the contract.
91
+ * @param deps The initialized plugin dependencies
92
+ * @returns A router with procedures matching the plugin's contract
93
+ */
94
+ createRouter(deps: TDeps): Router<TContract, any>;
95
+ }
96
+
97
+ export interface CreatePluginFn {
98
+ <
99
+ V extends AnySchema,
100
+ S extends AnySchema,
101
+ TContract extends AnyContractRouter,
102
+ TRequestContext extends AnySchema | undefined = undefined,
103
+ TDeps extends Context = Record<never, never>,
104
+ P extends Record<string, unknown> = Record<string, never>,
105
+ >(
106
+ config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
107
+ ): LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
108
+
109
+ withPlugins: <P extends Record<string, unknown>>() => CreatePluginWithPlugins<P>;
110
+ }
111
+
112
+ export const createPlugin: CreatePluginFn = function createPlugin<
113
+ V extends AnySchema,
114
+ S extends AnySchema,
115
+ TContract extends AnyContractRouter,
116
+ TRequestContext extends AnySchema | undefined = undefined,
117
+ TDeps extends Context = Record<never, never>,
118
+ P extends Record<string, unknown> = Record<string, never>,
119
+ >(config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>) {
120
+ const configSchema: PluginConfigFor<V, S, TRequestContext> = {
121
+ variables: config.variables,
122
+ secrets: config.secrets,
123
+ context: config.context as TRequestContext,
124
+ };
125
+
126
+ class CreatedPlugin implements Plugin<TContract, V, S, TRequestContext, TDeps> {
127
+ /** set during instantiation - registry key */
128
+ id!: string;
129
+ readonly contract = config.contract;
130
+ readonly configSchema = configSchema;
131
+
132
+ private _deps: TDeps | null = null;
133
+
134
+ initialize(
135
+ pluginConfig: PluginInitializeInput<V, S>,
136
+ plugins: Record<string, unknown> = {},
137
+ ): Effect.Effect<TDeps, unknown, Scope.Scope> {
138
+ const init = config.initialize ?? (() => Effect.succeed({} as TDeps));
139
+
140
+ return init(pluginConfig, plugins as P).pipe(
141
+ Effect.tap((deps) =>
142
+ Effect.sync(() => {
143
+ this._deps = deps;
144
+ }),
145
+ ),
146
+ Effect.map(() => this._deps as TDeps),
147
+ Effect.mapError((error) => error as unknown),
148
+ );
149
+ }
150
+
151
+ shutdown(): Effect.Effect<void, never> {
152
+ const self = this;
153
+ return Effect.gen(function* () {
154
+ if (config.shutdown && self._deps) {
155
+ yield* config.shutdown(self._deps).pipe(Effect.catchAll(() => Effect.void));
156
+ }
157
+ });
158
+ }
159
+
160
+ createRouter(deps: TDeps): Router<TContract, any> {
161
+ const base = implement(config.contract).$context<ContextOutput<TRequestContext>>();
162
+ const builder = (base as any).use(
163
+ onError((error: unknown) => {
164
+ const unwrapped = extractFromFiberFailure(error);
165
+
166
+ if (unwrapped !== error && unwrapped instanceof ORPCError) {
167
+ throw unwrapped;
168
+ }
169
+
170
+ formatORPCError(error);
171
+ }),
172
+ );
173
+ const router = config.createRouter(deps, builder as any);
174
+ return router as Router<TContract, any>;
175
+ }
176
+ }
177
+
178
+ const PluginConstructor = CreatedPlugin as unknown as {
179
+ new (): Plugin<TContract, V, S, TRequestContext, TDeps>;
180
+ binding: {
181
+ contract: TContract;
182
+ variables: V;
183
+ secrets: S;
184
+ context: TRequestContext;
185
+ };
186
+ };
187
+
188
+ PluginConstructor.binding = {
189
+ contract: config.contract,
190
+ variables: config.variables,
191
+ secrets: config.secrets,
192
+ context: config.context as TRequestContext,
193
+ };
194
+
195
+ return PluginConstructor as LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
196
+ };
197
+
198
+ export type CreatePluginWithPlugins<P extends Record<string, unknown>> = <
199
+ V extends AnySchema,
200
+ S extends AnySchema,
201
+ TContract extends AnyContractRouter,
202
+ TRequestContext extends AnySchema | undefined = undefined,
203
+ TDeps extends Context = Record<never, never>,
204
+ >(
205
+ config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
206
+ ) => LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
207
+
208
+ export function withPlugins<P extends Record<string, unknown>>(): CreatePluginWithPlugins<P> {
209
+ return <
210
+ V extends AnySchema,
211
+ S extends AnySchema,
212
+ TContract extends AnyContractRouter,
213
+ TRequestContext extends AnySchema | undefined = undefined,
214
+ TDeps extends Context = Record<never, never>,
215
+ >(
216
+ config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
217
+ ) => createPlugin<V, S, TContract, TRequestContext, TDeps, P>(config as any);
218
+ }
219
+
220
+ createPlugin.withPlugins = withPlugins;