@odata2ts/odata2ts 0.31.1 → 0.32.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 +20 -0
- package/lib/FactoryFunctionModel.d.ts +1 -1
- package/lib/FactoryFunctionModel.js.map +1 -1
- package/lib/OptionModel.d.ts +46 -61
- package/lib/OptionModel.js.map +1 -1
- package/lib/TypeModel.d.ts +10 -0
- package/lib/TypeModel.js +17 -0
- package/lib/TypeModel.js.map +1 -0
- package/lib/app.js +13 -0
- package/lib/app.js.map +1 -1
- package/lib/cli.js +1 -1
- package/lib/cli.js.map +1 -1
- package/lib/data-model/DataModel.d.ts +8 -4
- package/lib/data-model/DataModel.js +14 -8
- package/lib/data-model/DataModel.js.map +1 -1
- package/lib/data-model/DataModelDigestion.d.ts +3 -0
- package/lib/data-model/DataModelDigestion.js +69 -45
- package/lib/data-model/DataModelDigestion.js.map +1 -1
- package/lib/data-model/DataModelDigestionV2.js +10 -9
- package/lib/data-model/DataModelDigestionV2.js.map +1 -1
- package/lib/data-model/DataModelDigestionV4.js +31 -17
- package/lib/data-model/DataModelDigestionV4.js.map +1 -1
- package/lib/data-model/DataTypeModel.d.ts +1 -0
- package/lib/data-model/DataTypeModel.js.map +1 -1
- package/lib/data-model/NamingHelper.d.ts +1 -0
- package/lib/data-model/NamingHelper.js +5 -0
- package/lib/data-model/NamingHelper.js.map +1 -1
- package/lib/data-model/ServiceConfigHelper.d.ts +14 -17
- package/lib/data-model/ServiceConfigHelper.js +58 -72
- package/lib/data-model/ServiceConfigHelper.js.map +1 -1
- package/lib/data-model/validation/NameValidator.d.ts +28 -0
- package/lib/data-model/validation/NameValidator.js +80 -0
- package/lib/data-model/validation/NameValidator.js.map +1 -0
- package/lib/defaultConfig.js +2 -2
- package/lib/defaultConfig.js.map +1 -1
- package/lib/generator/ModelGenerator.js +1 -1
- package/lib/generator/ModelGenerator.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.32.0](https://github.com/odata2ts/odata2ts/compare/@odata2ts/odata2ts@0.31.1...@odata2ts/odata2ts@0.32.0) (2024-03-10)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* fully qualified name for EntitySet, Singleton & FunctionImport by EntityContainer name instead of namespace ([#245](https://github.com/odata2ts/odata2ts/issues/245)) ([6047122](https://github.com/odata2ts/odata2ts/commit/60471223deac8b14b2d3cfc0946acde7d33d2d64))
|
|
11
|
+
|
|
12
|
+
### Code Refactoring
|
|
13
|
+
|
|
14
|
+
* byTypeAndName option ([#238](https://github.com/odata2ts/odata2ts/issues/238)) ([e15f7a6](https://github.com/odata2ts/odata2ts/commit/e15f7a615e0cdf3865fbfce4dee08cdae60b46ad))
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* report name clashes & introduce auto name clash resolution ([#239](https://github.com/odata2ts/odata2ts/issues/239)) ([28b38dc](https://github.com/odata2ts/odata2ts/commit/28b38dc7945dcc4b66744f0b8474625702331b50))
|
|
19
|
+
|
|
20
|
+
### BREAKING CHANGES
|
|
21
|
+
|
|
22
|
+
* Config options `entitiesByName` and `operationsByName` have been dropped. You must use `byTypeAndName` instead and provide the new type property for each configuration.
|
|
23
|
+
|
|
24
|
+
Renaming now supports EntityType, ComplexType, EnumType and any operation type (FunctionImport, Function, Action).
|
|
25
|
+
|
|
6
26
|
## [0.31.1](https://github.com/odata2ts/odata2ts/compare/@odata2ts/odata2ts@0.31.0...@odata2ts/odata2ts@0.31.1) (2023-11-15)
|
|
7
27
|
|
|
8
28
|
### Bug Fixes
|
|
@@ -4,7 +4,7 @@ import { DataModel } from "./data-model/DataModel";
|
|
|
4
4
|
import { Schema } from "./data-model/edmx/ODataEdmxModelBase";
|
|
5
5
|
import { NamingHelper } from "./data-model/NamingHelper";
|
|
6
6
|
import { RunOptions } from "./OptionModel";
|
|
7
|
-
export type DigestionOptions = Pick<RunOptions, "converters" | "disableAutoManagedKey" | "propertiesByName" | "
|
|
7
|
+
export type DigestionOptions = Pick<RunOptions, "converters" | "disableAutoManagedKey" | "propertiesByName" | "byTypeAndName" | "v2ModelsWithExtraResultsWrapping" | "v4BigNumberAsString" | "skipEditableModels" | "skipComments" | "disableAutomaticNameClashResolution">;
|
|
8
8
|
/**
|
|
9
9
|
* Takes an EdmxSchema plus the run options and creates a DataModel.
|
|
10
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FactoryFunctionModel.js","sourceRoot":"","sources":["../src/FactoryFunctionModel.ts"],"names":[],"mappings":"","sourcesContent":["import { ODataVersions } from \"@odata2ts/odata-core\";\r\nimport { SourceFile } from \"ts-morph\";\r\n\r\nimport { DataModel } from \"./data-model/DataModel\";\r\nimport { Schema } from \"./data-model/edmx/ODataEdmxModelBase\";\r\nimport { NamingHelper } from \"./data-model/NamingHelper\";\r\nimport { RunOptions } from \"./OptionModel\";\r\n\r\nexport type DigestionOptions = Pick<\r\n RunOptions,\r\n | \"converters\"\r\n | \"disableAutoManagedKey\"\r\n | \"propertiesByName\"\r\n | \"
|
|
1
|
+
{"version":3,"file":"FactoryFunctionModel.js","sourceRoot":"","sources":["../src/FactoryFunctionModel.ts"],"names":[],"mappings":"","sourcesContent":["import { ODataVersions } from \"@odata2ts/odata-core\";\r\nimport { SourceFile } from \"ts-morph\";\r\n\r\nimport { DataModel } from \"./data-model/DataModel\";\r\nimport { Schema } from \"./data-model/edmx/ODataEdmxModelBase\";\r\nimport { NamingHelper } from \"./data-model/NamingHelper\";\r\nimport { RunOptions } from \"./OptionModel\";\r\n\r\nexport type DigestionOptions = Pick<\r\n RunOptions,\r\n | \"converters\"\r\n | \"disableAutoManagedKey\"\r\n | \"propertiesByName\"\r\n | \"byTypeAndName\"\r\n | \"v2ModelsWithExtraResultsWrapping\"\r\n | \"v4BigNumberAsString\"\r\n | \"skipEditableModels\"\r\n | \"skipComments\"\r\n | \"disableAutomaticNameClashResolution\"\r\n>;\r\n\r\n/**\r\n * Takes an EdmxSchema plus the run options and creates a DataModel.\r\n */\r\nexport type DigesterFunction<S extends Schema<any, any>> = (\r\n schema: Array<S>,\r\n options: DigestionOptions,\r\n namingHelper: NamingHelper\r\n) => Promise<DataModel>;\r\n\r\nexport type GeneratorFunctionOptions = Pick<\r\n RunOptions,\r\n \"skipEditableModels\" | \"skipIdModels\" | \"skipOperations\" | \"skipComments\" | \"v2ModelsWithExtraResultsWrapping\"\r\n>;\r\n\r\nexport type EntityBasedGeneratorFunction = (\r\n dataModel: DataModel,\r\n sourceFile: SourceFile,\r\n version: ODataVersions,\r\n options: GeneratorFunctionOptions,\r\n namingHelper: NamingHelper\r\n) => void;\r\n"]}
|
package/lib/OptionModel.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TypeConverterConfig } from "@odata2ts/converter-runtime";
|
|
2
2
|
import { AxiosRequestConfig } from "axios";
|
|
3
3
|
import { NameSettings, OverridableNamingOptions } from "./NamingModel";
|
|
4
|
+
import { TypeModel } from "./TypeModel";
|
|
4
5
|
/**
|
|
5
6
|
* Generation mode, by default "all".
|
|
6
7
|
*/
|
|
@@ -234,23 +235,35 @@ export interface ConfigFileOptions extends Omit<CliOptions, "sourceUrl" | "sourc
|
|
|
234
235
|
* Additionally, when sending data the very same value will be set for the "content-type" header.
|
|
235
236
|
*/
|
|
236
237
|
v4BigNumberAsString?: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* OData allows for namespaces so any entity is unique by virtue of it's name within a namespace.
|
|
240
|
+
* odata2ts works with these fully qualified names internally, but only uses the plain name when generating
|
|
241
|
+
* stuff. This might lead to name clashes (same name in different namespaces).
|
|
242
|
+
*
|
|
243
|
+
* odata2ts employs a simple, automatic resolution strategy: Adding a counter at the end of the name.
|
|
244
|
+
* Set this property to true in order to disable this automatism.
|
|
245
|
+
*/
|
|
246
|
+
disableAutomaticNameClashResolution?: boolean;
|
|
237
247
|
}
|
|
238
248
|
/**
|
|
239
249
|
* Custom generation options which are dependent on a specific odata service.
|
|
240
250
|
*/
|
|
241
251
|
export interface ServiceGenerationOptions extends Required<Pick<CliOptions, "source" | "output">>, Pick<CliOptions, "sourceUrl" | "refreshFile">, Omit<ConfigFileOptions, "services"> {
|
|
242
|
-
/**
|
|
243
|
-
* Configure generation process for EntityTypes and ComplexTypes including their keys and properties.
|
|
244
|
-
*/
|
|
245
|
-
entitiesByName?: Array<EntityGenerationOptions>;
|
|
246
252
|
/**
|
|
247
253
|
* Configure generation process for individual properties based on their name.
|
|
248
254
|
*/
|
|
249
255
|
propertiesByName?: Array<PropertyGenerationOptions>;
|
|
250
256
|
/**
|
|
251
|
-
*
|
|
257
|
+
* Rename any EntityType, ComplexType, EnumType, Function or Action.
|
|
258
|
+
*
|
|
259
|
+
* You must match the simple name (e.g. "Person") or the fully qualified name
|
|
260
|
+
* (e.g. "Trippin.Person") exactly. Alternatively, you can rename a bunch of types
|
|
261
|
+
* by using regular expressions.
|
|
262
|
+
*
|
|
263
|
+
* By providing additional type information via the "type" attribute you get even more options which only apply
|
|
264
|
+
* to the given type.
|
|
252
265
|
*/
|
|
253
|
-
|
|
266
|
+
byTypeAndName?: Array<ComplexTypeGenerationOptions | EntityTypeGenerationOptions | GenericTypeGenerationOptions>;
|
|
254
267
|
}
|
|
255
268
|
/**
|
|
256
269
|
* Available options for the actual generation run.
|
|
@@ -259,16 +272,12 @@ export interface ServiceGenerationOptions extends Required<Pick<CliOptions, "sou
|
|
|
259
272
|
export interface RunOptions extends Required<Omit<ServiceGenerationOptions, "serviceName" | "sourceUrl" | "sourceUrlConfig" | "refreshFile">>, Pick<ServiceGenerationOptions, "serviceName" | "sourceUrl" | "sourceUrlConfig" | "refreshFile"> {
|
|
260
273
|
naming: NameSettings;
|
|
261
274
|
}
|
|
262
|
-
|
|
263
|
-
* Configuration options for EntityTypes and ComplexTypes.
|
|
264
|
-
* This config applies if the name matches the name of an EntityType or ComplexType as it is specified
|
|
265
|
-
* in the metadata (e.g. in EDMX <EntityType name="Test" ...)
|
|
266
|
-
*/
|
|
267
|
-
export interface EntityGenerationOptions {
|
|
275
|
+
export interface RenameOptions {
|
|
268
276
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
277
|
+
* Matcher for the name of any EntityType, ComplexType, EnumType, Function or Action
|
|
278
|
+
* as it is stated in the EDMX model, e.g. "Person". As OData supports namespaces
|
|
279
|
+
* you can also use the fully qualified name (including the namespace) to address any model,
|
|
280
|
+
* e.g. "Trippin.Person". You can also match properties by their name.
|
|
272
281
|
*
|
|
273
282
|
* If the name is specified as plain string, it must match either the name or the fully qualified name
|
|
274
283
|
* exactly (case-sensitive).
|
|
@@ -277,76 +286,52 @@ export interface EntityGenerationOptions {
|
|
|
277
286
|
* (e.g. Trippin.Person). The regular expression must match the whole string
|
|
278
287
|
* (e.g. `/Person/` won't do, `/.*\.Person/` would work).
|
|
279
288
|
*
|
|
280
|
-
* To make regular expressions useful, captured groups are also supported
|
|
289
|
+
* To make regular expressions useful, captured groups are also supported in combination with
|
|
281
290
|
* the `mappedName` attribute.
|
|
282
291
|
*/
|
|
283
292
|
name: string | RegExp;
|
|
284
293
|
/**
|
|
285
|
-
* If specified, this attribute value is used as name for the matched
|
|
294
|
+
* If specified, this attribute value is used as final name for the matched name as it will
|
|
286
295
|
* appear in the generated typescript.
|
|
287
296
|
*
|
|
288
297
|
* When using a regular expression for matching the name, then captured groups can be referenced
|
|
289
298
|
* as usual via $1, $2, etc. For example:
|
|
290
299
|
* - name: /Trippin\.(.+)/
|
|
291
300
|
* - mappedName: "T_$1"
|
|
292
|
-
*
|
|
301
|
+
* The result would be "T_Person".
|
|
293
302
|
*/
|
|
294
303
|
mappedName?: string;
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
304
|
+
}
|
|
305
|
+
export type TypeBasedGenerationOptions = GenericTypeGenerationOptions | ComplexTypeGenerationOptions | EntityTypeGenerationOptions;
|
|
306
|
+
export interface GenericTypeGenerationOptions extends RenameOptions {
|
|
307
|
+
type: TypeModel.Any | TypeModel.EnumType | TypeModel.OperationType | TypeModel.OperationImportType | TypeModel.Singleton | TypeModel.EntitySet;
|
|
308
|
+
}
|
|
309
|
+
export interface ComplexTypeGenerationOptions extends RenameOptions {
|
|
310
|
+
type: TypeModel.ComplexType;
|
|
299
311
|
/**
|
|
300
312
|
* Configuration of individual properties.
|
|
301
313
|
*/
|
|
302
314
|
properties?: Array<PropertyGenerationOptions>;
|
|
303
315
|
}
|
|
304
316
|
/**
|
|
305
|
-
*
|
|
317
|
+
* Configuration options for EntityTypes and ComplexTypes.
|
|
318
|
+
* This config applies if the name matches the name of an EntityType or ComplexType as it is specified
|
|
319
|
+
* in the metadata (e.g. in EDMX <EntityType name="Test" ...)
|
|
306
320
|
*/
|
|
307
|
-
export interface
|
|
308
|
-
|
|
309
|
-
* Name of the property to match.
|
|
310
|
-
* Must match exactly or can be a regular expression.
|
|
311
|
-
*/
|
|
312
|
-
name: string | RegExp;
|
|
321
|
+
export interface EntityTypeGenerationOptions extends Omit<ComplexTypeGenerationOptions, "type"> {
|
|
322
|
+
type: TypeModel.EntityType;
|
|
313
323
|
/**
|
|
314
|
-
*
|
|
315
|
-
* If name is a regular expression, mappedName allows to specify captured groups (via $1, $2, ...).
|
|
324
|
+
* Overwrite the key specification by naming the props by their EDMX name.
|
|
316
325
|
*/
|
|
317
|
-
|
|
326
|
+
keys?: Array<string>;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* All configuration options for properties of models.
|
|
330
|
+
*/
|
|
331
|
+
export interface PropertyGenerationOptions extends RenameOptions {
|
|
318
332
|
/**
|
|
319
333
|
* Managed attributes - i.e. managed by the server - cannot be created or updated.
|
|
320
334
|
* Hence, they are left out of the editable model versions.
|
|
321
335
|
*/
|
|
322
336
|
managed?: boolean;
|
|
323
337
|
}
|
|
324
|
-
export interface OperationGenerationOptions {
|
|
325
|
-
/**
|
|
326
|
-
* Matches the name of the function or action as it is stated in the EDMX model, e.g. "Person".
|
|
327
|
-
* You can also address the fully qualified name including the namespace (annotated at the schema element), e.g.
|
|
328
|
-
* "Trippin.Person".
|
|
329
|
-
*
|
|
330
|
-
* If the name is specified as plain string, it must match either the name or the fully qualified name
|
|
331
|
-
* exactly (case-sensitive).
|
|
332
|
-
*
|
|
333
|
-
* Alternatively, a regular expression can be used which is always applied to the fully qualified name
|
|
334
|
-
* (e.g. Trippin.Person). The regular expression must match the whole string
|
|
335
|
-
* (e.g. `/Person/` won't do, `/.*\.Person/` would work).
|
|
336
|
-
*
|
|
337
|
-
* To make regular expressions useful, captured groups are also supported. Works in combination with
|
|
338
|
-
* the `mappedName` attribute.
|
|
339
|
-
*/
|
|
340
|
-
name: string | RegExp;
|
|
341
|
-
/**
|
|
342
|
-
* If specified, this attribute value is used as name for the matched operation as it will
|
|
343
|
-
* appear in the generated typescript.
|
|
344
|
-
*
|
|
345
|
-
* When using a regular expression for matching the name, then captured groups can be referenced
|
|
346
|
-
* as usual via $1, $2, etc. For example:
|
|
347
|
-
* - name: /Trippin\.(.+)/
|
|
348
|
-
* - mappedName: "T_$1"
|
|
349
|
-
* - result: "T_Person"
|
|
350
|
-
*/
|
|
351
|
-
mappedName?: string;
|
|
352
|
-
}
|
package/lib/OptionModel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptionModel.js","sourceRoot":"","sources":["../src/OptionModel.ts"],"names":[],"mappings":";;;AAKA;;GAEG;AACH,IAAY,KAKX;AALD,WAAY,KAAK;IACf,qCAAM,CAAA;IACN,yCAAQ,CAAA;IACR,uCAAO,CAAA;IACP,+BAAG,CAAA;AACL,CAAC,EALW,KAAK,qBAAL,KAAK,QAKhB;AAED;;GAEG;AACH,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,sBAAS,CAAA;IACT,sBAAS,CAAA;IACT,wBAAW,CAAA;IACX,8BAAiB,CAAA;AACnB,CAAC,EALW,SAAS,yBAAT,SAAS,QAKpB","sourcesContent":["import { TypeConverterConfig } from \"@odata2ts/converter-runtime\";\r\nimport { AxiosRequestConfig } from \"axios\";\r\n\r\nimport { NameSettings, OverridableNamingOptions } from \"./NamingModel\";\r\n\r\n/**\r\n * Generation mode, by default \"all\".\r\n */\r\nexport enum Modes {\r\n models,\r\n qobjects,\r\n service,\r\n all,\r\n}\r\n\r\n/**\r\n * What kind of stuff to emit: Either raw TS or TS that has been compiled to JS / DTS.\r\n */\r\nexport enum EmitModes {\r\n ts = \"ts\",\r\n js = \"js\",\r\n dts = \"dts\",\r\n js_dts = \"js_dts\",\r\n}\r\n\r\n/**\r\n * Config options for CLI.\r\n */\r\nexport interface CliOptions {\r\n /**\r\n * The URL to the root of your OData service. The URL might end in a slash or not, it might also end\r\n * in $metadata, but we usually add this for you.\r\n *\r\n * Specifying the URL is a convenience feature to download the metadata file from the given URL.\r\n * You can configure this request via `sourceConfig` option.\r\n *\r\n * The `source` option must still be specified as it is used to store the downloaded file on your disk.\r\n * By default, the file is used once it has been downloaded.\r\n */\r\n sourceUrl?: string;\r\n /**\r\n * Downloads the metadata file and overwrites the existing one, if any.\r\n *\r\n * Only takes effect, if option `sourceUrl` is specified.\r\n */\r\n refreshFile?: boolean;\r\n /**\r\n * The source is the file to use (must be an EDMX compliant XML file) or the URL to the\r\n * metadata (ROOT_SERVICE/$metadata).\r\n *\r\n * If not specified, at least one service must be configured in config file.\r\n */\r\n source?: string;\r\n /**\r\n * Specifies the output directory for the generated stuff.\r\n *\r\n * If not specified, at least one service must be configured in config file.\r\n */\r\n output?: string;\r\n /**\r\n * Only generates the specified services.\r\n * Relies on an existing config file where these service names are maintained.\r\n */\r\n services?: Array<string>;\r\n /**\r\n * Specifies what to generate:\r\n * - {@code Modes.models} will only generate TS interfaces\r\n * - {@code Modes.qobjects} will generate functional units used in QueryBuilder and for functions and actions\r\n * - {@code Modes.service} will generate one main OData service client and one per each entity\r\n * - {@code Modes.all} the same as {@code Modes.service}\r\n *\r\n * QObjects will also generate models, and generating the service client will also generate models and QObjects.\r\n * Defaults to {@code Modes.all}\r\n */\r\n mode?: Modes;\r\n /**\r\n * Specifies the type of the output files: TypeScript, JS, DTS only, JS with DTS.\r\n * Defaults to {@code EmitModes.js_dts}\r\n */\r\n emitMode?: EmitModes;\r\n /**\r\n * Uses prettier with your local configuration to pretty print TypeScript files.\r\n * Only applies if mode is set to {@code EmitModes.ts}.\r\n */\r\n prettier?: boolean;\r\n /**\r\n * When compiling TypeScript to JS, \"tsconfig.json\" is used by default to add compilerOptions.\r\n * This option allows to specify an alternative file.\r\n *\r\n * Only takes effect, when mode is set to anything else than {@code EmitModes.ts}.\r\n */\r\n tsconfig?: string;\r\n /**\r\n * Verbose debugging information.\r\n */\r\n debug?: boolean;\r\n /**\r\n * Overrides the service name found in the source file.\r\n *\r\n * The service name is the basis for all file names and the name of the main OData client service\r\n * that serves as entry point for the user.\r\n */\r\n serviceName?: string;\r\n /**\r\n * odata2ts will automatically decide if a key prop is managed on the server side.\r\n * If managed, the property will not be editable (create, update, patch).\r\n * The following rule applies:\r\n * If a property is the only key prop of an entity, then the prop is deemed to be managed;\r\n * in ony other case the prop is unmanaged.\r\n */\r\n disableAutoManagedKey?: boolean;\r\n /**\r\n * By default, odata2ts doesn't change param, operation, property or model names.\r\n * The generated models and their properties are named exactly as advertised by the server.\r\n *\r\n * By allowing odata2ts to change these names, certain predefined formatting strategies are used:\r\n * Model / class names are formatted with PascalCase; property, param, and operation names with camelCase.\r\n *\r\n * The naming configuration allows to control this and other naming related settings.\r\n * Note: Even if renaming is disabled, model prefixing / suffixing still applies.\r\n */\r\n allowRenaming?: boolean;\r\n}\r\n\r\n/**\r\n * Configuration options of the request to retrieve the metadata.\r\n * Only takes effect if `source` is a URL.\r\n */\r\nexport interface UrlSourceConfiguration {\r\n /**\r\n * Basic auth credentials: the username.\r\n * Only takes effect if `password` has also been set.\r\n */\r\n username?: string;\r\n /**\r\n * Basic auth credentials: the password.\r\n * Only takes effect if `username` has also been set.\r\n */\r\n password?: string;\r\n /**\r\n * Custom request configuration.\r\n * URL and method `GET` are set by default, but can be overwritten.\r\n */\r\n custom?: AxiosRequestConfig;\r\n}\r\n\r\n/**\r\n * Available options for configuration files, i.e. odata2ts.config.ts.\r\n */\r\nexport interface ConfigFileOptions extends Omit<CliOptions, \"sourceUrl\" | \"source\" | \"output\" | \"services\"> {\r\n /**\r\n * Configuration options of the request to retrieve the metadata.\r\n * Only takes effect if `sourceUrl` is a URL.\r\n */\r\n sourceUrlConfig?: UrlSourceConfiguration;\r\n\r\n /**\r\n * Configuration of each service.\r\n *\r\n * @example { services: { trippin: { source: \"...\", ... } }}\r\n */\r\n services?: { [serviceName: string]: ServiceGenerationOptions };\r\n\r\n /**\r\n * Specify which converters to use by their package name, e.g. \"@odata2ts/converter-v2-to-v4\".\r\n * Each converter knows which data type to map.\r\n *\r\n * To only use specific converters, the object syntax must be used, where supported converters\r\n * must be listed by their ids.\r\n */\r\n converters?: Array<string | TypeConverterConfig>;\r\n\r\n /**\r\n * For each model an editable version is generated which represents the model definition for\r\n * create, update and patch actions.\r\n *\r\n * You can skip the generation altogether, not generating editable model variants,\r\n * if the generation mode is {@code Mode.model} or {@code Mode.qobject}.\r\n */\r\n skipEditableModels?: boolean;\r\n\r\n /**\r\n * ID models are generated from entity id parameters.\r\n * The generation for one entity entails one model interface representing the id parameters and\r\n * one QId function which allows to format the parameters for URL usage and to parse parameters\r\n * from a URL string.\r\n *\r\n * You can skip the generation altogether, not generating models and QId objects, if the\r\n * generation mode is {@code Mode.model} or {@code Mode.qobject}.\r\n */\r\n skipIdModels?: boolean;\r\n /**\r\n * Operations are functions and actions of the OData service.\r\n * The generation for one operation entails one parameter model interface\r\n * and one QFunction / QAction class.\r\n *\r\n * You can skip the generation altogether, neither generating model nor query object,\r\n * if the generation mode is {@code Mode.model} or {@code Mode.qobject}.\r\n */\r\n skipOperations?: boolean;\r\n /**\r\n * Model properties have explaining comments by default.\r\n * With this option you can turn that off.\r\n */\r\n skipComments?: boolean;\r\n /**\r\n * With OData you can read, update and delete data on a primitive property (`Edm.*`).\r\n * Usually, you wouldn't do that, but go for a bigger request, fetching more relevant information in one go.\r\n *\r\n * There's one exception: Handling `Edm.Stream´ properties and Media entities. Services for stream / media\r\n * stuff are generated regardless of this setting.\r\n */\r\n enablePrimitivePropertyServices?: boolean;\r\n\r\n /**\r\n * The naming options regarding the generated artefacts.\r\n */\r\n naming?: OverridableNamingOptions;\r\n\r\n /**\r\n * Some OData V2 services generate an extra wrapping for entity collection attributes:\r\n * <code>trips: {results: [...]}</code>. So instead of directly returning an array of entities\r\n * an object with the property \"results\" is wrapped around the entity collection.\r\n *\r\n * If you're using the odata client then there's a build-in workaround in place which transforms\r\n * the results to remove this extra mapping. However, if you're only interested in the types, then\r\n * the generated models will not match that extra wrapping.\r\n *\r\n * Setting this configuration option to <code>true</code> (default: false) will add this extra\r\n * wrapping to the generated models. But this option is only valid if the generation mode is set\r\n * to <code>models</code>; it is ignored otherwise.\r\n */\r\n v2ModelsWithExtraResultsWrapping?: boolean;\r\n /**\r\n * Numbers of type `Edm.Int64` and `Edm.Decimal` are represented as `number` in V4.\r\n * However, these numbers might not fit into JS' number type, which might result in precision loss.\r\n *\r\n * OData offers a special IEEE754 format option to get those types as `string` instead to prevent any\r\n * precision loss. So if you're handling very large or very small numbers (JS roughly supports 15 digits),\r\n * then you should use this option and, probably, also an appropriate converter (see available converters).\r\n *\r\n * Activating this option affects the type generation and will use `string` for both mentioned types.\r\n * All requests are executed with the \"accept\" header set to \"application/json;IEEE754Compatible=true\".\r\n * Additionally, when sending data the very same value will be set for the \"content-type\" header.\r\n */\r\n v4BigNumberAsString?: boolean;\r\n}\r\n\r\n/**\r\n * Custom generation options which are dependent on a specific odata service.\r\n */\r\nexport interface ServiceGenerationOptions\r\n extends Required<Pick<CliOptions, \"source\" | \"output\">>,\r\n Pick<CliOptions, \"sourceUrl\" | \"refreshFile\">,\r\n Omit<ConfigFileOptions, \"services\"> {\r\n /**\r\n * Configure generation process for EntityTypes and ComplexTypes including their keys and properties.\r\n */\r\n entitiesByName?: Array<EntityGenerationOptions>;\r\n /**\r\n * Configure generation process for individual properties based on their name.\r\n */\r\n propertiesByName?: Array<PropertyGenerationOptions>;\r\n /**\r\n * Configure generation process for individual function or actions by matching their name.\r\n */\r\n operationsByName?: Array<OperationGenerationOptions>;\r\n}\r\n\r\n/**\r\n * Available options for the actual generation run.\r\n * Every property is required, except the overriding service name.\r\n */\r\nexport interface RunOptions\r\n extends Required<Omit<ServiceGenerationOptions, \"serviceName\" | \"sourceUrl\" | \"sourceUrlConfig\" | \"refreshFile\">>,\r\n Pick<ServiceGenerationOptions, \"serviceName\" | \"sourceUrl\" | \"sourceUrlConfig\" | \"refreshFile\"> {\r\n naming: NameSettings;\r\n}\r\n\r\n/**\r\n * Configuration options for EntityTypes and ComplexTypes.\r\n * This config applies if the name matches the name of an EntityType or ComplexType as it is specified\r\n * in the metadata (e.g. in EDMX <EntityType name=\"Test\" ...)\r\n */\r\nexport interface EntityGenerationOptions {\r\n /**\r\n * Matches the name of the EntityType or ComplexType as it is stated in the EDMX model, e.g. \"Person\".\r\n * You can also address the fully qualified name including the namespace (annotated at the schema element), e.g.\r\n * \"Trippin.Person\".\r\n *\r\n * If the name is specified as plain string, it must match either the name or the fully qualified name\r\n * exactly (case-sensitive).\r\n *\r\n * Alternatively, a regular expression can be used which is always applied to the fully qualified name\r\n * (e.g. Trippin.Person). The regular expression must match the whole string\r\n * (e.g. `/Person/` won't do, `/.*\\.Person/` would work).\r\n *\r\n * To make regular expressions useful, captured groups are also supported. Works in combination with\r\n * the `mappedName` attribute.\r\n */\r\n name: string | RegExp;\r\n /**\r\n * If specified, this attribute value is used as name for the matched entity, complex or enum type as it will\r\n * appear in the generated typescript.\r\n *\r\n * When using a regular expression for matching the name, then captured groups can be referenced\r\n * as usual via $1, $2, etc. For example:\r\n * - name: /Trippin\\.(.+)/\r\n * - mappedName: \"T_$1\"\r\n * - result: \"T_Person\"\r\n */\r\n mappedName?: string;\r\n /**\r\n * Overwrite the key specification by naming the props by their EDMX name.\r\n */\r\n keys?: Array<string>;\r\n /**\r\n * Configuration of individual properties.\r\n */\r\n properties?: Array<PropertyGenerationOptions>;\r\n\r\n // converter: string | Array<string>\r\n\r\n /**\r\n * Whether the generated service should allow for querying this model.\r\n * True by default.\r\n */\r\n // queryable?: boolean;\r\n /**\r\n * Whether the generated service should allow for creating new models (POST).\r\n * True by default.\r\n */\r\n // creatable?: boolean;\r\n /**\r\n * Whether the generated service should allow for updates (PUT).\r\n * True by default.\r\n */\r\n // updatable?: boolean;\r\n /**\r\n * Whether the generated service should allow for partial updates (PATCH).\r\n * True by default.\r\n */\r\n // patchable?: boolean;\r\n /**\r\n * Whether the generated service should allow for deletion.\r\n * True by default.\r\n */\r\n // deletable?: boolean;\r\n}\r\n\r\n/**\r\n * All configuration options for properties of models.\r\n */\r\nexport interface PropertyGenerationOptions {\r\n /**\r\n * Name of the property to match.\r\n * Must match exactly or can be a regular expression.\r\n */\r\n name: string | RegExp;\r\n /**\r\n * Use a different name.\r\n * If name is a regular expression, mappedName allows to specify captured groups (via $1, $2, ...).\r\n */\r\n mappedName?: string;\r\n /**\r\n * Managed attributes - i.e. managed by the server - cannot be created or updated.\r\n * Hence, they are left out of the editable model versions.\r\n */\r\n managed?: boolean;\r\n\r\n /**\r\n * TODO\r\n *\r\n * Each converter must specify its package name, e.g. \"@odata2ts/converter-v2-to-v4\",\r\n * as well it's i\r\n * and their ids, e.g. \"timeToDurationConverter\".\r\n *\r\n * To only use specific converters, the object syntax must be used, where supported converters\r\n * must be listed by their ids.\r\n */\r\n // converters?: Array<Required<TypeConverterConfig>>;\r\n}\r\n\r\nexport interface OperationGenerationOptions {\r\n /**\r\n * Matches the name of the function or action as it is stated in the EDMX model, e.g. \"Person\".\r\n * You can also address the fully qualified name including the namespace (annotated at the schema element), e.g.\r\n * \"Trippin.Person\".\r\n *\r\n * If the name is specified as plain string, it must match either the name or the fully qualified name\r\n * exactly (case-sensitive).\r\n *\r\n * Alternatively, a regular expression can be used which is always applied to the fully qualified name\r\n * (e.g. Trippin.Person). The regular expression must match the whole string\r\n * (e.g. `/Person/` won't do, `/.*\\.Person/` would work).\r\n *\r\n * To make regular expressions useful, captured groups are also supported. Works in combination with\r\n * the `mappedName` attribute.\r\n */\r\n name: string | RegExp;\r\n\r\n /**\r\n * If specified, this attribute value is used as name for the matched operation as it will\r\n * appear in the generated typescript.\r\n *\r\n * When using a regular expression for matching the name, then captured groups can be referenced\r\n * as usual via $1, $2, etc. For example:\r\n * - name: /Trippin\\.(.+)/\r\n * - mappedName: \"T_$1\"\r\n * - result: \"T_Person\"\r\n */\r\n mappedName?: string;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"OptionModel.js","sourceRoot":"","sources":["../src/OptionModel.ts"],"names":[],"mappings":";;;AAMA;;GAEG;AACH,IAAY,KAKX;AALD,WAAY,KAAK;IACf,qCAAM,CAAA;IACN,yCAAQ,CAAA;IACR,uCAAO,CAAA;IACP,+BAAG,CAAA;AACL,CAAC,EALW,KAAK,qBAAL,KAAK,QAKhB;AAED;;GAEG;AACH,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,sBAAS,CAAA;IACT,sBAAS,CAAA;IACT,wBAAW,CAAA;IACX,8BAAiB,CAAA;AACnB,CAAC,EALW,SAAS,yBAAT,SAAS,QAKpB","sourcesContent":["import { TypeConverterConfig } from \"@odata2ts/converter-runtime\";\nimport { AxiosRequestConfig } from \"axios\";\n\nimport { NameSettings, OverridableNamingOptions } from \"./NamingModel\";\nimport { TypeModel } from \"./TypeModel\";\n\n/**\n * Generation mode, by default \"all\".\n */\nexport enum Modes {\n models,\n qobjects,\n service,\n all,\n}\n\n/**\n * What kind of stuff to emit: Either raw TS or TS that has been compiled to JS / DTS.\n */\nexport enum EmitModes {\n ts = \"ts\",\n js = \"js\",\n dts = \"dts\",\n js_dts = \"js_dts\",\n}\n\n/**\n * Config options for CLI.\n */\nexport interface CliOptions {\n /**\n * The URL to the root of your OData service. The URL might end in a slash or not, it might also end\n * in $metadata, but we usually add this for you.\n *\n * Specifying the URL is a convenience feature to download the metadata file from the given URL.\n * You can configure this request via `sourceConfig` option.\n *\n * The `source` option must still be specified as it is used to store the downloaded file on your disk.\n * By default, the file is used once it has been downloaded.\n */\n sourceUrl?: string;\n /**\n * Downloads the metadata file and overwrites the existing one, if any.\n *\n * Only takes effect, if option `sourceUrl` is specified.\n */\n refreshFile?: boolean;\n /**\n * The source is the file to use (must be an EDMX compliant XML file) or the URL to the\n * metadata (ROOT_SERVICE/$metadata).\n *\n * If not specified, at least one service must be configured in config file.\n */\n source?: string;\n /**\n * Specifies the output directory for the generated stuff.\n *\n * If not specified, at least one service must be configured in config file.\n */\n output?: string;\n /**\n * Only generates the specified services.\n * Relies on an existing config file where these service names are maintained.\n */\n services?: Array<string>;\n /**\n * Specifies what to generate:\n * - {@code Modes.models} will only generate TS interfaces\n * - {@code Modes.qobjects} will generate functional units used in QueryBuilder and for functions and actions\n * - {@code Modes.service} will generate one main OData service client and one per each entity\n * - {@code Modes.all} the same as {@code Modes.service}\n *\n * QObjects will also generate models, and generating the service client will also generate models and QObjects.\n * Defaults to {@code Modes.all}\n */\n mode?: Modes;\n /**\n * Specifies the type of the output files: TypeScript, JS, DTS only, JS with DTS.\n * Defaults to {@code EmitModes.js_dts}\n */\n emitMode?: EmitModes;\n /**\n * Uses prettier with your local configuration to pretty print TypeScript files.\n * Only applies if mode is set to {@code EmitModes.ts}.\n */\n prettier?: boolean;\n /**\n * When compiling TypeScript to JS, \"tsconfig.json\" is used by default to add compilerOptions.\n * This option allows to specify an alternative file.\n *\n * Only takes effect, when mode is set to anything else than {@code EmitModes.ts}.\n */\n tsconfig?: string;\n /**\n * Verbose debugging information.\n */\n debug?: boolean;\n /**\n * Overrides the service name found in the source file.\n *\n * The service name is the basis for all file names and the name of the main OData client service\n * that serves as entry point for the user.\n */\n serviceName?: string;\n /**\n * odata2ts will automatically decide if a key prop is managed on the server side.\n * If managed, the property will not be editable (create, update, patch).\n * The following rule applies:\n * If a property is the only key prop of an entity, then the prop is deemed to be managed;\n * in ony other case the prop is unmanaged.\n */\n disableAutoManagedKey?: boolean;\n /**\n * By default, odata2ts doesn't change param, operation, property or model names.\n * The generated models and their properties are named exactly as advertised by the server.\n *\n * By allowing odata2ts to change these names, certain predefined formatting strategies are used:\n * Model / class names are formatted with PascalCase; property, param, and operation names with camelCase.\n *\n * The naming configuration allows to control this and other naming related settings.\n * Note: Even if renaming is disabled, model prefixing / suffixing still applies.\n */\n allowRenaming?: boolean;\n}\n\n/**\n * Configuration options of the request to retrieve the metadata.\n * Only takes effect if `source` is a URL.\n */\nexport interface UrlSourceConfiguration {\n /**\n * Basic auth credentials: the username.\n * Only takes effect if `password` has also been set.\n */\n username?: string;\n /**\n * Basic auth credentials: the password.\n * Only takes effect if `username` has also been set.\n */\n password?: string;\n /**\n * Custom request configuration.\n * URL and method `GET` are set by default, but can be overwritten.\n */\n custom?: AxiosRequestConfig;\n}\n\n/**\n * Available options for configuration files, i.e. odata2ts.config.ts.\n */\nexport interface ConfigFileOptions extends Omit<CliOptions, \"sourceUrl\" | \"source\" | \"output\" | \"services\"> {\n /**\n * Configuration options of the request to retrieve the metadata.\n * Only takes effect if `sourceUrl` is a URL.\n */\n sourceUrlConfig?: UrlSourceConfiguration;\n\n /**\n * Configuration of each service.\n *\n * @example { services: { trippin: { source: \"...\", ... } }}\n */\n services?: { [serviceName: string]: ServiceGenerationOptions };\n\n /**\n * Specify which converters to use by their package name, e.g. \"@odata2ts/converter-v2-to-v4\".\n * Each converter knows which data type to map.\n *\n * To only use specific converters, the object syntax must be used, where supported converters\n * must be listed by their ids.\n */\n converters?: Array<string | TypeConverterConfig>;\n\n /**\n * For each model an editable version is generated which represents the model definition for\n * create, update and patch actions.\n *\n * You can skip the generation altogether, not generating editable model variants,\n * if the generation mode is {@code Mode.model} or {@code Mode.qobject}.\n */\n skipEditableModels?: boolean;\n\n /**\n * ID models are generated from entity id parameters.\n * The generation for one entity entails one model interface representing the id parameters and\n * one QId function which allows to format the parameters for URL usage and to parse parameters\n * from a URL string.\n *\n * You can skip the generation altogether, not generating models and QId objects, if the\n * generation mode is {@code Mode.model} or {@code Mode.qobject}.\n */\n skipIdModels?: boolean;\n /**\n * Operations are functions and actions of the OData service.\n * The generation for one operation entails one parameter model interface\n * and one QFunction / QAction class.\n *\n * You can skip the generation altogether, neither generating model nor query object,\n * if the generation mode is {@code Mode.model} or {@code Mode.qobject}.\n */\n skipOperations?: boolean;\n /**\n * Model properties have explaining comments by default.\n * With this option you can turn that off.\n */\n skipComments?: boolean;\n /**\n * With OData you can read, update and delete data on a primitive property (`Edm.*`).\n * Usually, you wouldn't do that, but go for a bigger request, fetching more relevant information in one go.\n *\n * There's one exception: Handling `Edm.Stream´ properties and Media entities. Services for stream / media\n * stuff are generated regardless of this setting.\n */\n enablePrimitivePropertyServices?: boolean;\n\n /**\n * The naming options regarding the generated artefacts.\n */\n naming?: OverridableNamingOptions;\n\n /**\n * Some OData V2 services generate an extra wrapping for entity collection attributes:\n * <code>trips: {results: [...]}</code>. So instead of directly returning an array of entities\n * an object with the property \"results\" is wrapped around the entity collection.\n *\n * If you're using the odata client then there's a build-in workaround in place which transforms\n * the results to remove this extra mapping. However, if you're only interested in the types, then\n * the generated models will not match that extra wrapping.\n *\n * Setting this configuration option to <code>true</code> (default: false) will add this extra\n * wrapping to the generated models. But this option is only valid if the generation mode is set\n * to <code>models</code>; it is ignored otherwise.\n */\n v2ModelsWithExtraResultsWrapping?: boolean;\n /**\n * Numbers of type `Edm.Int64` and `Edm.Decimal` are represented as `number` in V4.\n * However, these numbers might not fit into JS' number type, which might result in precision loss.\n *\n * OData offers a special IEEE754 format option to get those types as `string` instead to prevent any\n * precision loss. So if you're handling very large or very small numbers (JS roughly supports 15 digits),\n * then you should use this option and, probably, also an appropriate converter (see available converters).\n *\n * Activating this option affects the type generation and will use `string` for both mentioned types.\n * All requests are executed with the \"accept\" header set to \"application/json;IEEE754Compatible=true\".\n * Additionally, when sending data the very same value will be set for the \"content-type\" header.\n */\n v4BigNumberAsString?: boolean;\n /**\n * OData allows for namespaces so any entity is unique by virtue of it's name within a namespace.\n * odata2ts works with these fully qualified names internally, but only uses the plain name when generating\n * stuff. This might lead to name clashes (same name in different namespaces).\n *\n * odata2ts employs a simple, automatic resolution strategy: Adding a counter at the end of the name.\n * Set this property to true in order to disable this automatism.\n */\n disableAutomaticNameClashResolution?: boolean;\n}\n\n/**\n * Custom generation options which are dependent on a specific odata service.\n */\nexport interface ServiceGenerationOptions\n extends Required<Pick<CliOptions, \"source\" | \"output\">>,\n Pick<CliOptions, \"sourceUrl\" | \"refreshFile\">,\n Omit<ConfigFileOptions, \"services\"> {\n /**\n * Configure generation process for individual properties based on their name.\n */\n propertiesByName?: Array<PropertyGenerationOptions>;\n /**\n * Rename any EntityType, ComplexType, EnumType, Function or Action.\n *\n * You must match the simple name (e.g. \"Person\") or the fully qualified name\n * (e.g. \"Trippin.Person\") exactly. Alternatively, you can rename a bunch of types\n * by using regular expressions.\n *\n * By providing additional type information via the \"type\" attribute you get even more options which only apply\n * to the given type.\n */\n byTypeAndName?: Array<ComplexTypeGenerationOptions | EntityTypeGenerationOptions | GenericTypeGenerationOptions>;\n}\n\n/**\n * Available options for the actual generation run.\n * Every property is required, except the overriding service name.\n */\nexport interface RunOptions\n extends Required<Omit<ServiceGenerationOptions, \"serviceName\" | \"sourceUrl\" | \"sourceUrlConfig\" | \"refreshFile\">>,\n Pick<ServiceGenerationOptions, \"serviceName\" | \"sourceUrl\" | \"sourceUrlConfig\" | \"refreshFile\"> {\n naming: NameSettings;\n}\n\nexport interface RenameOptions {\n /**\n * Matcher for the name of any EntityType, ComplexType, EnumType, Function or Action\n * as it is stated in the EDMX model, e.g. \"Person\". As OData supports namespaces\n * you can also use the fully qualified name (including the namespace) to address any model,\n * e.g. \"Trippin.Person\". You can also match properties by their name.\n *\n * If the name is specified as plain string, it must match either the name or the fully qualified name\n * exactly (case-sensitive).\n *\n * Alternatively, a regular expression can be used which is always applied to the fully qualified name\n * (e.g. Trippin.Person). The regular expression must match the whole string\n * (e.g. `/Person/` won't do, `/.*\\.Person/` would work).\n *\n * To make regular expressions useful, captured groups are also supported in combination with\n * the `mappedName` attribute.\n */\n name: string | RegExp;\n\n /**\n * If specified, this attribute value is used as final name for the matched name as it will\n * appear in the generated typescript.\n *\n * When using a regular expression for matching the name, then captured groups can be referenced\n * as usual via $1, $2, etc. For example:\n * - name: /Trippin\\.(.+)/\n * - mappedName: \"T_$1\"\n * The result would be \"T_Person\".\n */\n mappedName?: string;\n}\n\nexport type TypeBasedGenerationOptions =\n | GenericTypeGenerationOptions\n | ComplexTypeGenerationOptions\n | EntityTypeGenerationOptions;\n\nexport interface GenericTypeGenerationOptions extends RenameOptions {\n type:\n | TypeModel.Any\n | TypeModel.EnumType\n | TypeModel.OperationType\n | TypeModel.OperationImportType\n | TypeModel.Singleton\n | TypeModel.EntitySet;\n}\n\nexport interface ComplexTypeGenerationOptions extends RenameOptions {\n type: TypeModel.ComplexType;\n\n /**\n * Configuration of individual properties.\n */\n properties?: Array<PropertyGenerationOptions>;\n\n // converter: string | Array<string>\n}\n\n/**\n * Configuration options for EntityTypes and ComplexTypes.\n * This config applies if the name matches the name of an EntityType or ComplexType as it is specified\n * in the metadata (e.g. in EDMX <EntityType name=\"Test\" ...)\n */\nexport interface EntityTypeGenerationOptions extends Omit<ComplexTypeGenerationOptions, \"type\"> {\n type: TypeModel.EntityType;\n\n /**\n * Overwrite the key specification by naming the props by their EDMX name.\n */\n keys?: Array<string>;\n\n /**\n * Whether the generated service should allow for querying this model.\n * True by default.\n */\n // queryable?: boolean;\n /**\n * Whether the generated service should allow for creating new models (POST).\n * True by default.\n */\n // creatable?: boolean;\n /**\n * Whether the generated service should allow for updates (PUT).\n * True by default.\n */\n // updatable?: boolean;\n /**\n * Whether the generated service should allow for partial updates (PATCH).\n * True by default.\n */\n // patchable?: boolean;\n /**\n * Whether the generated service should allow for deletion.\n * True by default.\n */\n // deletable?: boolean;\n}\n\n/**\n * All configuration options for properties of models.\n */\nexport interface PropertyGenerationOptions extends RenameOptions {\n /**\n * Managed attributes - i.e. managed by the server - cannot be created or updated.\n * Hence, they are left out of the editable model versions.\n */\n managed?: boolean;\n\n /**\n * TODO\n *\n * Each converter must specify its package name, e.g. \"@odata2ts/converter-v2-to-v4\",\n * as well it's i\n * and their ids, e.g. \"timeToDurationConverter\".\n *\n * To only use specific converters, the object syntax must be used, where supported converters\n * must be listed by their ids.\n */\n // converters?: Array<Required<TypeConverterConfig>>;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare enum TypeModel {
|
|
2
|
+
Any = "Any",
|
|
3
|
+
EntitySet = "EntitySet",
|
|
4
|
+
Singleton = "Singleton",
|
|
5
|
+
EntityType = "EntityType",
|
|
6
|
+
ComplexType = "ComplexType",
|
|
7
|
+
EnumType = "EnumType",
|
|
8
|
+
OperationType = "OperationType",
|
|
9
|
+
OperationImportType = "OperationImportType"
|
|
10
|
+
}
|
package/lib/TypeModel.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypeModel = void 0;
|
|
4
|
+
var TypeModel;
|
|
5
|
+
(function (TypeModel) {
|
|
6
|
+
TypeModel["Any"] = "Any";
|
|
7
|
+
TypeModel["EntitySet"] = "EntitySet";
|
|
8
|
+
TypeModel["Singleton"] = "Singleton";
|
|
9
|
+
TypeModel["EntityType"] = "EntityType";
|
|
10
|
+
TypeModel["ComplexType"] = "ComplexType";
|
|
11
|
+
TypeModel["EnumType"] = "EnumType";
|
|
12
|
+
// Bundle Function and Action (bound or unbound; v4 only)
|
|
13
|
+
TypeModel["OperationType"] = "OperationType";
|
|
14
|
+
// Bundles ActionImport and FunctionImport elements
|
|
15
|
+
TypeModel["OperationImportType"] = "OperationImportType";
|
|
16
|
+
})(TypeModel || (exports.TypeModel = TypeModel = {}));
|
|
17
|
+
//# sourceMappingURL=TypeModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeModel.js","sourceRoot":"","sources":["../src/TypeModel.ts"],"names":[],"mappings":";;;AAAA,IAAY,SAWX;AAXD,WAAY,SAAS;IACnB,wBAAW,CAAA;IACX,oCAAuB,CAAA;IACvB,oCAAuB,CAAA;IACvB,sCAAyB,CAAA;IACzB,wCAA2B,CAAA;IAC3B,kCAAqB,CAAA;IACrB,yDAAyD;IACzD,4CAA+B,CAAA;IAC/B,mDAAmD;IACnD,wDAA2C,CAAA;AAC7C,CAAC,EAXW,SAAS,yBAAT,SAAS,QAWpB","sourcesContent":["export enum TypeModel {\n Any = \"Any\",\n EntitySet = \"EntitySet\",\n Singleton = \"Singleton\",\n EntityType = \"EntityType\",\n ComplexType = \"ComplexType\",\n EnumType = \"EnumType\",\n // Bundle Function and Action (bound or unbound; v4 only)\n OperationType = \"OperationType\",\n // Bundles ActionImport and FunctionImport elements\n OperationImportType = \"OperationImportType\",\n}\n"]}
|
package/lib/app.js
CHANGED
|
@@ -37,6 +37,19 @@ function runApp(metadataJson, options) {
|
|
|
37
37
|
const dataModel = version === odata_core_1.ODataVersions.V2
|
|
38
38
|
? yield (0, DataModelDigestionV2_1.digest)(dataService.Schema, options, namingHelper)
|
|
39
39
|
: yield (0, DataModelDigestionV4_1.digest)(dataService.Schema, options, namingHelper);
|
|
40
|
+
// Validation of entity names: the same name might be used across different namespaces
|
|
41
|
+
const validationErrors = dataModel.getNameValidation();
|
|
42
|
+
if (validationErrors.size) {
|
|
43
|
+
console.log("---");
|
|
44
|
+
validationErrors.forEach((errors, name) => {
|
|
45
|
+
console.log(`Duplicate name: ${name} - Fully Qualified Names: ${errors
|
|
46
|
+
.map((error) => error.fqName + (error.renamedTo ? ` (renamed to: ${error.renamedTo})` : ""))
|
|
47
|
+
.join(", ")}`);
|
|
48
|
+
});
|
|
49
|
+
if (options.disableAutomaticNameClashResolution) {
|
|
50
|
+
throw new Error("Name validation failed: Multiple entities have the same name across different namespaces!");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
40
53
|
// handling the overall generation project
|
|
41
54
|
const project = yield (0, ProjectManager_1.createProjectManager)(namingHelper.getFileNames(), options.output, options.emitMode, options.prettier, options.tsconfig);
|
|
42
55
|
// Generate Model Interfaces
|
package/lib/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;AAAA,qDAAqD;AAGrD,4EAAuE;AACvE,4EAAuE;AAIvE,4DAAyD;AACzD,2CAAqF;AACrF,+CAAkD;AAClD,6DAAgE;AAEhE,SAAS,YAAY,CAAC,IAAW;IAC/B,OAAO,CAAC,mBAAK,CAAC,QAAQ,EAAE,mBAAK,CAAC,OAAO,EAAE,mBAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,YAAY,CAAC,IAAW;IAC/B,OAAO,CAAC,mBAAK,CAAC,OAAO,EAAE,mBAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,SAAsB,MAAM,CAAC,YAAqC,EAAE,OAAmB;;QACrF,uCAAuC;QACvC,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxD,MAAM,OAAO,GAAG,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,0BAAa,CAAC,EAAE,CAAC,CAAC,CAAC,0BAAa,CAAC,EAAE,CAAC;QAE5E,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,WAAW,CAAC,MAAoC,CAAC;QAEjE,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,WAAC,OAAA,MAAM,CAAC,CAAC,CAAC,SAAS,KAAI,MAAA,MAAM,CAAC,UAAU,0CAAE,MAAM,CAAA,CAAA,EAAA,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/G,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAErG,qCAAqC;QACrC,MAAM,YAAY,GAAG,IAAI,2BAAY,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QACxE,2EAA2E;QAC3E,qCAAqC;QACrC,MAAM,SAAS,GACb,OAAO,KAAK,0BAAa,CAAC,EAAE;YAC1B,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,WAAW,CAAC,MAAyB,EAAE,OAAO,EAAE,YAAY,CAAC;YAC9E,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,WAAW,CAAC,MAAyB,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;AAAA,qDAAqD;AAGrD,4EAAuE;AACvE,4EAAuE;AAIvE,4DAAyD;AACzD,2CAAqF;AACrF,+CAAkD;AAClD,6DAAgE;AAEhE,SAAS,YAAY,CAAC,IAAW;IAC/B,OAAO,CAAC,mBAAK,CAAC,QAAQ,EAAE,mBAAK,CAAC,OAAO,EAAE,mBAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,YAAY,CAAC,IAAW;IAC/B,OAAO,CAAC,mBAAK,CAAC,OAAO,EAAE,mBAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,SAAsB,MAAM,CAAC,YAAqC,EAAE,OAAmB;;QACrF,uCAAuC;QACvC,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxD,MAAM,OAAO,GAAG,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,0BAAa,CAAC,EAAE,CAAC,CAAC,CAAC,0BAAa,CAAC,EAAE,CAAC;QAE5E,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,WAAW,CAAC,MAAoC,CAAC;QAEjE,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,WAAC,OAAA,MAAM,CAAC,CAAC,CAAC,SAAS,KAAI,MAAA,MAAM,CAAC,UAAU,0CAAE,MAAM,CAAA,CAAA,EAAA,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/G,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAErG,qCAAqC;QACrC,MAAM,YAAY,GAAG,IAAI,2BAAY,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QACxE,2EAA2E;QAC3E,qCAAqC;QACrC,MAAM,SAAS,GACb,OAAO,KAAK,0BAAa,CAAC,EAAE;YAC1B,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,WAAW,CAAC,MAAyB,EAAE,OAAO,EAAE,YAAY,CAAC;YAC9E,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,WAAW,CAAC,MAAyB,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAEnF,sFAAsF;QACtF,MAAM,gBAAgB,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;QACvD,IAAI,gBAAgB,CAAC,IAAI,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,gBAAgB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;gBACxC,OAAO,CAAC,GAAG,CACT,mBAAmB,IAAI,6BAA6B,MAAM;qBACvD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;qBAC3F,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,mCAAmC,EAAE;gBAC/C,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;aAC9G;SACF;QAED,0CAA0C;QAC1C,MAAM,OAAO,GAAG,MAAM,IAAA,qCAAoB,EACxC,YAAY,CAAC,YAAY,EAAE,EAC3B,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,QAAQ,CACjB,CAAC;QAEF,4BAA4B;QAC5B,0DAA0D;QAC1D,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC;QACnD,IAAA,0BAAc,EAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAEtE,yBAAyB;QACzB,gDAAgD;QAChD,mJAAmJ;QACnJ,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC9B,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC;YAChD,IAAA,gCAAoB,EAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;SACxE;QAED,oCAAoC;QACpC,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC9B,MAAM,IAAA,4BAAgB,EAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;SAC5E;QAED,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;CAAA;AAnED,wBAmEC","sourcesContent":["import { ODataVersions } from \"@odata2ts/odata-core\";\r\n\r\nimport { NamespaceWithAlias } from \"./data-model/DataModel\";\r\nimport { digest as digestV2 } from \"./data-model/DataModelDigestionV2\";\r\nimport { digest as digestV4 } from \"./data-model/DataModelDigestionV4\";\r\nimport { ODataEdmxModelBase, Schema } from \"./data-model/edmx/ODataEdmxModelBase\";\r\nimport { SchemaV3 } from \"./data-model/edmx/ODataEdmxModelV3\";\r\nimport { SchemaV4 } from \"./data-model/edmx/ODataEdmxModelV4\";\r\nimport { NamingHelper } from \"./data-model/NamingHelper\";\r\nimport { generateModels, generateQueryObjects, generateServices } from \"./generator\";\r\nimport { Modes, RunOptions } from \"./OptionModel\";\r\nimport { createProjectManager } from \"./project/ProjectManager\";\r\n\r\nfunction isQObjectGen(mode: Modes) {\r\n return [Modes.qobjects, Modes.service, Modes.all].includes(mode);\r\n}\r\n\r\nfunction isServiceGen(mode: Modes) {\r\n return [Modes.service, Modes.all].includes(mode);\r\n}\r\n\r\n/**\r\n *\r\n * @param metadataJson metadata of a given OData service already parsed as JSON\r\n * @param options further options\r\n */\r\nexport async function runApp(metadataJson: ODataEdmxModelBase<any>, options: RunOptions): Promise<void> {\r\n // determine edmx edmxVersion attribute\r\n const edmxVersion = metadataJson[\"edmx:Edmx\"].$.Version;\r\n const version = edmxVersion === \"1.0\" ? ODataVersions.V2 : ODataVersions.V4;\r\n\r\n const dataService = metadataJson[\"edmx:Edmx\"][\"edmx:DataServices\"][0];\r\n const schemas = dataService.Schema as Array<SchemaV3 | SchemaV4>;\r\n\r\n const detectedSchema = schemas.find((schema) => schema.$.Namespace && schema.EntityType?.length) || schemas[0];\r\n const serviceName = options.serviceName || detectedSchema.$.Namespace;\r\n\r\n const namespaces = schemas.map<NamespaceWithAlias>((schema) => [schema.$.Namespace, schema.$.Alias]);\r\n\r\n // encapsulate the whole naming logic\r\n const namingHelper = new NamingHelper(options, serviceName, namespaces);\r\n // parse model information from edmx into something we can really work with\r\n // => that stuff is called dataModel!\r\n const dataModel =\r\n version === ODataVersions.V2\r\n ? await digestV2(dataService.Schema as Array<SchemaV3>, options, namingHelper)\r\n : await digestV4(dataService.Schema as Array<SchemaV4>, options, namingHelper);\r\n\r\n // Validation of entity names: the same name might be used across different namespaces\r\n const validationErrors = dataModel.getNameValidation();\r\n if (validationErrors.size) {\r\n console.log(\"---\");\r\n validationErrors.forEach((errors, name) => {\r\n console.log(\r\n `Duplicate name: ${name} - Fully Qualified Names: ${errors\r\n .map((error) => error.fqName + (error.renamedTo ? ` (renamed to: ${error.renamedTo})` : \"\"))\r\n .join(\", \")}`\r\n );\r\n });\r\n\r\n if (options.disableAutomaticNameClashResolution) {\r\n throw new Error(\"Name validation failed: Multiple entities have the same name across different namespaces!\");\r\n }\r\n }\r\n\r\n // handling the overall generation project\r\n const project = await createProjectManager(\r\n namingHelper.getFileNames(),\r\n options.output,\r\n options.emitMode,\r\n options.prettier,\r\n options.tsconfig\r\n );\r\n\r\n // Generate Model Interfaces\r\n // supported edmx types: EntityType, ComplexType, EnumType\r\n const modelsFile = await project.createModelFile();\r\n generateModels(dataModel, modelsFile, version, options, namingHelper);\r\n\r\n // Generate Query Objects\r\n // supported edmx types: EntityType, ComplexType\r\n // supported edmx prop types: primitive types, enum types, primitive collection (incl enum types), entity collection, entity object, complex object\r\n if (isQObjectGen(options.mode)) {\r\n const qFile = await project.createQObjectFile();\r\n generateQueryObjects(dataModel, qFile, version, options, namingHelper);\r\n }\r\n\r\n // Generate Individual OData-Service\r\n if (isServiceGen(options.mode)) {\r\n await generateServices(dataModel, project, version, namingHelper, options);\r\n }\r\n\r\n await project.writeFiles();\r\n}\r\n"]}
|
package/lib/cli.js
CHANGED
|
@@ -112,7 +112,7 @@ function startServiceGenerationRun(options) {
|
|
|
112
112
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
113
113
|
const { source, output, sourceUrl, refreshFile, sourceUrlConfig, debug, mode, emitMode, prettier, serviceName } = options;
|
|
114
114
|
console.log("---------------------------");
|
|
115
|
-
console.log(
|
|
115
|
+
console.log(`Starting generation process. Service name ${serviceName ? `"${serviceName}"` : "will be detected automatically!"}`);
|
|
116
116
|
if (debug) {
|
|
117
117
|
console.log("Resolved config:", {
|
|
118
118
|
source,
|
package/lib/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import commander, { Option } from \"commander\";\r\nimport { cosmiconfig } from \"cosmiconfig\";\r\nimport { TypeScriptLoader } from \"cosmiconfig-typescript-loader\";\r\nimport { emptyDir, pathExists, readFile } from \"fs-extra\";\r\nimport { parseStringPromise } from \"xml2js\";\r\n\r\nimport { runApp } from \"./app\";\r\nimport { ODataEdmxModelBase } from \"./data-model/edmx/ODataEdmxModelBase\";\r\nimport { downloadMetadata, storeMetadata } from \"./download/\";\r\nimport { evaluateConfigOptions } from \"./evaluateConfig\";\r\nimport { CliOptions, ConfigFileOptions, EmitModes, Modes, RunOptions, UrlSourceConfiguration } from \"./OptionModel\";\r\nimport { logFilePath } from \"./project/logger/logFilePath\";\r\n\r\nfunction parseMode(value: string, dummyPrevious: Modes | undefined) {\r\n switch (value) {\r\n case \"models\":\r\n return Modes.models;\r\n case \"qobjects\":\r\n return Modes.qobjects;\r\n case \"service\":\r\n return Modes.service;\r\n case \"all\":\r\n return Modes.all;\r\n default:\r\n throw new Error(`Not a valid Mode: ${value}`);\r\n }\r\n}\r\n\r\nfunction parseEmitMode(value: string, dummyPrevious: EmitModes) {\r\n switch (value) {\r\n case \"dts\":\r\n return EmitModes.dts;\r\n case \"js\":\r\n return EmitModes.js;\r\n case \"ts\":\r\n return EmitModes.ts;\r\n case \"js_dts\":\r\n return EmitModes.js_dts;\r\n default:\r\n throw new Error(`Not a valid EmitMode: ${value}`);\r\n }\r\n}\r\n\r\nfunction processCliArgs() {\r\n const cli = new commander.Command()\r\n .version(\"0.3.0\")\r\n .description(\"CLI to generate Typescript Interfaces for models of a given OData service.\")\r\n .argument(\"[services...]\", \"Run the generation process only for certain services specified in config file\", [])\r\n .option(\"-s, --source <url or metadata.xml>\", \"Path to metadata file\")\r\n .option(\"-o, --output <path>\", \"Output location for generated files\")\r\n .option(\"-u, --source-url <sourceUrl>\", \"URL to the root of the OData service\")\r\n .option(\r\n \"-f, --refresh-file\",\r\n \"Download metadata again and overwrite existing file (only applies if sourceUrl is specified)\"\r\n )\r\n .addOption(\r\n new Option(\"-m, --mode <mode>\", \"What kind of stuff gets generated\")\r\n .choices(Object.values(Modes).filter((t): t is string => isNaN(Number(t))))\r\n .argParser<Modes>(parseMode)\r\n )\r\n .addOption(\r\n new Option(\r\n \"-e, --emit-mode <mode>\",\r\n \"Output TS source files, compiled JS files with/wihthout generated d.ts files\"\r\n )\r\n .choices(Object.values(EmitModes))\r\n .argParser<EmitModes>(parseEmitMode)\r\n )\r\n .option(\"-p, --prettier\", \"Format result with prettier (only applies if emitMode=ts)\")\r\n .option(\r\n \"-t, --tsconfig <path>\",\r\n \"Specify alternative to 'tsconfig.json' to use specific compilerOptions (applies if emitMode is not ts)\"\r\n )\r\n .option(\"-d, --debug\", \"Verbose debug infos\")\r\n .option(\"-name, --service-name <serviceName>\", \"Give the service your own name\")\r\n .option(\r\n \"-n, --disable-auto-managed-key\",\r\n \"Don't mark single key props as managed by the server side (not editable)\"\r\n )\r\n .option(\"-r, --allow-renaming\", \"Allow that property and entity names may be changed by configured casing\")\r\n .parse(process.argv);\r\n\r\n const args = cli.args?.length ? { services: cli.args } : {};\r\n return {\r\n ...cli.opts(),\r\n ...args,\r\n } as CliOptions;\r\n}\r\n\r\nasync function processConfigFile() {\r\n const moduleName = \"odata2ts\";\r\n const explorer = cosmiconfig(moduleName, {\r\n searchPlaces: [`${moduleName}.config.js`, `${moduleName}.config.ts`, `${moduleName}.config.cjs`],\r\n loaders: {\r\n \".ts\": TypeScriptLoader(),\r\n },\r\n });\r\n const discoveredConfig = await explorer.search();\r\n\r\n if (discoveredConfig?.config) {\r\n console.log(\"Loaded config file: \", logFilePath(discoveredConfig.filepath));\r\n } else {\r\n console.log(\"No config file found.\");\r\n }\r\n\r\n return discoveredConfig?.config as ConfigFileOptions;\r\n}\r\n\r\nexport class Cli {\r\n async run(): Promise<void> {\r\n let runs;\r\n try {\r\n const cliOpts = processCliArgs();\r\n if (cliOpts.debug) {\r\n console.log(\"CLI opts:\", cliOpts);\r\n }\r\n const fileOpts = await processConfigFile();\r\n\r\n runs = evaluateConfigOptions(cliOpts, fileOpts);\r\n } catch (error: any) {\r\n console.error(\"Bad arguments!\", error?.message);\r\n process.exit(1);\r\n }\r\n\r\n for (let run of runs) {\r\n await startServiceGenerationRun(run);\r\n }\r\n }\r\n}\r\n\r\nasync function startServiceGenerationRun(options: RunOptions) {\r\n const { source, output, sourceUrl, refreshFile, sourceUrlConfig, debug, mode, emitMode, prettier, serviceName } =\r\n options;\r\n console.log(\"---------------------------\");\r\n console.log(\"Starting generation process\");\r\n\r\n if (debug) {\r\n console.log(\"Resolved config:\", {\r\n source,\r\n output,\r\n sourceUrl,\r\n refreshFile,\r\n debug,\r\n mode: Modes[mode],\r\n emitMode,\r\n prettier,\r\n serviceName,\r\n });\r\n }\r\n\r\n // evaluate source\r\n const exists = await pathExists(source);\r\n console.log(`${exists ? \"Found\" : \"Didn't find\"} metadata file at: `, source);\r\n\r\n let metadataXml;\r\n // download metadata and store on disk\r\n if (sourceUrl && (!exists || refreshFile)) {\r\n try {\r\n metadataXml = await downloadMetadata(sourceUrl, sourceUrlConfig, debug);\r\n } catch (e) {\r\n console.error(`Failed to load metadata! Message: ${(e as Error)?.message}`);\r\n process.exit(10);\r\n }\r\n metadataXml = await storeMetadata(source, metadataXml, prettier);\r\n }\r\n // otherwise file must exist\r\n else if (!exists) {\r\n console.error(`Input source [${source}] doesn't exist!`);\r\n process.exit(2);\r\n }\r\n // read the metadata from file\r\n else {\r\n console.log(\"Reading metadata from file:\", source);\r\n metadataXml = await readFile(source);\r\n }\r\n\r\n const metadataJson = (await parseStringPromise(metadataXml)) as ODataEdmxModelBase<any>;\r\n // TODO find out if \"1.0\" and \"4.0\" are really correct\r\n // TODO exit here if no version not suitable version was detected\r\n // console.log(`OData version detected: ${metadataJson[\"edmx:Edmx\"].$.Version}`);\r\n\r\n // ensure that output directory exists\r\n try {\r\n await emptyDir(output);\r\n } catch (error) {\r\n console.error(`Output path [${output}] couldn't be created!`, error);\r\n process.exit(3);\r\n }\r\n\r\n // run the app\r\n try {\r\n await runApp(metadataJson, options);\r\n } catch (err: any) {\r\n console.error(\"Error while running the program\", err);\r\n process.exit(99);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import commander, { Option } from \"commander\";\nimport { cosmiconfig } from \"cosmiconfig\";\nimport { TypeScriptLoader } from \"cosmiconfig-typescript-loader\";\nimport { emptyDir, pathExists, readFile } from \"fs-extra\";\nimport { parseStringPromise } from \"xml2js\";\n\nimport { runApp } from \"./app\";\nimport { ODataEdmxModelBase } from \"./data-model/edmx/ODataEdmxModelBase\";\nimport { downloadMetadata, storeMetadata } from \"./download/\";\nimport { evaluateConfigOptions } from \"./evaluateConfig\";\nimport { CliOptions, ConfigFileOptions, EmitModes, Modes, RunOptions, UrlSourceConfiguration } from \"./OptionModel\";\nimport { logFilePath } from \"./project/logger/logFilePath\";\n\nfunction parseMode(value: string, dummyPrevious: Modes | undefined) {\n switch (value) {\n case \"models\":\n return Modes.models;\n case \"qobjects\":\n return Modes.qobjects;\n case \"service\":\n return Modes.service;\n case \"all\":\n return Modes.all;\n default:\n throw new Error(`Not a valid Mode: ${value}`);\n }\n}\n\nfunction parseEmitMode(value: string, dummyPrevious: EmitModes) {\n switch (value) {\n case \"dts\":\n return EmitModes.dts;\n case \"js\":\n return EmitModes.js;\n case \"ts\":\n return EmitModes.ts;\n case \"js_dts\":\n return EmitModes.js_dts;\n default:\n throw new Error(`Not a valid EmitMode: ${value}`);\n }\n}\n\nfunction processCliArgs() {\n const cli = new commander.Command()\n .version(\"0.3.0\")\n .description(\"CLI to generate Typescript Interfaces for models of a given OData service.\")\n .argument(\"[services...]\", \"Run the generation process only for certain services specified in config file\", [])\n .option(\"-s, --source <url or metadata.xml>\", \"Path to metadata file\")\n .option(\"-o, --output <path>\", \"Output location for generated files\")\n .option(\"-u, --source-url <sourceUrl>\", \"URL to the root of the OData service\")\n .option(\n \"-f, --refresh-file\",\n \"Download metadata again and overwrite existing file (only applies if sourceUrl is specified)\"\n )\n .addOption(\n new Option(\"-m, --mode <mode>\", \"What kind of stuff gets generated\")\n .choices(Object.values(Modes).filter((t): t is string => isNaN(Number(t))))\n .argParser<Modes>(parseMode)\n )\n .addOption(\n new Option(\n \"-e, --emit-mode <mode>\",\n \"Output TS source files, compiled JS files with/wihthout generated d.ts files\"\n )\n .choices(Object.values(EmitModes))\n .argParser<EmitModes>(parseEmitMode)\n )\n .option(\"-p, --prettier\", \"Format result with prettier (only applies if emitMode=ts)\")\n .option(\n \"-t, --tsconfig <path>\",\n \"Specify alternative to 'tsconfig.json' to use specific compilerOptions (applies if emitMode is not ts)\"\n )\n .option(\"-d, --debug\", \"Verbose debug infos\")\n .option(\"-name, --service-name <serviceName>\", \"Give the service your own name\")\n .option(\n \"-n, --disable-auto-managed-key\",\n \"Don't mark single key props as managed by the server side (not editable)\"\n )\n .option(\"-r, --allow-renaming\", \"Allow that property and entity names may be changed by configured casing\")\n .parse(process.argv);\n\n const args = cli.args?.length ? { services: cli.args } : {};\n return {\n ...cli.opts(),\n ...args,\n } as CliOptions;\n}\n\nasync function processConfigFile() {\n const moduleName = \"odata2ts\";\n const explorer = cosmiconfig(moduleName, {\n searchPlaces: [`${moduleName}.config.js`, `${moduleName}.config.ts`, `${moduleName}.config.cjs`],\n loaders: {\n \".ts\": TypeScriptLoader(),\n },\n });\n const discoveredConfig = await explorer.search();\n\n if (discoveredConfig?.config) {\n console.log(\"Loaded config file: \", logFilePath(discoveredConfig.filepath));\n } else {\n console.log(\"No config file found.\");\n }\n\n return discoveredConfig?.config as ConfigFileOptions;\n}\n\nexport class Cli {\n async run(): Promise<void> {\n let runs;\n try {\n const cliOpts = processCliArgs();\n if (cliOpts.debug) {\n console.log(\"CLI opts:\", cliOpts);\n }\n const fileOpts = await processConfigFile();\n\n runs = evaluateConfigOptions(cliOpts, fileOpts);\n } catch (error: any) {\n console.error(\"Bad arguments!\", error?.message);\n process.exit(1);\n }\n\n for (let run of runs) {\n await startServiceGenerationRun(run);\n }\n }\n}\n\nasync function startServiceGenerationRun(options: RunOptions) {\n const { source, output, sourceUrl, refreshFile, sourceUrlConfig, debug, mode, emitMode, prettier, serviceName } =\n options;\n console.log(\"---------------------------\");\n console.log(\n `Starting generation process. Service name ${serviceName ? `\"${serviceName}\"` : \"will be detected automatically!\"}`\n );\n\n if (debug) {\n console.log(\"Resolved config:\", {\n source,\n output,\n sourceUrl,\n refreshFile,\n debug,\n mode: Modes[mode],\n emitMode,\n prettier,\n serviceName,\n });\n }\n\n // evaluate source\n const exists = await pathExists(source);\n console.log(`${exists ? \"Found\" : \"Didn't find\"} metadata file at: `, source);\n\n let metadataXml;\n // download metadata and store on disk\n if (sourceUrl && (!exists || refreshFile)) {\n try {\n metadataXml = await downloadMetadata(sourceUrl, sourceUrlConfig, debug);\n } catch (e) {\n console.error(`Failed to load metadata! Message: ${(e as Error)?.message}`);\n process.exit(10);\n }\n metadataXml = await storeMetadata(source, metadataXml, prettier);\n }\n // otherwise file must exist\n else if (!exists) {\n console.error(`Input source [${source}] doesn't exist!`);\n process.exit(2);\n }\n // read the metadata from file\n else {\n console.log(\"Reading metadata from file:\", source);\n metadataXml = await readFile(source);\n }\n\n const metadataJson = (await parseStringPromise(metadataXml)) as ODataEdmxModelBase<any>;\n // TODO find out if \"1.0\" and \"4.0\" are really correct\n // TODO exit here if no version not suitable version was detected\n // console.log(`OData version detected: ${metadataJson[\"edmx:Edmx\"].$.Version}`);\n\n // ensure that output directory exists\n try {\n await emptyDir(output);\n } catch (error) {\n console.error(`Output path [${output}] couldn't be created!`, error);\n process.exit(3);\n }\n\n // run the app\n try {\n await runApp(metadataJson, options);\n } catch (err: any) {\n console.error(\"Error while running the program\", err);\n process.exit(99);\n }\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MappedConverterChains } from "@odata2ts/converter-runtime";
|
|
2
2
|
import { ODataTypesV2, ODataTypesV4 } from "@odata2ts/odata-core";
|
|
3
3
|
import { ActionImportType, ComplexType, EntityContainerModel, EntitySetType, EnumType, FunctionImportType, ModelType, ODataVersion, OperationType, PropertyModel, SingletonType } from "./DataTypeModel";
|
|
4
|
+
import { ValidationError } from "./validation/NameValidator";
|
|
4
5
|
export interface ProjectFiles {
|
|
5
6
|
model: string;
|
|
6
7
|
qObject: string;
|
|
@@ -14,6 +15,7 @@ export declare function withNamespace(ns: string, name: string): string;
|
|
|
14
15
|
export declare class DataModel {
|
|
15
16
|
private version;
|
|
16
17
|
private readonly converters;
|
|
18
|
+
private nameValidation;
|
|
17
19
|
private models;
|
|
18
20
|
/**
|
|
19
21
|
* Stores unbound operations by their fully qualified name.
|
|
@@ -89,11 +91,13 @@ export declare class DataModel {
|
|
|
89
91
|
addBoundOperationType(namespace: string, bindingProp: PropertyModel, operationType: OperationType): void;
|
|
90
92
|
getEntityTypeOperations(fqEntityName: string): Array<OperationType>;
|
|
91
93
|
getEntitySetOperations(fqEntityName: string): Array<OperationType>;
|
|
92
|
-
addAction(
|
|
93
|
-
addFunction(
|
|
94
|
-
addSingleton(
|
|
95
|
-
addEntitySet(
|
|
94
|
+
addAction(fqName: string, action: ActionImportType): void;
|
|
95
|
+
addFunction(fqName: string, func: FunctionImportType): void;
|
|
96
|
+
addSingleton(fqName: string, singleton: SingletonType): void;
|
|
97
|
+
addEntitySet(fqName: string, entitySet: EntitySetType): void;
|
|
96
98
|
getEntityContainer(): EntityContainerModel;
|
|
97
99
|
getConverter(dataType: ODataTypesV2 | ODataTypesV4 | string): import("@odata2ts/converter-runtime").ValueConverterChain | undefined;
|
|
98
100
|
private sortModelsByInheritance;
|
|
101
|
+
setNameValidation(map: Map<string, ValidationError[]>): void;
|
|
102
|
+
getNameValidation(): Map<string, ValidationError[]>;
|
|
99
103
|
}
|
|
@@ -159,17 +159,17 @@ class DataModel {
|
|
|
159
159
|
const operations = this.retrieveType(fqEntityName, this.entityCollectionBoundOperationTypes);
|
|
160
160
|
return operations || [];
|
|
161
161
|
}
|
|
162
|
-
addAction(
|
|
163
|
-
this.container.actions[
|
|
162
|
+
addAction(fqName, action) {
|
|
163
|
+
this.container.actions[fqName] = action;
|
|
164
164
|
}
|
|
165
|
-
addFunction(
|
|
166
|
-
this.container.functions[
|
|
165
|
+
addFunction(fqName, func) {
|
|
166
|
+
this.container.functions[fqName] = func;
|
|
167
167
|
}
|
|
168
|
-
addSingleton(
|
|
169
|
-
this.container.singletons[
|
|
168
|
+
addSingleton(fqName, singleton) {
|
|
169
|
+
this.container.singletons[fqName] = singleton;
|
|
170
170
|
}
|
|
171
|
-
addEntitySet(
|
|
172
|
-
this.container.entitySets[
|
|
171
|
+
addEntitySet(fqName, entitySet) {
|
|
172
|
+
this.container.entitySets[fqName] = entitySet;
|
|
173
173
|
}
|
|
174
174
|
getEntityContainer() {
|
|
175
175
|
return this.container;
|
|
@@ -206,6 +206,12 @@ class DataModel {
|
|
|
206
206
|
}
|
|
207
207
|
return sorted;
|
|
208
208
|
}
|
|
209
|
+
setNameValidation(map) {
|
|
210
|
+
this.nameValidation = map;
|
|
211
|
+
}
|
|
212
|
+
getNameValidation() {
|
|
213
|
+
return this.nameValidation;
|
|
214
|
+
}
|
|
209
215
|
}
|
|
210
216
|
exports.DataModel = DataModel;
|
|
211
217
|
//# sourceMappingURL=DataModel.js.map
|