@skmtc/core 0.0.794 → 0.0.796

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.
@@ -6,14 +6,183 @@ const lodash_es_1 = require("lodash-es");
6
6
  const ts_pattern_1 = require("ts-pattern");
7
7
  const List_js_1 = require("./List.js");
8
8
  const isEmpty_js_1 = require("../helpers/isEmpty.js");
9
+ /**
10
+ * Generates TypeScript function parameters with advanced handling for different parameter patterns.
11
+ *
12
+ * `FunctionParameter` is a sophisticated utility for generating TypeScript function parameter
13
+ * syntax that handles multiple parameter patterns including named parameters, destructured
14
+ * object parameters, and void parameters. It provides intelligent type handling and can
15
+ * generate both the parameter declaration and the parameter usage patterns.
16
+ *
17
+ * This class is essential for generating type-safe function signatures in API clients,
18
+ * utility functions, and other generated code where parameters need to be handled
19
+ * consistently and safely.
20
+ *
21
+ * ## Supported Parameter Patterns
22
+ *
23
+ * - **Named Parameters**: Traditional `paramName: Type` syntax
24
+ * - **Destructured Parameters**: `{ prop1, prop2 }: ObjectType` syntax
25
+ * - **Void Parameters**: No parameters when dealing with void types
26
+ * - **Optional Parameters**: Automatic handling of optional parameter markers
27
+ * - **Empty Filtering**: Option to skip empty properties in destructured objects
28
+ *
29
+ * @example Named parameter generation
30
+ * ```typescript
31
+ * import { FunctionParameter, Definition, Identifier } from '@skmtc/core';
32
+ *
33
+ * const userIdParam = new FunctionParameter({
34
+ * name: 'userId',
35
+ * typeDefinition: new Definition({
36
+ * context: generateContext,
37
+ * identifier: Identifier.createType('string'),
38
+ * value: { type: 'string' }
39
+ * }),
40
+ * required: true
41
+ * });
42
+ *
43
+ * console.log(userIdParam.toString()); // 'userId: string'
44
+ * console.log(userIdParam.toInbound()); // 'userId'
45
+ * ```
46
+ *
47
+ * @example Destructured parameter generation
48
+ * ```typescript
49
+ * const destructuredParam = new FunctionParameter({
50
+ * typeDefinition: new Definition({
51
+ * context: generateContext,
52
+ * identifier: Identifier.createType('UserParams'),
53
+ * value: {
54
+ * type: 'object',
55
+ * objectProperties: {
56
+ * properties: {
57
+ * name: { type: 'string' },
58
+ * email: { type: 'string' },
59
+ * age: { type: 'number' }
60
+ * }
61
+ * }
62
+ * }
63
+ * }),
64
+ * destructure: true,
65
+ * required: true
66
+ * });
67
+ *
68
+ * console.log(destructuredParam.toString());
69
+ * // '{ name, email, age }: UserParams'
70
+ *
71
+ * console.log(destructuredParam.toInbound());
72
+ * // '{ name, email, age }'
73
+ * ```
74
+ *
75
+ * @example Optional parameter handling
76
+ * ```typescript
77
+ * const optionalParam = new FunctionParameter({
78
+ * name: 'options',
79
+ * typeDefinition: optionsTypeDefinition,
80
+ * required: false
81
+ * });
82
+ *
83
+ * console.log(optionalParam.toString()); // 'options?: OptionsType'
84
+ * ```
85
+ *
86
+ * @example Void parameter handling
87
+ * ```typescript
88
+ * const voidParam = new FunctionParameter({
89
+ * typeDefinition: new Definition({
90
+ * context: generateContext,
91
+ * identifier: Identifier.createType('void'),
92
+ * value: { type: 'void' }
93
+ * })
94
+ * });
95
+ *
96
+ * console.log(voidParam.toString()); // ''
97
+ * console.log(voidParam.toInbound()); // ''
98
+ * ```
99
+ *
100
+ * @example Property checking
101
+ * ```typescript
102
+ * const objectParam = new FunctionParameter({
103
+ * typeDefinition: userTypeDefinition,
104
+ * destructure: true,
105
+ * required: true
106
+ * });
107
+ *
108
+ * if (objectParam.hasProperty('email')) {
109
+ * // Handle email property access
110
+ * console.log('Parameter includes email property');
111
+ * }
112
+ *
113
+ * const propertyList = objectParam.toPropertyList();
114
+ * console.log(propertyList.toString()); // 'name, email, age'
115
+ * ```
116
+ *
117
+ * @example API method generation with parameters
118
+ * ```typescript
119
+ * class ApiMethodGenerator {
120
+ * generateMethod(
121
+ * methodName: string,
122
+ * pathParams?: FunctionParameter,
123
+ * bodyParam?: FunctionParameter
124
+ * ) {
125
+ * const parameters = [pathParams, bodyParam]
126
+ * .filter(p => p && p.toString())
127
+ * .map(p => p!.toString())
128
+ * .join(', ');
129
+ *
130
+ * const pathInbound = pathParams?.toInbound() || '';
131
+ * const bodyInbound = bodyParam?.toInbound() || '';
132
+ *
133
+ * return `
134
+ * async ${methodName}(${parameters}) {
135
+ * const path = this.buildPath(${pathInbound});
136
+ * return this.request('POST', path, ${bodyInbound});
137
+ * }`;
138
+ * }
139
+ * }
140
+ * ```
141
+ *
142
+ * @example Empty property filtering
143
+ * ```typescript
144
+ * const filteredParam = new FunctionParameter({
145
+ * typeDefinition: sparseObjectDefinition,
146
+ * destructure: true,
147
+ * required: true,
148
+ * skipEmpty: true // Skip properties with empty types
149
+ * });
150
+ *
151
+ * // Only non-empty properties will be included in destructuring
152
+ * console.log(filteredParam.toString());
153
+ * // '{ validProp1, validProp2 }: FilteredType' (empty props omitted)
154
+ * ```
155
+ */
9
156
  class FunctionParameter {
157
+ /**
158
+ * Creates a new FunctionParameter instance with the specified configuration.
159
+ *
160
+ * The constructor analyzes the provided type definition and configuration options
161
+ * to determine the appropriate parameter pattern (void, regular, or destructured).
162
+ * It handles the complex logic of parameter type determination and validation.
163
+ *
164
+ * @param args - Configuration options for the function parameter
165
+ *
166
+ * @throws {Error} When the parameter configuration is invalid
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * const param = new FunctionParameter({
171
+ * name: 'userData',
172
+ * typeDefinition: userTypeDefinition,
173
+ * required: true
174
+ * });
175
+ * ```
176
+ */
10
177
  constructor(args) {
178
+ /** The internal parameter configuration determining how the parameter is generated */
11
179
  Object.defineProperty(this, "properties", {
12
180
  enumerable: true,
13
181
  configurable: true,
14
182
  writable: true,
15
183
  value: void 0
16
184
  });
185
+ /** Whether to skip empty properties in destructured parameters */
17
186
  Object.defineProperty(this, "skipEmpty", {
18
187
  enumerable: true,
19
188
  configurable: true,
@@ -42,6 +211,34 @@ class FunctionParameter {
42
211
  this.properties = { type: 'void' };
43
212
  }
44
213
  }
214
+ /**
215
+ * Checks if the parameter has a specific property (for object-based parameters).
216
+ *
217
+ * This method determines whether a given property name exists within the parameter's
218
+ * type structure. It's useful for conditional code generation based on available
219
+ * properties and only returns true for object-based parameters (regular object
220
+ * parameters or destructured parameters).
221
+ *
222
+ * @param name - The property name to check for
223
+ * @returns True if the property exists in the parameter's type structure
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * const userParam = new FunctionParameter({
228
+ * typeDefinition: userTypeDefinition, // has properties: name, email, age
229
+ * destructure: true,
230
+ * required: true
231
+ * });
232
+ *
233
+ * if (userParam.hasProperty('email')) {
234
+ * console.log('Parameter includes email property');
235
+ * }
236
+ *
237
+ * if (userParam.hasProperty('nonexistent')) {
238
+ * // This won't execute
239
+ * }
240
+ * ```
241
+ */
45
242
  hasProperty(name) {
46
243
  return (0, ts_pattern_1.match)(this.properties)
47
244
  .with({ type: 'void' }, () => false)
@@ -54,6 +251,37 @@ class FunctionParameter {
54
251
  })
55
252
  .exhaustive();
56
253
  }
254
+ /**
255
+ * Generates a List of property names from the parameter.
256
+ *
257
+ * This method extracts property names from object-based parameters and returns
258
+ * them as a List instance. For regular parameters, it returns the parameter name,
259
+ * for destructured parameters it returns all object properties, and for void
260
+ * parameters it returns an empty list.
261
+ *
262
+ * @returns List containing the relevant property or parameter names
263
+ *
264
+ * @example
265
+ * ```typescript
266
+ * const destructuredParam = new FunctionParameter({
267
+ * typeDefinition: userTypeDefinition, // has properties: name, email, age
268
+ * destructure: true,
269
+ * required: true
270
+ * });
271
+ *
272
+ * const propertyList = destructuredParam.toPropertyList();
273
+ * console.log(propertyList.toString()); // 'name, email, age'
274
+ *
275
+ * const regularParam = new FunctionParameter({
276
+ * name: 'userData',
277
+ * typeDefinition: userTypeDefinition,
278
+ * required: true
279
+ * });
280
+ *
281
+ * const regularList = regularParam.toPropertyList();
282
+ * console.log(regularList.toString()); // 'userData'
283
+ * ```
284
+ */
57
285
  toPropertyList() {
58
286
  return (0, ts_pattern_1.match)(this.properties)
59
287
  .with({ type: 'void' }, () => List_js_1.List.toEmpty())
@@ -63,6 +291,35 @@ class FunctionParameter {
63
291
  })
64
292
  .exhaustive();
65
293
  }
294
+ /**
295
+ * Generates the inbound parameter syntax for function calls.
296
+ *
297
+ * This method produces the syntax used when calling a function with this parameter.
298
+ * For regular parameters, it returns the parameter name. For destructured parameters,
299
+ * it returns the destructured object syntax. For void parameters, it returns an
300
+ * empty string.
301
+ *
302
+ * @returns The inbound parameter syntax string
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const regularParam = new FunctionParameter({
307
+ * name: 'userId',
308
+ * typeDefinition: stringTypeDefinition,
309
+ * required: true
310
+ * });
311
+ *
312
+ * console.log(regularParam.toInbound()); // 'userId'
313
+ *
314
+ * const destructuredParam = new FunctionParameter({
315
+ * typeDefinition: userTypeDefinition,
316
+ * destructure: true,
317
+ * required: true
318
+ * });
319
+ *
320
+ * console.log(destructuredParam.toInbound()); // '{ name, email, age }'
321
+ * ```
322
+ */
66
323
  toInbound() {
67
324
  return (0, ts_pattern_1.match)(this.properties)
68
325
  .with({ type: 'void' }, () => '')
@@ -72,6 +329,42 @@ class FunctionParameter {
72
329
  })
73
330
  .exhaustive();
74
331
  }
