@odata-effect/odata-effect-generator 0.5.0 → 0.6.1

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/dist/cjs/generator/Generator.js +10 -5
  2. package/dist/cjs/generator/Generator.js.map +1 -1
  3. package/dist/cjs/generator/IndexGenerator.js +7 -6
  4. package/dist/cjs/generator/IndexGenerator.js.map +1 -1
  5. package/dist/cjs/generator/ModelsGenerator.js +22 -36
  6. package/dist/cjs/generator/ModelsGenerator.js.map +1 -1
  7. package/dist/cjs/generator/NamingHelper.js +23 -1
  8. package/dist/cjs/generator/NamingHelper.js.map +1 -1
  9. package/dist/cjs/generator/NavigationGenerator.js +5 -4
  10. package/dist/cjs/generator/NavigationGenerator.js.map +1 -1
  11. package/dist/cjs/generator/OperationsGenerator.js +5 -4
  12. package/dist/cjs/generator/OperationsGenerator.js.map +1 -1
  13. package/dist/cjs/generator/QueryModelsGenerator.js +3 -2
  14. package/dist/cjs/generator/QueryModelsGenerator.js.map +1 -1
  15. package/dist/cjs/generator/ServiceFnGenerator.js +13 -15
  16. package/dist/cjs/generator/ServiceFnGenerator.js.map +1 -1
  17. package/dist/cjs/model/GeneratorConfig.js.map +1 -1
  18. package/dist/dts/generator/Generator.d.ts +6 -0
  19. package/dist/dts/generator/Generator.d.ts.map +1 -1
  20. package/dist/dts/generator/IndexGenerator.d.ts +14 -1
  21. package/dist/dts/generator/IndexGenerator.d.ts.map +1 -1
  22. package/dist/dts/generator/ModelsGenerator.d.ts.map +1 -1
  23. package/dist/dts/generator/NamingHelper.d.ts +15 -0
  24. package/dist/dts/generator/NamingHelper.d.ts.map +1 -1
  25. package/dist/dts/generator/NavigationGenerator.d.ts +14 -1
  26. package/dist/dts/generator/NavigationGenerator.d.ts.map +1 -1
  27. package/dist/dts/generator/OperationsGenerator.d.ts +14 -1
  28. package/dist/dts/generator/OperationsGenerator.d.ts.map +1 -1
  29. package/dist/dts/generator/QueryModelsGenerator.d.ts +14 -1
  30. package/dist/dts/generator/QueryModelsGenerator.d.ts.map +1 -1
  31. package/dist/dts/generator/ServiceFnGenerator.d.ts +14 -1
  32. package/dist/dts/generator/ServiceFnGenerator.d.ts.map +1 -1
  33. package/dist/dts/model/GeneratorConfig.d.ts +20 -0
  34. package/dist/dts/model/GeneratorConfig.d.ts.map +1 -1
  35. package/dist/esm/generator/Generator.js +10 -5
  36. package/dist/esm/generator/Generator.js.map +1 -1
  37. package/dist/esm/generator/IndexGenerator.js +8 -7
  38. package/dist/esm/generator/IndexGenerator.js.map +1 -1
  39. package/dist/esm/generator/ModelsGenerator.js +22 -36
  40. package/dist/esm/generator/ModelsGenerator.js.map +1 -1
  41. package/dist/esm/generator/NamingHelper.js +21 -0
  42. package/dist/esm/generator/NamingHelper.js.map +1 -1
  43. package/dist/esm/generator/NavigationGenerator.js +6 -5
  44. package/dist/esm/generator/NavigationGenerator.js.map +1 -1
  45. package/dist/esm/generator/OperationsGenerator.js +6 -5
  46. package/dist/esm/generator/OperationsGenerator.js.map +1 -1
  47. package/dist/esm/generator/QueryModelsGenerator.js +4 -3
  48. package/dist/esm/generator/QueryModelsGenerator.js.map +1 -1
  49. package/dist/esm/generator/ServiceFnGenerator.js +14 -16
  50. package/dist/esm/generator/ServiceFnGenerator.js.map +1 -1
  51. package/dist/esm/model/GeneratorConfig.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/generator/Generator.ts +15 -5
  54. package/src/generator/IndexGenerator.ts +27 -6
  55. package/src/generator/ModelsGenerator.ts +24 -41
  56. package/src/generator/NamingHelper.ts +26 -0
  57. package/src/generator/NavigationGenerator.ts +23 -5
  58. package/src/generator/OperationsGenerator.ts +25 -5
  59. package/src/generator/QueryModelsGenerator.ts +27 -3
  60. package/src/generator/ServiceFnGenerator.ts +31 -17
  61. package/src/model/GeneratorConfig.ts +22 -0
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { DataModel, EntitySetModel, EntityTypeModel } from "../model/DataModel.js"
10
10
  import type { ODataVersion } from "../parser/EdmxSchema.js"
11
- import { getEditableTypeName, getIdTypeName, getServiceClassName } from "./NamingHelper.js"
11
+ import { formatRelativeImport, getEditableTypeName, getIdTypeName, getServiceClassName } from "./NamingHelper.js"
12
12
 
