@odata-effect/odata-effect-generator 0.2.0 → 0.3.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.
Files changed (61) hide show
  1. package/README.md +17 -8
  2. package/dist/cjs/Cli.js +2 -2
  3. package/dist/cjs/Cli.js.map +1 -1
  4. package/dist/cjs/generator/Generator.js +5 -13
  5. package/dist/cjs/generator/Generator.js.map +1 -1
  6. package/dist/cjs/generator/IndexGenerator.js +14 -11
  7. package/dist/cjs/generator/IndexGenerator.js.map +1 -1
  8. package/dist/cjs/generator/ModelsGenerator.js +2 -5
  9. package/dist/cjs/generator/ModelsGenerator.js.map +1 -1
  10. package/dist/cjs/generator/NamingHelper.js.map +1 -1
  11. package/dist/cjs/generator/NavigationGenerator.js +43 -11
  12. package/dist/cjs/generator/NavigationGenerator.js.map +1 -1
  13. package/dist/cjs/generator/OperationsGenerator.js +2 -2
  14. package/dist/cjs/generator/OperationsGenerator.js.map +1 -1
  15. package/dist/cjs/generator/ServiceFnGenerator.js +102 -224
  16. package/dist/cjs/generator/ServiceFnGenerator.js.map +1 -1
  17. package/dist/cjs/index.js +3 -3
  18. package/dist/dts/Cli.d.ts.map +1 -1
  19. package/dist/dts/generator/Generator.d.ts.map +1 -1
  20. package/dist/dts/generator/IndexGenerator.d.ts.map +1 -1
  21. package/dist/dts/generator/NamingHelper.d.ts.map +1 -1
  22. package/dist/dts/generator/NavigationGenerator.d.ts.map +1 -1
  23. package/dist/dts/generator/ServiceFnGenerator.d.ts +10 -11
  24. package/dist/dts/generator/ServiceFnGenerator.d.ts.map +1 -1
  25. package/dist/dts/index.d.ts +4 -4
  26. package/dist/dts/index.d.ts.map +1 -1
  27. package/dist/esm/Cli.js +2 -2
  28. package/dist/esm/Cli.js.map +1 -1
  29. package/dist/esm/generator/Generator.js +5 -13
  30. package/dist/esm/generator/Generator.js.map +1 -1
  31. package/dist/esm/generator/IndexGenerator.js +14 -11
  32. package/dist/esm/generator/IndexGenerator.js.map +1 -1
  33. package/dist/esm/generator/ModelsGenerator.js +2 -5
  34. package/dist/esm/generator/ModelsGenerator.js.map +1 -1
  35. package/dist/esm/generator/NamingHelper.js.map +1 -1
  36. package/dist/esm/generator/NavigationGenerator.js +43 -11
  37. package/dist/esm/generator/NavigationGenerator.js.map +1 -1
  38. package/dist/esm/generator/OperationsGenerator.js +2 -2
  39. package/dist/esm/generator/OperationsGenerator.js.map +1 -1
  40. package/dist/esm/generator/ServiceFnGenerator.js +102 -224
  41. package/dist/esm/generator/ServiceFnGenerator.js.map +1 -1
  42. package/dist/esm/index.js +4 -4
  43. package/dist/esm/index.js.map +1 -1
  44. package/package.json +1 -9
  45. package/src/Cli.ts +8 -1
  46. package/src/generator/Generator.ts +8 -17
  47. package/src/generator/IndexGenerator.ts +14 -12
  48. package/src/generator/ModelsGenerator.ts +2 -5
  49. package/src/generator/NamingHelper.ts +5 -3
  50. package/src/generator/NavigationGenerator.ts +58 -24
  51. package/src/generator/OperationsGenerator.ts +40 -14
  52. package/src/generator/ServiceFnGenerator.ts +117 -265
  53. package/src/index.ts +4 -4
  54. package/dist/cjs/generator/ServiceFnPromiseGenerator.js +0 -183
  55. package/dist/cjs/generator/ServiceFnPromiseGenerator.js.map +0 -1
  56. package/dist/dts/generator/ServiceFnPromiseGenerator.d.ts +0 -40
  57. package/dist/dts/generator/ServiceFnPromiseGenerator.d.ts.map +0 -1
  58. package/dist/esm/generator/ServiceFnPromiseGenerator.js +0 -175
  59. package/dist/esm/generator/ServiceFnPromiseGenerator.js.map +0 -1
  60. package/generator/ServiceFnPromiseGenerator/package.json +0 -6
  61. package/src/generator/ServiceFnPromiseGenerator.ts +0 -243
