Skip to content

Commit f38358b

Browse files
authored
handle metadata with namespaces (#27)
* handle metadata with namespaces * change structure name * 2.17.0
1 parent 53e8718 commit f38358b

5 files changed

Lines changed: 270 additions & 3 deletions

File tree

karma-test-api-server.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
// karma-test-api-server.js
22
const {getApplication, serveApplication, getServerAddress} = require('@themost/test');
3+
// noinspection NpmUsedModulesInstalled
4+
const {ODataModelBuilder} = require('@themost/data');
35
const { URL } = require('url');
46
function serveKarmaTestApiServer(proxies) {
57
const app = getApplication();
8+
/**
9+
* @type {import('@themost/express').ExpressDataApplication}
10+
*/
11+
const service = app.get('ExpressDataApplication');
12+
service.getConfiguration().setSourceAt('settings/builder/defaultNamespace', 'App');
13+
/**
14+
* @type {import('@themost/data').ODataModelBuilder}
15+
*/
16+
const builder = service.getService(ODataModelBuilder);
17+
builder.clean(true);
618
return serveApplication(app).then( function(liveServer) {
719
const serverAddress = getServerAddress(liveServer);
820
Object.assign(proxies, {

package-lock.json

Lines changed: 111 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@themost/client",
3-
"version": "2.16.3",
3+
"version": "2.17.0",
44
"description": "MOST Web Framework Codename Blueshift - Client Common",
55
"module": "dist/index.esm.js",
66
"main": "dist/index.js",
@@ -38,6 +38,7 @@
3838
"devDependencies": {
3939
"@rollup/plugin-typescript": "^11.1.1",
4040
"@themost/test": "^2.9.0",
41+
"@types/express": "^4.17.25",
4142
"@types/jasmine": "^3.10.0",
4243
"@types/minimist": "^1.2.5",
4344
"@types/node": "^16.11.4",

src/metadata.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ export declare interface EntitySetAnnotation {
1414
}
1515
}
1616

17+
export declare interface FullQualifiedName {
18+
Name: string;
19+
Namespace?: string;
20+
QualifiedName: string;
21+
}
22+
1723
/**
1824
* Represents an OData service metadata document
1925
*/
@@ -28,11 +34,60 @@ export class EdmSchema {
2834
return XSerializer.deserialize(schemaElement, EdmSchema);
2935
}
3036

37+
public static isPrimitiveType(typeName: string): boolean {
38+
return /^Edm\.\w+$/.test(typeName) || /^Collection\(Edm\.\w+\)$/.test(typeName);
39+
}
40+
41+
public static isCollectionOf(typeName: string): string {
42+
const matches = /^Collection\(((\w+\.?)+)\)$/.exec(typeName);
43+
if (matches) {
44+
return matches[1];
45+
}
46+
return null;
47+
}
48+
49+
public static hasNameWithNamespace(typeName: string): FullQualifiedName {
50+
if (typeName == null) {
51+
return null;
52+
}
53+
if (EdmSchema.isPrimitiveType(typeName)) {
54+
return null;
55+
}
56+
// check for collection type
57+
const collectionTypeName = EdmSchema.isCollectionOf(typeName);
58+
// if collection type
59+
if (collectionTypeName) {
60+
// check for type name with namespace
61+
const collectionNameWithNamespace = EdmSchema.hasNameWithNamespace(collectionTypeName);
62+
if (collectionNameWithNamespace) {
63+
const collectionParts = collectionTypeName.split('.');
64+
collectionParts.pop();
65+
return {
66+
Name: `Collection(${collectionNameWithNamespace.Name})`,
67+
Namespace: collectionParts.join('.'),
68+
QualifiedName: `Collection(${collectionNameWithNamespace.QualifiedName})`
69+
};
70+
}
71+
return null;
72+
}
73+
const parts = typeName.split('.');
74+
if (parts.length > 1) {
75+
return {
76+
Name: parts.pop(),
77+
Namespace: parts.join('.'),
78+
QualifiedName: typeName
79+
};
80+
}
81+
return null;
82+
}
83+
84+
public Namespace: string;
3185
public EntityType: EdmEntityType[] = [];
3286
public EntityContainer = new EdmEntityContainer();
3387
public Action: EdmAction[] = [];
3488
public Function: EdmFunction[] = [];
3589
public readXml(node: XNode) {
90+
this.Namespace = node.getAttribute('Namespace');
3691
this.EntityType = node.selectNodes('EntityType').map((x) => {
3792
return XSerializer.deserialize(x, EdmEntityType);
3893
});
@@ -126,10 +181,13 @@ export class EdmAction extends EdmProcedure {
126181
export class EdmParameter {
127182
public Name: string;
128183
public Type: string;
184+
public TypeName?: FullQualifiedName;
129185
public Nullable = true;
130186
public readXml(node: XNode) {
131187
this.Name = node.getAttribute('Name');
132188
this.Type = node.getAttribute('Type');
189+
this.TypeName = EdmSchema.hasNameWithNamespace(this.Type);
190+
if (this.TypeName) { this.Type = this.TypeName.Name; }
133191
if (node.hasAttribute('Nullable')) {
134192
this.Nullable = node.getAttribute('Nullable') === 'true';
135193
}
@@ -141,9 +199,12 @@ export class EdmParameter {
141199
*/
142200
export class EdmReturnType {
143201
public Type: string;
202+
public TypeName?: FullQualifiedName;
144203
public Nullable = true;
145204
public readXml(node: XNode) {
146205
this.Type = node.getAttribute('Type');
206+
this.TypeName = EdmSchema.hasNameWithNamespace(this.Type);
207+
if (this.TypeName) { this.Type = this.TypeName.Name; }
147208
if (node.hasAttribute('Nullable')) {
148209
this.Nullable = node.getAttribute('Nullable') === 'true';
149210
}
@@ -156,6 +217,7 @@ export class EdmReturnType {
156217
export class EdmProperty {
157218
public Name: string;
158219
public Type: string;
220+
public TypeName?: FullQualifiedName;
159221
public Nullable = true;
160222
public Immutable = false;
161223
public Description: string;
@@ -165,9 +227,12 @@ export class EdmProperty {
165227
constructor() {
166228
//
167229
}
230+
168231
public readXml(node: XNode) {
169232
this.Name = node.getAttribute('Name');
170233
this.Type = node.getAttribute('Type');
234+
this.TypeName = EdmSchema.hasNameWithNamespace(this.Type);
235+
if (this.TypeName) { this.Type = this.TypeName.Name; }
171236
if (node.hasAttribute('Nullable')) {
172237
this.Nullable = node.getAttribute('Nullable') === 'true';
173238
}
@@ -199,6 +264,7 @@ export class EdmProperty {
199264
export class EdmNavigationProperty {
200265
public Name: string;
201266
public Type: string;
267+
public TypeName?: FullQualifiedName;
202268
public Immutable = false;
203269
public Description: string;
204270
public LongDescription: string;
@@ -210,6 +276,8 @@ export class EdmNavigationProperty {
210276
public readXml(node: XNode) {
211277
this.Name = node.getAttribute('Name');
212278
this.Type = node.getAttribute('Type');
279+
this.TypeName = EdmSchema.hasNameWithNamespace(this.Type);
280+
if (this.TypeName) { this.Type = this.TypeName.Name; }
213281
const immutable = node.selectSingleNode('Annotation[@Term="Org.OData.Core.V1.Immutable"]');
214282
if (immutable) {
215283
this.Immutable = (immutable.getAttribute('Tag') === 'true') || (immutable.getAttribute('Bool') === 'true');
@@ -260,6 +328,7 @@ export class EdmPropertyRef {
260328
export class EdmEntityType {
261329
public Name: string;
262330
public BaseType: string;
331+
public BaseTypeName?: FullQualifiedName;
263332
public OpenType: boolean;
264333
public Key: EdmKey;
265334
public Property: EdmProperty[] = [];
@@ -273,6 +342,8 @@ export class EdmEntityType {
273342
this.Name = node.getAttribute('Name');
274343
this.OpenType = node.getAttribute('OpenType') === 'true';
275344
this.BaseType = node.getAttribute('BaseType');
345+
this.BaseTypeName = EdmSchema.hasNameWithNamespace(this.BaseType);
346+
if (this.BaseTypeName) { this.BaseType = this.BaseTypeName.Name; }
276347
const keyNode = node.selectSingleNode('Key');
277348
if (keyNode) {
278349
this.Key = XSerializer.deserialize(keyNode, EdmKey);
@@ -301,13 +372,16 @@ export class EdmEntityType {
301372
export class EdmEntitySet {
302373
public Name: string;
303374
public EntityType: string;
375+
public EntityTypeName?: FullQualifiedName;
304376
public ResourcePath: string;
305377
constructor() {
306378
//
307379
}
308380
public readXml(node: XNode) {
309381
this.Name = node.getAttribute('Name');
310382
this.EntityType = node.getAttribute('EntityType');
383+
this.EntityTypeName = EdmSchema.hasNameWithNamespace(this.EntityType);
384+
if (this.EntityTypeName) { this.EntityType = this.EntityTypeName.Name; }
311385
// get resource path
312386
const resourcePathNode = node.selectSingleNode('Annotation[@Term="Org.OData.Core.V1.ResourcePath"]');
313387
if (resourcePathNode) {

0 commit comments

Comments
 (0)