13
13
  /**
14
14
  * Generated service file.
@@ -31,14 +31,32 @@ export interface ServiceGenerationResult {
31
31
  readonly servicesFile: GeneratedServiceFile
32
32
  }
33
33
 
34
+ /**
35
+ * Options for service generation.
36
+ *
37
+ * @since 1.0.0
38
+ * @category types
39
+ */
40
+ export interface ServiceGeneratorOptions {
41
+ /**
42
+ * Add .js extensions to relative imports for ESM compatibility.
43
+ * @default true
44
+ */
45
+ readonly esmExtensions?: boolean
46
+ }
47
+
34
48
  /**
35
49
  * Generate the Services.ts file using crud factory.
36
50
  *
37
51
  * @since 1.0.0
38
52
  * @category generation
39
53
  */
40
- export const generateServiceFns = (dataModel: DataModel): ServiceGenerationResult => {
41
- const content = generateServicesFile(dataModel)
54
+ export const generateServiceFns = (
55
+ dataModel: DataModel,
56
+ options?: ServiceGeneratorOptions
57
+ ): ServiceGenerationResult => {
58
+ const esmExtensions = options?.esmExtensions ?? true
59
+ const content = generateServicesFile(dataModel, esmExtensions)
42
60
  return {
43
61
  servicesFile: {
44
62
  fileName: "Services.ts",
@@ -50,7 +68,7 @@ export const generateServiceFns = (dataModel: DataModel): ServiceGenerationResul
50
68
  /**
51
69
  * Generate the Services.ts file content.
52
70
  */
53
- const generateServicesFile = (dataModel: DataModel): string => {
71
+ const generateServicesFile = (dataModel: DataModel, esmExtensions: boolean): string => {
54
72
  const lines: Array<string> = []
55
73
  const isV4 = dataModel.version === "V4"
56
74
  const crudImportPath = isV4
@@ -97,7 +115,7 @@ const generateServicesFile = (dataModel: DataModel): string => {
97
115
  const isLast = i === modelImports.length - 1
98
116
  lines.push(` ${modelImports[i]}${isLast ? "" : ","}`)
99
117
  }
100
- lines.push(`} from "./Models"`)
118
+ lines.push(`} from "${formatRelativeImport("Models", esmExtensions)}"`)
101
119
  lines.push(``)
102
120
 
103
121
  // Re-export types from the crud module
@@ -159,7 +177,6 @@ const generateIdToKeyFunction = (
159
177
  if (entityType.keys.length === 1) {
160
178
  const keyProp = entityType.keys[0]
161
179
  const keyTsType = keyProp.typeMapping.tsType
162
- const primitiveCheck = keyTsType === "number" ? "number" : "string"
163
180
 
164
181
  if (isV4) {
165
182
  // V4 can use number keys directly
@@ -169,19 +186,16 @@ const generateIdToKeyFunction = (
169
186
  return `(id: ${idTypeName}) => typeof id === "string" ? { ${keyProp.odataName}: id } : { ${keyProp.odataName}: id.${keyProp.name} }`
170
187
  }
171
188
  } else {
172
- // V2 needs string keys
173
- return `(id: ${idTypeName}) => typeof id === "${primitiveCheck}" ? { ${keyProp.odataName}: String(id) } : { ${keyProp.odataName}: String(id.${keyProp.name}) }`
174
- }
175
- } else {
176
- // Composite key
177
- const keyMapping = entityType.keys.map((k) => {
178
- if (isV4) {
179
- return `${k.odataName}: id.${k.name}`
189
+ // V2 supports both numeric and string keys
190
+ if (keyTsType === "number") {
191
+ return `(id: ${idTypeName}) => typeof id === "number" ? { ${keyProp.odataName}: id } : { ${keyProp.odataName}: id.${keyProp.name} }`
180
192
  } else {
181
- return `${k.odataName}: String(id.${k.name})`
193
+ return `(id: ${idTypeName}) => typeof id === "string" ? { ${keyProp.odataName}: id } : { ${keyProp.odataName}: id.${keyProp.name} }`
182
194
  }
183
- }).join(", ")
184
-
195
+ }
196
+ } else {
197
+ // Composite key - both V2 and V4 can use native types
198
+ const keyMapping = entityType.keys.map((k) => `${k.odataName}: id.${k.name}`).join(", ")
185
199
  return `(id: ${idTypeName}) => ({ ${keyMapping} })`
186
200
  }
187
201
  }
@@ -4,6 +4,28 @@
4
4
  * @since 1.0.0
5
5
  */
6
6
 
7
+ /**
8
+ * Generator options for code generation.
9
+ *
10
+ * @since 1.0.0
11
+ * @category config
12
+ */
13
+ export interface GeneratorOptions {
14
+ /**
15
+ * Add .js extensions to relative imports for ESM compatibility.
16
+ * Required for moduleResolution: node16/nodenext.
17
+ * Default: true (recommended for ESM projects)
18
+ *
19
+ * @default true
20
+ */
21
+ readonly esmExtensions?: boolean
22
+
23
+ /**
24
+ * Naming overrides for customizing generated type and property names.
25
+ */
26
+ readonly overrides?: NamingOverrides
27
+ }
28
+
7
29
  /**
8
30
  * Override configuration for property names.
9
31
  * Maps OData property names to TypeScript property names.