332
+ /**
333
+ * Generates the complete function parameter declaration syntax.
334
+ *
335
+ * This method produces the full parameter declaration that appears in a function
336
+ * signature, including the parameter name, type annotation, and optional markers.
337
+ * It handles all parameter patterns supported by the class.
338
+ *
339
+ * @returns The complete parameter declaration string
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const requiredParam = new FunctionParameter({
344
+ * name: 'userId',
345
+ * typeDefinition: stringTypeDefinition,
346
+ * required: true
347
+ * });
348
+ *
349
+ * console.log(requiredParam.toString()); // 'userId: string'
350
+ *
351
+ * const optionalParam = new FunctionParameter({
352
+ * name: 'options',
353
+ * typeDefinition: optionsTypeDefinition,
354
+ * required: false
355
+ * });
356
+ *
357
+ * console.log(optionalParam.toString()); // 'options?: OptionsType'
358
+ *
359
+ * const destructuredParam = new FunctionParameter({
360
+ * typeDefinition: userTypeDefinition,
361
+ * destructure: true,
362
+ * required: true
363
+ * });
364
+ *
365
+ * console.log(destructuredParam.toString()); // '{ name, email, age }: UserType'
366
+ * ```
367
+ */
75
368
  toString() {
76
369
  return (0, ts_pattern_1.match)(this.properties)
77
370
  .with({ type: 'void' }, () => '')
@@ -90,6 +383,41 @@ class FunctionParameter {
90
383
  }
91
384
  }