@@ -21,15 +21,9 @@
21
21
  *
22
22
  * @since 1.0.0
23
23
  */
24
- import type {
25
- DataModel,
26
- EntityTypeModel
27
- } from "../model/DataModel.js"
24
+ import type { DataModel, EntityTypeModel } from "../model/DataModel.js"
28
25
  import type { ODataVersion } from "../parser/EdmxSchema.js"
29
- import {
30
- getClassName,
31
- toCamelCase
32
- } from "./NamingHelper.js"
26
+ import { getClassName, toCamelCase } from "./NamingHelper.js"
33
27
 
34
28
  /**
35
29
  * Version-specific configuration.
@@ -52,8 +46,7 @@ const V4_CONFIG: VersionConfig = {
52
46
  queryOptionsType: "ODataV4QueryOptions"
53
47
  }
54
48
 
55
- const getVersionConfig = (version: ODataVersion): VersionConfig =>
56
- version === "V4" ? V4_CONFIG : V2_CONFIG
49
+ const getVersionConfig = (version: ODataVersion): VersionConfig => version === "V4" ? V4_CONFIG : V2_CONFIG
57
50
 
58
51
  /**
59
52
  * Get the path builders module name.
@@ -163,7 +156,10 @@ const getDerivedTypes = (
163
156
  if (entityType.baseType === baseTypeFqName) {
164
157
  derived.push(entityType)
165
158
  // Recursively get further derived types
166
- derived.push(...getDerivedTypes(entityType.fqName, dataModel))
159
+ const furtherDerived = getDerivedTypes(entityType.fqName, dataModel)
160
+ for (const d of furtherDerived) {
161
+ derived.push(d)
162
+ }
167
163
  }
168
164
  }
169
165
 
@@ -226,9 +222,12 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
226
222
  lines.push(``)
227
223
 
228
224
  // Imports
229
- lines.push(`import * as ${versionConfig.odataNamespace} from "@odata-effect/odata-effect/${versionConfig.odataNamespace}"`)
230
- lines.push(`import type { ${versionConfig.queryOptionsType} } from "@odata-effect/odata-effect/${versionConfig.clientModule}"`)
231
- lines.push(`import type * as Schema from "effect/Schema"`)
225
+ lines.push(
226
+ `import { ${versionConfig.odataNamespace}, ${versionConfig.clientModule}} from "@odata-effect/odata-effect"`
227
+ )
228
+ const runtimeType = dataModel.version === "V4" ? "ODataV4Runtime" : "ODataRuntime"
229
+ lines.push(`import type { Runtime } from "@odata-effect/odata-effect-promise"`)
230
+ lines.push(`import type { Effect, Schema } from "effect"`)
232
231
  lines.push(``)
233
232
 
234
233
  // Import model types with Model suffix to avoid collision with entity set names
@@ -276,7 +275,9 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
276
275
  lines.push(` * @since 1.0.0`)
277
276
  lines.push(` * @category entity-sets`)
278
277
  lines.push(` */`)
279
- lines.push(`export const ${entitySet.name}: Path<${entityType.name}Model, true> = "${entitySet.name}" as Path<${entityType.name}Model, true>`)
278
+ lines.push(
279
+ `export const ${entitySet.name}: Path<${entityType.name}Model, true> = "${entitySet.name}" as Path<${entityType.name}Model, true>`
280
+ )
280
281
  lines.push(``)
281
282
  }
282
283
  }
@@ -331,7 +332,9 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
331
332
  lines.push(` * @since 1.0.0`)
332
333
  lines.push(` * @category navigation`)
333
334
  lines.push(` */`)
334
- lines.push(`export const ${fnName} = (base: Path<${sourceEntity}Model, false>): Path<${targetType}Model, ${prop.isCollection}> =>`)
335
+ lines.push(
336
+ `export const ${fnName} = (base: Path<${sourceEntity}Model, false>): Path<${targetType}Model, ${prop.isCollection}> =>`
337
+ )
335
338
  lines.push(` \`\${base}/${prop.odataName}\` as Path<${targetType}Model, ${prop.isCollection}>`)
