ts-forge 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ ## v1.0.0
2
+
3
+ - `@Resolver()` and `@ResolverFn()` decorators were created
4
+ - Created `getDefinitionsForClass()` function which handles resolver functions definition
package/README.md ADDED
@@ -0,0 +1,228 @@
1
+ **Warning:** The first version of this library is ready, however documentation is still in progress
2
+
3
+ ## @Resolver
4
+
5
+ ```ts
6
+ import { Resolver, ResolverFn } from "ts-forge";
7
+
8
+ @Resolver({
9
+ middlewares: [authMiddleware, adminMiddleware],
10
+ errorHandler: myErrorHandler
11
+ })
12
+ class HelloWorldResolver {}
13
+ ```
14
+
15
+ #### Parameters
16
+
17
+ Parameter 1 (Resolver config) - Optional
18
+
19
+ - `errorHandler: (error: any, request: Request) => any | Promise<any>`
20
+ - Optional
21
+ - If an error is thrown in your resolver function or middlewares, this function will be called so that you can handle the error and return a response
22
+ - `middlewares: ((request: Request) => any | Promise<any>)[]`
23
+ - Optional
24
+ - This is an array of middleware functions, each function will be called before the resolver function
25
+ - If you return a value it will be sent to the frontend, pending middlewares and resolver function won't be called
26
+
27
+ ## @ResolverFn
28
+
29
+ ```ts
30
+ import { Request } from "@forge/resolver";
31
+ import { Resolver, ResolverFn } from "ts-forge";
32
+
33
+ @Resolver()
34
+ class HelloWorldResolver {
35
+ @ResolverFn("my-resolver")
36
+ public async hello(req: Request) {
37
+ return { message: "Hello world!" };
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### Parameters
43
+
44
+ **Parameter 1 (Resolver key or resolver function config) - Required**
45
+
46
+ You could use either, a string or an object
47
+
48
+ **Resolver key**
49
+
50
+ - `string`
51
+ - Required
52
+ - This is the resolver key that you will use when you call `invoke()` method in your addon's UI
53
+
54
+ **Resolver function config**
55
+
56
+ - `{ key: string, middlewares?: MiddlewareFn[], errorHandler?: ErrorHandlerFn }`
57
+ - `key: string`
58
+ - Required
59
+ - This is the resolver key that you will use when you call `invoke()` method in your addon's UI
60
+ - `middlewares: ((request: Request) => any | Promise<any>)[]`
61
+ - Optional
62
+ - This is an array of middleware functions, each function will be called before the resolver function
63
+ - If you return a value it will be sent to the frontend, pending middlewares and resolver function won't be called
64
+ - `errorHandler: (error: any, request: Request) => any | Promise<any>`
65
+ - Optional
66
+ - If an error is thrown in your resolver function or middlewares, this function will be called so that you can handle the error and return a response
67
+
68
+ The `@ResolverFn()` decorator takes only one argument, which can be either a string or an object
69
+ If you don't need to define middlewares or an error handler, you could just pass the resolver key
70
+
71
+ ```ts
72
+ @Resolver()
73
+ class HelloWorldResolver {
74
+ @ResolverFn("my-resolver")
75
+ async hello(req: Request) {}
76
+ }
77
+ ```
78
+
79
+ or, if you need to define middlewares or an error handler for that resolver function, you could pass a config object like this:
80
+
81
+ ```ts
82
+ @Resolver()
83
+ class HelloWorldResolver {
84
+ @ResolverFn({
85
+ key: "my-resolver",
86
+ middlewares: [authMiddleware, adminMiddleware],
87
+ errorHandler: myErrorHandler
88
+ })
89
+ async hello(req: Request) {}
90
+ }
91
+ ```
92
+
93
+ ## getDefinitionsForClass
94
+
95
+ This function is used to get definitions of the resolvers that you created, it uses `@forge/resolver` under the hood to define resolvers then calls `getDefinitions()` method and returns its result
96
+
97
+ ```ts
98
+ import { getDefinitionsForClass } from "ts-forge";
99
+
100
+ getDefinitionsForClass({
101
+ resolvers: [HelloWorldResolver, GetJiraProjectResolver],
102
+ errorHandler: ErrorHandlerFn,
103
+ middlewares: MiddlewareFn[]
104
+ });
105
+ ```
106
+
107
+ #### Parameters
108
+
109
+ **Parameter 1 (Config) - Required**
110
+
111
+ - `{ resolvers: [], middlewares: MiddlewareFn[], errorHandler: ErrorHandlerFn }`
112
+ - `resolvers`
113
+ - Required
114
+ - This is an array of class instances in which you used the `@Resolver()` decorator
115
+ - Must have at least one element
116
+ - `middlewares: ((request: Request) => any | Promise<any>)[]`
117
+ - Optional
118
+ - This is an array of middleware functions, each function will be called before the resolver function
119
+ - If you return a value it will be sent to the frontend, pending middlewares and resolver function won't be called
120
+ - Those middlewares will be called before each resolver function defined in `resolvers`
121
+ - **Note:** Middlewares defined here will be the last to be called, in case you have defined middlewares in `@Resolver()` or `@ResolverFn()`
122
+ - `errorHandler: (error: any, request: Request) => any | Promise<any>`
123
+ - Optional
124
+ - If an error is thrown in your resolver function or middlewares, this function will be called so that you can handle the error and return a response
125
+ - This function will handle errors for all the resolver functions defined in `resolvers`
126
+ - **Note:** This function will be called only when an error handler was not defined in `@Resolver()` and `@ResolverFn()`
127
+
128
+ ## Middlewares
129
+
130
+ You can define middlewares in `@ResolverFn()`, `@Resolver()` and `getDefinitionsForClass()`. It only takes one parameter which is the same request object you have access to in resolver functions
131
+
132
+ Middleware functions have priority depending where they were defined. When a resolver function is invoked, the middlewares will be called in the following order:
133
+
134
+ 1. `@ResolverFn()`: Middlewares defined in this decorator's config will be the first to be called
135
+ 2. `@Resolver()`: Middlewares defined in this decorator's config will run after `@ResolverFn()`'s middlewares are called. If no middlewares were defined in `@ResolverFn()`, middlewares defined in `@Resolver()` would be the first to be called
136
+ 3. `getDefinitionsForClass()`: Middlewares defined in this function will be the last to be called. If no middlewares were defined in `@ResolverFn()` and `@Resolver()`, middlewares defined in `getDefinitionsForClass()` would be the first to be called, this is useful when you want the same middlewares to be called for all of your resolver functions, so that you don't have to define the same middlewares in each `@ResolverFn()` or `@Resolver()`
137
+
138
+ #### Usage
139
+
140
+ This is an example of a middleware function
141
+
142
+ ```ts
143
+ import { Request } from "@forge/resolver";
144
+
145
+ // Request is the same object you have access to in your resolver functions
146
+ function verifyUserIsJiraAdmin(request: Request): any | Promise<any> {
147
+ // Verify that the current user is a jira admin ...
148
+ }
149
+ ```
150
+
151
+ Then you can use this middleware in `@ResolverFn()`, `@Resolver()` or `getDefinitionsForClass()`
152
+
153
+ In the following example the `verifyUserIsJiraAdmin` middleware is used in `@ResolverFn()`. This is useful when you want certain middleware to be called for some resolver functions
154
+
155
+ ```ts
156
+ @Resolver()
157
+ class HelloWorldResolver {
158
+ @ResolverFn({
159
+ key: "hello-world",
160
+ middlewares: [verifyUserIsJiraAdmin]
161
+ })
162
+ async helloWorld() {
163
+ // Do whatever this resolver should do
164
+ }
165
+
166
+ // verifyUserIsJiraAdmin won't be called when this resolver function is invoked
167
+ @ResolverFn({
168
+ key: "get-current-user",
169
+ middlewares: []
170
+ })
171
+ async getCurrentUser() {
172
+ // Return current user
173
+ }
174
+ }
175
+ ```
176
+
177
+ In this example the `verifyUserIsJiraAdmin` middleware is used in `@Resolver()`. Middlewares defined in this decorator will be called for all resolver functions defined in the class.
178
+
179
+ ```ts
180
+ @Resolver({
181
+ // Middlewares defined in this array will be called in each resolver function defined in this class
182
+ middlewares: [verifyUserIsJiraAdmin]
183
+ })
184
+ class HelloWorldResolver {
185
+ // There's no need to add the same middleware in @ResolverFn()
186
+ @ResolverFn("hello-world")
187
+ async helloWorld() {
188
+ // Do whatever this resolver should do
189
+ }
190
+
191
+ // verifyUserIsJiraAdmin will also be called before this resolver function
192
+ @ResolverFn("get-current-user")
193
+ async getCurrentUser() {
194
+ // Return current user
195
+ }
196
+ }
197
+ ```
198
+
199
+ Last but not least, you can define middlewares in the `getDefinitionsForClass` function. Middlewares defined here will be called in all resolvers that you pass to the `resolvers` array
200
+
201
+ ```ts
202
+ @Resolver()
203
+ class HelloWorldResolver {
204
+ @ResolverFn("hello-world")
205
+ helloWorld(request: Request) {
206
+ return { message: "Hello world!" };
207
+ }
208
+ }
209
+
210
+ @Resolver()
211
+ class UserResolver {
212
+ @ResolverFn("get-user")
213
+ getUser(request: Request) {
214
+ return {...};
215
+ }
216
+ }
217
+
218
+ const definitions = getDefinitionsForClass({
219
+ middlewares: [verifyUserIsJiraAdmin],
220
+ // Middlewares will be called before each resolver function, you don't need to add the verifyUserIsJiraAdmin middleware
221
+ // in @Resolver or @ResolverFn decorators
222
+ resolvers: [HelloWorldResolver, UserResolver]
223
+ })
224
+ ```
225
+
226
+ ## Error handler
227
+
228
+ An error handler is a function that is called when an error is thrown in a resolver function
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ RESOLVER_FUNCTIONS: symbol;
3
+ RESOLVER_CONFIG: symbol;
4
+ };
5
+ export default _default;
@@ -0,0 +1,4 @@
1
+ export default {
2
+ RESOLVER_FUNCTIONS: Symbol.for("@@resolver__functions@@"),
3
+ RESOLVER_CONFIG: Symbol.for("@@resolver__config@@")
4
+ };
@@ -0,0 +1,20 @@
1
+ import { ResolverConfig } from "../types";
2
+ /**
3
+ * Decorator for defining forge resolvers.
4
+ * @param ResolverConfig - Configuration object for the resolver.
5
+ * @param ResolverConfig.middlewares - Array of middleware functions to be applied to the resolver functions.
6
+ * @param ResolverConfig.errorHandler - Custom error handler function for the resolver functions.
7
+ * @returns A modified class with resolver configuration.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * \@Resolver({
12
+ * middlewares: [myMiddleware],
13
+ * errorHandler: myErrorHandler,
14
+ * })
15
+ * class MyResolver{}
16
+ * ```
17
+ */
18
+ export declare function Resolver(config?: ResolverConfig): <T extends {
19
+ new (...args: any[]): {};
20
+ }>(constructor: T) => void;
@@ -0,0 +1,26 @@
1
+ import _ from "../constants";
2
+ /**
3
+ * Decorator for defining forge resolvers.
4
+ * @param ResolverConfig - Configuration object for the resolver.
5
+ * @param ResolverConfig.middlewares - Array of middleware functions to be applied to the resolver functions.
6
+ * @param ResolverConfig.errorHandler - Custom error handler function for the resolver functions.
7
+ * @returns A modified class with resolver configuration.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * \@Resolver({
12
+ * middlewares: [myMiddleware],
13
+ * errorHandler: myErrorHandler,
14
+ * })
15
+ * class MyResolver{}
16
+ * ```
17
+ */
18
+ export function Resolver(config) {
19
+ if (config === void 0) { config = { middlewares: [], errorHandler: undefined }; }
20
+ return function (constructor) {
21
+ constructor.prototype[_.RESOLVER_CONFIG] = {
22
+ middlewares: Array.from(config.middlewares || []),
23
+ errorHandler: config.errorHandler
24
+ };
25
+ };
26
+ }
@@ -0,0 +1,9 @@
1
+ import { ResolverFnConfig } from "../types";
2
+ /**
3
+ * Define a resolver function
4
+ * @param resolverFnConfig - Resolver function config
5
+ * @param resolverFnConfig.middlewares - Array of middleware functions to be applied to this resolver function
6
+ * @param resolverFnConfig.errorHandler - Custom error handler function for this resolver function
7
+ * @returns - Response
8
+ */
9
+ export declare function ResolverFn(resolverFnConfig: ResolverFnConfig | string): (target: any, propertyKey: string, descriptor: any) => void;
@@ -0,0 +1,135 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import isResolverFnConfig from "../utils/isResolverFnConfig";
38
+ import _ from "../constants";
39
+ /**
40
+ * Define a resolver function
41
+ * @param resolverFnConfig - Resolver function config
42
+ * @param resolverFnConfig.middlewares - Array of middleware functions to be applied to this resolver function
43
+ * @param resolverFnConfig.errorHandler - Custom error handler function for this resolver function
44
+ * @returns - Response
45
+ */
46
+ export function ResolverFn(resolverFnConfig) {
47
+ return function (target, propertyKey, descriptor) {
48
+ // Handle the case where resolverFnConfig is a string
49
+ var config = isResolverFnConfig(resolverFnConfig)
50
+ ? resolverFnConfig
51
+ : { key: resolverFnConfig, middlewares: [], errorHandler: undefined };
52
+ // If the middlewares property is not an array, initialize it as an empty array
53
+ if (!Array.isArray(config.middlewares)) {
54
+ config.middlewares = [];
55
+ }
56
+ // Check if the target has the resolverNames property
57
+ if (!target[_.RESOLVER_FUNCTIONS]) {
58
+ target[_.RESOLVER_FUNCTIONS] = [];
59
+ }
60
+ // Add the resolver's data to the target
61
+ target[_.RESOLVER_FUNCTIONS].push({
62
+ config: config,
63
+ methodName: propertyKey
64
+ });
65
+ var method = descriptor.value;
66
+ descriptor.value = function (req) {
67
+ return __awaiter(this, void 0, void 0, function () {
68
+ var targetConfig, middlewares, _i, middlewares_1, middleware, response, error_1, errorHandlerFn, err_1;
69
+ return __generator(this, function (_a) {
70
+ switch (_a.label) {
71
+ case 0:
72
+ targetConfig = this[_.RESOLVER_CONFIG] || {};
73
+ _a.label = 1;
74
+ case 1:
75
+ _a.trys.push([1, 7, , 12]);
76
+ middlewares = Array.from(config.middlewares || []);
77
+ // If there are middlewares defined in the resolver class, add them to the middlewares array
78
+ if (Array.isArray(targetConfig.middlewares)) {
79
+ middlewares.push.apply(middlewares, targetConfig.middlewares);
80
+ }
81
+ // If there are middlewares defined in the getDefinitionsForClass config, add them to the middlewares array
82
+ if (Array.isArray(targetConfig.globalMiddlewares)) {
83
+ middlewares.push.apply(middlewares, targetConfig.globalMiddlewares);
84
+ }
85
+ _i = 0, middlewares_1 = middlewares;
86
+ _a.label = 2;
87
+ case 2:
88
+ if (!(_i < middlewares_1.length)) return [3 /*break*/, 5];
89
+ middleware = middlewares_1[_i];
90
+ return [4 /*yield*/, middleware(req)];
91
+ case 3:
92
+ response = _a.sent();
93
+ // If response is provided, send it to the frontend
94
+ // This means that the resolver or next middleware will not be called
95
+ if (response) {
96
+ return [2 /*return*/, response];
97
+ }
98
+ _a.label = 4;
99
+ case 4:
100
+ _i++;
101
+ return [3 /*break*/, 2];
102
+ case 5: return [4 /*yield*/, method.call(this, req)];
103
+ case 6:
104
+ // Call the original method
105
+ return [2 /*return*/, _a.sent()];
106
+ case 7:
107
+ error_1 = _a.sent();
108
+ errorHandlerFn = config.errorHandler || (targetConfig === null || targetConfig === void 0 ? void 0 : targetConfig.errorHandler) || (targetConfig === null || targetConfig === void 0 ? void 0 : targetConfig.globalErrorHandler);
109
+ if (!errorHandlerFn) return [3 /*break*/, 11];
110
+ _a.label = 8;
111
+ case 8:
112
+ _a.trys.push([8, 10, , 11]);
113
+ req.context.resolver = {
114
+ key: config.key,
115
+ className: target.constructor.name,
116
+ methodName: propertyKey
117
+ };
118
+ return [4 /*yield*/, errorHandlerFn(error_1, req)];
119
+ case 9: return [2 /*return*/, _a.sent()];
120
+ case 10:
121
+ err_1 = _a.sent();
122
+ // If the error handler throws an error, log it and return the original error
123
+ console.error(err_1);
124
+ return [2 /*return*/, error_1];
125
+ case 11:
126
+ // If no error handler is provided, log the error, then return it
127
+ console.error(error_1);
128
+ return [2 /*return*/, error_1];
129
+ case 12: return [2 /*return*/];
130
+ }
131
+ });
132
+ });
133
+ };
134
+ };
135
+ }
@@ -0,0 +1,4 @@
1
+ export { Resolver } from "./decorators/resolver";
2
+ export { ResolverFn } from "./decorators/resolverFn";
3
+ export { getDefinitionsForClass } from "./utils/getDefinitionsForClass";
4
+ export { RequestError, ErrorHandlerFn, MiddlewareFn } from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Resolver } from "./decorators/resolver";
2
+ export { ResolverFn } from "./decorators/resolverFn";
3
+ export { getDefinitionsForClass } from "./utils/getDefinitionsForClass";
@@ -0,0 +1,15 @@
1
+ import { ResolverFunction, Request } from "@forge/resolver";
2
+ interface InvokePayload {
3
+ call: {
4
+ functionKey: string;
5
+ payload?: {
6
+ [key in number | string]: any;
7
+ };
8
+ jobId?: string;
9
+ };
10
+ context: {
11
+ [key: string]: any;
12
+ };
13
+ }
14
+ export type DefinitionsHandler = (payload: InvokePayload, backendRuntimePayload?: Request["payload"]) => Promise<ReturnType<ResolverFunction>>;
15
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from "./forge";
2
+ export * from "./resolver";
3
+ export * from "./utils";
@@ -0,0 +1,3 @@
1
+ export * from "./forge";
2
+ export * from "./resolver";
3
+ export * from "./utils";
@@ -0,0 +1,29 @@
1
+ import { Request } from "@forge/resolver";
2
+ export interface ResolverConfig {
3
+ middlewares?: MiddlewareFn[];
4
+ errorHandler?: ErrorHandlerFn;
5
+ }
6
+ export interface ResolverClassConfig extends ResolverConfig {
7
+ globalMiddlewares?: MiddlewareFn[];
8
+ globalErrorHandler?: ErrorHandlerFn;
9
+ }
10
+ export type MiddlewareFn = (req: Request) => Promise<any> | any;
11
+ export type ErrorHandlerFn = (error: any, req: RequestError) => any;
12
+ export type RequestError = Request & {
13
+ context: Request["context"] & {
14
+ resolver: {
15
+ key: string;
16
+ className: string;
17
+ methodName: string;
18
+ };
19
+ };
20
+ };
21
+ export interface ResolverFnConfig {
22
+ key: string;
23
+ middlewares?: MiddlewareFn[];
24
+ errorHandler?: ErrorHandlerFn;
25
+ }
26
+ export interface TargetResolverFnConfig {
27
+ config: ResolverFnConfig;
28
+ methodName: string;
29
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { MiddlewareFn, ErrorHandlerFn } from "./resolver";
2
+ export interface GetDefinitionsForClassParams {
3
+ resolvers: any[];
4
+ middlewares?: MiddlewareFn[];
5
+ errorHandler?: ErrorHandlerFn;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { DefinitionsHandler, GetDefinitionsForClassParams } from "@/types";
2
+ /**
3
+ * Get definitions for the provided resolvers
4
+ * @param config - Config
5
+ * @param config.resolvers - Array of resolvers
6
+ * @param config.middlewares - Array of middlewares to be applied to the provided resolvers
7
+ * @param config.errorHandler - Custom error handler to be applied to the provided resolvers
8
+ * @returns - Resolver definitions
9
+ */
10
+ export declare function getDefinitionsForClass({ resolvers, middlewares, errorHandler }: GetDefinitionsForClassParams): DefinitionsHandler;
@@ -0,0 +1,43 @@
1
+ import ForgeResolver from "@forge/resolver";
2
+ import _ from "../constants";
3
+ /**
4
+ * Get definitions for the provided resolvers
5
+ * @param config - Config
6
+ * @param config.resolvers - Array of resolvers
7
+ * @param config.middlewares - Array of middlewares to be applied to the provided resolvers
8
+ * @param config.errorHandler - Custom error handler to be applied to the provided resolvers
9
+ * @returns - Resolver definitions
10
+ */
11
+ export function getDefinitionsForClass(_a) {
12
+ var resolvers = _a.resolvers, _b = _a.middlewares, middlewares = _b === void 0 ? [] : _b, errorHandler = _a.errorHandler;
13
+ var forgeResolver = new ForgeResolver();
14
+ if (!Array.isArray(middlewares)) {
15
+ throw new Error("Middlewares must be an array");
16
+ }
17
+ if (middlewares.length > 0 && !middlewares.every(function (m) { return typeof m === "function"; })) {
18
+ throw new Error("All middlewares must be functions");
19
+ }
20
+ if (errorHandler && typeof errorHandler !== "function") {
21
+ throw new Error("Error handler must be a function");
22
+ }
23
+ for (var _i = 0, resolvers_1 = resolvers; _i < resolvers_1.length; _i++) {
24
+ var instance = resolvers_1[_i];
25
+ if (instance[_.RESOLVER_CONFIG]) {
26
+ // Set global middlewares and error handler for the resolver class
27
+ var instanceConfig = {
28
+ middlewares: Array.from(instance[_.RESOLVER_CONFIG].middlewares || []),
29
+ errorHandler: instance[_.RESOLVER_CONFIG].errorHandler
30
+ };
31
+ instanceConfig.globalMiddlewares = Array.from(middlewares);
32
+ // Set the global error handler
33
+ instanceConfig.globalErrorHandler = errorHandler;
34
+ // Set the updated config on the instance
35
+ instance[_.RESOLVER_CONFIG] = instanceConfig;
36
+ }
37
+ for (var _c = 0, _d = instance[_.RESOLVER_FUNCTIONS]; _c < _d.length; _c++) {
38
+ var resolver = _d[_c];
39
+ forgeResolver.define(resolver.config.key, instance[resolver.methodName].bind(instance));
40
+ }
41
+ }
42
+ return forgeResolver.getDefinitions();
43
+ }
@@ -0,0 +1,2 @@
1
+ import { ResolverFnConfig } from "../types";
2
+ export default function isResolverFnConfig(config: ResolverFnConfig | string): config is ResolverFnConfig;
@@ -0,0 +1,6 @@
1
+ export default function isResolverFnConfig(config) {
2
+ return (typeof config === "object" &&
3
+ typeof config.key === "string" &&
4
+ (typeof config.middlewares === "undefined" || Array.isArray(config.middlewares)) &&
5
+ (typeof config.errorHandler === "undefined" || typeof config.errorHandler === "function"));
6
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "ts-forge",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "scripts": {
6
+ "test": "vitest --run",
7
+ "test:ui": "vitest --ui",
8
+ "test:watch": "vitest",
9
+ "test:coverage": "vitest --run --coverage",
10
+ "dev": "tsc -p ./tsconfig.json --watch",
11
+ "build": "eval $(rm -r dist) && tsc -p ./tsconfig.json",
12
+ "prepublish": "npm run build"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://www.github.com/gustavo0197/ts-forge"
17
+ },
18
+ "keywords": [
19
+ "forge",
20
+ "atlassian",
21
+ "addon"
22
+ ],
23
+ "author": "Gustavo Velazquez",
24
+ "license": "ISC",
25
+ "description": "Decorators for creating resolvers in Atlassian's Forge addons",
26
+ "peerDependencies": {
27
+ "@forge/resolver": ">=1.6.0 <2.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@vitest/coverage-v8": "3.1.4",
31
+ "jsdom": "^26.1.0",
32
+ "typescript": "5.8.3",
33
+ "vitest": "^3.1.4"
34
+ }
35
+ }