@sap-ux/axios-extension
Advanced tools
Comparing version 1.14.4 to 1.15.1
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -29,3 +20,8 @@ exports.AbapServiceProvider = void 0; | ||
class AbapServiceProvider extends service_provider_1.ServiceProvider { | ||
atoSettings; | ||
/** | ||
* Maintain the public facing URL which is required for destination related flows | ||
*/ | ||
_publicUrl; | ||
/** | ||
* Get the name of the currently logged in user. This is the basic implementation that could be overwritten by subclasses. | ||
@@ -37,4 +33,3 @@ * The function returns a promise because it may be required to fetch the information from the backend. | ||
user() { | ||
var _a; | ||
return Promise.resolve((_a = this.defaults.auth) === null || _a === void 0 ? void 0 : _a.username); | ||
return Promise.resolve(this.defaults.auth?.username); | ||
} | ||
@@ -54,22 +49,20 @@ /** | ||
*/ | ||
getAtoInfo() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.atoSettings) { | ||
return this.atoSettings; | ||
async getAtoInfo() { | ||
if (this.atoSettings) { | ||
return this.atoSettings; | ||
} | ||
let atoService; | ||
try { | ||
atoService = await this.getAdtService(services_1.AtoService); | ||
if (atoService) { | ||
this.atoSettings = await atoService.getAtoInfo(); | ||
} | ||
let atoService; | ||
try { | ||
atoService = yield this.getAdtService(services_1.AtoService); | ||
if (atoService) { | ||
this.atoSettings = yield atoService.getAtoInfo(); | ||
} | ||
else { | ||
this.atoSettings = {}; | ||
} | ||
} | ||
catch (error) { | ||
else { | ||
this.atoSettings = {}; | ||
} | ||
return this.atoSettings; | ||
}); | ||
} | ||
catch (error) { | ||
this.atoSettings = {}; | ||
} | ||
return this.atoSettings; | ||
} | ||
@@ -97,12 +90,10 @@ /** | ||
*/ | ||
isS4Cloud() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.atoSettings === undefined) { | ||
yield this.getAtoInfo(); | ||
} | ||
return (this.atoSettings.tenantType === types_1.TenantType.Customer && | ||
this.atoSettings.operationsType === 'C' && | ||
this.atoSettings.developmentPrefix !== '' && | ||
this.atoSettings.developmentPackage !== ''); | ||
}); | ||
async isS4Cloud() { | ||
if (this.atoSettings === undefined) { | ||
await this.getAtoInfo(); | ||
} | ||
return (this.atoSettings.tenantType === types_1.TenantType.Customer && | ||
this.atoSettings.operationsType === 'C' && | ||
this.atoSettings.developmentPrefix !== '' && | ||
this.atoSettings.developmentPackage !== ''); | ||
} | ||
@@ -128,11 +119,12 @@ /** | ||
catalog(version) { | ||
var _a, _b; | ||
let service; | ||
if (version === odata_service_1.ODataVersion.v2) { | ||
service = | ||
(_a = this.services[catalog_1.V2CatalogService.PATH]) !== null && _a !== void 0 ? _a : this.createService(catalog_1.V2CatalogService.PATH, catalog_1.V2CatalogService); | ||
this.services[catalog_1.V2CatalogService.PATH] ?? | ||
this.createService(catalog_1.V2CatalogService.PATH, catalog_1.V2CatalogService); | ||
} | ||
else if (version === odata_service_1.ODataVersion.v4) { | ||
service = | ||
(_b = this.services[catalog_1.V4CatalogService.PATH]) !== null && _b !== void 0 ? _b : this.createService(catalog_1.V4CatalogService.PATH, catalog_1.V4CatalogService); | ||
this.services[catalog_1.V4CatalogService.PATH] ?? | ||
this.createService(catalog_1.V4CatalogService.PATH, catalog_1.V4CatalogService); | ||
} | ||
@@ -154,3 +146,3 @@ else { | ||
getUi5AbapRepository(alias) { | ||
const path = alias !== null && alias !== void 0 ? alias : ui5_abap_repository_service_1.Ui5AbapRepositoryService.PATH; | ||
const path = alias ?? ui5_abap_repository_service_1.Ui5AbapRepositoryService.PATH; | ||
if (!this.services[path]) { | ||
@@ -179,3 +171,3 @@ this.services[path] = this.createService(path, ui5_abap_repository_service_1.Ui5AbapRepositoryService); | ||
getLayeredRepository(alias) { | ||
const path = alias !== null && alias !== void 0 ? alias : lrep_service_1.LayeredRepositoryService.PATH; | ||
const path = alias ?? lrep_service_1.LayeredRepositoryService.PATH; | ||
if (!this.services[path]) { | ||
@@ -196,19 +188,17 @@ this.services[path] = this.createService(path, lrep_service_1.LayeredRepositoryService); | ||
*/ | ||
getAdtService(adtServiceSubclass) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const subclassName = adtServiceSubclass.name; | ||
if (!this.services[subclassName]) { | ||
// Retrieve ADT schema for the specific input AdtService subclass | ||
const adtCatalogService = this.getAdtCatalogService(); | ||
const adtSchema = yield adtCatalogService.getServiceDefinition(adtServiceSubclass.getAdtCatagory()); | ||
// No ADT schema available neither locally nor from service query. | ||
if (!adtSchema) { | ||
return null; | ||
} | ||
// Create singleton instance of AdtService subclass | ||
this.services[subclassName] = this.createService(adtSchema.href, adtServiceSubclass); | ||
this.services[subclassName].attachAdtSchema(adtSchema); | ||
async getAdtService(adtServiceSubclass) { | ||
const subclassName = adtServiceSubclass.name; | ||
if (!this.services[subclassName]) { | ||
// Retrieve ADT schema for the specific input AdtService subclass | ||
const adtCatalogService = this.getAdtCatalogService(); | ||
const adtSchema = await adtCatalogService.getServiceDefinition(adtServiceSubclass.getAdtCatagory()); | ||
// No ADT schema available neither locally nor from service query. | ||
if (!adtSchema) { | ||
return null; | ||
} | ||
return this.services[subclassName]; | ||
}); | ||
// Create singleton instance of AdtService subclass | ||
this.services[subclassName] = this.createService(adtSchema.href, adtServiceSubclass); | ||
this.services[subclassName].attachAdtSchema(adtSchema); | ||
} | ||
return this.services[subclassName]; | ||
} | ||
@@ -221,13 +211,11 @@ /** | ||
*/ | ||
getUiServiceGenerator(bo) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const generatorService = yield this.getAdtService(services_1.GeneratorService); | ||
if (!generatorService) { | ||
throw new Error('Generators are not support on this system'); | ||
} | ||
const config = yield generatorService.getUIServiceGeneratorConfig(bo.name); | ||
const gen = this.createService(this.getServiceUrlFromConfig(config), ui_service_generator_1.UiServiceGenerator); | ||
gen.configure(config, bo); | ||
return gen; | ||
}); | ||
async getUiServiceGenerator(bo) { | ||
const generatorService = await this.getAdtService(services_1.GeneratorService); | ||
if (!generatorService) { | ||
throw new Error('Generators are not support on this system'); | ||
} | ||
const config = await generatorService.getUIServiceGeneratorConfig(bo.name); | ||
const gen = this.createService(this.getServiceUrlFromConfig(config), ui_service_generator_1.UiServiceGenerator); | ||
gen.configure(config, bo); | ||
return gen; | ||
} | ||
@@ -241,5 +229,4 @@ /** | ||
getServiceUrlFromConfig(config) { | ||
var _a; | ||
// make code in this function defensive against undefined href | ||
if (Array.isArray(config.link) && !((_a = config.link[0]) === null || _a === void 0 ? void 0 : _a.href)) { | ||
if (Array.isArray(config.link) && !config.link[0]?.href) { | ||
throw new Error('No service URL found in the generator config'); | ||
@@ -256,7 +243,5 @@ } | ||
*/ | ||
createLockServiceBindingGenerator(path) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const gen = this.createService(path, ui_service_generator_1.UiServiceGenerator); | ||
return gen; | ||
}); | ||
async createLockServiceBindingGenerator(path) { | ||
const gen = this.createService(path, ui_service_generator_1.UiServiceGenerator); | ||
return gen; | ||
} | ||
@@ -263,0 +248,0 @@ } |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,7 +12,8 @@ exports.AdtCatalogService = void 0; | ||
class AdtCatalogService extends axios_1.Axios { | ||
constructor() { | ||
super(...arguments); | ||
// Cache of fetched discovery schema | ||
this.schemaStore = new adt_schema_store_1.AdtSchemaStore(); | ||
} | ||
// Discovery service url provided by ADT team | ||
static ADT_DISCOVERY_SERVICE_PATH = '/sap/bc/adt/discovery'; | ||
// Cache of fetched discovery schema | ||
schemaStore = new adt_schema_store_1.AdtSchemaStore(); | ||
// Instantiated by calling ServiceProvider.createService() | ||
log; | ||
/** | ||
@@ -34,16 +26,14 @@ * Adt Catalog Service which fetches the Adt service | ||
*/ | ||
getServiceDefinition(adtCategory) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.checkOrLoadAdtDiscoverySchema(); | ||
// Find the schema for the input service url path | ||
const serviceSchema = this.schemaStore.getAdtCollection(adtCategory); | ||
const isValidSchema = this.validateServiceSchema(adtCategory, serviceSchema); | ||
if (isValidSchema) { | ||
return serviceSchema; | ||
} | ||
else { | ||
this.log.warn('Invalid Discovery Schema'); | ||
return null; | ||
} | ||
}); | ||
async getServiceDefinition(adtCategory) { | ||
await this.checkOrLoadAdtDiscoverySchema(); | ||
// Find the schema for the input service url path | ||
const serviceSchema = this.schemaStore.getAdtCollection(adtCategory); | ||
const isValidSchema = this.validateServiceSchema(adtCategory, serviceSchema); | ||
if (isValidSchema) { | ||
return serviceSchema; | ||
} | ||
else { | ||
this.log.warn('Invalid Discovery Schema'); | ||
return null; | ||
} | ||
} | ||
@@ -75,15 +65,13 @@ /** | ||
*/ | ||
checkOrLoadAdtDiscoverySchema() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.schemaStore.isAdtSchemaEmpty()) { | ||
return; | ||
async checkOrLoadAdtDiscoverySchema() { | ||
if (!this.schemaStore.isAdtSchemaEmpty()) { | ||
return; | ||
} | ||
const response = await this.get('', { | ||
headers: { | ||
Accept: 'application/*' | ||
} | ||
const response = yield this.get('', { | ||
headers: { | ||
Accept: 'application/*' | ||
} | ||
}); | ||
const schemaData = this.parseAdtSchemaData(response.data); | ||
this.schemaStore.updateSchemaData(schemaData); | ||
}); | ||
const schemaData = this.parseAdtSchemaData(response.data); | ||
this.schemaStore.updateSchemaData(schemaData); | ||
} | ||
@@ -117,4 +105,2 @@ /** | ||
exports.AdtCatalogService = AdtCatalogService; | ||
// Discovery service url provided by ADT team | ||
AdtCatalogService.ADT_DISCOVERY_SERVICE_PATH = '/sap/bc/adt/discovery'; | ||
//# sourceMappingURL=adt-catalog-service.js.map |
@@ -9,2 +9,6 @@ "use strict"; | ||
/** | ||
* ADT schema is modeled as a map for fast access | ||
*/ | ||
adtSchema; | ||
/** | ||
* Given the ID of a particular ADT service, return the schema of this service. | ||
@@ -11,0 +15,0 @@ * |
@@ -1,2 +0,1 @@ | ||
import type { Logger } from '@sap-ux/logger'; | ||
import type { GeneratorEntry } from './types'; | ||
@@ -9,3 +8,2 @@ import type { BusinessObject, ValidationResponse } from '../../types'; | ||
export declare class UiServiceGenerator extends AdtService { | ||
log: Logger; | ||
protected bo: BusinessObject; | ||
@@ -12,0 +10,0 @@ /** |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -18,2 +9,3 @@ exports.UiServiceGenerator = void 0; | ||
class UiServiceGenerator extends services_1.AdtService { | ||
bo; | ||
/** | ||
@@ -33,14 +25,12 @@ * Configure the UI service generator. | ||
*/ | ||
getSchema() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.get('/schema', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.repository.generator.schema.v1+json' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri | ||
} | ||
}); | ||
return JSON.parse(response.data); | ||
async getSchema() { | ||
const response = await this.get('/schema', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.repository.generator.schema.v1+json' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri | ||
} | ||
}); | ||
return JSON.parse(response.data); | ||
} | ||
@@ -53,22 +43,20 @@ /** | ||
*/ | ||
getContent(pckg) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.get('/content', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.repository.generator.content.v1+json' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
package: pckg | ||
} | ||
}); | ||
const content = response.data; | ||
const contentObj = JSON.parse(content); | ||
if (!contentObj['metadata']) { | ||
contentObj['metadata'] = { | ||
package: pckg | ||
}; | ||
async getContent(pckg) { | ||
const response = await this.get('/content', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.repository.generator.content.v1+json' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
package: pckg | ||
} | ||
return JSON.stringify(contentObj); | ||
}); | ||
const content = response.data; | ||
const contentObj = JSON.parse(content); | ||
if (!contentObj['metadata']) { | ||
contentObj['metadata'] = { | ||
package: pckg | ||
}; | ||
} | ||
return JSON.stringify(contentObj); | ||
} | ||
@@ -81,16 +69,14 @@ /** | ||
*/ | ||
validatePackage(pckg) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.get('/validation', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.validationMessages.v1+xml' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
package: pckg, | ||
checks: 'package' | ||
} | ||
}); | ||
return this.parseResponse(response.data); | ||
async validatePackage(pckg) { | ||
const response = await this.get('/validation', { | ||
headers: { | ||
Accept: 'application/vnd.sap.adt.validationMessages.v1+xml' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
package: pckg, | ||
checks: 'package' | ||
} | ||
}); | ||
return this.parseResponse(response.data); | ||
} | ||
@@ -103,18 +89,15 @@ /** | ||
*/ | ||
validateContent(content) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.post('/validation', content, { | ||
headers: { | ||
'Content-Type': 'application/vnd.sap.adt.repository.generator.content.v1+json', | ||
Accept: 'application/vnd.sap.adt.validationMessages.v1+xml' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
checks: 'package,referencedobject,authorization' | ||
} | ||
}); | ||
const data = this.parseResponse(response.data); | ||
return (_a = data.validationMessages) === null || _a === void 0 ? void 0 : _a.validationMessage; | ||
async validateContent(content) { | ||
const response = await this.post('/validation', content, { | ||
headers: { | ||
'Content-Type': 'application/vnd.sap.adt.repository.generator.content.v1+json', | ||
Accept: 'application/vnd.sap.adt.validationMessages.v1+xml' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
checks: 'package,referencedobject,authorization' | ||
} | ||
}); | ||
const data = this.parseResponse(response.data); | ||
return data.validationMessages?.validationMessage; | ||
} | ||
@@ -128,16 +111,14 @@ /** | ||
*/ | ||
generate(content, transport) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.post('', content, { | ||
headers: { | ||
'Content-Type': 'application/vnd.sap.adt.repository.generator.content.v1+json', | ||
Accept: 'application/vnd.sap.adt.repository.generator.v1+json, application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.StatusMessage' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
corrNr: transport | ||
} | ||
}); | ||
return this.parseResponse(response.data); | ||
async generate(content, transport) { | ||
const response = await this.post('', content, { | ||
headers: { | ||
'Content-Type': 'application/vnd.sap.adt.repository.generator.content.v1+json', | ||
Accept: 'application/vnd.sap.adt.repository.generator.v1+json, application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.StatusMessage' | ||
}, | ||
params: { | ||
referencedObject: this.bo.uri, | ||
corrNr: transport | ||
} | ||
}); | ||
return this.parseResponse(response.data); | ||
} | ||
@@ -144,0 +125,0 @@ } |
@@ -11,2 +11,6 @@ "use strict"; | ||
class AdtService extends axios_1.Axios { | ||
// Instantiated by calling ServiceProvider.createService() | ||
log; | ||
// ADT schema for the corresponding AdtService subclass | ||
serviceSchema; | ||
/** | ||
@@ -13,0 +17,0 @@ * Subclass that implements each specific ADT service |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,2 +12,9 @@ exports.AtoService = void 0; | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/ato', | ||
term: 'settings' | ||
}; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
* @returns AdtCategory | ||
@@ -32,12 +30,10 @@ */ | ||
*/ | ||
getAtoInfo() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'application/*' | ||
} | ||
}; | ||
const response = yield this.get('', acceptHeaders); | ||
return this.parseAtoResponse(response.data); | ||
}); | ||
async getAtoInfo() { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'application/*' | ||
} | ||
}; | ||
const response = await this.get('', acceptHeaders); | ||
return this.parseAtoResponse(response.data); | ||
} | ||
@@ -68,9 +64,2 @@ /** | ||
exports.AtoService = AtoService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
AtoService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/ato', | ||
term: 'settings' | ||
}; | ||
//# sourceMappingURL=ato-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -19,2 +10,9 @@ exports.BusinessObjectsService = void 0; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'search' | ||
}; | ||
/** | ||
* Get ADT scheme ID. | ||
@@ -33,19 +31,17 @@ * | ||
*/ | ||
getBusinessObjects(maxResults = 10000) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml' | ||
}, | ||
params: { | ||
operation: 'quickSearch', | ||
query: `*`, | ||
maxResults: maxResults, | ||
objectType: 'BDEF', | ||
releaseState: 'USE_IN_CLOUD_DEVELOPMENT' | ||
} | ||
}; | ||
const response = yield this.get('', config); | ||
return this.parseBOResponse(response.data); | ||
}); | ||
async getBusinessObjects(maxResults = 10000) { | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml' | ||
}, | ||
params: { | ||
operation: 'quickSearch', | ||
query: `*`, | ||
maxResults: maxResults, | ||
objectType: 'BDEF', | ||
releaseState: 'USE_IN_CLOUD_DEVELOPMENT' | ||
} | ||
}; | ||
const response = await this.get('', config); | ||
return this.parseBOResponse(response.data); | ||
} | ||
@@ -59,6 +55,5 @@ /** | ||
parseBOResponse(xml) { | ||
var _a; | ||
const parsed = this.parseResponse(xml); | ||
let boArray = []; | ||
if ((_a = parsed === null || parsed === void 0 ? void 0 : parsed.objectReferences) === null || _a === void 0 ? void 0 : _a.objectReference) { | ||
if (parsed?.objectReferences?.objectReference) { | ||
if (Array.isArray(parsed.objectReferences.objectReference)) { | ||
@@ -78,9 +73,2 @@ boArray = parsed.objectReferences.objectReference; | ||
exports.BusinessObjectsService = BusinessObjectsService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
BusinessObjectsService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'search' | ||
}; | ||
//# sourceMappingURL=businessobjects-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,2 +12,9 @@ exports.FileStoreService = void 0; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/filestore', | ||
term: 'filestore-ui5-bsp' | ||
}; | ||
/** | ||
* Get ADT scheme ID. | ||
@@ -45,18 +43,16 @@ * | ||
*/ | ||
getAppArchiveContent(type, appName, path = '') { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const contentType = type === 'folder' ? 'application/atom+xml' : 'application/octet-stream'; | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml', | ||
'Content-Type': contentType | ||
} | ||
}; | ||
if (path && !path.startsWith('/')) { | ||
throw new Error('Input argument "path" needs to start with /'); | ||
async getAppArchiveContent(type, appName, path = '') { | ||
const contentType = type === 'folder' ? 'application/atom+xml' : 'application/octet-stream'; | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml', | ||
'Content-Type': contentType | ||
} | ||
const encodedFullPath = encodeURIComponent(`${appName}${path}`); | ||
const response = yield this.get(`/${encodedFullPath}/content`, config); | ||
return this.parseArchiveContentResponse(appName, response.data, type); | ||
}); | ||
}; | ||
if (path && !path.startsWith('/')) { | ||
throw new Error('Input argument "path" needs to start with /'); | ||
} | ||
const encodedFullPath = encodeURIComponent(`${appName}${path}`); | ||
const response = await this.get(`/${encodedFullPath}/content`, config); | ||
return this.parseArchiveContentResponse(appName, response.data, type); | ||
} | ||
@@ -93,3 +89,3 @@ /** | ||
let fileNodeArray = []; | ||
if (parsed === null || parsed === void 0 ? void 0 : parsed.feed) { | ||
if (parsed?.feed) { | ||
if (Array.isArray(parsed.feed.entry)) { | ||
@@ -113,9 +109,2 @@ fileNodeArray = parsed.feed.entry; | ||
exports.FileStoreService = FileStoreService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
FileStoreService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/filestore', | ||
term: 'filestore-ui5-bsp' | ||
}; | ||
//# sourceMappingURL=filestore-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -19,2 +10,9 @@ exports.GeneratorService = void 0; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'generators' | ||
}; | ||
/** | ||
* Get ADT scheme ID. | ||
@@ -27,2 +25,3 @@ * | ||
} | ||
id; | ||
/** | ||
@@ -34,32 +33,22 @@ * Get the UI service generator for the given business object. | ||
*/ | ||
getUIServiceGeneratorConfig(businessObjectName) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.get('', { | ||
headers: { | ||
Accept: 'application/atom+xml;type=feed' | ||
}, | ||
params: { | ||
referencedObject: `/sap/bc/adt/bo/behaviordefinitions/${businessObjectName.toLocaleLowerCase()}`, | ||
type: 'webapi' | ||
} | ||
}); | ||
const data = (_a = this.parseResponse(response.data).feed) === null || _a === void 0 ? void 0 : _a.entry; | ||
if ((data === null || data === void 0 ? void 0 : data.id) === 'published-ui-service') { | ||
return data; | ||
async getUIServiceGeneratorConfig(businessObjectName) { | ||
const response = await this.get('', { | ||
headers: { | ||
Accept: 'application/atom+xml;type=feed' | ||
}, | ||
params: { | ||
referencedObject: `/sap/bc/adt/bo/behaviordefinitions/${businessObjectName.toLocaleLowerCase()}`, | ||
type: 'webapi' | ||
} | ||
else { | ||
throw new Error('UI Service Generator not found'); | ||
} | ||
}); | ||
const data = this.parseResponse(response.data).feed?.entry; | ||
if (data?.id === 'published-ui-service') { | ||
return data; | ||
} | ||
else { | ||
throw new Error('UI Service Generator not found'); | ||
} | ||
} | ||
} | ||
exports.GeneratorService = GeneratorService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
GeneratorService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'generators' | ||
}; | ||
//# sourceMappingURL=generator-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -23,2 +14,9 @@ exports.ListPackageService = void 0; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'search' | ||
}; | ||
/** | ||
* Get ADT scheme ID. | ||
@@ -48,20 +46,18 @@ * | ||
*/ | ||
listPackages(params) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { maxResults = 50, phrase = '' } = params; | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml' | ||
}, | ||
params: { | ||
operation: 'quickSearch', | ||
query: `${phrase}*`, | ||
useSearchProvider: 'X', | ||
maxResults, | ||
objectType: 'DEVC/K' | ||
} | ||
}; | ||
const response = yield this.get('', config); | ||
return this.parsePackageListResponse(response.data); | ||
}); | ||
async listPackages(params) { | ||
const { maxResults = 50, phrase = '' } = params; | ||
const config = { | ||
headers: { | ||
Accept: 'application/xml' | ||
}, | ||
params: { | ||
operation: 'quickSearch', | ||
query: `${phrase}*`, | ||
useSearchProvider: 'X', | ||
maxResults, | ||
objectType: 'DEVC/K' | ||
} | ||
}; | ||
const response = await this.get('', config); | ||
return this.parsePackageListResponse(response.data); | ||
} | ||
@@ -75,3 +71,2 @@ /** | ||
parsePackageListResponse(xml) { | ||
var _a; | ||
if (fast_xml_parser_1.XMLValidator.validate(xml) !== true) { | ||
@@ -91,3 +86,3 @@ this.log.warn(`Invalid XML: ${xml}`); | ||
let packageArray = []; | ||
if ((_a = parsed === null || parsed === void 0 ? void 0 : parsed.objectReferences) === null || _a === void 0 ? void 0 : _a.objectReference) { | ||
if (parsed?.objectReferences?.objectReference) { | ||
if (Array.isArray(parsed.objectReferences.objectReference)) { | ||
@@ -104,9 +99,2 @@ packageArray = parsed.objectReferences.objectReference; | ||
exports.ListPackageService = ListPackageService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
ListPackageService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/respository', | ||
term: 'search' | ||
}; | ||
//# sourceMappingURL=list-package-service.js.map |
@@ -25,11 +25,2 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -49,2 +40,9 @@ exports.TransportChecksService = void 0; | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/cts', | ||
term: 'transportchecks' | ||
}; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
* @returns AdtCategory | ||
@@ -55,2 +53,3 @@ */ | ||
} | ||
static LocalPackageError = 'LocalPackageError'; | ||
/** | ||
@@ -63,11 +62,10 @@ * TransportChecksService API function to fetch a list of available transport requests. | ||
*/ | ||
getTransportRequests(packageName, appName) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'application/vnd.sap.as+xml; dataname=com.sap.adt.transport.service.checkData', | ||
'content-type': 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData' | ||
} | ||
}; | ||
const data = ` | ||
async getTransportRequests(packageName, appName) { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'application/vnd.sap.as+xml; dataname=com.sap.adt.transport.service.checkData', | ||
'content-type': 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData' | ||
} | ||
}; | ||
const data = ` | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
@@ -88,5 +86,4 @@ <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"> | ||
`; | ||
const response = yield this.post('', data, acceptHeaders); | ||
return this.getTransportRequestList(response.data); | ||
}); | ||
const response = await this.post('', data, acceptHeaders); | ||
return this.getTransportRequestList(response.data); | ||
} | ||
@@ -101,3 +98,2 @@ /** | ||
getTransportRequestList(xml) { | ||
var _a; | ||
if (fast_xml_parser_1.XMLValidator.validate(xml) !== true) { | ||
@@ -108,3 +104,3 @@ this.log.warn(`Invalid XML: ${xml}`); | ||
const doc = new xmldom_1.DOMParser().parseFromString(xml); | ||
const status = (_a = xpath.select1('//RESULT/text()', doc)) === null || _a === void 0 ? void 0 : _a.toString(); | ||
const status = xpath.select1('//RESULT/text()', doc)?.toString(); | ||
switch (status) { | ||
@@ -127,7 +123,6 @@ case 'S': | ||
logErrorMsgs(doc) { | ||
var _a, _b; | ||
const messages = doc.getElementsByTagName('CTS_MESSAGE'); | ||
for (const msg of Array.from(messages)) { | ||
if (((_a = msg.getElementsByTagName('SEVERITY')[0]) === null || _a === void 0 ? void 0 : _a.textContent) === 'E') { | ||
const text = (_b = msg.getElementsByTagName('TEXT')[0]) === null || _b === void 0 ? void 0 : _b.textContent; | ||
if (msg.getElementsByTagName('SEVERITY')[0]?.textContent === 'E') { | ||
const text = msg.getElementsByTagName('TEXT')[0]?.textContent; | ||
this.log.error(text); | ||
@@ -149,6 +144,5 @@ } | ||
getTransportList(doc) { | ||
var _a, _b, _c; | ||
const recording = (_a = xpath.select1('//RECORDING/text()', doc)) === null || _a === void 0 ? void 0 : _a.toString(); | ||
const locked = (_b = xpath.select1('//LOCKS', doc)) === null || _b === void 0 ? void 0 : _b.textContent; | ||
const localPackage = (_c = xpath.select1('//DLVUNIT/text()', doc)) === null || _c === void 0 ? void 0 : _c.toString(); | ||
const recording = xpath.select1('//RECORDING/text()', doc)?.toString(); | ||
const locked = xpath.select1('//LOCKS', doc)?.textContent; | ||
const localPackage = xpath.select1('//DLVUNIT/text()', doc)?.toString(); | ||
if (recording && !locked) { | ||
@@ -211,7 +205,6 @@ return this.getTransportListForNewProject(doc); | ||
convertTransportRequest(transportReqEle) { | ||
var _a, _b, _c, _d, _e; | ||
if (!transportReqEle) { | ||
return undefined; | ||
} | ||
const transportNumber = (_a = xpath.select1('TRKORR/text()', transportReqEle)) === null || _a === void 0 ? void 0 : _a.toString(); | ||
const transportNumber = xpath.select1('TRKORR/text()', transportReqEle)?.toString(); | ||
if (!transportNumber) { | ||
@@ -222,6 +215,6 @@ return undefined; | ||
transportNumber: transportNumber, | ||
user: (_b = xpath.select1('AS4USER/text()', transportReqEle)) === null || _b === void 0 ? void 0 : _b.toString(), | ||
description: (_c = xpath.select1('AS4TEXT/text()', transportReqEle)) === null || _c === void 0 ? void 0 : _c.toString(), | ||
client: (_d = xpath.select1('CLIENT/text()', transportReqEle)) === null || _d === void 0 ? void 0 : _d.toString(), | ||
targetSystem: (_e = xpath.select1('TARSYSTEM/text()', transportReqEle)) === null || _e === void 0 ? void 0 : _e.toString() | ||
user: xpath.select1('AS4USER/text()', transportReqEle)?.toString(), | ||
description: xpath.select1('AS4TEXT/text()', transportReqEle)?.toString(), | ||
client: xpath.select1('CLIENT/text()', transportReqEle)?.toString(), | ||
targetSystem: xpath.select1('TARSYSTEM/text()', transportReqEle)?.toString() | ||
}; | ||
@@ -231,10 +224,2 @@ } | ||
exports.TransportChecksService = TransportChecksService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
TransportChecksService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/cts', | ||
term: 'transportchecks' | ||
}; | ||
TransportChecksService.LocalPackageError = 'LocalPackageError'; | ||
//# sourceMappingURL=transportcheck-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,2 +12,9 @@ exports.TransportRequestService = void 0; | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
static adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/cts', | ||
term: 'transports' | ||
}; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
* @returns AdtCategory | ||
@@ -33,11 +31,10 @@ */ | ||
*/ | ||
createTransportRequest(reqParam) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'text/plain', | ||
'content-type': 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.CreateCorrectionRequest' | ||
} | ||
}; | ||
const data = ` | ||
async createTransportRequest(reqParam) { | ||
const acceptHeaders = { | ||
headers: { | ||
Accept: 'text/plain', | ||
'content-type': 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.CreateCorrectionRequest' | ||
} | ||
}; | ||
const data = ` | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
@@ -55,5 +52,4 @@ <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"> | ||
`; | ||
const response = yield this.post('', data, acceptHeaders); | ||
return this.getTransportNumberFromResponse(response.data); | ||
}); | ||
const response = await this.post('', data, acceptHeaders); | ||
return this.getTransportNumberFromResponse(response.data); | ||
} | ||
@@ -78,9 +74,2 @@ /** | ||
exports.TransportRequestService = TransportRequestService; | ||
/** | ||
* @see AdtService.getAdtCatagory() | ||
*/ | ||
TransportRequestService.adtCategory = { | ||
scheme: 'http://www.sap.com/adt/categories/cts', | ||
term: 'transports' | ||
}; | ||
//# sourceMappingURL=transportrequest-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -19,2 +10,4 @@ exports.AppIndexService = void 0; | ||
class AppIndexService extends axios_1.Axios { | ||
static PATH = '/sap/bc/ui2/app_index'; | ||
log; | ||
/** | ||
@@ -27,11 +20,9 @@ * Returns list of applications matching the search query from the catalog service. | ||
*/ | ||
search(searchParams = {}, resultFields) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const params = Object.assign({}, searchParams); | ||
if (resultFields) { | ||
params['fields'] = resultFields.join(','); | ||
} | ||
const response = yield this.get('/', { params }); | ||
return JSON.parse(response.data).results; | ||
}); | ||
async search(searchParams = {}, resultFields) { | ||
const params = Object.assign({}, searchParams); | ||
if (resultFields) { | ||
params['fields'] = resultFields.join(','); | ||
} | ||
const response = await this.get('/', { params }); | ||
return JSON.parse(response.data).results; | ||
} | ||
@@ -44,23 +35,20 @@ /** | ||
*/ | ||
getAppInfo(appId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.get('/ui5_app_info_json', { params: { id: appId } }); | ||
return JSON.parse(response.data); | ||
async getAppInfo(appId) { | ||
try { | ||
const response = await this.get('/ui5_app_info_json', { params: { id: appId } }); | ||
return JSON.parse(response.data); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.log.error(`Failed fetching ui5_app_info_json for app with id ${appId}.`); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.log.error(`Failed fetching ui5_app_info_json for app with id ${appId}.`); | ||
} | ||
else { | ||
this.log.error(`Parsing error: ui5_app_info_json is not in expected format for app with id ${appId}.`); | ||
} | ||
this.log.debug(error); | ||
throw error; | ||
else { | ||
this.log.error(`Parsing error: ui5_app_info_json is not in expected format for app with id ${appId}.`); | ||
} | ||
}); | ||
this.log.debug(error); | ||
throw error; | ||
} | ||
} | ||
} | ||
exports.AppIndexService = AppIndexService; | ||
AppIndexService.PATH = '/sap/bc/ui2/app_index'; | ||
//# sourceMappingURL=app-index-service.js.map |
import type { ODataVersion } from '../../base/odata-service'; | ||
import { ODataService } from '../../base/odata-service'; | ||
export declare const ServiceType: { | ||
readonly UI: "UI"; | ||
readonly NotClassified: "Not Classified"; | ||
readonly WebApi: "WEB_API"; | ||
readonly NotDetermined: "Not Determined"; | ||
}; | ||
export type ServiceType = (typeof ServiceType)[keyof typeof ServiceType]; | ||
export interface ODataServiceInfo { | ||
@@ -10,2 +17,3 @@ id: string; | ||
serviceVersion: string; | ||
serviceType?: ServiceType; | ||
} | ||
@@ -44,3 +52,4 @@ /** | ||
abstract getAnnotations({ id, title, path }: FilterOptions): Promise<Annotations[]>; | ||
abstract getServiceType(path: string): Promise<ServiceType | undefined>; | ||
} | ||
//# sourceMappingURL=base.d.ts.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CatalogService = void 0; | ||
exports.CatalogService = exports.ServiceType = void 0; | ||
const odata_service_1 = require("../../base/odata-service"); | ||
exports.ServiceType = { | ||
UI: 'UI', | ||
NotClassified: 'Not Classified', | ||
WebApi: 'WEB_API', | ||
NotDetermined: 'Not Determined' | ||
}; | ||
/** | ||
@@ -18,2 +15,5 @@ * OData version independent abstract base class of SAP's catalog service | ||
class CatalogService extends odata_service_1.ODataService { | ||
entitySet; | ||
services; | ||
isS4Cloud; | ||
/** | ||
@@ -24,9 +24,7 @@ * Returns list of services from the catalog service. | ||
*/ | ||
listServices() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.services) { | ||
this.services = yield this.fetchServices(); | ||
} | ||
return this.services; | ||
}); | ||
async listServices() { | ||
if (!this.services) { | ||
this.services = await this.fetchServices(); | ||
} | ||
return this.services; | ||
} | ||
@@ -33,0 +31,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { ODataServiceInfo, Annotations, FilterOptions } from './base'; | ||
import type { ODataServiceInfo, Annotations, FilterOptions, ServiceType } from './base'; | ||
import { CatalogService } from './base'; | ||
@@ -16,2 +16,3 @@ /** | ||
TechnicalServiceVersion: number; | ||
ServiceType: ServiceType; | ||
} | ||
@@ -74,3 +75,10 @@ /** | ||
getAnnotations({ id, title, path }: FilterOptions): Promise<Annotations[]>; | ||
/** | ||
* Calls endpoint `ServiceTypeForHUBServices` to determine the service type. | ||
* | ||
* @param path service path | ||
* @returns service type | ||
*/ | ||
getServiceType(path: string): Promise<ServiceType | undefined>; | ||
} | ||
//# sourceMappingURL=v2-catalog-service.d.ts.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -23,9 +14,8 @@ exports.V2CatalogService = void 0; | ||
class V2CatalogService extends base_1.CatalogService { | ||
determineEntitySet() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const doc = yield this.document(); | ||
this.entitySet = doc.EntitySets.includes(V2_RECOMMENDED_ENTITYSET) | ||
? V2_RECOMMENDED_ENTITYSET | ||
: V2_CLASSIC_ENTITYSET; | ||
}); | ||
static PATH = '/sap/opu/odata/IWFND/CATALOGSERVICE;v=2'; | ||
async determineEntitySet() { | ||
const doc = await this.document(); | ||
this.entitySet = doc.EntitySets.includes(V2_RECOMMENDED_ENTITYSET) | ||
? V2_RECOMMENDED_ENTITYSET | ||
: V2_CLASSIC_ENTITYSET; | ||
} | ||
@@ -44,3 +34,3 @@ /** | ||
} | ||
catch (_a) { | ||
catch { | ||
// there are cases where the service url is just the path and not the full service url | ||
@@ -65,3 +55,4 @@ parsedUrl = new URL(serviceUrl, baseUrl); | ||
serviceVersion: service.TechnicalServiceVersion + '', | ||
odataVersion: odata_service_1.ODataVersion.v2 | ||
odataVersion: odata_service_1.ODataVersion.v2, | ||
serviceType: service.ServiceType | ||
}; | ||
@@ -75,21 +66,19 @@ }); | ||
*/ | ||
fetchServices() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const params = { | ||
$format: 'json' | ||
}; | ||
if (!this.entitySet) { | ||
yield this.determineEntitySet(); | ||
} | ||
if (this.entitySet === V2_CLASSIC_ENTITYSET && (yield this.isS4Cloud)) { | ||
params['$filter'] = V2_S4CLOUD_FILTER; | ||
} | ||
const response = yield this.get(`/${this.entitySet}`, { params }); | ||
const data = response.odata(); | ||
// check if the service responded with an odata error | ||
if (odata_request_error_1.ODataRequestError.containsError(data)) { | ||
throw new odata_request_error_1.ODataRequestError(data); | ||
} | ||
return this.mapServices(data); | ||
}); | ||
async fetchServices() { | ||
const params = { | ||
$format: 'json' | ||
}; | ||
if (!this.entitySet) { | ||
await this.determineEntitySet(); | ||
} | ||
if (this.entitySet === V2_CLASSIC_ENTITYSET && (await this.isS4Cloud)) { | ||
params['$filter'] = V2_S4CLOUD_FILTER; | ||
} | ||
const response = await this.get(`/${this.entitySet}`, { params }); | ||
const data = response.odata(); | ||
// check if the service responded with an odata error | ||
if (odata_request_error_1.ODataRequestError.containsError(data)) { | ||
throw new odata_request_error_1.ODataRequestError(data); | ||
} | ||
return this.mapServices(data); | ||
} | ||
@@ -104,39 +93,37 @@ /** | ||
*/ | ||
findService({ title, path }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let version = 1; | ||
async findService({ title, path }) { | ||
let version = 1; | ||
if (!title) { | ||
const titleWithParameters = path.replace(/\/$/, '').split('/').pop().split(';'); | ||
title = titleWithParameters[0].toUpperCase(); | ||
if (!title) { | ||
const titleWithParameters = path.replace(/\/$/, '').split('/').pop().split(';'); | ||
title = titleWithParameters[0].toUpperCase(); | ||
if (!title) { | ||
throw new Error(`Cannot determine service title from path: ${path}`); | ||
} | ||
const segParams = titleWithParameters.slice(1); | ||
segParams.forEach((parameter) => { | ||
const [key, value] = parameter.split('='); | ||
if (key === 'v') { | ||
version = parseInt(value, 10); | ||
} | ||
}); | ||
throw new Error(`Cannot determine service title from path: ${path}`); | ||
} | ||
const params = { | ||
$format: 'json', | ||
$filter: `Title eq '${title}' and TechnicalServiceVersion eq ${version}` | ||
}; | ||
const requestPath = this.entitySet ? `/${this.entitySet}` : '/ServiceCollection'; | ||
const response = yield this.get(requestPath, { params }); | ||
const services = response.odata(); | ||
if (services.length > 1) { | ||
// #14793: Fix for user created multi namespaces for the same service | ||
const servicesWithSameNameSpace = services.filter((service) => { var _a; return (_a = service.ServiceUrl) === null || _a === void 0 ? void 0 : _a.toUpperCase().includes((path || title).toUpperCase()); }); | ||
if (servicesWithSameNameSpace.length > 1) { | ||
this.log.warn('Service filter was not sufficient to identify one service.'); | ||
const segParams = titleWithParameters.slice(1); | ||
segParams.forEach((parameter) => { | ||
const [key, value] = parameter.split('='); | ||
if (key === 'v') { | ||
version = parseInt(value, 10); | ||
} | ||
else if (servicesWithSameNameSpace.length > 0) { | ||
this.log.info(`Service filter chose service: ${servicesWithSameNameSpace[0].TechnicalServiceName}`); | ||
return servicesWithSameNameSpace[0]; | ||
} | ||
}); | ||
} | ||
const params = { | ||
$format: 'json', | ||
$filter: `Title eq '${title}' and TechnicalServiceVersion eq ${version}` | ||
}; | ||
const requestPath = this.entitySet ? `/${this.entitySet}` : '/ServiceCollection'; | ||
const response = await this.get(requestPath, { params }); | ||
const services = response.odata(); | ||
if (services.length > 1) { | ||
// #14793: Fix for user created multi namespaces for the same service | ||
const servicesWithSameNameSpace = services.filter((service) => service.ServiceUrl?.toUpperCase().includes((path || title).toUpperCase())); | ||
if (servicesWithSameNameSpace.length > 1) { | ||
this.log.warn('Service filter was not sufficient to identify one service.'); | ||
} | ||
return services.length > 0 ? services[0] : undefined; | ||
}); | ||
else if (servicesWithSameNameSpace.length > 0) { | ||
this.log.info(`Service filter chose service: ${servicesWithSameNameSpace[0].TechnicalServiceName}`); | ||
return servicesWithSameNameSpace[0]; | ||
} | ||
} | ||
return services.length > 0 ? services[0] : undefined; | ||
} | ||
@@ -152,20 +139,18 @@ /** | ||
*/ | ||
getServiceAnnotations({ id, title, path }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!id) { | ||
const ServiceConfig = yield this.findService({ title, path }); | ||
if (ServiceConfig) { | ||
id = ServiceConfig.ID; | ||
} | ||
async getServiceAnnotations({ id, title, path }) { | ||
if (!id) { | ||
const ServiceConfig = await this.findService({ title, path }); | ||
if (ServiceConfig) { | ||
id = ServiceConfig.ID; | ||
} | ||
if (id) { | ||
const response = yield this.get(`/ServiceCollection('${encodeURIComponent(id)}')/Annotations`, { | ||
params: { $format: 'json' } | ||
}); | ||
return response.odata(); | ||
} | ||
else { | ||
return []; | ||
} | ||
}); | ||
} | ||
if (id) { | ||
const response = await this.get(`/ServiceCollection('${encodeURIComponent(id)}')/Annotations`, { | ||
params: { $format: 'json' } | ||
}); | ||
return response.odata(); | ||
} | ||
else { | ||
return []; | ||
} | ||
} | ||
@@ -181,34 +166,48 @@ /** | ||
*/ | ||
getAnnotations({ id, title, path }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!id && !title && !path) { | ||
throw new Error('No filter parameters passed in'); | ||
} | ||
const serviceAnnotations = yield this.getServiceAnnotations({ id, title, path }); | ||
const annotations = []; | ||
for (const service of serviceAnnotations) { | ||
const _path = `/Annotations(TechnicalName='${encodeURIComponent(service.TechnicalName)}',Version='${service.Version}')/$value/`; | ||
const response = yield this.get(_path, { | ||
headers: { | ||
Accept: 'application/xml' | ||
} | ||
async getAnnotations({ id, title, path }) { | ||
if (!id && !title && !path) { | ||
throw new Error('No filter parameters passed in'); | ||
} | ||
const serviceAnnotations = await this.getServiceAnnotations({ id, title, path }); | ||
const annotations = []; | ||
for (const service of serviceAnnotations) { | ||
const _path = `/Annotations(TechnicalName='${encodeURIComponent(service.TechnicalName)}',Version='${service.Version}')/$value/`; | ||
const response = await this.get(_path, { | ||
headers: { | ||
Accept: 'application/xml' | ||
} | ||
}); | ||
if (response.data) { | ||
annotations.push({ | ||
TechnicalName: service.TechnicalName, | ||
Version: service.Version, | ||
Definitions: response.data, | ||
Uri: this.defaults.baseURL + _path | ||
}); | ||
if (response.data) { | ||
annotations.push({ | ||
TechnicalName: service.TechnicalName, | ||
Version: service.Version, | ||
Definitions: response.data, | ||
Uri: this.defaults.baseURL + _path | ||
}); | ||
} | ||
else { | ||
this.log.warn(`No annotations found for TechnicalName=${service.TechnicalName}, Version=${service.Version}`); | ||
} | ||
} | ||
return annotations; | ||
}); | ||
else { | ||
this.log.warn(`No annotations found for TechnicalName=${service.TechnicalName}, Version=${service.Version}`); | ||
} | ||
} | ||
return annotations; | ||
} | ||
/** | ||
* Calls endpoint `ServiceTypeForHUBServices` to determine the service type. | ||
* | ||
* @param path service path | ||
* @returns service type | ||
*/ | ||
async getServiceType(path) { | ||
let serviceType; | ||
const { ID: id } = await this.findService({ path }); | ||
if (id) { | ||
const result = await this.get(`/ServiceTypeForHUBServices('${encodeURIComponent(id)}')`); | ||
if (result) { | ||
serviceType = result.odata().ServiceType; | ||
} | ||
} | ||
return serviceType; | ||
} | ||
} | ||
exports.V2CatalogService = V2CatalogService; | ||
V2CatalogService.PATH = '/sap/opu/odata/IWFND/CATALOGSERVICE;v=2'; | ||
//# sourceMappingURL=v2-catalog-service.js.map |
@@ -1,2 +0,2 @@ | ||
import type { Annotations, ODataServiceInfo } from './base'; | ||
import type { Annotations, ODataServiceInfo, ServiceType } from './base'; | ||
import { CatalogService } from './base'; | ||
@@ -10,2 +10,3 @@ export interface V4Service { | ||
ServiceUrl: string; | ||
ServiceType: ServiceType; | ||
} | ||
@@ -49,3 +50,9 @@ /** | ||
getAnnotations(): Promise<Annotations[]>; | ||
/** | ||
* For OData v4, no additonal call is required to retrieve the service type. | ||
* | ||
* @returns undefined | ||
*/ | ||
getServiceType(): Promise<undefined>; | ||
} | ||
//# sourceMappingURL=v4-catalog-service.d.ts.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -22,2 +13,3 @@ exports.V4CatalogService = void 0; | ||
class V4CatalogService extends base_1.CatalogService { | ||
static PATH = '/sap/opu/odata4/iwfnd/config/default/iwfnd/catalog/0002'; | ||
/** | ||
@@ -33,3 +25,3 @@ * Map the V4 service information to a version independent structure. | ||
groups | ||
.filter((group) => { var _a, _b; return ((_b = (_a = group === null || group === void 0 ? void 0 : group.DefaultSystem) === null || _a === void 0 ? void 0 : _a[entitySet]) === null || _b === void 0 ? void 0 : _b.length) > 0; }) | ||
.filter((group) => group?.DefaultSystem?.[entitySet]?.length > 0) | ||
.forEach((group) => { | ||
@@ -43,3 +35,4 @@ services.push(...group.DefaultSystem[entitySet].map((service) => { | ||
serviceVersion: service.ServiceVersion, | ||
odataVersion: odata_service_1.ODataVersion.v4 | ||
odataVersion: odata_service_1.ODataVersion.v4, | ||
serviceType: service.ServiceType | ||
}; | ||
@@ -55,31 +48,26 @@ })); | ||
*/ | ||
fetchServices() { | ||
const _super = Object.create(null, { | ||
get: { get: () => super.get } | ||
}); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.entitySet === undefined) { | ||
const metadata = yield this.metadata(); | ||
this.entitySet = metadata.includes('Name="RecommendedServices"') | ||
? V4_RECOMMENDED_ENTITYSET | ||
: V4_CLASSIC_ENTITYSET; | ||
} | ||
const params = { | ||
$count: true, | ||
$expand: `DefaultSystem($expand=${this.entitySet})` | ||
}; | ||
let response = yield this.get('/ServiceGroups', { params }); | ||
const serviceGroups = response.odata() || []; | ||
// paging required | ||
while (response.data['@odata.nextLink']) { | ||
const nextLink = new URL(response.data['@odata.nextLink']); | ||
response = yield _super.get.call(this, '/ServiceGroups', { params: Object.assign(Object.assign({}, params), nextLink.searchParams) }); | ||
serviceGroups.push(...response.odata()); | ||
} | ||
// check if the service responded with an odata error | ||
if (odata_request_error_1.ODataRequestError.containsError(serviceGroups)) { | ||
throw new odata_request_error_1.ODataRequestError(serviceGroups); | ||
} | ||
return this.mapServices(serviceGroups, this.entitySet); | ||
}); | ||
async fetchServices() { | ||
if (this.entitySet === undefined) { | ||
const metadata = await this.metadata(); | ||
this.entitySet = metadata.includes('Name="RecommendedServices"') | ||
? V4_RECOMMENDED_ENTITYSET | ||
: V4_CLASSIC_ENTITYSET; | ||
} | ||
const params = { | ||
$count: true, | ||
$expand: `DefaultSystem($expand=${this.entitySet})` | ||
}; | ||
let response = await this.get('/ServiceGroups', { params }); | ||
const serviceGroups = response.odata() || []; | ||
// paging required | ||
while (response.data['@odata.nextLink']) { | ||
const nextLink = new URL(response.data['@odata.nextLink']); | ||
response = await super.get('/ServiceGroups', { params: { ...params, ...nextLink.searchParams } }); | ||
serviceGroups.push(...response.odata()); | ||
} | ||
// check if the service responded with an odata error | ||
if (odata_request_error_1.ODataRequestError.containsError(serviceGroups)) { | ||
throw new odata_request_error_1.ODataRequestError(serviceGroups); | ||
} | ||
return this.mapServices(serviceGroups, this.entitySet); | ||
} | ||
@@ -94,5 +82,12 @@ /** | ||
} | ||
/** | ||
* For OData v4, no additonal call is required to retrieve the service type. | ||
* | ||
* @returns undefined | ||
*/ | ||
getServiceType() { | ||
return Promise.resolve(undefined); | ||
} | ||
} | ||
exports.V4CatalogService = V4CatalogService; | ||
V4CatalogService.PATH = '/sap/opu/odata4/iwfnd/config/default/iwfnd/catalog/0002'; | ||
//# sourceMappingURL=v4-catalog-service.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -44,2 +35,4 @@ exports.LayeredRepositoryService = void 0; | ||
class LayeredRepositoryService extends axios_1.Axios { | ||
static PATH = '/sap/bc/lrep'; | ||
log; | ||
/** | ||
@@ -50,14 +43,12 @@ * Simple request to fetch a CSRF token required for all writing operations. | ||
*/ | ||
getCsrfToken() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
return yield this.get('/actions/getcsrftoken/'); | ||
async getCsrfToken() { | ||
try { | ||
return await this.get('/actions/getcsrftoken/'); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
} | ||
throw error; | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -70,19 +61,17 @@ /** | ||
*/ | ||
mergeAppDescriptorVariant(appDescriptorVariant) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.put('/appdescr_variant_preview/', appDescriptorVariant, { | ||
headers: { | ||
'Content-Type': 'application/zip' | ||
} | ||
}); | ||
return JSON.parse(response.data); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
async mergeAppDescriptorVariant(appDescriptorVariant) { | ||
try { | ||
const response = await this.put('/appdescr_variant_preview/', appDescriptorVariant, { | ||
headers: { | ||
'Content-Type': 'application/zip' | ||
} | ||
throw error; | ||
}); | ||
return JSON.parse(response.data); | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -96,26 +85,23 @@ /** | ||
*/ | ||
isExistingVariant(namespace, layer = 'CUSTOMER_BASE') { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.get(DTA_PATH_SUFFIX, { | ||
params: { | ||
name: getNamespaceAsString(namespace), | ||
layer, | ||
timestamp: Date.now() | ||
} | ||
}); | ||
this.tryLogResponse(response); | ||
return response; | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) { | ||
return error.response; | ||
} | ||
async isExistingVariant(namespace, layer = 'CUSTOMER_BASE') { | ||
try { | ||
const response = await this.get(DTA_PATH_SUFFIX, { | ||
params: { | ||
name: getNamespaceAsString(namespace), | ||
layer, | ||
timestamp: Date.now() | ||
} | ||
throw error; | ||
}); | ||
this.tryLogResponse(response); | ||
return response; | ||
} | ||
catch (error) { | ||
if ((0, odata_request_error_1.isAxiosError)(error)) { | ||
this.tryLogResponse(error.response); | ||
if (error.response?.status === 404) { | ||
return error.response; | ||
} | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -129,33 +115,30 @@ /** | ||
*/ | ||
deploy(archive, config) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const data = isBuffer(archive) ? archive : (0, fs_1.readFileSync)(archive); | ||
const checkResponse = yield this.isExistingVariant(config.namespace); | ||
const params = { | ||
name: getNamespaceAsString(config.namespace), | ||
layer: (_a = config.layer) !== null && _a !== void 0 ? _a : 'CUSTOMER_BASE' | ||
}; | ||
params['package'] = (_b = config.package) !== null && _b !== void 0 ? _b : '$TMP'; | ||
if (params['package'].toUpperCase() !== '$TMP') { | ||
params['changelist'] = config.transport; | ||
} | ||
try { | ||
const response = yield this.request({ | ||
method: checkResponse.status === 200 ? 'PUT' : 'POST', | ||
url: DTA_PATH_SUFFIX, | ||
data, | ||
params, | ||
headers: { | ||
'Content-Type': 'application/octet-stream' | ||
} | ||
}); | ||
this.tryLogResponse(response, 'Deployment successful.'); | ||
return response; | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, log: this.log }); | ||
throw error; | ||
} | ||
}); | ||
async deploy(archive, config) { | ||
const data = isBuffer(archive) ? archive : (0, fs_1.readFileSync)(archive); | ||
const checkResponse = await this.isExistingVariant(config.namespace); | ||
const params = { | ||
name: getNamespaceAsString(config.namespace), | ||
layer: config.layer ?? 'CUSTOMER_BASE' | ||
}; | ||
params['package'] = config.package ?? '$TMP'; | ||
if (params['package'].toUpperCase() !== '$TMP') { | ||
params['changelist'] = config.transport; | ||
} | ||
try { | ||
const response = await this.request({ | ||
method: checkResponse.status === 200 ? 'PUT' : 'POST', | ||
url: DTA_PATH_SUFFIX, | ||
data, | ||
params, | ||
headers: { | ||
'Content-Type': 'application/octet-stream' | ||
} | ||
}); | ||
this.tryLogResponse(response, 'Deployment successful.'); | ||
return response; | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, log: this.log }); | ||
throw error; | ||
} | ||
} | ||
@@ -168,30 +151,27 @@ /** | ||
*/ | ||
undeploy(config) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const checkResponse = yield this.isExistingVariant(config.namespace); | ||
if (checkResponse.status !== 200) { | ||
throw new Error('Undeploy failed because the given project does not exist.'); | ||
async undeploy(config) { | ||
const checkResponse = await this.isExistingVariant(config.namespace); | ||
if (checkResponse.status !== 200) { | ||
throw new Error('Undeploy failed because the given project does not exist.'); | ||
} | ||
const params = { | ||
name: getNamespaceAsString(config.namespace), | ||
layer: config.layer ?? 'CUSTOMER_BASE' | ||
}; | ||
if (config.transport) { | ||
params['changelist'] = config.transport; | ||
} | ||
try { | ||
const response = await this.delete(DTA_PATH_SUFFIX, { params }); | ||
this.tryLogResponse(response, 'Undeployment successful.'); | ||
return response; | ||
} | ||
catch (error) { | ||
this.log.error('Undeployment failed'); | ||
this.log.debug(error); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && error.response?.status === 405) { | ||
this.log.error('Newer version of SAP_UI required, please check https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/delete-adaptation-project'); | ||
} | ||
const params = { | ||
name: getNamespaceAsString(config.namespace), | ||
layer: (_a = config.layer) !== null && _a !== void 0 ? _a : 'CUSTOMER_BASE' | ||
}; | ||
if (config.transport) { | ||
params['changelist'] = config.transport; | ||
} | ||
try { | ||
const response = yield this.delete(DTA_PATH_SUFFIX, { params }); | ||
this.tryLogResponse(response, 'Undeployment successful.'); | ||
return response; | ||
} | ||
catch (error) { | ||
this.log.error('Undeployment failed'); | ||
this.log.debug(error); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && ((_b = error.response) === null || _b === void 0 ? void 0 : _b.status) === 405) { | ||
this.log.error('Newer version of SAP_UI required, please check https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/delete-adaptation-project'); | ||
} | ||
throw error; | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -205,3 +185,2 @@ /** | ||
tryLogResponse(response, alternativeMessage) { | ||
var _a; | ||
try { | ||
@@ -212,3 +191,3 @@ const info = response.data ? JSON.parse(response.data) : {}; | ||
} | ||
((_a = info.messages) !== null && _a !== void 0 ? _a : []).forEach((message) => { | ||
(info.messages ?? []).forEach((message) => { | ||
this.logMessage(message); | ||
@@ -230,6 +209,5 @@ }); | ||
logMessage(msg) { | ||
var _a; | ||
const level = msg.severity === 'Error' ? logger_1.LogLevel.Error : logger_1.LogLevel.Info; | ||
this.log.log({ level, message: msg.text }); | ||
((_a = msg.details) !== null && _a !== void 0 ? _a : []).forEach((message) => { | ||
(msg.details ?? []).forEach((message) => { | ||
this.log.log({ level, message }); | ||
@@ -240,3 +218,2 @@ }); | ||
exports.LayeredRepositoryService = LayeredRepositoryService; | ||
LayeredRepositoryService.PATH = '/sap/bc/lrep'; | ||
//# sourceMappingURL=lrep-service.js.map |
@@ -87,8 +87,7 @@ "use strict"; | ||
function prettyPrintError({ error, log, host, isDest }, showAllMessages = true) { | ||
var _a, _b, _c; | ||
if (error) { | ||
if (showAllMessages) { | ||
log.error(((_a = error.message) === null || _a === void 0 ? void 0 : _a.value) || 'An unknown error occurred.'); | ||
log.error(error.message?.value || 'An unknown error occurred.'); | ||
} | ||
(((_b = error.innererror) === null || _b === void 0 ? void 0 : _b.errordetails) || []).forEach((entry) => { | ||
(error.innererror?.errordetails || []).forEach((entry) => { | ||
if (!entry.message.startsWith('<![CDATA')) { | ||
@@ -99,3 +98,3 @@ logLevel(entry.severity, entry.message, log, true); | ||
}); | ||
if (showAllMessages && ((_c = error.innererror) === null || _c === void 0 ? void 0 : _c.Error_Resolution)) { | ||
if (showAllMessages && error.innererror?.Error_Resolution) { | ||
for (const key in error.innererror.Error_Resolution) { | ||
@@ -137,6 +136,5 @@ log.error(`${key}: ${error.innererror.Error_Resolution[key]}`); | ||
function logError({ error, host, log, isDest }) { | ||
var _a, _b; | ||
log.error(error.message); | ||
if ((0, axios_1.isAxiosError)(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data)) { | ||
const errorMessage = getErrorMessageFromString((_b = error.response) === null || _b === void 0 ? void 0 : _b.data); | ||
if ((0, axios_1.isAxiosError)(error) && error.response?.data) { | ||
const errorMessage = getErrorMessageFromString(error.response?.data); | ||
if (errorMessage) { | ||
@@ -166,3 +164,3 @@ prettyPrintError({ error: errorMessage, log: log, host: host, isDest: isDest }); | ||
} | ||
catch (_a) { | ||
catch { | ||
// Not much we can do! | ||
@@ -169,0 +167,0 @@ } |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -42,2 +33,5 @@ exports.Ui5AbapRepositoryService = exports.abapUrlReplaceMap = void 0; | ||
class Ui5AbapRepositoryService extends odata_service_1.ODataService { | ||
static PATH = '/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV'; | ||
publicUrl; | ||
isDest; | ||
/** | ||
@@ -49,7 +43,6 @@ * Extension of the base constructor to set preferred response format if not provided by caller. | ||
constructor(config) { | ||
var _a, _b; | ||
config = config !== null && config !== void 0 ? config : {}; | ||
config.headers = (_a = config.headers) !== null && _a !== void 0 ? _a : {}; | ||
config = config ?? {}; | ||
config.headers = config.headers ?? {}; | ||
// @see https://axios-http.com/docs/config_defaults | ||
config.headers['Accept'] = (_b = config.headers['Accept']) !== null && _b !== void 0 ? _b : 'application/json,application/xml,text/plain,*/*'; | ||
config.headers['Accept'] = config.headers['Accept'] ?? 'application/json,application/xml,text/plain,*/*'; | ||
super(config); | ||
@@ -65,17 +58,14 @@ this.publicUrl = config.publicUrl || this.defaults.baseURL; | ||
*/ | ||
getInfo(app) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.get(`/Repositories('${encodeURIComponent(app)}')`); | ||
return response.odata(); | ||
async getInfo(app) { | ||
try { | ||
const response = await this.get(`/Repositories('${encodeURIComponent(app)}')`); | ||
return response.odata(); | ||
} | ||
catch (error) { | ||
this.log.debug(`Retrieving application ${app} from ${Ui5AbapRepositoryService.PATH}, ${error}`); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && error.response?.status === 404) { | ||
return undefined; | ||
} | ||
catch (error) { | ||
this.log.debug(`Retrieving application ${app} from ${Ui5AbapRepositoryService.PATH}, ${error}`); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) { | ||
return undefined; | ||
} | ||
throw error; | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -88,23 +78,20 @@ /** | ||
*/ | ||
downloadFiles(app) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.get(`/Repositories('${encodeURIComponent(app)}')`, { | ||
params: { | ||
CodePage: 'UTF8', | ||
DownloadFiles: 'RUNTIME' | ||
} | ||
}); | ||
const data = response.odata(); | ||
return data.ZipArchive ? Buffer.from(data.ZipArchive) : undefined; | ||
} | ||
catch (error) { | ||
this.log.debug(`Retrieving application ${app}, ${error}`); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) { | ||
return undefined; | ||
async downloadFiles(app) { | ||
try { | ||
const response = await this.get(`/Repositories('${encodeURIComponent(app)}')`, { | ||
params: { | ||
CodePage: 'UTF8', | ||
DownloadFiles: 'RUNTIME' | ||
} | ||
throw error; | ||
}); | ||
const data = response.odata(); | ||
return data.ZipArchive ? Buffer.from(data.ZipArchive) : undefined; | ||
} | ||
catch (error) { | ||
this.log.debug(`Retrieving application ${app}, ${error}`); | ||
if ((0, odata_request_error_1.isAxiosError)(error) && error.response?.status === 404) { | ||
return undefined; | ||
} | ||
}); | ||
throw error; | ||
} | ||
} | ||
@@ -121,45 +108,42 @@ /** | ||
*/ | ||
deploy({ archive, bsp, testMode = false, safeMode }) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const info = yield this.getInfo(bsp.name); | ||
const payload = this.createPayload(archive, bsp.name, bsp.description || 'Deployed with SAP Fiori tools', info ? info.Package : bsp.package); | ||
this.log.debug(`Payload:\n ID: ${this.publicUrl}/Repositories('${bsp.name}') \n ABAP Package: ${info ? info.Package : bsp.package}`); | ||
const config = this.createConfig(bsp.transport, testMode, safeMode); | ||
const frontendUrl = this.getAbapFrontendUrl(); | ||
try { | ||
const response = yield this.updateRepoRequest(!!info, bsp.name, payload, config); | ||
// An app can be successfully deployed after a timeout exception, no value in showing exception headers | ||
if ((_a = response === null || response === void 0 ? void 0 : response.headers) === null || _a === void 0 ? void 0 : _a['sap-message']) { | ||
(0, message_1.prettyPrintMessage)({ | ||
msg: response.headers['sap-message'], | ||
log: this.log, | ||
host: frontendUrl, | ||
isDest: this.isDest | ||
}); | ||
} | ||
if (!testMode) { | ||
// log url of created/updated app | ||
const path = '/sap/bc/ui5_ui5' + (!bsp.name.startsWith('/') ? '/sap/' : '') + bsp.name.toLowerCase(); | ||
const query = ((_b = this.defaults.params) === null || _b === void 0 ? void 0 : _b['sap-client']) | ||
? '?sap-client=' + this.defaults.params['sap-client'] | ||
: ''; | ||
this.log.info(`App available at ${frontendUrl}${path}${query}`); | ||
} | ||
else { | ||
// Test mode returns a HTTP response code of 403 so we dont want to show all error messages | ||
(0, message_1.prettyPrintError)({ | ||
error: (0, message_1.getErrorMessageFromString)(response === null || response === void 0 ? void 0 : response.data), | ||
log: this.log, | ||
host: frontendUrl, | ||
isDest: this.isDest | ||
}, false); | ||
} | ||
return response; | ||
async deploy({ archive, bsp, testMode = false, safeMode }) { | ||
const info = await this.getInfo(bsp.name); | ||
const payload = this.createPayload(archive, bsp.name, bsp.description || 'Deployed with SAP Fiori tools', info ? info.Package : bsp.package); | ||
this.log.debug(`Payload:\n ID: ${this.publicUrl}/Repositories('${bsp.name}') \n ABAP Package: ${info ? info.Package : bsp.package}`); | ||
const config = this.createConfig(bsp.transport, testMode, safeMode); | ||
const frontendUrl = this.getAbapFrontendUrl(); | ||
try { | ||
const response = await this.updateRepoRequest(!!info, bsp.name, payload, config); | ||
// An app can be successfully deployed after a timeout exception, no value in showing exception headers | ||
if (response?.headers?.['sap-message']) { | ||
(0, message_1.prettyPrintMessage)({ | ||
msg: response.headers['sap-message'], | ||
log: this.log, | ||
host: frontendUrl, | ||
isDest: this.isDest | ||
}); | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, host: frontendUrl, log: this.log, isDest: this.isDest }); | ||
throw error; | ||
if (!testMode) { | ||
// log url of created/updated app | ||
const path = '/sap/bc/ui5_ui5' + (!bsp.name.startsWith('/') ? '/sap/' : '') + bsp.name.toLowerCase(); | ||
const query = this.defaults.params?.['sap-client'] | ||
? '?sap-client=' + this.defaults.params['sap-client'] | ||
: ''; | ||
this.log.info(`App available at ${frontendUrl}${path}${query}`); | ||
} | ||
}); | ||
else { | ||
// Test mode returns a HTTP response code of 403 so we dont want to show all error messages | ||
(0, message_1.prettyPrintError)({ | ||
error: (0, message_1.getErrorMessageFromString)(response?.data), | ||
log: this.log, | ||
host: frontendUrl, | ||
isDest: this.isDest | ||
}, false); | ||
} | ||
return response; | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, host: frontendUrl, log: this.log, isDest: this.isDest }); | ||
throw error; | ||
} | ||
} | ||
@@ -174,31 +158,28 @@ /** | ||
*/ | ||
undeploy({ bsp, testMode = false }) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const config = this.createConfig(bsp.transport, testMode); | ||
const host = this.getAbapFrontendUrl(); | ||
const info = yield this.getInfo(bsp.name); | ||
try { | ||
if (info) { | ||
const response = yield this.deleteRepoRequest(bsp.name, config); | ||
if ((_a = response === null || response === void 0 ? void 0 : response.headers) === null || _a === void 0 ? void 0 : _a['sap-message']) { | ||
(0, message_1.prettyPrintMessage)({ | ||
msg: response.headers['sap-message'], | ||
log: this.log, | ||
host, | ||
isDest: this.isDest | ||
}); | ||
} | ||
return response; | ||
async undeploy({ bsp, testMode = false }) { | ||
const config = this.createConfig(bsp.transport, testMode); | ||
const host = this.getAbapFrontendUrl(); | ||
const info = await this.getInfo(bsp.name); | ||
try { | ||
if (info) { | ||
const response = await this.deleteRepoRequest(bsp.name, config); | ||
if (response?.headers?.['sap-message']) { | ||
(0, message_1.prettyPrintMessage)({ | ||
msg: response.headers['sap-message'], | ||
log: this.log, | ||
host, | ||
isDest: this.isDest | ||
}); | ||
} | ||
else { | ||
this.log.warn(`Application ${bsp.name} not found, nothing to undeploy.`); | ||
return undefined; | ||
} | ||
return response; | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, host, log: this.log }); | ||
throw error; | ||
else { | ||
this.log.warn(`Application ${bsp.name} not found, nothing to undeploy.`); | ||
return undefined; | ||
} | ||
}); | ||
} | ||
catch (error) { | ||
(0, message_1.logError)({ error, host, log: this.log }); | ||
throw error; | ||
} | ||
} | ||
@@ -279,3 +260,3 @@ /** | ||
` <d:Name>${escapedName}</d:Name>` + | ||
` <d:Package>${abapPackage === null || abapPackage === void 0 ? void 0 : abapPackage.toUpperCase()}</d:Package>` + | ||
` <d:Package>${abapPackage?.toUpperCase()}</d:Package>` + | ||
` <d:Description>${encodeXmlValue(description)}</d:Description>` + | ||
@@ -298,41 +279,38 @@ ` <d:ZipArchive>${base64Data}</d:ZipArchive>` + | ||
*/ | ||
updateRepoRequest(isExisting, appName, payload, config, tryCount = 1) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
// Was the app deployed after the first failed attempt? | ||
if (tryCount === 2) { | ||
this.log.warn('Warning: The application was deployed despite a time out response from the backend. Increasing the value of the HTML5.Timeout property for the destination may solve the issue'); | ||
} | ||
// If its already deployed, then dont try to create it again | ||
if (tryCount !== 1 && !isExisting && (yield this.getInfo(appName)) !== undefined) { | ||
// We've nothing to return as we dont want to show the exception to the user! | ||
return Promise.resolve(undefined); | ||
} | ||
else { | ||
this.log.info(`${appName} found on target system: ${isExisting}`); | ||
const response = isExisting | ||
? yield this.put(`/Repositories('${encodeURIComponent(appName)}')`, payload, config) | ||
: yield this.post('/Repositories', payload, config); | ||
return response; | ||
} | ||
async updateRepoRequest(isExisting, appName, payload, config, tryCount = 1) { | ||
try { | ||
// Was the app deployed after the first failed attempt? | ||
if (tryCount === 2) { | ||
this.log.warn('Warning: The application was deployed despite a time out response from the backend. Increasing the value of the HTML5.Timeout property for the destination may solve the issue'); | ||
} | ||
catch (error) { | ||
// Known ABAP timeout exception codes should re-trigger a deployment again to confirm the app was deployed | ||
if ([504, 408].includes((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status)) { | ||
// Kill the flow after three attempts | ||
if (tryCount >= 3) { | ||
throw error; | ||
} | ||
return this.updateRepoRequest(isExisting, appName, payload, config, tryCount + 1); | ||
} | ||
else if ((_b = config === null || config === void 0 ? void 0 : config.params) === null || _b === void 0 ? void 0 : _b.TestMode) { | ||
// TestMode returns HTTP 403 but includes details of the uploaded files and request | ||
return error.response; | ||
} | ||
else { | ||
// If its already deployed, then dont try to create it again | ||
if (tryCount !== 1 && !isExisting && (await this.getInfo(appName)) !== undefined) { | ||
// We've nothing to return as we dont want to show the exception to the user! | ||
return Promise.resolve(undefined); | ||
} | ||
else { | ||
this.log.info(`${appName} found on target system: ${isExisting}`); | ||
const response = isExisting | ||
? await this.put(`/Repositories('${encodeURIComponent(appName)}')`, payload, config) | ||
: await this.post('/Repositories', payload, config); | ||
return response; | ||
} | ||
} | ||
catch (error) { | ||
// Known ABAP timeout exception codes should re-trigger a deployment again to confirm the app was deployed | ||
if ([504, 408].includes(error?.response?.status)) { | ||
// Kill the flow after three attempts | ||
if (tryCount >= 3) { | ||
throw error; | ||
} | ||
return this.updateRepoRequest(isExisting, appName, payload, config, tryCount + 1); | ||
} | ||
}); | ||
else if (config?.params?.TestMode) { | ||
// TestMode returns HTTP 403 but includes details of the uploaded files and request | ||
return error.response; | ||
} | ||
else { | ||
throw error; | ||
} | ||
} | ||
} | ||
@@ -347,28 +325,24 @@ /** | ||
*/ | ||
deleteRepoRequest(appName, config, tryCount = 1) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
if (tryCount === 2) { | ||
this.log.warn('Warning: retry undeploy to handle a backend rejection...'); | ||
} | ||
return yield this.delete(`/Repositories('${encodeURIComponent(appName)}')`, config); | ||
async deleteRepoRequest(appName, config, tryCount = 1) { | ||
try { | ||
if (tryCount === 2) { | ||
this.log.warn('Warning: retry undeploy to handle a backend rejection...'); | ||
} | ||
catch (error) { | ||
if (((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) === 400) { | ||
// Kill the flow after 1 attempt | ||
if (tryCount >= 2) { | ||
throw error; | ||
} | ||
return this.deleteRepoRequest(appName, config, tryCount + 1); | ||
} | ||
else { | ||
return await this.delete(`/Repositories('${encodeURIComponent(appName)}')`, config); | ||
} | ||
catch (error) { | ||
if (error?.response?.status === 400) { | ||
// Kill the flow after 1 attempt | ||
if (tryCount >= 2) { | ||
throw error; | ||
} | ||
return this.deleteRepoRequest(appName, config, tryCount + 1); | ||
} | ||
}); | ||
else { | ||
throw error; | ||
} | ||
} | ||
} | ||
} | ||
exports.Ui5AbapRepositoryService = Ui5AbapRepositoryService; | ||
Ui5AbapRepositoryService.PATH = '/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV'; | ||
//# sourceMappingURL=ui5-abap-repository-service.js.map |
@@ -21,5 +21,3 @@ "use strict"; | ||
class Cookies { | ||
constructor() { | ||
this.cookies = {}; | ||
} | ||
cookies = {}; | ||
/** | ||
@@ -32,4 +30,3 @@ * Update the cookies based on 'set-cookie' headers of a response. | ||
setCookies(response) { | ||
var _a; | ||
if ((_a = response.headers) === null || _a === void 0 ? void 0 : _a['set-cookie']) { | ||
if (response.headers?.['set-cookie']) { | ||
response.headers['set-cookie'].forEach((cookieString) => this.addCookie(cookieString)); | ||
@@ -46,6 +43,5 @@ } | ||
addCookie(cookieString) { | ||
var _a; | ||
const cookie = cookieString.split(';'); | ||
const [key, ...values] = ((_a = cookie[0]) === null || _a === void 0 ? void 0 : _a.split('=')) || []; | ||
const value = values === null || values === void 0 ? void 0 : values.join('='); // Account for embedded '=' in the value | ||
const [key, ...values] = cookie[0]?.split('=') || []; | ||
const value = values?.join('='); // Account for embedded '=' in the value | ||
if (key && cookieString.indexOf('Max-Age=0') >= 0) { | ||
@@ -80,3 +76,3 @@ delete this.cookies[key]; | ||
function isSamlLogonNeeded(response) { | ||
return ((response === null || response === void 0 ? void 0 : response.status) === 200 && | ||
return (response?.status === 200 && | ||
isHtmlResponse(response) && | ||
@@ -93,3 +89,3 @@ typeof response.data === 'string' && | ||
function throwIfHtmlLoginForm(response) { | ||
if ((response === null || response === void 0 ? void 0 : response.status) !== 200) { | ||
if (response?.status !== 200) { | ||
return; | ||
@@ -127,3 +123,2 @@ } | ||
function getContentType(contentTypeHeader, responseData) { | ||
var _a, _b; | ||
if (contentTypeHeader) { | ||
@@ -134,3 +129,3 @@ return contentTypeHeader.toLowerCase(); | ||
// Try to infer it from the data | ||
return (_b = (_a = (0, detect_content_type_1.default)(Buffer.from(responseData))) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : ''; | ||
return (0, detect_content_type_1.default)(Buffer.from(responseData))?.toLowerCase() ?? ''; | ||
} | ||
@@ -149,4 +144,3 @@ else { | ||
const oneTimeReqInterceptorId = provider.interceptors.request.use((request) => { | ||
var _a; | ||
request.headers = (_a = request.headers) !== null && _a !== void 0 ? _a : new axios_1.AxiosHeaders(); | ||
request.headers = request.headers ?? new axios_1.AxiosHeaders(); | ||
request.headers[CSRF.RequestHeaderName] = CSRF.RequestHeaderValue; | ||
@@ -157,6 +151,5 @@ return request; | ||
const oneTimeRespInterceptorId = provider.interceptors.response.use((response) => { | ||
var _a, _b, _c; | ||
// if a redirect to a SAML login page happened try again with disable saml param | ||
if (isSamlLogonNeeded(response) && ((_a = provider.defaults.params) === null || _a === void 0 ? void 0 : _a.saml2) !== 'disabled') { | ||
provider.defaults.params = (_b = provider.defaults.params) !== null && _b !== void 0 ? _b : {}; | ||
if (isSamlLogonNeeded(response) && provider.defaults.params?.saml2 !== 'disabled') { | ||
provider.defaults.params = provider.defaults.params ?? {}; | ||
provider.defaults.params.saml2 = 'disabled'; | ||
@@ -168,3 +161,3 @@ return provider.request(response.config); | ||
// remember xsrf token | ||
if ((_c = response.headers) === null || _c === void 0 ? void 0 : _c[CSRF.ResponseHeaderName]) { | ||
if (response.headers?.[CSRF.ResponseHeaderName]) { | ||
provider.defaults.headers.common[CSRF.RequestHeaderName] = | ||
@@ -178,6 +171,5 @@ response.headers[CSRF.ResponseHeaderName]; | ||
}, (error) => { | ||
var _a; | ||
// remember xsrf token if provided even on error | ||
if (error.response) { | ||
if ((_a = error.response.headers) === null || _a === void 0 ? void 0 : _a[CSRF.ResponseHeaderName]) { | ||
if (error.response.headers?.[CSRF.ResponseHeaderName]) { | ||
provider.defaults.headers.common[CSRF.RequestHeaderName] = | ||
@@ -193,4 +185,3 @@ error.response.headers[CSRF.ResponseHeaderName]; | ||
provider.interceptors.request.use((request) => { | ||
var _a; | ||
request.headers = (_a = request.headers) !== null && _a !== void 0 ? _a : new axios_1.AxiosHeaders(); | ||
request.headers = request.headers ?? new axios_1.AxiosHeaders(); | ||
request.headers.cookie = provider.cookies.toString(); | ||
@@ -197,0 +188,0 @@ return request; |
@@ -6,2 +6,3 @@ "use strict"; | ||
class BaseError extends Error { | ||
cause; | ||
/** | ||
@@ -8,0 +9,0 @@ * Constructor taking a message and any object. |
@@ -16,11 +16,2 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -54,21 +45,19 @@ exports.getReentranceTicketAuthInterceptor = exports.attachReentranceTicketAuthInterceptor = exports.attachUaaAuthInterceptor = exports.attachBasicAuthInterceptor = exports.Uaa = void 0; | ||
let token; | ||
const getToken = () => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
return ((_a = service.uaa) === null || _a === void 0 ? void 0 : _a.username) | ||
? yield uaa.getAccessTokenWithClientCredentials() | ||
: yield uaa.getAccessToken(refreshToken, refreshTokenUpdateCb); | ||
}); | ||
const getToken = async () => { | ||
return service.uaa?.username | ||
? await uaa.getAccessTokenWithClientCredentials() | ||
: await uaa.getAccessToken(refreshToken, refreshTokenUpdateCb); | ||
}; | ||
// provide function to fetch user info from UAA if needed | ||
provider.user = () => __awaiter(this, void 0, void 0, function* () { | ||
token = token !== null && token !== void 0 ? token : (yield getToken()); | ||
provider.user = async () => { | ||
token = token ?? (await getToken()); | ||
return uaa.getUserInfo(token); | ||
}); | ||
provider.interceptors.request.use((request) => __awaiter(this, void 0, void 0, function* () { | ||
var _b; | ||
token = token !== null && token !== void 0 ? token : (yield getToken()); | ||
}; | ||
provider.interceptors.request.use(async (request) => { | ||
token = token ?? (await getToken()); | ||
// add token as auth header | ||
request.headers = (_b = request.headers) !== null && _b !== void 0 ? _b : new axios_1.AxiosHeaders(); | ||
request.headers = request.headers ?? new axios_1.AxiosHeaders(); | ||
request.headers.authorization = `bearer ${token}`; | ||
return request; | ||
})); | ||
}); | ||
} | ||
@@ -99,5 +88,4 @@ exports.attachUaaAuthInterceptor = attachUaaAuthInterceptor; | ||
function getReentranceTicketAuthInterceptor({ provider, ejectCallback }) { | ||
return (request) => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
const { reentranceTicket, apiUrl } = yield (0, reentrance_ticket_1.getReentranceTicket)({ | ||
return async (request) => { | ||
const { reentranceTicket, apiUrl } = await (0, reentrance_ticket_1.getReentranceTicket)({ | ||
backendUrl: provider.defaults.baseURL, | ||
@@ -112,3 +100,3 @@ logger: provider.log | ||
} | ||
request.headers = (_a = request.headers) !== null && _a !== void 0 ? _a : new axios_1.AxiosHeaders(); | ||
request.headers = request.headers ?? new axios_1.AxiosHeaders(); | ||
request.headers.MYSAPSSO2 = reentranceTicket; | ||
@@ -118,5 +106,5 @@ // remove this interceptor since it is not needed anymore | ||
return request; | ||
}); | ||
}; | ||
} | ||
exports.getReentranceTicketAuthInterceptor = getReentranceTicketAuthInterceptor; | ||
//# sourceMappingURL=index.js.map |
@@ -8,2 +8,4 @@ "use strict"; | ||
class Redirect { | ||
static path = '/oauth/client/redirect'; | ||
port; | ||
/** | ||
@@ -27,3 +29,2 @@ * Constructor with a port number. | ||
exports.Redirect = Redirect; | ||
Redirect.path = '/oauth/client/redirect'; | ||
//# sourceMappingURL=redirect.js.map |
@@ -8,2 +8,5 @@ "use strict"; | ||
class ABAPSystem { | ||
apiURL; | ||
uiURL; | ||
systemURL; | ||
/** | ||
@@ -10,0 +13,0 @@ * |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -30,16 +21,13 @@ exports.getReentranceTicket = void 0; | ||
*/ | ||
function getReentranceTicket({ backendUrl, logger, timeout = connection_1.defaultTimeout }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
var _a, _b; | ||
const backend = new abap_system_1.ABAPSystem(backendUrl); | ||
// Start local server to listen to redirect call, with timeout | ||
const { server, redirectUrl } = (0, redirect_1.setupRedirectHandling)({ resolve, reject, timeout, backend, logger }); | ||
server.listen(); | ||
const redirectPort = server.address().port; | ||
// Open browser to handle SAML flow and return the reentrance ticket | ||
const scenario = (_a = process.env.FIORI_TOOLS_SCENARIO) !== null && _a !== void 0 ? _a : 'FTO1'; | ||
const url = `${backend.uiHostname()}${ADT_REENTRANCE_ENDPOINT}?scenario=${scenario}&redirect-url=${redirectUrl(redirectPort)}`; | ||
(_b = open(url)) === null || _b === void 0 ? void 0 : _b.catch((error) => logger.error(error)); | ||
}); | ||
async function getReentranceTicket({ backendUrl, logger, timeout = connection_1.defaultTimeout }) { | ||
return new Promise((resolve, reject) => { | ||
const backend = new abap_system_1.ABAPSystem(backendUrl); | ||
// Start local server to listen to redirect call, with timeout | ||
const { server, redirectUrl } = (0, redirect_1.setupRedirectHandling)({ resolve, reject, timeout, backend, logger }); | ||
server.listen(); | ||
const redirectPort = server.address().port; | ||
// Open browser to handle SAML flow and return the reentrance ticket | ||
const scenario = process.env.FIORI_TOOLS_SCENARIO ?? 'FTO1'; | ||
const url = `${backend.uiHostname()}${ADT_REENTRANCE_ENDPOINT}?scenario=${scenario}&redirect-url=${redirectUrl(redirectPort)}`; | ||
open(url)?.catch((error) => logger.error(error)); | ||
}); | ||
@@ -46,0 +34,0 @@ } |
@@ -26,3 +26,3 @@ "use strict"; | ||
const handleTimeout = () => { | ||
server === null || server === void 0 ? void 0 : server.close(); | ||
server?.close(); | ||
reject(new error_1.TimeoutError(`Timeout. Did not get a response within ${(0, message_1.prettyPrintTimeInMs)(timeout)}`)); | ||
@@ -32,3 +32,2 @@ }; | ||
server = http_1.default.createServer((req, res) => { | ||
var _a; | ||
const reqUrl = new URL(req.url, `http://${req.headers.host}`); | ||
@@ -39,3 +38,3 @@ if (reqUrl.pathname === REDIRECT_PATH) { | ||
} | ||
const reentranceTicket = (_a = reqUrl.searchParams.get('reentrance-ticket')) === null || _a === void 0 ? void 0 : _a.toString(); | ||
const reentranceTicket = reqUrl.searchParams.get('reentrance-ticket')?.toString(); | ||
if (reentranceTicket) { | ||
@@ -42,0 +41,0 @@ logger.debug('Got reentrance ticket: ' + reentranceTicket); |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -29,2 +20,4 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
class Uaa { | ||
log; | ||
serviceInfo; | ||
/** | ||
@@ -196,14 +189,11 @@ * @param serviceInfo service Information | ||
*/ | ||
getUserInfo(accessToken) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const userInfoResp = yield axios_1.default.request({ | ||
url: `${this.url}/userinfo`, | ||
method: 'GET', | ||
headers: { | ||
authorization: `bearer ${accessToken}` | ||
} | ||
}); | ||
return ((_a = userInfoResp === null || userInfoResp === void 0 ? void 0 : userInfoResp.data) === null || _a === void 0 ? void 0 : _a.email) || ((_b = userInfoResp === null || userInfoResp === void 0 ? void 0 : userInfoResp.data) === null || _b === void 0 ? void 0 : _b.name); | ||
async getUserInfo(accessToken) { | ||
const userInfoResp = await axios_1.default.request({ | ||
url: `${this.url}/userinfo`, | ||
method: 'GET', | ||
headers: { | ||
authorization: `bearer ${accessToken}` | ||
} | ||
}); | ||
return userInfoResp?.data?.email || userInfoResp?.data?.name; | ||
} | ||
@@ -216,34 +206,31 @@ /** | ||
*/ | ||
getAuthCode(timeout = connection_1.defaultTimeout) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
var _a; | ||
// eslint-disable-next-line prefer-const | ||
let redirect; | ||
// eslint-disable-next-line prefer-const | ||
let server; | ||
const handleTimeout = () => { | ||
server === null || server === void 0 ? void 0 : server.close(); | ||
reject(new error_1.UAATimeoutError(`Timeout. Did not get a response within ${(0, message_1.prettyPrintTimeInMs)(timeout)}`)); | ||
}; | ||
const timer = setTimeout(handleTimeout, timeout); | ||
server = http_1.default.createServer((req, res) => { | ||
const reqUrl = new URL(req.url, `http://${req.headers.host}`); | ||
if (reqUrl.pathname === redirect_1.Redirect.path) { | ||
res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
res.end(Buffer.from((0, static_1.redirectSuccessHtml)(this.logoutUrl, this.systemId))); | ||
this.log.info('Got authCode'); | ||
resolve({ authCode: reqUrl.searchParams.get('code') + '', redirect }); | ||
if (timer) { | ||
clearTimeout(timer); | ||
} | ||
server.close(); | ||
async getAuthCode(timeout = connection_1.defaultTimeout) { | ||
return new Promise((resolve, reject) => { | ||
// eslint-disable-next-line prefer-const | ||
let redirect; | ||
// eslint-disable-next-line prefer-const | ||
let server; | ||
const handleTimeout = () => { | ||
server?.close(); | ||
reject(new error_1.UAATimeoutError(`Timeout. Did not get a response within ${(0, message_1.prettyPrintTimeInMs)(timeout)}`)); | ||
}; | ||
const timer = setTimeout(handleTimeout, timeout); | ||
server = http_1.default.createServer((req, res) => { | ||
const reqUrl = new URL(req.url, `http://${req.headers.host}`); | ||
if (reqUrl.pathname === redirect_1.Redirect.path) { | ||
res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
res.end(Buffer.from((0, static_1.redirectSuccessHtml)(this.logoutUrl, this.systemId))); | ||
this.log.info('Got authCode'); | ||
resolve({ authCode: reqUrl.searchParams.get('code') + '', redirect }); | ||
if (timer) { | ||
clearTimeout(timer); | ||
} | ||
}); | ||
// Start listening. Let the OS assign an available port | ||
server.listen(); | ||
redirect = new redirect_1.Redirect(server.address().port); | ||
const oauthUrl = this.getAuthCodeUrl({ redirectUri: redirect.url() }); | ||
(_a = open(oauthUrl)) === null || _a === void 0 ? void 0 : _a.catch((error) => this.log.error(error)); | ||
server.close(); | ||
} | ||
}); | ||
// Start listening. Let the OS assign an available port | ||
server.listen(); | ||
redirect = new redirect_1.Redirect(server.address().port); | ||
const oauthUrl = this.getAuthCodeUrl({ redirectUri: redirect.url() }); | ||
open(oauthUrl)?.catch((error) => this.log.error(error)); | ||
}); | ||
@@ -256,44 +243,41 @@ } | ||
*/ | ||
getAccessToken(refreshToken, refreshTokenChangedCb) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let response; | ||
let startFreshLogin = false; | ||
let newRefreshToken; | ||
if (refreshToken) { | ||
this.log.info('Refresh token passed in'); | ||
const tokenRequest = this.getTokenRequestForRefreshToken(refreshToken); | ||
try { | ||
response = yield axios_1.default.request(tokenRequest); | ||
// Has refresh token expired? | ||
if (response.status === 401 || response.data.error === 'invalid_token') { | ||
startFreshLogin = true; | ||
this.log.warn('Cannot use stored refresh token. Starting fresh request'); | ||
} | ||
else if (refreshToken !== response.data.refresh_token) { | ||
this.log.info('New refresh token issued'); | ||
newRefreshToken = response.data.refresh_token; | ||
} | ||
} | ||
catch (e) { | ||
async getAccessToken(refreshToken, refreshTokenChangedCb) { | ||
let response; | ||
let startFreshLogin = false; | ||
let newRefreshToken; | ||
if (refreshToken) { | ||
this.log.info('Refresh token passed in'); | ||
const tokenRequest = this.getTokenRequestForRefreshToken(refreshToken); | ||
try { | ||
response = await axios_1.default.request(tokenRequest); | ||
// Has refresh token expired? | ||
if (response.status === 401 || response.data.error === 'invalid_token') { | ||
startFreshLogin = true; | ||
this.log.warn('Cannot use stored refresh token. Starting fresh request'); | ||
} | ||
else if (refreshToken !== response.data.refresh_token) { | ||
this.log.info('New refresh token issued'); | ||
newRefreshToken = response.data.refresh_token; | ||
} | ||
} | ||
if (!refreshToken || startFreshLogin) { | ||
const { authCode, redirect } = yield this.getAuthCode(); | ||
const tokenRequest = this.getTokenRequestForAuthCode({ | ||
redirectUri: redirect.url(), // Redirection URL needs to match | ||
authCode | ||
}); | ||
response = yield axios_1.default.request(tokenRequest); | ||
this.log.info('Refresh token issued'); | ||
newRefreshToken = response.data.refresh_token; | ||
catch (e) { | ||
startFreshLogin = true; | ||
} | ||
if (refreshTokenChangedCb) { | ||
this.log.info('Sending notification that refresh token changed'); | ||
yield refreshTokenChangedCb(newRefreshToken, (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.access_token); | ||
} | ||
this.log.info('Got access token successfully'); | ||
return (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.access_token; | ||
}); | ||
} | ||
if (!refreshToken || startFreshLogin) { | ||
const { authCode, redirect } = await this.getAuthCode(); | ||
const tokenRequest = this.getTokenRequestForAuthCode({ | ||
redirectUri: redirect.url(), // Redirection URL needs to match | ||
authCode | ||
}); | ||
response = await axios_1.default.request(tokenRequest); | ||
this.log.info('Refresh token issued'); | ||
newRefreshToken = response.data.refresh_token; | ||
} | ||
if (refreshTokenChangedCb) { | ||
this.log.info('Sending notification that refresh token changed'); | ||
await refreshTokenChangedCb(newRefreshToken, response?.data?.access_token); | ||
} | ||
this.log.info('Got access token successfully'); | ||
return response?.data?.access_token; | ||
} | ||
@@ -305,10 +289,7 @@ /** | ||
*/ | ||
getAccessTokenWithClientCredentials() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const tokenRequest = this.getTokenRequestForClientCredential(); | ||
const response = yield axios_1.default.request(tokenRequest); | ||
this.log.info('Got access token successfully using client credentials'); | ||
return (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.access_token; | ||
}); | ||
async getAccessTokenWithClientCredentials() { | ||
const tokenRequest = this.getTokenRequestForClientCredential(); | ||
const response = await axios_1.default.request(tokenRequest); | ||
this.log.info('Got access token successfully using client credentials'); | ||
return response?.data?.access_token; | ||
} | ||
@@ -315,0 +296,0 @@ } |
@@ -25,3 +25,3 @@ "use strict"; | ||
static containsError(odata) { | ||
if (odata === null || odata === void 0 ? void 0 : odata['error']) { | ||
if (odata?.['error']) { | ||
return true; | ||
@@ -28,0 +28,0 @@ } |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -54,2 +45,5 @@ exports.ODataService = exports.ODataVersion = void 0; | ||
class ODataService extends axios_1.Axios { | ||
log; | ||
doc; | ||
metadataDoc; | ||
/** | ||
@@ -60,18 +54,16 @@ * Get the service description document. | ||
*/ | ||
document() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.doc) { | ||
const response = yield this.get('/'); | ||
const data = response.odata(); | ||
if (data['EntitySets']) { | ||
this.doc = data; | ||
} | ||
else { | ||
this.doc = { | ||
EntitySets: data.map((obj) => obj.name) | ||
}; | ||
} | ||
async document() { | ||
if (!this.doc) { | ||
const response = await this.get('/'); | ||
const data = response.odata(); | ||
if (data['EntitySets']) { | ||
this.doc = data; | ||
} | ||
return this.doc; | ||
}); | ||
else { | ||
this.doc = { | ||
EntitySets: data.map((obj) => obj.name) | ||
}; | ||
} | ||
} | ||
return this.doc; | ||
} | ||
@@ -83,10 +75,8 @@ /** | ||
*/ | ||
metadata() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.metadataDoc) { | ||
const response = yield this.get('/$metadata', { headers: { Accept: 'application/xml' } }); | ||
this.metadataDoc = response.data; | ||
} | ||
return this.metadataDoc; | ||
}); | ||
async metadata() { | ||
if (!this.metadataDoc) { | ||
const response = await this.get('/$metadata', { headers: { Accept: 'application/xml' } }); | ||
this.metadataDoc = response.data; | ||
} | ||
return this.metadataDoc; | ||
} | ||
@@ -100,21 +90,15 @@ /** | ||
*/ | ||
get(url, config = {}) { | ||
const _super = Object.create(null, { | ||
get: { get: () => super.get } | ||
}); | ||
var _a, _b, _c, _d, _e; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// request json if not otherwise specified | ||
if (((_a = config.params) === null || _a === void 0 ? void 0 : _a['$format']) === undefined && !((_b = config.headers) === null || _b === void 0 ? void 0 : _b.Accept)) { | ||
config.params = (_c = config.params) !== null && _c !== void 0 ? _c : {}; | ||
config.params['$format'] = 'json'; | ||
config.headers = (_d = config.headers) !== null && _d !== void 0 ? _d : {}; | ||
config.headers.Accept = 'application/json'; | ||
} | ||
const response = yield _super.get.call(this, url, config); | ||
if (response.data && ((_e = config.params) === null || _e === void 0 ? void 0 : _e['$format']) === 'json') { | ||
response.odata = parseODataResponse.bind(response); | ||
} | ||
return response; | ||
}); | ||
async get(url, config = {}) { | ||
// request json if not otherwise specified | ||
if (config.params?.['$format'] === undefined && !config.headers?.Accept) { | ||
config.params = config.params ?? {}; | ||
config.params['$format'] = 'json'; | ||
config.headers = config.headers ?? {}; | ||
config.headers.Accept = 'application/json'; | ||
} | ||
const response = await super.get(url, config); | ||
if (response.data && config.params?.['$format'] === 'json') { | ||
response.odata = parseODataResponse.bind(response); | ||
} | ||
return response; | ||
} | ||
@@ -121,0 +105,0 @@ } |
@@ -14,2 +14,3 @@ "use strict"; | ||
class TlsPatch { | ||
static _patched; | ||
/** | ||
@@ -16,0 +17,0 @@ * Test if the patch is already applied. |
@@ -12,8 +12,5 @@ "use strict"; | ||
class ServiceProvider extends axios_1.Axios { | ||
constructor() { | ||
super(...arguments); | ||
this.log = new logger_1.ToolsLogger(); | ||
this.cookies = new auth_1.Cookies(); | ||
this.services = {}; | ||
} | ||
log = new logger_1.ToolsLogger(); | ||
cookies = new auth_1.Cookies(); | ||
services = {}; | ||
/** | ||
@@ -38,5 +35,8 @@ * Create a service instance or return an existing one for the given path. | ||
generateServiceConfig(path) { | ||
var _a, _b; | ||
const config = Object.assign({}, this.defaults); | ||
return Object.assign(Object.assign({}, config), { baseURL: this.defaults.baseURL + path, headers: (_b = (_a = this.defaults.headers) === null || _a === void 0 ? void 0 : _a.common) !== null && _b !== void 0 ? _b : {} }); | ||
return { | ||
...config, | ||
baseURL: this.defaults.baseURL + path, | ||
headers: this.defaults.headers?.common ?? {} | ||
}; | ||
} | ||
@@ -51,3 +51,3 @@ /** | ||
createService(path, ServiceClass) { | ||
const service = new ServiceClass(Object.assign(Object.assign({}, this.generateServiceConfig(path)), { publicUrl: this.publicUrl })); | ||
const service = new ServiceClass({ ...this.generateServiceConfig(path), publicUrl: this.publicUrl }); | ||
service.log = this.log; | ||
@@ -54,0 +54,0 @@ service.interceptors = this.interceptors; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -43,3 +23,2 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
function createInstance(ProviderType, config) { | ||
var _a, _b; | ||
const providerConfig = (0, cloneDeep_1.default)(config); | ||
@@ -50,3 +29,3 @@ providerConfig.httpsAgent = new https_1.Agent({ | ||
delete providerConfig.ignoreCertErrors; | ||
providerConfig.withCredentials = (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.auth) && Object.keys(providerConfig.auth).length > 0; | ||
providerConfig.withCredentials = providerConfig?.auth && Object.keys(providerConfig.auth).length > 0; | ||
/** | ||
@@ -60,3 +39,3 @@ * Make axios throw an error for 4xx errors. | ||
const instance = new ProviderType(providerConfig); | ||
instance.defaults.headers = (_a = instance.defaults.headers) !== null && _a !== void 0 ? _a : { | ||
instance.defaults.headers = instance.defaults.headers ?? { | ||
common: {}, | ||
@@ -71,3 +50,3 @@ 'delete': {}, | ||
(0, auth_1.attachConnectionHandler)(instance); | ||
if ((_b = providerConfig.auth) === null || _b === void 0 ? void 0 : _b.password) { | ||
if (providerConfig.auth?.password) { | ||
(0, auth_1.attachBasicAuthInterceptor)(instance); | ||
@@ -128,4 +107,8 @@ } | ||
case AbapCloudEnvironment.Standalone: { | ||
const { service, refreshToken, refreshTokenChangedCb, cookies } = options, config = __rest(options, ["service", "refreshToken", "refreshTokenChangedCb", "cookies"]); | ||
provider = createInstance(abap_1.AbapServiceProvider, Object.assign({ baseURL: service.url, cookies }, config)); | ||
const { service, refreshToken, refreshTokenChangedCb, cookies, ...config } = options; | ||
provider = createInstance(abap_1.AbapServiceProvider, { | ||
baseURL: service.url, | ||
cookies, | ||
...config | ||
}); | ||
if (!cookies) { | ||
@@ -137,4 +120,8 @@ (0, auth_1.attachUaaAuthInterceptor)(provider, service, refreshToken, refreshTokenChangedCb); | ||
case AbapCloudEnvironment.EmbeddedSteampunk: { | ||
const { url, cookies } = options, config = __rest(options, ["url", "cookies"]); | ||
provider = createInstance(abap_1.AbapServiceProvider, Object.assign({ baseURL: url, cookies }, config)); | ||
const { url, cookies, ...config } = options; | ||
provider = createInstance(abap_1.AbapServiceProvider, { | ||
baseURL: url, | ||
cookies, | ||
...config | ||
}); | ||
if (!cookies) { | ||
@@ -161,7 +148,10 @@ (0, auth_1.attachReentranceTicketAuthInterceptor)({ provider }); | ||
function createForDestination(options, destination, destinationServiceInstance) { | ||
var _a; | ||
const { cookies } = options, config = __rest(options, ["cookies"]); | ||
const providerConfig = Object.assign(Object.assign({}, config), { baseURL: (0, btp_utils_1.getDestinationUrlForAppStudio)(destination.Name, destination.Host ? new URL(destination.Host).pathname : undefined), cookies: cookies }); | ||
const { cookies, ...config } = options; | ||
const providerConfig = { | ||
...config, | ||
baseURL: (0, btp_utils_1.getDestinationUrlForAppStudio)(destination.Name, destination.Host ? new URL(destination.Host).pathname : undefined), | ||
cookies: cookies | ||
}; | ||
// SAML in AppStudio is not yet supported | ||
providerConfig.params = (_a = providerConfig.params) !== null && _a !== void 0 ? _a : {}; | ||
providerConfig.params = providerConfig.params ?? {}; | ||
providerConfig.params.saml2 = 'disabled'; | ||
@@ -179,8 +169,8 @@ let provider; | ||
if (destinationServiceInstance) { | ||
const oneTimeReqInterceptorId = provider.interceptors.request.use((request) => __awaiter(this, void 0, void 0, function* () { | ||
const credentials = yield (0, btp_utils_1.getCredentialsForDestinationService)(destinationServiceInstance); | ||
const oneTimeReqInterceptorId = provider.interceptors.request.use(async (request) => { | ||
const credentials = await (0, btp_utils_1.getCredentialsForDestinationService)(destinationServiceInstance); | ||
provider.defaults.headers.common[btp_utils_1.BAS_DEST_INSTANCE_CRED_HEADER] = credentials; | ||
provider.interceptors.request.eject(oneTimeReqInterceptorId); | ||
return request; | ||
})); | ||
}); | ||
} | ||
@@ -187,0 +177,0 @@ return provider; |
@@ -9,3 +9,4 @@ import type { AxiosError, AxiosRequestConfig } from 'axios'; | ||
export * from './abap/message'; | ||
export { ServiceType } from './abap/catalog/base'; | ||
export { AxiosError, AxiosRequestConfig, isAxiosError }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -17,3 +17,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isAxiosError = void 0; | ||
exports.isAxiosError = exports.ServiceType = void 0; | ||
const odata_request_error_1 = require("./base/odata-request-error"); | ||
@@ -27,2 +27,4 @@ Object.defineProperty(exports, "isAxiosError", { enumerable: true, get: function () { return odata_request_error_1.isAxiosError; } }); | ||
__exportStar(require("./abap/message"), exports); | ||
var base_1 = require("./abap/catalog/base"); | ||
Object.defineProperty(exports, "ServiceType", { enumerable: true, get: function () { return base_1.ServiceType; } }); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@sap-ux/axios-extension", | ||
"version": "1.14.4", | ||
"version": "1.15.1", | ||
"description": "Extension of the Axios module adding convenience methods to interact with SAP systems especially with OData services.", | ||
@@ -25,4 +25,4 @@ "repository": { | ||
"@xmldom/xmldom": "0.8.10", | ||
"@sap-ux/btp-utils": "0.14.4", | ||
"@sap-ux/logger": "0.5.1" | ||
"@sap-ux/btp-utils": "0.15.0", | ||
"@sap-ux/logger": "0.6.0" | ||
}, | ||
@@ -33,3 +33,3 @@ "devDependencies": { | ||
"supertest": "6.3.3", | ||
"@sap-ux/project-access": "1.22.3" | ||
"@sap-ux/project-access": "1.23.0" | ||
}, | ||
@@ -36,0 +36,0 @@ "files": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
249518
6005
+ Added@sap-ux/btp-utils@0.15.0(transitive)
+ Added@sap-ux/logger@0.6.0(transitive)
- Removed@sap-ux/btp-utils@0.14.4(transitive)
- Removed@sap-ux/logger@0.5.1(transitive)
Updated@sap-ux/btp-utils@0.15.0
Updated@sap-ux/logger@0.6.0