@balena/pinejs 21.1.0-build-odata-metadata-json-395a55cb54e7b9ce0960ab93aad5f69d6c0e0462-2 → 21.1.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.
@@ -6,199 +6,6 @@ import type {
6
6
  import type { SbvrType } from '@balena/sbvr-types';
7
7
  import { sbvrTypes } from '../sbvr-api/sbvr-utils.js';
8
8
  import { version } from '../config-loader/env.js';
9
- import type { PermissionLookup } from '../sbvr-api/permissions.js';
10
-
11
- // OData JSON v4 CSDL Vocabulary constants
12
- // http://docs.oasis-open.org/odata/odata-vocabularies/v4.0/odata-vocabularies-v4.0.html
13
- const odataVocabularyReferences: ODataCsdlV4References = {
14
- 'https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json':
15
- {
16
- $Include: [
17
- {
18
- $Namespace: 'Org.OData.Core.V1',
19
- $Alias: 'Core',
20
- '@Core.DefaultNamespace': true,
21
- },
22
- ],
23
- },
24
- 'https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json':
25
- {
26
- $Include: [
27
- {
28
- $Namespace: 'Org.OData.Measures.V1',
29
- $Alias: 'Measures',
30
- },
31
- ],
32
- },
33
- 'https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Aggregation.V1.json':
34
- {
35
- $Include: [
36
- {
37
- $Namespace: 'Org.OData.Aggregation.V1',
38
- $Alias: 'Aggregation',
39
- },
40
- ],
41
- },
42
- 'https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json':
43
- {
44
- $Include: [
45
- {
46
- $Namespace: 'Org.OData.Capabilities.V1',
47
- $Alias: 'Capabilities',
48
- },
49
- ],
50
- },
51
- };
52
-
53
- /**
54
- * Odata Common Schema Definition Language JSON format
55
- * http://docs.oasis-open.org/odata/odata-json-format/v4.0/odata-json-format-v4.0.html
56
- */
57
-
58
- type ODataCsdlV4References = {
59
- [URI: string]: {
60
- $Include: Array<{
61
- $Namespace: string;
62
- $Alias: string;
63
- [annotation: string]: string | boolean;
64
- }>;
65
- };
66
- };
67
-
68
- type ODataCsdlV4BaseProperty = {
69
- [annotation: string]: string | boolean | undefined;
70
- $Type?: string;
71
- $Nullable?: boolean;
72
- };
73
-
74
- type ODataCsdlV4StructuralProperty = ODataCsdlV4BaseProperty & {
75
- $Kind?: 'Property'; // This member SHOULD be omitted to reduce document size.
76
- };
77
-
78
- type ODataCsdlV4NavigationProperty = ODataCsdlV4BaseProperty & {
79
- $Kind: 'NavigationProperty';
80
- $Partner?: string;
81
- };
82
-
83
- type ODataCsdlV4Property =
84
- | ODataCsdlV4BaseProperty
85
- | ODataCsdlV4StructuralProperty
86
- | ODataCsdlV4NavigationProperty;
87
-
88
- type ODataCsdlV4EntityType = {
89
- $Kind: 'EntityType';
90
- $Key: string[];
91
- [property: string]: true | string[] | string | ODataCsdlV4Property;
92
- };
93
-
94
- type ODataCsdlV4EntityContainerEntries = {
95
- // $Collection: true;
96
- $Type: string;
97
- [property: string]: true | string | ODataCapabilitiesUDIRRestrictionsMethod;
98
- };
99
-
100
- type ODataCsdlV4Entities = {
101
- [resource: string]: ODataCsdlV4EntityType;
102
- };
103
-
104
- type ODataCsdlV4EntityContainer = {
105
- $Kind: 'EntityContainer';
106
- '@Capabilities.BatchSupported'?: boolean;
107
- [resourceOrAnnotation: string]:
108
- | boolean
109
- | string
110
- | ODataCsdlV4EntityContainerEntries
111
- | undefined;
112
- };
113
-
114
- type ODataCsdlV4Schema = {
115
- $Alias: string;
116
- '@Core.DefaultNamespace': true;
117
- [resource: string]:
118
- | string
119
- | boolean
120
- | ODataCsdlV4EntityContainer
121
- | ODataCsdlV4EntityType;
122
- };
123
-
124
- type OdataCsdlV4 = {
125
- $Version: string;
126
- $Reference: ODataCsdlV4References;
127
- $EntityContainer: string;
128
- [schema: string]: string | ODataCsdlV4References | ODataCsdlV4Schema;
129
- };
130
-
131
- type PreparedPermissionsLookup = {
132
- [vocabulary: string]: {
133
- [resource: string]: {
134
- read: boolean;
135
- create: boolean;
136
- update: boolean;
137
- delete: boolean;
138
- };
139
- };
140
- };
141
-
142
- type PreparedAbstractModel = {
143
- vocabulary: string;
144
- abstractSqlModel: AbstractSqlModel;
145
- preparedPermissionLookup: PreparedPermissionsLookup;
146
- };
147
-
148
- type ODataCapabilitiesUDIRRestrictionsMethod =
149
- | { Updatable: boolean }
150
- | { Deletable: boolean }
151
- | { Insertable: boolean }
152
- | { Readable: boolean }
153
- | { Filterable: boolean };
154
-
155
- const restrictionsLookup = (
156
- method: keyof PreparedPermissionsLookup[string][string] | 'all',
157
- value: boolean,
158
- ) => {
159
- const lookup = {
160
- update: {
161
- '@Capabilities.UpdateRestrictions': {
162
- Updatable: value,
163
- },
164
- '@Capabilities.FilterRestrictions': {
165
- Filterable: true,
166
- },
167
- },
168
- delete: {
169
- '@Capabilities.DeleteRestrictions': {
170
- Deletable: value,
171
- },
172
- '@Capabilities.FilterRestrictions': {
173
- Filterable: true,
174
- },
175
- },
176
- create: {
177
- '@Capabilities.InsertRestrictions': {
178
- Insertable: value,
179
- },
180
- },
181
- read: {
182
- '@Capabilities.ReadRestrictions': {
183
- Readable: value,
184
- },
185
- '@Capabilities.FilterRestrictions': {
186
- Filterable: true,
187
- },
188
- },
189
- };
190
-
191
- if (method === 'all') {
192
- return {
193
- ...lookup['update'],
194
- ...lookup['delete'],
195
- ...lookup['create'],
196
- ...lookup['read'],
197
- };
198
- } else {
199
- return lookup[method] ?? {};
200
- }
201
- };
202
9
 
203
10
  const getResourceName = (resourceName: string): string =>
204
11
  resourceName
@@ -207,25 +14,17 @@ const getResourceName = (resourceName: string): string =>
207
14
  .join('__');
208
15
 
209
16
  const forEachUniqueTable = <T>(
210
- model: PreparedAbstractModel,
211
- callback: (
212
- tableName: string,
213
- table: AbstractSqlTable & { referenceScheme: string },
214
- ) => T,
17
+ model: AbstractSqlModel['tables'],
18
+ callback: (tableName: string, table: AbstractSqlTable) => T,
215
19
  ): T[] => {
216
20
  const usedTableNames: { [tableName: string]: true } = {};
217
21
 
218
22
  const result = [];
219
-
220
- for (const key of Object.keys(model.abstractSqlModel.tables).sort()) {
221
- const table = model.abstractSqlModel.tables[key] as AbstractSqlTable & {
222
- referenceScheme: string;
223
- };
23
+ for (const [key, table] of Object.entries(model)) {
224
24
  if (
225
25
  typeof table !== 'string' &&
226
26
  !table.primitive &&
227
- !usedTableNames[table.name] &&
228
- model.preparedPermissionLookup
27
+ !usedTableNames[table.name]
229
28
  ) {
230
29
  usedTableNames[table.name] = true;
231
30
  result.push(callback(key, table));
@@ -234,49 +33,9 @@ const forEachUniqueTable = <T>(
234
33
  return result;
235
34
  };
236
35
 
237
- /**
238
- * parsing dictionary of vocabulary.resource.operation permissions string
239
- * into dictionary of resource to operation for later lookup
240
- */
241
-
242
- const preparePermissionsLookup = (
243
- permissionLookup: PermissionLookup,
244
- ): PreparedPermissionsLookup => {
245
- const resourcesAndOps: PreparedPermissionsLookup = {};
246
-
247
- for (const resourceOpsAuths of Object.keys(permissionLookup)) {
248
- const [vocabulary, resource, rule] = resourceOpsAuths.split('.');
249
- resourcesAndOps[vocabulary] ??= {};
250
- resourcesAndOps[vocabulary][resource] ??= {
251
- ['read']: false,
252
- ['create']: false,
253
- ['update']: false,
254
- ['delete']: false,
255
- };
256
-
257
- if (rule === 'all' || (resource === 'all' && rule === undefined)) {
258
- resourcesAndOps[vocabulary][resource] = {
259
- ['read']: true,
260
- ['create']: true,
261
- ['update']: true,
262
- ['delete']: true,
263
- };
264
- } else if (
265
- rule === 'read' ||
266
- rule === 'create' ||
267
- rule === 'update' ||
268
- rule === 'delete'
269
- ) {
270
- resourcesAndOps[vocabulary][resource][rule] = true;
271
- }
272
- }
273
- return resourcesAndOps;
274
- };
275
-
276
36
  export const generateODataMetadata = (
277
37
  vocabulary: string,
278
38
  abstractSqlModel: AbstractSqlModel,
279
- permissionsLookup?: PermissionLookup,
280
39
  ) => {
281
40
  const complexTypes: { [fieldType: string]: string } = {};
282
41
  const resolveDataType = (fieldType: keyof typeof sbvrTypes): string => {
@@ -291,109 +50,132 @@ export const generateODataMetadata = (
291
50
  return sbvrTypes[fieldType].types.odata.name;
292
51
  };
293
52
 
294
- const prepPermissionsLookup = permissionsLookup
295
- ? preparePermissionsLookup(permissionsLookup)
296
- : {};
297
-
298
- const model: PreparedAbstractModel = {
299
- vocabulary,
300
- abstractSqlModel,
301
- preparedPermissionLookup: prepPermissionsLookup,
302
- };
303
-
304
- const metaBalenaEntries: ODataCsdlV4Entities = {};
305
- const entityContainer: ODataCsdlV4EntityContainer = {
306
- $Kind: 'EntityContainer',
307
- '@Capabilities.KeyAsSegmentSupported': false,
308
- };
309
-
310
- forEachUniqueTable(model, (_key, { idField, name: resourceName, fields }) => {
53
+ const model = abstractSqlModel.tables;
54
+ const associations: Array<{
55
+ name: string;
56
+ ends: Array<{
57
+ resourceName: string;
58
+ cardinality: '1' | '0..1' | '*';
59
+ }>;
60
+ }> = [];
61
+ forEachUniqueTable(model, (_key, { name: resourceName, fields }) => {
311
62
  resourceName = getResourceName(resourceName);
312
- // no path nor entity when permissions not contain resource
313
- const permissions: PreparedPermissionsLookup[string][string] =
314
- model?.preparedPermissionLookup?.['resource']?.['all'] ??
315
- model?.preparedPermissionLookup?.[model.vocabulary]?.['all'] ??
316
- model?.preparedPermissionLookup?.[model.vocabulary]?.[resourceName];
317
-
318
- if (!permissions) {
319
- return;
320
- }
321
-
322
- const uniqueTable: ODataCsdlV4EntityType = {
323
- $Kind: 'EntityType',
324
- $Key: [idField],
325
- };
326
-
327
- fields
328
- .filter(({ dataType }) => dataType !== 'ForeignKey')
329
- .map(({ dataType, fieldName, required }) => {
330
- dataType = resolveDataType(dataType as keyof typeof sbvrTypes);
331
- fieldName = getResourceName(fieldName);
332
-
333
- uniqueTable[fieldName] = {
334
- $Type: dataType,
335
- $Nullable: !required,
336
- '@Core.Computed':
337
- fieldName === 'created_at' || fieldName === 'modified_at'
338
- ? true
339
- : false,
340
- };
341
- });
342
-
343
- fields
344
- .filter(
345
- ({ dataType, references }) =>
346
- dataType === 'ForeignKey' && references != null,
347
- )
348
- .map(({ fieldName, references, required }) => {
349
- const { resourceName: referencedResource } = references!;
350
- const referencedResourceName =
351
- model.abstractSqlModel.tables[referencedResource]?.name;
352
- const typeReference = referencedResourceName || referencedResource;
353
-
354
- fieldName = getResourceName(fieldName);
355
- uniqueTable[fieldName] = {
356
- $Kind: 'NavigationProperty',
357
- $Partner: resourceName,
358
- $Nullable: !required,
359
- $Type: vocabulary + '.' + getResourceName(typeReference),
360
- };
361
- });
362
-
363
- metaBalenaEntries[resourceName] = uniqueTable;
364
-
365
- let entityCon: ODataCsdlV4EntityContainerEntries = {
366
- $Collection: true,
367
- $Type: vocabulary + '.' + resourceName,
368
- };
369
- for (const [resKey, resValue] of Object.entries(permissions) as Array<
370
- [keyof PreparedPermissionsLookup[string][string], boolean]
371
- >) {
372
- entityCon = { ...entityCon, ...restrictionsLookup(resKey, resValue) };
63
+ for (const { dataType, required, references } of fields) {
64
+ if (dataType === 'ForeignKey' && references != null) {
65
+ const { resourceName: referencedResource } = references;
66
+ associations.push({
67
+ name: resourceName + referencedResource,
68
+ ends: [
69
+ { resourceName, cardinality: required ? '1' : '0..1' },
70
+ { resourceName: referencedResource, cardinality: '*' },
71
+ ],
72
+ });
73
+ }
373
74
  }
374
-
375
- entityContainer[resourceName] = entityCon;
376
75
  });
377
76
 
378
- const odataCsdl: OdataCsdlV4 = {
379
- // needs to be === '4.0' as > '4.0' in csdl2openapi will switch to drop the `$` query parameter prefix for eg $top, $skip as it became optional in OData V4.01
380
- $Version: '3.0',
381
- $EntityContainer: vocabulary + '.ODataApi',
382
- $Reference: odataVocabularyReferences,
383
- [vocabulary]: {
384
- // schema
385
- $Alias: vocabulary,
386
- '@Core.DefaultNamespace': true,
387
- '@Core.Description': `OpenAPI specification for PineJS served SBVR datamodel: ${vocabulary}`,
388
- '@Core.LongDescription':
389
- 'Auto-Genrated OpenAPI specification by utilizing OData CSDL to OpenAPI spec transformer.',
390
- '@Core.SchemaVersion': version,
391
- ...metaBalenaEntries,
392
- ['ODataApi']: entityContainer,
393
- },
394
- };
395
-
396
- return odataCsdl;
77
+ return (
78
+ `
79
+ <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
80
+ <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
81
+ <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="2.0">
82
+ <Schema Namespace="${vocabulary}"
83
+ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
84
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
85
+ xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
86
+
87
+ ` +
88
+ forEachUniqueTable(
89
+ model,
90
+ (_key, { idField, name: resourceName, fields }) => {
91
+ resourceName = getResourceName(resourceName);
92
+ return (
93
+ `
94
+ <EntityType Name="${resourceName}">
95
+ <Key>
96
+ <PropertyRef Name="${idField}" />
97
+ </Key>
98
+
99
+ ` +
100
+ fields
101
+ .filter(({ dataType }) => dataType !== 'ForeignKey')
102
+ .map(({ dataType, fieldName, required }) => {
103
+ dataType = resolveDataType(dataType as keyof typeof sbvrTypes);
104
+ fieldName = getResourceName(fieldName);
105
+ return `<Property Name="${fieldName}" Type="${dataType}" Nullable="${!required}" />`;
106
+ })
107
+ .join('\n') +
108
+ '\n' +
109
+ fields
110
+ .filter(
111
+ ({ dataType, references }) =>
112
+ dataType === 'ForeignKey' && references != null,
113
+ )
114
+ .map(({ fieldName, references }) => {
115
+ const { resourceName: referencedResource } = references!;
116
+ fieldName = getResourceName(fieldName);
117
+ return `<NavigationProperty Name="${fieldName}" Relationship="${vocabulary}.${
118
+ resourceName + referencedResource
119
+ }" FromRole="${resourceName}" ToRole="${referencedResource}" />`;
120
+ })
121
+ .join('\n') +
122
+ '\n' +
123
+ `
124
+ </EntityType>`
125
+ );
126
+ },
127
+ ).join('\n\n') +
128
+ associations
129
+ .map(({ name, ends }) => {
130
+ name = getResourceName(name);
131
+ return (
132
+ `<Association Name="${name}">` +
133
+ '\n\t' +
134
+ ends
135
+ .map(
136
+ ({ resourceName, cardinality }) =>
137
+ `<End Role="${resourceName}" Type="${vocabulary}.${resourceName}" Multiplicity="${cardinality}" />`,
138
+ )
139
+ .join('\n\t') +
140
+ '\n' +
141
+ `</Association>`
142
+ );
143
+ })
144
+ .join('\n') +
145
+ `
146
+ <EntityContainer Name="${vocabulary}Service" m:IsDefaultEntityContainer="true">
147
+
148
+ ` +
149
+ forEachUniqueTable(model, (_key, { name: resourceName }) => {
150
+ resourceName = getResourceName(resourceName);
151
+ return `<EntitySet Name="${resourceName}" EntityType="${vocabulary}.${resourceName}" />`;
152
+ }).join('\n') +
153
+ '\n' +
154
+ associations
155
+ .map(({ name, ends }) => {
156
+ name = getResourceName(name);
157
+ return (
158
+ `<AssociationSet Name="${name}" Association="${vocabulary}.${name}">` +
159
+ '\n\t' +
160
+ ends
161
+ .map(
162
+ ({ resourceName }) =>
163
+ `<End Role="${resourceName}" EntitySet="${vocabulary}.${resourceName}" />`,
164
+ )
165
+ .join('\n\t') +
166
+ `
167
+ </AssociationSet>`
168
+ );
169
+ })
170
+ .join('\n') +
171
+ `
172
+ </EntityContainer>` +
173
+ Object.values(complexTypes).join('\n') +
174
+ `
175
+ </Schema>
176
+ </edmx:DataServices>
177
+ </edmx:Edmx>`
178
+ );
397
179
  };
398
180
 
399
181
  generateODataMetadata.version = version;
@@ -328,7 +328,7 @@ const namespaceRelationships = (
328
328
  }
329
329
  };
330
330
 
331
- export type PermissionLookup = Dictionary<true | string[]>;
331
+ type PermissionLookup = Dictionary<true | string[]>;
332
332
 
333
333
  const getPermissionsLookup = env.createCache(
334
334
  'permissionsLookup',
@@ -1707,7 +1707,7 @@ const getGuestPermissions = memoize(
1707
1707
  { promise: true },
1708
1708
  );
1709
1709
 
1710
- export const getReqPermissions = async (
1710
+ const getReqPermissions = async (
1711
1711
  req: PermissionReq,
1712
1712
  odataBinds: ODataBinds = [] as any as ODataBinds,
1713
1713
  ) => {
@@ -48,7 +48,6 @@ import * as asyncMigrator from '../migrator/async.js';
48
48
  import * as syncMigrator from '../migrator/sync.js';
49
49
  import { generateODataMetadata } from '../odata-metadata/odata-metadata-generator.js';
50
50
  import { importSBVR } from '../server-glue/sbvr-loader.js';
51
- import { generateODataMetadataAsOpenApi } from '../odata-metadata/open-api-specification-generator.js';
52
51
 
53
52
  import type DevModel from './dev.js';
54
53
  const devModel = await importSBVR('./dev.sbvr', import.meta);
@@ -112,7 +111,6 @@ import {
112
111
  type MigrationExecutionResult,
113
112
  setExecutedMigrations,
114
113
  } from '../migrator/utils.js';
115
- import { metadataEndpoints } from './uri-parser.js';
116
114
 
117
115
  const LF2AbstractSQLTranslator = LF2AbstractSQL.createTranslator(sbvrTypes);
118
116
  const LF2AbstractSQLTranslatorVersion = `${LF2AbstractSQLVersion}+${sbvrTypesVersion}`;
@@ -1337,10 +1335,7 @@ const runODataRequest = (req: Express.Request, vocabulary: string) => {
1337
1335
  })
1338
1336
  : resolveSynonym($request);
1339
1337
 
1340
- if (
1341
- abstractSqlModel.tables[resolvedResourceName] == null &&
1342
- !metadataEndpoints.includes(resolvedResourceName)
1343
- ) {
1338
+ if (abstractSqlModel.tables[resolvedResourceName] == null) {
1344
1339
  throw new UnauthorizedError();
1345
1340
  }
1346
1341
 
@@ -1843,35 +1838,10 @@ const respondGet = async (
1843
1838
  return response;
1844
1839
  } else {
1845
1840
  if (request.resourceName === '$metadata') {
1846
- const permLookup = await permissions.getReqPermissions(req);
1847
- const spec = generateODataMetadata(
1848
- vocab,
1849
- models[vocab].abstractSql,
1850
- permLookup,
1851
- );
1852
- return {
1853
- statusCode: 200,
1854
- body: spec,
1855
- headers: { 'content-type': 'application/json' },
1856
- };
1857
- } else if (request.resourceName === 'openapi.json') {
1858
- // https://docs.oasis-open.org/odata/odata-openapi/v1.0/cn01/odata-openapi-v1.0-cn01.html#sec_ProvidingOASDocumentsforanODataServi
1859
- // Following the OASIS OData to openapi translation guide the openapi.json is an independent resource
1860
- const permLookup = await permissions.getReqPermissions(req);
1861
- const spec = generateODataMetadata(
1862
- vocab,
1863
- models[vocab].abstractSql,
1864
- permLookup,
1865
- );
1866
- const openApispec = generateODataMetadataAsOpenApi(
1867
- spec,
1868
- req.originalUrl.replace('openapi.json', ''),
1869
- req.hostname,
1870
- );
1871
1841
  return {
1872
1842
  statusCode: 200,
1873
- body: openApispec,
1874
- headers: { 'content-type': 'application/json' },
1843
+ body: models[vocab].odataMetadata,
1844
+ headers: { 'content-type': 'xml' },
1875
1845
  };
1876
1846
  } else {
1877
1847
  // TODO: request.resourceName can be '$serviceroot' or a resource and we should return an odata xml document based on that
@@ -267,7 +267,7 @@ const memoizedOdata2AbstractSQL = (() => {
267
267
  };
268
268
  })();
269
269
 
270
- export const metadataEndpoints = ['$metadata', '$serviceroot', 'openapi.json'];
270
+ export const metadataEndpoints = ['$metadata', '$serviceroot'];
271
271
 
272
272
  export function parseOData(
273
273
  b: UnparsedRequest & { _isChangeSet?: false },
@@ -1,2 +0,0 @@
1
- import type { generateODataMetadata } from './odata-metadata-generator.js';
2
- export declare const generateODataMetadataAsOpenApi: (odataCsdl: ReturnType<typeof generateODataMetadata>, versionBasePathUrl?: string, hostname?: string) => any;
@@ -1,50 +0,0 @@
1
- import * as odataMetadata from 'odata-openapi';
2
- import _ from 'lodash';
3
- export const generateODataMetadataAsOpenApi = (odataCsdl, versionBasePathUrl = '', hostname = '') => {
4
- const openAPIJson = odataMetadata.csdl2openapi(odataCsdl, {
5
- scheme: 'https',
6
- host: hostname,
7
- basePath: versionBasePathUrl,
8
- diagram: false,
9
- maxLevels: 5,
10
- });
11
- const parameters = openAPIJson?.components?.parameters;
12
- parameters['filter'] = {
13
- name: '$filter',
14
- description: 'Filter items by property values, see [Filtering](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)',
15
- in: 'query',
16
- schema: {
17
- type: 'string',
18
- },
19
- };
20
- for (const idx of Object.keys(openAPIJson.paths)) {
21
- const properties = openAPIJson?.paths[idx]?.get?.responses?.['200']?.content?.['application/json']?.schema?.properties;
22
- if (properties?.value) {
23
- properties['d'] = properties.value;
24
- delete properties.value;
25
- }
26
- if (properties?.['@odata.count']) {
27
- delete properties['@odata.count'];
28
- }
29
- const entityCollectionPath = openAPIJson?.paths[idx];
30
- const singleEntityPath = openAPIJson?.paths[idx + '({id})'];
31
- if (entityCollectionPath != null && singleEntityPath != null) {
32
- const genericFilterParameterRef = {
33
- $ref: '#/components/parameters/filter',
34
- };
35
- for (const action of ['delete', 'patch']) {
36
- entityCollectionPath[action] = _.clone(singleEntityPath?.[action]);
37
- if (entityCollectionPath[action]) {
38
- entityCollectionPath[action]['parameters'] = [
39
- genericFilterParameterRef,
40
- ];
41
- }
42
- }
43
- }
44
- }
45
- if (openAPIJson?.paths['/$batch']) {
46
- delete openAPIJson.paths['/$batch'];
47
- }
48
- return openAPIJson;
49
- };
50
- //# sourceMappingURL=open-api-specification-generator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"open-api-specification-generator.js","sourceRoot":"","sources":["../../src/odata-metadata/open-api-specification-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAE/C,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC7C,SAAmD,EACnD,kBAAkB,GAAG,EAAE,EACvB,QAAQ,GAAG,EAAE,EACZ,EAAE;IAEH,MAAM,WAAW,GAAQ,aAAa,CAAC,YAAY,CAAC,SAAS,EAAE;QAC9D,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,CAAC;KACZ,CAAC,CAAC;IA2BH,MAAM,UAAU,GAAG,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC;IACvD,UAAU,CAAC,QAAQ,CAAC,GAAG;QACtB,IAAI,EAAE,SAAS;QACf,WAAW,EACV,4JAA4J;QAC7J,EAAE,EAAE,OAAO;QACX,MAAM,EAAE;YACP,IAAI,EAAE,QAAQ;SACd;KACD,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QAElD,MAAM,UAAU,GACf,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAC1D,kBAAkB,CAClB,EAAE,MAAM,EAAE,UAAU,CAAC;QACvB,IAAI,UAAU,EAAE,KAAK,EAAE,CAAC;YACvB,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;YACnC,OAAO,UAAU,CAAC,KAAK,CAAC;QACzB,CAAC;QAGD,IAAI,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;YAClC,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;QAKD,MAAM,oBAAoB,GAAG,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,gBAAgB,GAAG,WAAW,EAAE,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;QAC5D,IAAI,oBAAoB,IAAI,IAAI,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;YAC9D,MAAM,yBAAyB,GAAG;gBACjC,IAAI,EAAE,gCAAgC;aACtC,CAAC;YACF,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC1C,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBACnE,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,oBAAoB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,GAAG;wBAC5C,yBAAyB;qBACzB,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAID,IAAI,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,OAAO,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,WAAW,CAAC;AACpB,CAAC,CAAC"}