@aws/nx-plugin 0.80.1 → 0.81.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.
@@ -46,20 +46,46 @@ export interface HttpApiIntegration {
46
46
  }
47
47
 
48
48
  /**
49
- * Options for constructing an IntegrationBuilder
49
+ * Common options shared by all IntegrationBuilder configurations
50
50
  */
51
- export interface IntegrationBuilderProps<
51
+ interface IntegrationBuilderPropsBase<
52
52
  TOperation extends string,
53
- TBaseIntegration,
54
53
  TDefaultIntegrationProps extends object,
55
- TDefaultIntegration extends TBaseIntegration,
56
54
  > {
57
55
  /** Map of operation names to their API path and HTTP method details */
58
56
  operations: Record<TOperation, OperationDetails>;
59
57
 
60
58
  /** Default configuration options for integrations */
61
59
  defaultIntegrationOptions: TDefaultIntegrationProps;
60
+ }
61
+
62
+ /**
63
+ * Options for constructing an IntegrationBuilder with a shared integration pattern.
64
+ * A single default integration is built once (for '$router') and reused for all operations.
65
+ */
66
+ interface SharedIntegrationBuilderProps<
67
+ TOperation extends string,
68
+ TDefaultIntegrationProps extends object,
69
+ TDefaultIntegration,
70
+ > extends IntegrationBuilderPropsBase<TOperation, TDefaultIntegrationProps> {
71
+ pattern: 'shared';
72
+ /** Function to create a default integration for the shared router */
73
+ buildDefaultIntegration: (
74
+ op: '$router',
75
+ props: TDefaultIntegrationProps,
76
+ ) => TDefaultIntegration;
77
+ }
62
78
 
79
+ /**
80
+ * Options for constructing an IntegrationBuilder with an isolated integration pattern.
81
+ * A separate default integration is built per operation.
82
+ */
83
+ interface IsolatedIntegrationBuilderProps<
84
+ TOperation extends string,
85
+ TDefaultIntegrationProps extends object,
86
+ TDefaultIntegration,
87
+ > extends IntegrationBuilderPropsBase<TOperation, TDefaultIntegrationProps> {
88
+ pattern: 'isolated';
63
89
  /** Function to create a default integration for an operation */
64
90
  buildDefaultIntegration: (
65
91
  op: TOperation,
@@ -67,6 +93,71 @@ export interface IntegrationBuilderProps<
67
93
  ) => TDefaultIntegration;
68
94
  }
69
95
 