336
339
  lines.push(``)
337
340
  }
@@ -344,16 +347,18 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
344
347
  lines.push(`// Type Casting (for entity inheritance)`)
345
348
  lines.push(`// ============================================================================`)
346
349
  lines.push(``)
347
- lines.push(...castFunctions)
350
+ for (const castFunction of castFunctions) {
351
+ lines.push(castFunction)
352
+ }
348
353
  }
349
354
 
350
- // Terminal operations
355
+ // Terminal operations (Effect-based)
351
356
  lines.push(`// ============================================================================`)
352
- lines.push(`// Terminal Operations`)
357
+ lines.push(`// Terminal Operations (Effect-based)`)
353
358
  lines.push(`// ============================================================================`)
354
359
  lines.push(``)
355
360
  lines.push(`/**`)
356
- lines.push(` * Fetch a collection of entities at the given path.`)
361
+ lines.push(` * Fetch a collection of entities at the given path (Effect-based).`)
357
362
  lines.push(` *`)
358
363
  lines.push(` * @example`)
359
364
  lines.push(` * \`\`\`typescript`)
@@ -364,11 +369,11 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
364
369
  lines.push(` * @category operations`)
365
370
  lines.push(` */`)
366
371
  lines.push(`export const fetchCollection = <T, I>(schema: Schema.Schema<T, I>) =>`)
367
- lines.push(` (path: Path<T, true>, options?: ${versionConfig.queryOptionsType}) =>`)
372
+ lines.push(` (path: Path<T, true>, options?: ${versionConfig.clientModule}.${versionConfig.queryOptionsType}) =>`)
368
373
  lines.push(` ${versionConfig.odataNamespace}.getCollection(path, schema, options)`)
369
374
  lines.push(``)
370
375
  lines.push(`/**`)
371
- lines.push(` * Fetch a single entity at the given path.`)
376
+ lines.push(` * Fetch a single entity at the given path (Effect-based).`)
372
377
  lines.push(` *`)
373
378
  lines.push(` * @example`)
374
379
  lines.push(` * \`\`\`typescript`)
@@ -379,10 +384,37 @@ const generatePathBuildersFile = (dataModel: DataModel): string => {
379
384
  lines.push(` * @category operations`)
380
385
  lines.push(` */`)
381
386
  lines.push(`export const fetchOne = <T, I>(schema: Schema.Schema<T, I>) =>`)
382
- lines.push(` (path: Path<T, false>, options?: ${versionConfig.queryOptionsType}) =>`)
387
+ lines.push(` (path: Path<T, false>, options?: ${versionConfig.clientModule}.${versionConfig.queryOptionsType}) =>`)
383
388
  lines.push(` ${versionConfig.odataNamespace}.get(path, schema, options)`)
384
389
  lines.push(``)
385
390
 
391
+ // Promise conversion (pipe-friendly)
392
+ lines.push(`// ============================================================================`)
393
+ lines.push(`// Promise Conversion`)
394
+ lines.push(`// ============================================================================`)
395
+ lines.push(``)
396
+ lines.push(`/**`)
397
+ lines.push(` * Convert an Effect to a Promise. Use at the end of a pipe chain.`)
398
+ lines.push(` *`)
399
+ lines.push(` * @example`)
400
+ lines.push(` * \`\`\`typescript`)
401
+ lines.push(` * const myTrips = await pipe(`)
402
+ lines.push(` * People,`)
403
+ lines.push(` * byKey("russell"),`)
404
+ lines.push(` * trips,`)
405
+ lines.push(` * fetchCollection(Trip),`)
406
+ lines.push(` * toPromise(runtime)`)
407
+ lines.push(` * )`)
408
+ lines.push(` * \`\`\``)
409
+ lines.push(` *`)
410
+ lines.push(` * @since 1.0.0`)
411
+ lines.push(` * @category operations`)
412
+ lines.push(` */`)
413
+ lines.push(`export const toPromise = (runtime: Runtime.${runtimeType}) =>`)
414
+ lines.push(` <A, E, R>(effect: Effect.Effect<A, E, R>): Promise<A> =>`)
415
+ lines.push(` runtime.runPromise(effect as any)`)
416
+ lines.push(``)
417
+
386
418
  return lines.join("\n")
387
419
  }
