@odata2ts/odata2ts 0.18.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 +601 -0
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/lib/FactoryFunctionModel.d.ts +13 -0
- package/lib/FactoryFunctionModel.js +3 -0
- package/lib/FactoryFunctionModel.js.map +1 -0
- package/lib/NamingModel.d.ts +191 -0
- package/lib/NamingModel.js +12 -0
- package/lib/NamingModel.js.map +1 -0
- package/lib/OptionModel.d.ts +208 -0
- package/lib/OptionModel.js +24 -0
- package/lib/OptionModel.js.map +1 -0
- package/lib/app.d.ts +8 -0
- package/lib/app.js +61 -0
- package/lib/app.js.map +1 -0
- package/lib/cli.d.ts +3 -0
- package/lib/cli.js +154 -0
- package/lib/cli.js.map +1 -0
- package/lib/data-model/DataModel.d.ts +68 -0
- package/lib/data-model/DataModel.js +114 -0
- package/lib/data-model/DataModel.js.map +1 -0
- package/lib/data-model/DataModelDigestion.d.ts +43 -0
- package/lib/data-model/DataModelDigestion.js +224 -0
- package/lib/data-model/DataModelDigestion.js.map +1 -0
- package/lib/data-model/DataModelDigestionV2.d.ts +10 -0
- package/lib/data-model/DataModelDigestionV2.js +201 -0
- package/lib/data-model/DataModelDigestionV2.js.map +1 -0
- package/lib/data-model/DataModelDigestionV4.d.ts +3 -0
- package/lib/data-model/DataModelDigestionV4.js +196 -0
- package/lib/data-model/DataModelDigestionV4.js.map +1 -0
- package/lib/data-model/DataTypeModel.d.ts +102 -0
- package/lib/data-model/DataTypeModel.js +9 -0
- package/lib/data-model/DataTypeModel.js.map +1 -0
- package/lib/data-model/NamingHelper.d.ts +57 -0
- package/lib/data-model/NamingHelper.js +225 -0
- package/lib/data-model/NamingHelper.js.map +1 -0
- package/lib/data-model/ServiceConfigHelper.d.ts +13 -0
- package/lib/data-model/ServiceConfigHelper.js +63 -0
- package/lib/data-model/ServiceConfigHelper.js.map +1 -0
- package/lib/data-model/edmx/ODataEdmxModelBase.d.ts +79 -0
- package/lib/data-model/edmx/ODataEdmxModelBase.js +3 -0
- package/lib/data-model/edmx/ODataEdmxModelBase.js.map +1 -0
- package/lib/data-model/edmx/ODataEdmxModelV3.d.ts +63 -0
- package/lib/data-model/edmx/ODataEdmxModelV3.js +3 -0
- package/lib/data-model/edmx/ODataEdmxModelV3.js.map +1 -0
- package/lib/data-model/edmx/ODataEdmxModelV4.d.ts +67 -0
- package/lib/data-model/edmx/ODataEdmxModelV4.js +3 -0
- package/lib/data-model/edmx/ODataEdmxModelV4.js.map +1 -0
- package/lib/defaultConfig.d.ts +9 -0
- package/lib/defaultConfig.js +176 -0
- package/lib/defaultConfig.js.map +1 -0
- package/lib/evaluateConfig.d.ts +25 -0
- package/lib/evaluateConfig.js +78 -0
- package/lib/evaluateConfig.js.map +1 -0
- package/lib/generator/ImportContainer.d.ts +16 -0
- package/lib/generator/ImportContainer.js +92 -0
- package/lib/generator/ImportContainer.js.map +1 -0
- package/lib/generator/ModelGenerator.d.ts +2 -0
- package/lib/generator/ModelGenerator.js +178 -0
- package/lib/generator/ModelGenerator.js.map +1 -0
- package/lib/generator/QueryObjectGenerator.d.ts +2 -0
- package/lib/generator/QueryObjectGenerator.js +234 -0
- package/lib/generator/QueryObjectGenerator.js.map +1 -0
- package/lib/generator/ServiceGenerator.d.ts +5 -0
- package/lib/generator/ServiceGenerator.js +412 -0
- package/lib/generator/ServiceGenerator.js.map +1 -0
- package/lib/generator/index.d.ts +3 -0
- package/lib/generator/index.js +10 -0
- package/lib/generator/index.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/project/ProjectManager.d.ts +30 -0
- package/lib/project/ProjectManager.js +177 -0
- package/lib/project/ProjectManager.js.map +1 -0
- package/lib/project/formatter/BaseFormatter.d.ts +49 -0
- package/lib/project/formatter/BaseFormatter.js +31 -0
- package/lib/project/formatter/BaseFormatter.js.map +1 -0
- package/lib/project/formatter/FileFormatter.d.ts +16 -0
- package/lib/project/formatter/FileFormatter.js +3 -0
- package/lib/project/formatter/FileFormatter.js.map +1 -0
- package/lib/project/formatter/NoopFormatter.d.ts +29 -0
- package/lib/project/formatter/NoopFormatter.js +43 -0
- package/lib/project/formatter/NoopFormatter.js.map +1 -0
- package/lib/project/formatter/PrettierFormatter.d.ts +46 -0
- package/lib/project/formatter/PrettierFormatter.js +93 -0
- package/lib/project/formatter/PrettierFormatter.js.map +1 -0
- package/lib/project/formatter/index.d.ts +2 -0
- package/lib/project/formatter/index.js +15 -0
- package/lib/project/formatter/index.js.map +1 -0
- package/lib/project/logger/logFilePath.d.ts +1 -0
- package/lib/project/logger/logFilePath.js +13 -0
- package/lib/project/logger/logFilePath.js.map +1 -0
- package/lib/run-cli.d.ts +2 -0
- package/lib/run-cli.js +7 -0
- package/lib/run-cli.js.map +1 -0
- package/package.json +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/@odata2ts/odata2ts)
|
|
2
|
+
|
|
3
|
+
# OData 2 TS
|
|
4
|
+
|
|
5
|
+
Generate TypeScript models, query objects and / or complete client services from a given metadata description of an OData service.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
npm install --save-dev @odata2ts/odata2ts
|
|
11
|
+
|
|
12
|
+
yarn add --dev @odata2ts/odata2ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
First download the metadata description file of your OData service.
|
|
18
|
+
|
|
19
|
+
You just add `/$metadata` to the base path of the service, e.g. https://services.odata.org/V4/Northwind/Northwind.svc/$metadata.
|
|
20
|
+
<br/>Save the XML in an own file, e.g. `src/odata/northwind.xml`.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
`odata2ts` is the main command which is called via script in package.json, or directly via npx or yarn:
|
|
25
|
+
```
|
|
26
|
+
// package.json script
|
|
27
|
+
scripts: {
|
|
28
|
+
...
|
|
29
|
+
"gen-odata": "npm run odata2ts -s src/odata/northwind.xml -o build/northwind"
|
|
30
|
+
}
|
|
31
|
+
// then from command line
|
|
32
|
+
npm run gen-odata
|
|
33
|
+
```
|
|
34
|
+
```
|
|
35
|
+
// directly from command line via npx or yarn
|
|
36
|
+
yarn odata2ts -s src/odata/northwind.xml -o build/northwind
|
|
37
|
+
```
|
|
38
|
+
These usage examples highlight the minimal configuration which is required for each OData service:
|
|
39
|
+
- source: the downloaded metadata file
|
|
40
|
+
- output: the output directory for the generated files
|
|
41
|
+
|
|
42
|
+
### Config file: `odata2ts.config.ts`
|
|
43
|
+
Instead of specifying these or other parameters via the command line you can use a config file written in TypeScript.
|
|
44
|
+
It centralizes all configurations and allows for handling multiple OData services:
|
|
45
|
+
```ts
|
|
46
|
+
import { ConfigFileOptions } from "@odata2ts/odata2ts";
|
|
47
|
+
|
|
48
|
+
const config: ConfigFileOptions = {
|
|
49
|
+
services: {
|
|
50
|
+
northwind: {
|
|
51
|
+
source: "src/odata/northwind.xml",
|
|
52
|
+
output: "build/northwind",
|
|
53
|
+
},
|
|
54
|
+
trippin: {
|
|
55
|
+
source: "src/odata/trippin.xml",
|
|
56
|
+
output: "build/trippin",
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export default config;
|
|
61
|
+
```
|
|
62
|
+
With this configuration in place, we can now call `odata2ts` without any options.
|
|
63
|
+
Additionally, individual services can be addressed as arguments:
|
|
64
|
+
```
|
|
65
|
+
yarn odata2ts // start generation process for all configured services
|
|
66
|
+
yarn odata2ts northwind // start generation process for one specific service
|
|
67
|
+
yarn odata2ts northwind trippin // start generation process for multiple services
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Command Line Options
|
|
71
|
+
Options specified on the command line always win over other configuration possibilities.
|
|
72
|
+
|
|
73
|
+
Options `source` and `output` are required unless the config file is used
|
|
74
|
+
containing appropriate service definitions.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
| Option | Shorthand | Required | Default | Description |
|
|
78
|
+
|----------------------------|-----------|:--------:|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
79
|
+
| --source | -s | (x) | | Specifies the source file, i.e. metadata description |
|
|
80
|
+
| --output | -o | (x) | | Specifies the output directory |
|
|
81
|
+
| --mode | -m | | "all" | Allowed are: all, models, qobjects, service |
|
|
82
|
+
| --emit-mode | -e | | "js_dts" | Specify what to emit. ALlowed values: ts, js, dts, js_dts |
|
|
83
|
+
| --prettier | -p | | false | Use prettier to pretty print the TS result files; only applies when emitMode = ts |
|
|
84
|
+
| --tsconfig | -t | | "tsconfig.json" | When compiling TS to JS, the compilerOptions of the specified file are used; only takes effect, when emitMode != ts |
|
|
85
|
+
| --allow-renaming | -r | | false | Allow renaming of model entities and their props by applying naming strategies like camelCase or PascalCase |
|
|
86
|
+
| --disable-auto-managed-key | -n | | false | odata2ts will automatically decide if a key prop is managed on the server side and therefore not editable; here you can turn off this automatism |
|
|
87
|
+
| --debug | -d | | false | Add debug information |
|
|
88
|
+
| --service-name | -name | | | Overwrites the service name found in OData metadata => controls name of main odata service |
|
|
89
|
+
|
|
90
|
+
## Configuration File
|
|
91
|
+
|
|
92
|
+
Create a file at the root of your project (beside package.json)
|
|
93
|
+
and call it: `odata2ts.config.ts`.
|
|
94
|
+
|
|
95
|
+
None of the options are required, so here is just an example:
|
|
96
|
+
```ts
|
|
97
|
+
import { ConfigFileOptions, EmitModes } from "@odata2ts/odata2ts";
|
|
98
|
+
|
|
99
|
+
const config: ConfigFileOptions = {
|
|
100
|
+
debug: true,
|
|
101
|
+
emitMode: EmitModes.ts,
|
|
102
|
+
prettier: true,
|
|
103
|
+
converters: ["@odata2ts/v2-to-v4-converter"],
|
|
104
|
+
services: {
|
|
105
|
+
northwind: {
|
|
106
|
+
source: "src/odata/northwind.xml",
|
|
107
|
+
output: "build/northwind",
|
|
108
|
+
serviceName: "StrongWind"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export default config;
|
|
113
|
+
```
|
|
114
|
+
As you can see, enums are provided for `emitMode` and the same goes for the `mode` option.
|
|
115
|
+
|
|
116
|
+
The usage of converters is documented in the [converter-api](../converter-api).
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
### Default Settings vs Base Settings vs Service Settings
|
|
120
|
+
The [defaultConfig](src/defaultConfig.ts) lists all default values, which are always used.
|
|
121
|
+
|
|
122
|
+
All settings except the `services` attribute are **base settings**, which will also be used as default settings,
|
|
123
|
+
i.e. on top of the defaultConfig.
|
|
124
|
+
|
|
125
|
+
All settings starting from the `services` attribute are only valid for a specific service and only applied
|
|
126
|
+
for its generation run. Service specific settings are applied on top of the base settings.
|
|
127
|
+
|
|
128
|
+
Additionally, CLI options can be used to override base or service settings.
|
|
129
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ODataVersions } from "@odata2ts/odata-core";
|
|
2
|
+
import { SourceFile } from "ts-morph";
|
|
3
|
+
import { DataModel } from "./data-model/DataModel";
|
|
4
|
+
import { Schema } from "./data-model/edmx/ODataEdmxModelBase";
|
|
5
|
+
import { NamingHelper } from "./data-model/NamingHelper";
|
|
6
|
+
import { RunOptions } from "./OptionModel";
|
|
7
|
+
export declare type DigestionOptions = Pick<RunOptions, "converters" | "disableAutoManagedKey" | "propertiesByName">;
|
|
8
|
+
/**
|
|
9
|
+
* Takes an EdmxSchema plus the run options and creates a DataModel.
|
|
10
|
+
*/
|
|
11
|
+
export declare type DigesterFunction<S extends Schema<any, any>> = (schema: S, options: DigestionOptions, namingHelper: NamingHelper) => Promise<DataModel>;
|
|
12
|
+
export declare type GeneratorFunctionOptions = Pick<RunOptions, "skipEditableModels" | "skipIdModels" | "skipOperations">;
|
|
13
|
+
export declare type EntityBasedGeneratorFunction = (dataModel: DataModel, sourceFile: SourceFile, version: ODataVersions, options: GeneratorFunctionOptions, namingHelper: NamingHelper) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FactoryFunctionModel.js","sourceRoot":"","sources":["../src/FactoryFunctionModel.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The available naming strategies.
|
|
3
|
+
*/
|
|
4
|
+
import { PartialDeep } from "type-fest";
|
|
5
|
+
export declare enum NamingStrategies {
|
|
6
|
+
NONE = "",
|
|
7
|
+
PASCAL_CASE = "pascalCase",
|
|
8
|
+
CAMEL_CASE = "camelCase",
|
|
9
|
+
CONSTANT_CASE = "constantCase",
|
|
10
|
+
SNAKE_CASE = "snakeCase"
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Based on an existing configuration (for example default settings) the user only specifies what needs
|
|
14
|
+
* to be changed. Hence, all options are completely optional.
|
|
15
|
+
*/
|
|
16
|
+
export interface OverridableNamingOptions extends PartialDeep<NameSettings> {
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The required and optional name settings for the generator.
|
|
20
|
+
*/
|
|
21
|
+
export interface NameSettings {
|
|
22
|
+
/**
|
|
23
|
+
* Because multiple artefacts are generated out of the same entity, some name settings are required in order
|
|
24
|
+
* to differentiate those artefacts. Out-of-the-box odata2ts provides you with sensible default settings,
|
|
25
|
+
* so that you only need to override those settings you want to change.
|
|
26
|
+
*
|
|
27
|
+
* However, sometimes it makes more sense to start from scratch, so that the defaults don't interfere with
|
|
28
|
+
* your own configuration. In this scenario this switch should be enabled to only have default values for
|
|
29
|
+
* the required name settings.
|
|
30
|
+
*/
|
|
31
|
+
minimalDefaults?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Generation options for models, i.e. interfaces representing entity or complex types.
|
|
34
|
+
*/
|
|
35
|
+
models: ModelNamingOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Generation options for Query Objects.
|
|
38
|
+
*
|
|
39
|
+
* By default, prefix = "Q"
|
|
40
|
+
*/
|
|
41
|
+
queryObjects: QueryObjectNamingOptions;
|
|
42
|
+
services: ServiceNamingOptions;
|
|
43
|
+
}
|
|
44
|
+
export interface ModelNamingOptions extends NamingStrategyOption, StandardNamingOptions {
|
|
45
|
+
/**
|
|
46
|
+
* All generated models are bundled into one file.
|
|
47
|
+
* This option specifies the formatting of the file name.
|
|
48
|
+
*/
|
|
49
|
+
fileName: FileNamingStrategyOption & RequiredNamingOptions;
|
|
50
|
+
/**
|
|
51
|
+
* Choose a specific strategy to format property names of models: pascal-case, camel-case, etc.
|
|
52
|
+
* By default, camel-case.
|
|
53
|
+
*/
|
|
54
|
+
propNamingStrategy?: NamingStrategies;
|
|
55
|
+
/**
|
|
56
|
+
* For each model an editable version is generated which represents the model definition for
|
|
57
|
+
* create, update and patch actions.
|
|
58
|
+
*
|
|
59
|
+
* You can override the naming options here.
|
|
60
|
+
* By default, prefix = "Editable"
|
|
61
|
+
*/
|
|
62
|
+
editableModels: EntityDerivedNamingOptions;
|
|
63
|
+
/**
|
|
64
|
+
* ID models are generated from entity id parameters.
|
|
65
|
+
*
|
|
66
|
+
* You can configure the naming options here.
|
|
67
|
+
* By default, suffix = "Id"
|
|
68
|
+
*/
|
|
69
|
+
idModels: EntityDerivedNamingOptions;
|
|
70
|
+
/**
|
|
71
|
+
* Operation parameter models are generated from function or action signatures.
|
|
72
|
+
*
|
|
73
|
+
* You can configure the naming options here.
|
|
74
|
+
* By default, suffix = "Params"
|
|
75
|
+
*/
|
|
76
|
+
operationParamModels: EntityDerivedNamingOptions;
|
|
77
|
+
}
|
|
78
|
+
export interface EntityDerivedNamingOptions extends RequiredNamingOptions {
|
|
79
|
+
applyModelNaming?: boolean;
|
|
80
|
+
}
|
|
81
|
+
export interface QueryObjectNamingOptions extends NamingStrategyOption, RequiredNamingOptions {
|
|
82
|
+
/**
|
|
83
|
+
* All generated models are bundled into one file.
|
|
84
|
+
* This option specifies the formatting of the file name.
|
|
85
|
+
*/
|
|
86
|
+
fileName: FileNamingStrategyOption & RequiredNamingOptions;
|
|
87
|
+
/**
|
|
88
|
+
* Choose a specific strategy to format property names of query objects: pascal-case, camel-case, etc.
|
|
89
|
+
* By default, camel-case.
|
|
90
|
+
*/
|
|
91
|
+
propNamingStrategy?: NamingStrategies;
|
|
92
|
+
idFunctions: RequiredNamingOptions;
|
|
93
|
+
operations?: OperationNamingOptions;
|
|
94
|
+
}
|
|
95
|
+
export interface OperationNamingOptions extends StandardNamingOptions {
|
|
96
|
+
/**
|
|
97
|
+
* Naming options for actions only.
|
|
98
|
+
* When this configuration is provided, the parent configuration regarding suffix and prefix is ignored.
|
|
99
|
+
*/
|
|
100
|
+
action?: StandardNamingOptions;
|
|
101
|
+
/**
|
|
102
|
+
* Naming options for functions only.
|
|
103
|
+
* When this configuration is provided, the parent configuration regarding suffix and prefix is ignored.
|
|
104
|
+
*/
|
|
105
|
+
function?: StandardNamingOptions;
|
|
106
|
+
}
|
|
107
|
+
export interface NamingStrategyOption {
|
|
108
|
+
/**
|
|
109
|
+
* Choose a specific strategy to format names: pascal-case, camel-case, etc.
|
|
110
|
+
* Defaults to pascal-case.
|
|
111
|
+
*/
|
|
112
|
+
namingStrategy?: NamingStrategies;
|
|
113
|
+
}
|
|
114
|
+
export interface FileNamingStrategyOption {
|
|
115
|
+
/**
|
|
116
|
+
* Choose a specific strategy to format names: pascal-case, camel-case, etc.
|
|
117
|
+
* Defaults to pascal-case.
|
|
118
|
+
*/
|
|
119
|
+
namingStrategy?: NamingStrategies;
|
|
120
|
+
}
|
|
121
|
+
export interface StandardNamingOptions {
|
|
122
|
+
/**
|
|
123
|
+
* Prefix all names, e.g. "I" => "ITest"
|
|
124
|
+
*/
|
|
125
|
+
prefix?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Suffix all names, e.g. "model" => "TestModel"
|
|
128
|
+
*/
|
|
129
|
+
suffix?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface RequiredNamingOptions extends Required<StandardNamingOptions> {
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Naming options for generated service classes.
|
|
135
|
+
* These options affect the main service as well as all services generated for each entity, complex and collection type.
|
|
136
|
+
*
|
|
137
|
+
* There exists one specialty about services: The file names are not configurable.
|
|
138
|
+
* File names are determined by the name of their corresponding classes, so that service file name
|
|
139
|
+
* and service class name always correspond.
|
|
140
|
+
*
|
|
141
|
+
* By default, suffix = Service and namingStrategy = PascalCase
|
|
142
|
+
*/
|
|
143
|
+
export interface ServiceNamingOptions extends NamingStrategyOption, RequiredNamingOptions {
|
|
144
|
+
/**
|
|
145
|
+
* Controls the naming options for the main odata service.
|
|
146
|
+
* By default, the base service naming options are applied.
|
|
147
|
+
* But since this is the main entry point for users, it can be configured individually here.
|
|
148
|
+
*
|
|
149
|
+
* By default, applyServiceNaming = true
|
|
150
|
+
*/
|
|
151
|
+
main?: NamingStrategyOption & StandardNamingOptions & {
|
|
152
|
+
applyServiceNaming?: boolean;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Name of the service responsible for entity collections.
|
|
156
|
+
*
|
|
157
|
+
* By default, suffix = Collection and applyServiceNaming = true
|
|
158
|
+
*/
|
|
159
|
+
collection: RequiredNamingOptions & {
|
|
160
|
+
applyServiceNaming?: boolean;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Naming for factory function for EntityServiceResolvers.
|
|
164
|
+
*
|
|
165
|
+
* By default, prefix = create, suffix = ServiceResolver
|
|
166
|
+
* @example createTestEntityServiceResolver
|
|
167
|
+
*/
|
|
168
|
+
serviceResolverFunction: NamingStrategyOption & RequiredNamingOptions;
|
|
169
|
+
/**
|
|
170
|
+
* Naming for getter method. Another related service is returned.
|
|
171
|
+
*
|
|
172
|
+
* By default, prefix = "navTo" and namingStrategy = camelCase
|
|
173
|
+
*/
|
|
174
|
+
relatedServiceGetter: NamingStrategyOption & RequiredNamingOptions;
|
|
175
|
+
/**
|
|
176
|
+
* Operations are functions and actions of the OData service and are represented as methods
|
|
177
|
+
* of the generated service class. This setting controls the naming of the corresponding
|
|
178
|
+
* function.
|
|
179
|
+
*
|
|
180
|
+
* By default, namingStrategy = camelCase
|
|
181
|
+
*/
|
|
182
|
+
operations?: NamingStrategyOption & OperationNamingOptions;
|
|
183
|
+
/**
|
|
184
|
+
* Naming options for private properties of service classes.
|
|
185
|
+
*/
|
|
186
|
+
privateProps: NamingStrategyOption & RequiredNamingOptions;
|
|
187
|
+
/**
|
|
188
|
+
* Naming options for public properties of service classes.
|
|
189
|
+
*/
|
|
190
|
+
publicProps?: NamingStrategyOption;
|
|
191
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NamingStrategies = void 0;
|
|
4
|
+
var NamingStrategies;
|
|
5
|
+
(function (NamingStrategies) {
|
|
6
|
+
NamingStrategies["NONE"] = "";
|
|
7
|
+
NamingStrategies["PASCAL_CASE"] = "pascalCase";
|
|
8
|
+
NamingStrategies["CAMEL_CASE"] = "camelCase";
|
|
9
|
+
NamingStrategies["CONSTANT_CASE"] = "constantCase";
|
|
10
|
+
NamingStrategies["SNAKE_CASE"] = "snakeCase";
|
|
11
|
+
})(NamingStrategies = exports.NamingStrategies || (exports.NamingStrategies = {}));
|
|
12
|
+
//# sourceMappingURL=NamingModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NamingModel.js","sourceRoot":"","sources":["../src/NamingModel.ts"],"names":[],"mappings":";;;AAKA,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,6BAAS,CAAA;IACT,8CAA0B,CAAA;IAC1B,4CAAwB,CAAA;IACxB,kDAA8B,CAAA;IAC9B,4CAAwB,CAAA;AAC1B,CAAC,EANW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAM3B"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { TypeConverterConfig } from "@odata2ts/converter-runtime";
|
|
2
|
+
import { NameSettings, OverridableNamingOptions } from "./NamingModel";
|
|
3
|
+
/**
|
|
4
|
+
* Generation mode, by default "all".
|
|
5
|
+
*/
|
|
6
|
+
export declare enum Modes {
|
|
7
|
+
models = 0,
|
|
8
|
+
qobjects = 1,
|
|
9
|
+
service = 2,
|
|
10
|
+
all = 3
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* What kind of stuff to emit: Either raw TS or TS that has been compiled to JS / DTS.
|
|
14
|
+
*/
|
|
15
|
+
export declare enum EmitModes {
|
|
16
|
+
ts = "ts",
|
|
17
|
+
js = "js",
|
|
18
|
+
dts = "dts",
|
|
19
|
+
js_dts = "js_dts"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Config options for CLI.
|
|
23
|
+
*/
|
|
24
|
+
export interface CliOptions {
|
|
25
|
+
/**
|
|
26
|
+
* The source file to use. Must be an EDMX compliant XML file.
|
|
27
|
+
*
|
|
28
|
+
* If not specified, at least one service must be configured in config file.
|
|
29
|
+
*/
|
|
30
|
+
source?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Specifies the output directory for the generated stuff.
|
|
33
|
+
*
|
|
34
|
+
* If not specified, at least one service must be configured in config file.
|
|
35
|
+
*/
|
|
36
|
+
output?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Only generates the specified services.
|
|
39
|
+
* Relies on an existing config file where these service names are maintained.
|
|
40
|
+
*/
|
|
41
|
+
services?: Array<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Specifies what to generate:
|
|
44
|
+
* - {@code Modes.models} will only generate TS interfaces
|
|
45
|
+
* - {@code Modes.qobjects} will generate functional units used in QueryBuilder and for functions and actions
|
|
46
|
+
* - {@code Modes.service} will generate one main OData service client and one per each entity
|
|
47
|
+
* - {@code Modes.all} the same as {@code Modes.service}
|
|
48
|
+
*
|
|
49
|
+
* QObjects will also generate models, and generating the service client will also generate models and QObjects.
|
|
50
|
+
* Defaults to {@code Modes.all}
|
|
51
|
+
*/
|
|
52
|
+
mode?: Modes;
|
|
53
|
+
/**
|
|
54
|
+
* Specifies the type of the output files: TypeScript, JS, DTS only, JS with DTS.
|
|
55
|
+
* Defaults to {@code EmitModes.js_dts}
|
|
56
|
+
*/
|
|
57
|
+
emitMode?: EmitModes;
|
|
58
|
+
/**
|
|
59
|
+
* Uses prettier with your local configuration to pretty print TypeScript files.
|
|
60
|
+
* Only applies if mode is set to {@code EmitModes.ts}.
|
|
61
|
+
*/
|
|
62
|
+
prettier?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* When compiling TypeScript to JS, "tsconfig.json" is used by default to add compilerOptions.
|
|
65
|
+
* This option allows to specify an alternative file.
|
|
66
|
+
*
|
|
67
|
+
* Only takes effect, when mode is set to anything else than {@code EmitModes.ts}.
|
|
68
|
+
*/
|
|
69
|
+
tsconfig?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Verbose debugging information.
|
|
72
|
+
*/
|
|
73
|
+
debug?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Overrides the service name found in the source file.
|
|
76
|
+
*
|
|
77
|
+
* The service name is the basis for all file names and the name of the main OData client service
|
|
78
|
+
* that serves as entry point for the user.
|
|
79
|
+
*/
|
|
80
|
+
serviceName?: string;
|
|
81
|
+
/**
|
|
82
|
+
* odata2ts will automatically decide if a key prop is managed on the server side.
|
|
83
|
+
* If managed, the property will not be editable (create, update, patch).
|
|
84
|
+
* The following rule applies:
|
|
85
|
+
* If a property is the only key prop of an entity, then the prop is deemed to be managed;
|
|
86
|
+
* in ony other case the prop is unmanaged.
|
|
87
|
+
*/
|
|
88
|
+
disableAutoManagedKey?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* By default, odata2ts doesn't change param, operation, property or model names.
|
|
91
|
+
* The generated models and their properties are named exactly as advertised by the server.
|
|
92
|
+
*
|
|
93
|
+
* By allowing odata2ts to change these names, certain predefined formatting strategies are used:
|
|
94
|
+
* Model / class names are formatted with PascalCase; property, param, and operation names with camelCase.
|
|
95
|
+
*
|
|
96
|
+
* The naming configuration allows to control this and other naming related settings.
|
|
97
|
+
* Note: Even if renaming is disabled, model prefixing / suffing still applies.
|
|
98
|
+
*/
|
|
99
|
+
allowRenaming?: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Available options for the actual generation run.
|
|
103
|
+
* Every property is required, except the overriding service name.
|
|
104
|
+
*/
|
|
105
|
+
export interface RunOptions extends Required<Omit<ServiceGenerationOptions, "serviceName">> {
|
|
106
|
+
serviceName?: string;
|
|
107
|
+
naming: NameSettings;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Available options for configuration files, i.e. odata2ts.config.ts.
|
|
111
|
+
*/
|
|
112
|
+
export interface ConfigFileOptions extends Omit<CliOptions, "source" | "output" | "services"> {
|
|
113
|
+
services?: {
|
|
114
|
+
[serviceName: string]: ServiceGenerationOptions;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Specify which converters to use by their package name, e.g. "@odata2ts/converter-v2-to-v4".
|
|
118
|
+
* Each converter knows which data type to map.
|
|
119
|
+
*
|
|
120
|
+
* To only use specific converters, the object syntax must be used, where supported converters
|
|
121
|
+
* must be listed by their ids.
|
|
122
|
+
*/
|
|
123
|
+
converters?: Array<string | TypeConverterConfig>;
|
|
124
|
+
/**
|
|
125
|
+
* For each model an editable version is generated which represents the model definition for
|
|
126
|
+
* create, update and patch actions.
|
|
127
|
+
*
|
|
128
|
+
* You can skip the generation altogether, not generating editable model variants,
|
|
129
|
+
* if the generation mode is {@code Mode.model} or {@code Mode.qobject}.
|
|
130
|
+
*/
|
|
131
|
+
skipEditableModels?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* ID models are generated from entity id parameters.
|
|
134
|
+
* The generation for one entity entails one model interface representing the id parameters and
|
|
135
|
+
* one QId function which allows to format the parameters for URL usage and to parse parameters
|
|
136
|
+
* from a URL string.
|
|
137
|
+
*
|
|
138
|
+
* You can skip the generation altogether, not generating models and QId objects, if the
|
|
139
|
+
* generation mode is {@code Mode.model} or {@code Mode.qobject}.
|
|
140
|
+
*/
|
|
141
|
+
skipIdModels?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Operations are functions and actions of the OData service.
|
|
144
|
+
* The generation for one operation entails one parameter model interface
|
|
145
|
+
* and one QFunction / QAction class.
|
|
146
|
+
*
|
|
147
|
+
* You can skip the generation altogether, neither generating model nor query object,
|
|
148
|
+
* if the generation mode is {@code Mode.model} or {@code Mode.qobject}.
|
|
149
|
+
*/
|
|
150
|
+
skipOperations?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* The naming options regarding the generated artefacts.
|
|
153
|
+
*/
|
|
154
|
+
naming?: OverridableNamingOptions;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Custom generation options which are dependent on a specific odata service.
|
|
158
|
+
*/
|
|
159
|
+
export interface ServiceGenerationOptions extends Required<Pick<CliOptions, "source" | "output">>, Omit<ConfigFileOptions, "services"> {
|
|
160
|
+
/**
|
|
161
|
+
* Configure generation process for EntityTypes and ComplexTypes including their properties.
|
|
162
|
+
*/
|
|
163
|
+
/**
|
|
164
|
+
* Configure generation process for individual properties based on their name.
|
|
165
|
+
*/
|
|
166
|
+
propertiesByName?: Array<PropertyGenerationOptions>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Configuration options for EntityTypes and ComplexTypes.
|
|
170
|
+
* This config applies if the name matches the name of an EntityType or ComplexType as it is specified
|
|
171
|
+
* in the metadata (e.g. in EDMX <EntityType name="Test" ....)
|
|
172
|
+
*/
|
|
173
|
+
export interface EntityGenerationOptions {
|
|
174
|
+
/**
|
|
175
|
+
* Name of the EntityType or ComplexType, e.g. "Person".
|
|
176
|
+
* Must match exactly or can be a regular expression.
|
|
177
|
+
*/
|
|
178
|
+
name: string | RegExp;
|
|
179
|
+
/**
|
|
180
|
+
* Use a different name.
|
|
181
|
+
* If name is a regular expression, mappedName allows to specify captured groups (via $1, $2, ...).
|
|
182
|
+
*/
|
|
183
|
+
mappedName?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Configuration of individual properties.
|
|
186
|
+
*/
|
|
187
|
+
properties?: Array<PropertyGenerationOptions>;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* All configuration options for properties of models.
|
|
191
|
+
*/
|
|
192
|
+
export interface PropertyGenerationOptions {
|
|
193
|
+
/**
|
|
194
|
+
* Name of the property to match.
|
|
195
|
+
* Must match exactly or can be a regular expression.
|
|
196
|
+
*/
|
|
197
|
+
name: string | RegExp;
|
|
198
|
+
/**
|
|
199
|
+
* Use a different name.
|
|
200
|
+
* If name is a regular expression, mappedName allows to specify captured groups (via $1, $2, ...).
|
|
201
|
+
*/
|
|
202
|
+
mappedName?: string;
|
|
203
|
+
/**
|
|
204
|
+
* Managed attributes - i.e. managed by the server - cannot be created or updated.
|
|
205
|
+
* Hence, they are left out of the editable model versions.
|
|
206
|
+
*/
|
|
207
|
+
managed?: boolean;
|
|
208
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmitModes = exports.Modes = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Generation mode, by default "all".
|
|
6
|
+
*/
|
|
7
|
+
var Modes;
|
|
8
|
+
(function (Modes) {
|
|
9
|
+
Modes[Modes["models"] = 0] = "models";
|
|
10
|
+
Modes[Modes["qobjects"] = 1] = "qobjects";
|
|
11
|
+
Modes[Modes["service"] = 2] = "service";
|
|
12
|
+
Modes[Modes["all"] = 3] = "all";
|
|
13
|
+
})(Modes = exports.Modes || (exports.Modes = {}));
|
|
14
|
+
/**
|
|
15
|
+
* What kind of stuff to emit: Either raw TS or TS that has been compiled to JS / DTS.
|
|
16
|
+
*/
|
|
17
|
+
var EmitModes;
|
|
18
|
+
(function (EmitModes) {
|
|
19
|
+
EmitModes["ts"] = "ts";
|
|
20
|
+
EmitModes["js"] = "js";
|
|
21
|
+
EmitModes["dts"] = "dts";
|
|
22
|
+
EmitModes["js_dts"] = "js_dts";
|
|
23
|
+
})(EmitModes = exports.EmitModes || (exports.EmitModes = {}));
|
|
24
|
+
//# sourceMappingURL=OptionModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionModel.js","sourceRoot":"","sources":["../src/OptionModel.ts"],"names":[],"mappings":";;;AAIA;;GAEG;AACH,IAAY,KAKX;AALD,WAAY,KAAK;IACf,qCAAM,CAAA;IACN,yCAAQ,CAAA;IACR,uCAAO,CAAA;IACP,+BAAG,CAAA;AACL,CAAC,EALW,KAAK,GAAL,aAAK,KAAL,aAAK,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,GAAT,iBAAS,KAAT,iBAAS,QAKpB"}
|
package/lib/app.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ODataEdmxModelBase } from "./data-model/edmx/ODataEdmxModelBase";
|
|
2
|
+
import { RunOptions } from "./OptionModel";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param metadataJson metadata of a given OData service already parsed as JSON
|
|
6
|
+
* @param options further options
|
|
7
|
+
*/
|
|
8
|
+
export declare function runApp(metadataJson: ODataEdmxModelBase<any>, options: RunOptions): Promise<void>;
|
package/lib/app.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runApp = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const odata_core_1 = require("@odata2ts/odata-core");
|
|
6
|
+
const DataModelDigestionV2_1 = require("./data-model/DataModelDigestionV2");
|
|
7
|
+
const DataModelDigestionV4_1 = require("./data-model/DataModelDigestionV4");
|
|
8
|
+
const NamingHelper_1 = require("./data-model/NamingHelper");
|
|
9
|
+
const generator_1 = require("./generator");
|
|
10
|
+
const OptionModel_1 = require("./OptionModel");
|
|
11
|
+
const ProjectManager_1 = require("./project/ProjectManager");
|
|
12
|
+
function isQObjectGen(mode) {
|
|
13
|
+
return [OptionModel_1.Modes.qobjects, OptionModel_1.Modes.service, OptionModel_1.Modes.all].includes(mode);
|
|
14
|
+
}
|
|
15
|
+
function isServiceGen(mode) {
|
|
16
|
+
return [OptionModel_1.Modes.service, OptionModel_1.Modes.all].includes(mode);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param metadataJson metadata of a given OData service already parsed as JSON
|
|
21
|
+
* @param options further options
|
|
22
|
+
*/
|
|
23
|
+
function runApp(metadataJson, options) {
|
|
24
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
// determine edmx edmxVersion attribute
|
|
26
|
+
const edmxVersion = metadataJson["edmx:Edmx"].$.Version;
|
|
27
|
+
const version = edmxVersion === "1.0" ? odata_core_1.ODataVersions.V2 : odata_core_1.ODataVersions.V4;
|
|
28
|
+
const dataService = metadataJson["edmx:Edmx"]["edmx:DataServices"][0];
|
|
29
|
+
// handling multiple schemas => merge them
|
|
30
|
+
// TODO only necessary for NorthwindModel => other use cases?
|
|
31
|
+
const schemaRaw = dataService.Schema.reduce((collector, schema) => (Object.assign(Object.assign({}, schema), collector)), {});
|
|
32
|
+
// encapsulate the whole naming logic
|
|
33
|
+
const namingHelper = new NamingHelper_1.NamingHelper(options, schemaRaw.$.Namespace, options.serviceName);
|
|
34
|
+
// parse model information from edmx into something we can really work with
|
|
35
|
+
// => that stuff is called dataModel!
|
|
36
|
+
const dataModel = version === odata_core_1.ODataVersions.V2
|
|
37
|
+
? yield (0, DataModelDigestionV2_1.digest)(schemaRaw, options, namingHelper)
|
|
38
|
+
: yield (0, DataModelDigestionV4_1.digest)(schemaRaw, options, namingHelper);
|
|
39
|
+
// handling the overall generation project
|
|
40
|
+
const project = yield (0, ProjectManager_1.createProjectManager)(namingHelper.getFileNames(), options.output, options.emitMode, options.prettier, options.tsconfig);
|
|
41
|
+
// Generate Model Interfaces
|
|
42
|
+
// supported edmx types: EntityType, ComplexType, EnumType
|
|
43
|
+
const modelsFile = yield project.createModelFile();
|
|
44
|
+
(0, generator_1.generateModels)(dataModel, modelsFile, version, options, namingHelper);
|
|
45
|
+
// Generate Query Objects
|
|
46
|
+
// supported edmx types: EntityType, ComplexType
|
|
47
|
+
// supported edmx prop types: primitive types, enum types, primitive collection (incl enum types), entity collection, entity object, complex object
|
|
48
|
+
if (isQObjectGen(options.mode)) {
|
|
49
|
+
const qFile = yield project.createQObjectFile();
|
|
50
|
+
(0, generator_1.generateQueryObjects)(dataModel, qFile, version, options, namingHelper);
|
|
51
|
+
}
|
|
52
|
+
// Generate Individual OData-Service
|
|
53
|
+
if (isServiceGen(options.mode)) {
|
|
54
|
+
yield project.cleanServiceDir();
|
|
55
|
+
yield (0, generator_1.generateServices)(dataModel, project, version, namingHelper);
|
|
56
|
+
}
|
|
57
|
+
yield project.writeFiles();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
exports.runApp = runApp;
|
|
61
|
+
//# sourceMappingURL=app.js.map
|
package/lib/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;AAAA,qDAAqD;AAErD,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;QAEtE,0CAA0C;QAC1C,6DAA6D;QAC7D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CACzC,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,iCAClB,MAAM,GACN,SAAS,EACZ,EACF,EAAsB,CACvB,CAAC;QAEF,qCAAqC;QACrC,MAAM,YAAY,GAAG,IAAI,2BAAY,CAAC,OAAO,EAAG,SAAsB,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACzG,2EAA2E;QAC3E,qCAAqC;QACrC,MAAM,SAAS,GACb,OAAO,KAAK,0BAAa,CAAC,EAAE;YAC1B,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,SAAqB,EAAE,OAAO,EAAE,YAAY,CAAC;YAC9D,CAAC,CAAC,MAAM,IAAA,6BAAQ,EAAC,SAAqB,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACnE,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,OAAO,CAAC,eAAe,EAAE,CAAC;YAChC,MAAM,IAAA,4BAAgB,EAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;SACnE;QAED,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;CAAA;AAtDD,wBAsDC"}
|