96
+ /**
97
+ * Options for constructing an IntegrationBuilder
98
+ */
99
+ export type IntegrationBuilderProps<
100
+ TOperation extends string,
101
+ TBaseIntegration,
102
+ TDefaultIntegrationProps extends object,
103
+ TDefaultIntegration extends TBaseIntegration,
104
+ > =
105
+ | SharedIntegrationBuilderProps<
106
+ TOperation,
107
+ TDefaultIntegrationProps,
108
+ TDefaultIntegration
109
+ >
110
+ | IsolatedIntegrationBuilderProps<
111
+ TOperation,
112
+ TDefaultIntegrationProps,
113
+ TDefaultIntegration
114
+ >;
115
+
116
+ /**
117
+ * Extracts the IntegrationBuilderProps variant matching the given pattern.
118
+ */
119
+ type IntegrationBuilderPropsForPattern<
120
+ TOperation extends string,
121
+ TBaseIntegration,
122
+ TDefaultIntegrationProps extends object,
123
+ TDefaultIntegration extends TBaseIntegration,
124
+ TPattern extends 'shared' | 'isolated',
125
+ > = Extract<
126
+ IntegrationBuilderProps<
127
+ TOperation,
128
+ TBaseIntegration,
129
+ TDefaultIntegrationProps,
130
+ TDefaultIntegration
131
+ >,
132
+ { pattern: TPattern }
133
+ >;
134
+
135
+ /**
136
+ * Resolves the default integration keys based on the pattern.
137
+ * - 'shared': only '$router' is a default key
138
+ * - 'isolated': all TOperation keys are default keys
139
+ */
140
+ type DefaultIntegrationKeys<
141
+ TPattern extends 'shared' | 'isolated',
142
+ TOperation extends string,
143
+ > = TPattern extends 'shared' ? '$router' : TOperation;
144
+
145
+ /**
146
+ * Shared integration record: $router is required, individual operations are optional.
147
+ */
148
+ type SharedIntegrations<TOperation extends string, TBaseIntegration> = {
149
+ $router: TBaseIntegration;
150
+ } & Partial<Record<TOperation, TBaseIntegration>>;
151
+
152
+ /**
153
+ * Valid integration record types for an API.
154
+ * Either all operations are provided (isolated), or $router is provided
155
+ * with optional per-operation overrides (shared).
156
+ */
157
+ export type ApiIntegrations<TOperation extends string, TBaseIntegration> =
158
+ | SharedIntegrations<TOperation, TBaseIntegration>
159
+ | (Record<TOperation, TBaseIntegration> & { $router?: never });
160
+
70
161
  /**
71
162
  * A builder class for creating API integrations with flexible configuration options.
72
163
  *
@@ -75,16 +166,18 @@ export interface IntegrationBuilderProps<
75
166
  *
76
167
  * @template TOperation - String literal type representing operation names
77
168
  * @template TBaseIntegration - Base type for all integrations
78
- * @template TIntegrations - Record mapping operation names to their integrations
169
+ * @template TIntegrations - Record mapping integration keys to their integrations
79
170
  * @template TDefaultIntegrationProps - Type for default integration properties
80
171
  * @template TDefaultIntegration - Type for default integration implementation
172
+ * @template TPattern - The integration pattern ('shared' or 'isolated')
81
173
  */
82
174
  export class IntegrationBuilder<
83
175
  TOperation extends string,
84
176
  TBaseIntegration,
85
- TIntegrations extends Record<TOperation, TBaseIntegration>,
177
+ TIntegrations extends Record<string, TBaseIntegration>,
86
178
  TDefaultIntegrationProps extends object,
87
179
  TDefaultIntegration extends TBaseIntegration,