388
420
 
@@ -409,7 +441,9 @@ const generateTypeCastFunctions = (dataModel: DataModel): Array<string> => {
409
441
  lines.push(` * @since 1.0.0`)
410
442
  lines.push(` * @category casting`)
411
443
  lines.push(` */`)
412
- lines.push(`export const ${fnName} = (base: Path<${entityType.name}Model, true>): Path<${derived.name}Model, true> =>`)
444
+ lines.push(
445
+ `export const ${fnName} = (base: Path<${entityType.name}Model, true>): Path<${derived.name}Model, true> =>`
446
+ )
413
447
  lines.push(` \`\${base}/${castPath}\` as Path<${derived.name}Model, true>`)
414
448
  lines.push(``)
415
449
  }
@@ -125,7 +125,7 @@ const returnsModelType = (operation: OperationModel, dataModel: DataModel): bool
125
125
  const getReturnTypeName = (operation: OperationModel): string => {
126
126
  if (!operation.returnType) return "void"
127
127
 
128
- const { typeMapping, isCollection } = operation.returnType
128
+ const { isCollection, typeMapping } = operation.returnType
129
129
  const baseType = typeMapping.tsType
130
130
 
131
131
  return isCollection ? `ReadonlyArray<${baseType}>` : baseType
@@ -364,19 +364,29 @@ const generateV2FunctionImport = (
364
364
 
365
365
  // Determine the execute function to use
366
366
  if (!operation.returnType) {
367
- lines.push(` return yield* ODataOps.executeFunctionImportVoid(client, config, "${operation.odataName}", ${paramsArg})`)
367
+ lines.push(
368
+ ` return yield* ODataOps.executeFunctionImportVoid(client, config, "${operation.odataName}", ${paramsArg})`
369
+ )
368
370
  } else if (operation.returnType.isCollection) {
369
371
  if (returnsModel) {
370
- lines.push(` return yield* ODataOps.executeFunctionImportCollection(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.tsType}, ${paramsArg})`)
372
+ lines.push(
373
+ ` return yield* ODataOps.executeFunctionImportCollection(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.tsType}, ${paramsArg})`
374
+ )
371
375
  } else {
372
- lines.push(` return yield* ODataOps.executeFunctionImportCollection(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.effectSchema}, ${paramsArg})`)
376
+ lines.push(
377
+ ` return yield* ODataOps.executeFunctionImportCollection(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.effectSchema}, ${paramsArg})`
378
+ )
373
379
  }
374
380
  } else if (returnsModel) {
375
- lines.push(` return yield* ODataOps.executeFunctionImportEntity(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.tsType}, ${paramsArg})`)
381
+ lines.push(
382
+ ` return yield* ODataOps.executeFunctionImportEntity(client, config, "${operation.odataName}", ${operation.returnType.typeMapping.tsType}, ${paramsArg})`
383
+ )
376
384
  } else {
377
385
  // Primitive return
378
386
  const propertyName = operation.odataName
379
- lines.push(` return yield* ODataOps.executeFunctionImportPrimitive(client, config, "${operation.odataName}", "${propertyName}", ${operation.returnType.typeMapping.effectSchema}, ${paramsArg})`)
387
+ lines.push(
388
+ ` return yield* ODataOps.executeFunctionImportPrimitive(client, config, "${operation.odataName}", "${propertyName}", ${operation.returnType.typeMapping.effectSchema}, ${paramsArg})`
389
+ )
380
390
  }
381
391
 
382
392
  lines.push(` })`)
@@ -444,15 +454,23 @@ const generateV4Operation = (
444
454
  lines.push(` return yield* ODataOps.executeV4FunctionVoid(client, config, url)`)
445
455
  } else if (operation.returnType.isCollection) {
446
456
  if (returnsModel) {
447
- lines.push(` return yield* ODataOps.executeV4FunctionCollection(client, config, url, ${operation.returnType.typeMapping.tsType})`)
457
+ lines.push(
458
+ ` return yield* ODataOps.executeV4FunctionCollection(client, config, url, ${operation.returnType.typeMapping.tsType})`
459
+ )
448
460
  } else {
449
- lines.push(` return yield* ODataOps.executeV4FunctionCollection(client, config, url, ${operation.returnType.typeMapping.effectSchema})`)
461
+ lines.push(
462
+ ` return yield* ODataOps.executeV4FunctionCollection(client, config, url, ${operation.returnType.typeMapping.effectSchema})`
463
+ )
450
464
  }
451
465
  } else if (returnsModel) {
452
- lines.push(` return yield* ODataOps.executeV4FunctionEntity(client, config, url, ${operation.returnType.typeMapping.tsType})`)
466
+ lines.push(
467
+ ` return yield* ODataOps.executeV4FunctionEntity(client, config, url, ${operation.returnType.typeMapping.tsType})`
468
+ )
453
469
  } else {
454
470
  // Primitive return
455
- lines.push(` return yield* ODataOps.executeV4FunctionPrimitive(client, config, url, ${operation.returnType.typeMapping.effectSchema})`)
471
+ lines.push(
472
+ ` return yield* ODataOps.executeV4FunctionPrimitive(client, config, url, ${operation.returnType.typeMapping.effectSchema})`
473
+ )
456
474
  }
457
475
  } else {
458
476
  // V4 Actions use POST with body
@@ -465,15 +483,23 @@ const generateV4Operation = (
465
483
  lines.push(` return yield* ODataOps.executeV4ActionVoid(client, config, url, ${bodyArg})`)
466
484
  } else if (operation.returnType.isCollection) {
467
485
  if (returnsModel) {
468
- lines.push(` return yield* ODataOps.executeV4ActionCollection(client, config, url, ${operation.returnType.typeMapping.tsType}, ${bodyArg})`)
486
+ lines.push(
487
+ ` return yield* ODataOps.executeV4ActionCollection(client, config, url, ${operation.returnType.typeMapping.tsType}, ${bodyArg})`
488
+ )
469
489
  } else {
470
- lines.push(` return yield* ODataOps.executeV4ActionCollection(client, config, url, ${operation.returnType.typeMapping.effectSchema}, ${bodyArg})`)
490
+ lines.push(
491
+ ` return yield* ODataOps.executeV4ActionCollection(client, config, url, ${operation.returnType.typeMapping.effectSchema}, ${bodyArg})`
492
+ )
471
493
  }
472
494
  } else if (returnsModel) {
473
- lines.push(` return yield* ODataOps.executeV4ActionEntity(client, config, url, ${operation.returnType.typeMapping.tsType}, ${bodyArg})`)
495
+ lines.push(
496
+ ` return yield* ODataOps.executeV4ActionEntity(client, config, url, ${operation.returnType.typeMapping.tsType}, ${bodyArg})`
497
+ )
474
498
  } else {
475
499
  // Primitive return - use entity with schema
476
- lines.push(` return yield* ODataOps.executeV4FunctionPrimitive(client, config, url, ${operation.returnType.typeMapping.effectSchema})`)
500
+ lines.push(
501
+ ` return yield* ODataOps.executeV4FunctionPrimitive(client, config, url, ${operation.returnType.typeMapping.effectSchema})`
502
+ )
477
503
  }
478
504
  }
479
505