92
385
  exports.FunctionParameter = FunctionParameter;
386
+ /**
387
+ * Generates destructured object parameter syntax from a type definition.
388
+ *
389
+ * This helper function creates the destructured parameter syntax for object types,
390
+ * handling property name validation and optional camelCase conversion for invalid
391
+ * JavaScript identifiers. It integrates with the List system to produce properly
392
+ * formatted destructured parameter lists.
393
+ *
394
+ * @param typeDefinition - The object type definition to destructure
395
+ * @param options - Options for controlling the destructuring behavior
396
+ * @param options.skipEmpty - Whether to skip empty properties
397
+ * @returns List instance representing the destructured parameter structure
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * const objectDef = new Definition({
402
+ * context: generateContext,
403
+ * identifier: Identifier.createType('ApiParams'),
404
+ * value: {
405
+ * type: 'object',
406
+ * objectProperties: {
407
+ * properties: {
408
+ * 'user-id': { type: 'string' },
409
+ * 'valid_name': { type: 'string' },
410
+ * 'api-key': { type: 'string' }
411
+ * }
412
+ * }
413
+ * }
414
+ * });
415
+ *
416
+ * const result = toDestructured(objectDef);
417
+ * console.log(result.toString());
418
+ * // "{ 'user-id': userId, valid_name, 'api-key': apiKey }"
419
+ * ```
420
+ */
93
421
  const toDestructured = (typeDefinition, { skipEmpty } = {}) => {
94
422
  return List_js_1.List.fromKeys(typeDefinition.value.objectProperties?.properties).toObject(key => {
95
423
  return (0, helper_validator_identifier_1.isIdentifierName)(key) ? key : List_js_1.List.toKeyValue(key, (0, lodash_es_1.camelCase)(key));