180
+ TPattern extends 'shared' | 'isolated',
88
181
  > {
89
182
  /** Options for the integration builder */
90
183
  private options: IntegrationBuilderProps<
@@ -102,23 +195,25 @@ export class IntegrationBuilder<
102
195
  */
103
196
  public static http = <
104
197
  TOperation extends string,
105
- TIntegrations extends Record<TOperation, TDefaultIntegration>,
106
198
  TDefaultIntegrationProps extends object,
107
199
  TDefaultIntegration extends HttpApiIntegration,
200
+ TPattern extends 'shared' | 'isolated',
108
201
  >(
109
- options: IntegrationBuilderProps<
202
+ options: IntegrationBuilderPropsForPattern<
110
203
  TOperation,
111
204
  HttpApiIntegration,
112
205
  TDefaultIntegrationProps,
113
- TDefaultIntegration
206
+ TDefaultIntegration,
207
+ TPattern
114
208
  >,
115
209
  ) => {
116
210
  return new IntegrationBuilder<
117
211
  TOperation,
118
212
  HttpApiIntegration,
119
- TIntegrations,
213
+ Record<DefaultIntegrationKeys<TPattern, TOperation>, TDefaultIntegration>,
120
214
  TDefaultIntegrationProps,
121
- TDefaultIntegration
215
+ TDefaultIntegration,
216
+ TPattern
122
217
  >(options);
123
218
  };
124
219
 
@@ -127,23 +222,25 @@ export class IntegrationBuilder<
127
222
  */
128
223
  public static rest = <
129
224
  TOperation extends string,
130
- TIntegrations extends Record<TOperation, TDefaultIntegration>,
131
225
  TDefaultIntegrationProps extends object,
132
226
  TDefaultIntegration extends RestApiIntegration,
227
+ TPattern extends 'shared' | 'isolated',
133
228
  >(
134
- options: IntegrationBuilderProps<
229
+ options: IntegrationBuilderPropsForPattern<
135
230
  TOperation,
136
231
  RestApiIntegration,
137
232
  TDefaultIntegrationProps,
138
- TDefaultIntegration
233
+ TDefaultIntegration,
234
+ TPattern
139
235
  >,
140
236
  ) => {
141
237
  return new IntegrationBuilder<
142
238
  TOperation,
143
239
  RestApiIntegration,
144
- TIntegrations,
240
+ Record<DefaultIntegrationKeys<TPattern, TOperation>, TDefaultIntegration>,
145
241
  TDefaultIntegrationProps,
146
- TDefaultIntegration
242
+ TDefaultIntegration,
243
+ TPattern
147
244
  >(options);
148
245
  };
149
246
 
@@ -168,13 +265,20 @@ export class IntegrationBuilder<
168
265
  TOverrideIntegrations extends Partial<Record<TOperation, TBaseIntegration>>,
169
266
  >(overrides: TOverrideIntegrations) {
170
267
  this.integrations = { ...this.integrations, ...overrides };
171
- // Re-type to include the overridden integration types
268
+ // Re-type to include the overridden integration types.
269
+ // If all operations are overridden in a 'shared' pattern, drop '$router' from the type.
270
+ type MergedIntegrations = [TOperation] extends [keyof TOverrideIntegrations]
271
+ ? Omit<TIntegrations, keyof TOverrideIntegrations | '$router'> &
272
+ TOverrideIntegrations
273
+ : Omit<TIntegrations, keyof TOverrideIntegrations> &
274
+ TOverrideIntegrations;
172
275
  return this as unknown as IntegrationBuilder<
173
276
  TOperation,
174
277
  TBaseIntegration,
175
- Omit<TIntegrations, keyof TOverrideIntegrations> & TOverrideIntegrations,
278
+ MergedIntegrations,
176
279
  TDefaultIntegrationProps,
177
- TDefaultIntegration
280
+ TDefaultIntegration,
281
+ TPattern
178
282
  >;
179
283
  }
180
284
 
@@ -200,24 +304,39 @@ export class IntegrationBuilder<
200
304
  * 1. Including all custom overrides provided via withOverrides()
201
305
  * 2. Creating default integrations for any operations without custom overrides
202
306
  *
203
- * @returns A complete map of operation names to their integrations
307
+ * For the 'shared' pattern, a single router integration is built and assigned to '$router'.
308
+ * For the 'isolated' pattern, each operation without an override gets its own integration.
309
+ *
310
+ * @returns A complete map of integration keys to their integrations
204
311
  */
205
312
  public build(): TIntegrations {
313
+ const options = this.options;
206
314
  return {
207
- ...this.integrations,
208
315
  ...Object.fromEntries(
209
- (Object.keys(this.options.operations) as TOperation[])
210
- .filter(
211
- (op) => !this.integrations[op as keyof typeof this.integrations],
212
- )
213
- .map((op) => [
214
- op,
215
- this.options.buildDefaultIntegration(
216
- op,
217
- this.options.defaultIntegrationOptions,
218
- ),
219
- ]),
316
+ options.pattern === 'shared'
317
+ ? [
318
+ [
319
+ '$router',
320
+ options.buildDefaultIntegration(
321
+ '$router',
322
+ options.defaultIntegrationOptions,
323
+ ),
324
+ ],
325
+ ]
326
+ : (Object.keys(options.operations) as TOperation[])
327
+ .filter(
328
+ (op) =>
329
+ !this.integrations[op as keyof typeof this.integrations],
330
+ )
331
+ .map((op) => [
332
+ op,
333
+ options.buildDefaultIntegration(
334
+ op,
335
+ options.defaultIntegrationOptions,
336
+ ),
337
+ ]),
220
338
  ),
339
+ ...this.integrations,
221
340
  } as unknown as TIntegrations;
222
341
  }
223
342
  }