UNPKG

@mindconnect/mindconnect-nodejs

Version:

NodeJS Library for Siemens Insights Hub Connectivity - TypeScript SDK for Insights Hub and Industrial IoT - Command Line Interface - Insights Hub Development Proxy (Siemens Insights Hub was formerly known as MindSphere)

782 lines (781 loc) 31.5 kB
"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.DataLakeClient = void 0; const cross_fetch_1 = require("cross-fetch"); const fs = require("fs"); const https_proxy_agent_1 = require("https-proxy-agent"); const utils_1 = require("../../utils"); const sdk_client_1 = require("../common/sdk-client"); class DataLakeClient extends sdk_client_1.SdkClient { constructor() { super(...arguments); this._baseUrl = "/api/datalake/v3"; } /** * * Object Metadata Catalog Operations * * Get Metadata for the object. If tenant is operating for a subtenant object, * he should specify subtenant in request query parameter. * If path contains special characters which require URL encoding, it should be done as appropriate. * * @param {string} path path of an object denoting folders and object name. e.g. basefolder/subfolder/objectname.objectext * @param {{ subtenantid?: string }} [optional] Only to be used by tenants, to address a subtenants object metadata. If not provided by a tenant, its own object metadata is addressed. Subtenants are not allowed to use this parameter and can only address their own object metadata. e.g. subtenantId 204a896c-a23a-11e9-a2a3-2a2ae2dbcce4 * @returns {Promise<DataLakeModels.ObjectMetaDataResponse>} * * @memberOf DataLakeClient */ GetObjectMetaData(path, optional) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectMetadata/${path}?${(0, utils_1.toQueryString)(optional)}`, })); }); } /** * * Object Metadata Catalog Operations * * Get a list of metadata information with a filter * * @param {string} path * @param {{ filter: string; subtenantid?: string; size?: number; page?: number }} params * @returns {Promise<DataLakeModels.SearchResponse>} * * @memberOf DataLakeClient */ GetObjectMetaDatas(path, params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectMetadata/${path}?${(0, utils_1.toQueryString)(params)}`, })); }); } /** * * * Object Metadata Catalog Operations * * Create/Update metadata. If tenant is operating for a subtenant object, * he should specify subtenant in request query parameter. * If path contains special characters which require URL encoding, it should be done as appropriate. * Maximum 8 tags are allowed, where each tag can be maximum 128 characters. * * @param {string} path path of an object denoting folders and object name. e.g. basefolder/subfolder/objectname.objectext * @param {DataLakeModels.Metadata} Metadata * @param {{ subtenantid?: string }} [optional] Only to be used by tenants, to address a subtenants object metadata. If not provided by a tenant, its own object metadata is addressed. Subtenants are not allowed to use this parameter and can only address their own object metadata. e.g. subtenantId 204a896c-a23a-11e9-a2a3-2a2ae2dbcce4 * @returns * * @memberOf DataLakeClient */ PutObjectMetaData(path, metadata, optional) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "PUT", gateway: this.GetGateway(), authorization: yield this.GetToken(), body: metadata, baseUrl: `${this._baseUrl}/objectMetadata/${path}?${(0, utils_1.toQueryString)(optional)}`, }); }); } /** * * * Object Access Operations * * * Generate signed URLs to upload an object. * * @param {DataLakeModels.GenerateUrlPayload} generateUrlPayload * upload payload with path details array and optional subtenant id * @returns * * @memberOf DataLakeClient */ GenerateUploadObjectUrls(generateUrlPayload) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/generateUploadObjectUrls`, body: generateUrlPayload, })); }); } /** * * * Object Access Operations * * * Generate signed URLs to download an object * * @param {DataLakeModels.GenerateUrlPayload} generateUrlPayload * @returns {Promise<DataLakeModels.SignedUrlResponse>} * * @memberOf DataLakeClient */ GenerateDownloadObjectUrls(generateUrlPayload) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/generateDownloadObjectUrls`, body: generateUrlPayload, })); }); } /** * * Object Access Operations * * Upload file to data lake via pre-signed URL * * @param {(string | Buffer)} file * @param {string} signedUrl * @returns {Promise<Headers>} * * @memberOf DataLakeClient */ PutFile(file, signedUrl) { return __awaiter(this, void 0, void 0, function* () { const myBuffer = typeof file === "string" ? fs.readFileSync(file) : file; const proxy = process.env.http_proxy || process.env.HTTP_PROXY; const proxyHttpAgent = proxy ? new https_proxy_agent_1.HttpsProxyAgent(proxy) : null; let headers; // in china the Object Storage Service needs Content-Type to be application/octet-stream if (this.GetGateway().toLowerCase().includes("mindsphere-in.cn")) { headers = { "Content-Type": "application/octet-stream" }; } else { // x-ms-blob is necessary on eu2 and is ignored on eu1 headers = { "x-ms-blob-type": "BlockBlob" }; } const request = { method: "PUT", headers: headers, agent: proxyHttpAgent }; request.body = myBuffer; const response = yield (0, cross_fetch_1.default)(signedUrl, request); return response.headers; }); } /** * * Object Access Operations * * Create a cross account * * Create a cross account on which access needs to be given for paths. * If, in request body subtenant is denoted as "**", it is a special cross account. * In this case, on this cross account, tenant implicitly gets Read Only access to the storage * account's root level data path for itself and for all its subtenants. * For this case, the authorization token should be that of the tenant. * * @param {DataLakeModels.CrossAccountRequest} crossAccountRequest * @returns {Promise<DataLakeModels.CrossAccount>} * * @memberOf DataLakeClient */ PostCrossAccount(crossAccountRequest) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts`, body: crossAccountRequest, })); }); } /** * * Object Access Operations * * Get list of cross accounts on which access was given. * * If requester is tenant, all the cross account for the tenant as well as its all subtenants are returned. * If requester is a subtenant, all the cross accounts for the subtenant are returned. * If tenant wants to filter results for a particular subtenant, filter query parameter subtenantId can be used. This filter query parameter is applicable only if the requester is tenant. * * @param {{ * page?: number; * size?: number; * filter?: string; * }} [params] * @returns {Promise<DataLakeModels.CrossAccountListResource>} * * @memberOf DataLakeClient */ GetCrossAccounts(params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts?${(0, utils_1.toQueryString)(params)}`, })); }); } /** * * * Object Access Operations * * Get details of selected cross account. * * @param {string} id unique identifier of the cross account * @returns {Promise<DataLakeModels.CrossAccount>} * * @memberOf DataLakeClient */ GetCrossAccount(id) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}`, })); }); } /** * * Object Access Operations * * Update a cross account on which access needs to be managed. * * @param {string} id * @param {DataLakeModels.CrossAccountUpdateRequest} crossAccountUpdateRequest * @param {{ ifMatch: number }} params * @returns {Promise<DataLakeModels.CrossAccount>} * * @memberOf DataLakeClient */ PatchCrossAccount(id, crossAccountUpdateRequest, params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "PATCH", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}`, additionalHeaders: { "If-Match": params.ifMatch }, body: crossAccountUpdateRequest, })); }); } /** * * Object Access Operations * * Delete cross account and corresponding accesses. * * @param {string} id * @param {{ ifMatch: number }} params * @returns * * @memberOf DataLakeClient */ DeleteCrossAccount(id, params) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "DELETE", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}`, additionalHeaders: { "If-Match": params.ifMatch }, noResponse: true, }); }); } /** * * Object Access Operations * * Create a cross account access. * If the cross account is created for tenant and all subtenants (**), * then this operation is implicitly handled and not allowed through API. * Maximum 5 cross account accesses can be created with ENABLED status. * Maximum 10 cross accounts can be created with DISABLED status. * @param {string} id * @param {DataLakeModels.CrossAccountAccessRequest} crossAccountAccessRequest * @returns {Promise<DataLakeModels.CrossAccountAccess>} * * @memberOf DataLakeClient */ PostCrossAccountAccess(id, crossAccountAccessRequest) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts${id}/accesses`, body: crossAccountAccessRequest, })); }); } /** * * Object Access Operations * *Get list of cross account accesses. * * @param {string} id * @param {{ * page?: number; * size?: number; * }} [params] * @returns {Promise<DataLakeModels.CrossAccountAccessListResource>} * * @memberOf DataLakeClient */ GetCrossAccountAccesses(id, params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}/accesses?${(0, utils_1.toQueryString)(params)}`, })); }); } /** * * Object Access Operations * * Get a selected access for a selected cross account. * * @param {string} id * @param {string} accessId * @returns {Promise<DataLakeModels.CrossAccountAccess>} * * @memberOf DataLakeClient */ GetCrossAccountAccess(id, accessId) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}/accesses/${accessId}`, })); }); } /** * * Object Access Operations * * Update a cross account access. * * This operation is not allowed when the cross account is created * for special case of tenant and all subtenants (**). * Maximum 5 cross account accesses can be present with ENABLED status. * Maximum 10 cross accounts can be present with DISABLED status. * * @param {string} id * @param {string} accessId * @param {DataLakeModels.CrossAccountAccessRequest} crossAcccountAccessRequest * @param {{ ifMatch: number }} params * @returns {Promise<DataLakeModels.CrossAccountAccess>} * * @memberOf DataLakeClient */ PatchCrossAccountAccess(id, accessId, crossAcccountAccessRequest, params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "PATCH", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}/accesses/${accessId}`, body: crossAcccountAccessRequest, additionalHeaders: { "If-Match": params.ifMatch }, })); }); } /** * * Delete a cross account access. * * If the cross account is created for tenant and all subtenants (**), * then this operation is implicitly handled by deletion of cross account and not allowed through API * * * @param {string} id * @param {string} accessId * @param {{ ifMatch: number }} params * @returns * * @memberOf DataLakeClient */ DeleteCrossAccountAccess(id, accessId, params) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "DELETE", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/crossAccounts/${id}/accesses/${accessId}`, additionalHeaders: { "If-Match": params.ifMatch }, noResponse: true, }); }); } /** * * Object Event Subscription Operations * * Create Object Event Subscription * * Allows users to subscribe for event notifications generated * when the objects of a tenant or subtenant are created, * updated, or deleted. Multiple subscriptions for the same path * can be created when each has a different destination. Similarly, multiple subscriptions * for the same destination can be created when each has a different path. * Maximum 15 subscriptions can be created for a tenant or for a subtenant. * Path in request payload should be upto folders and not upto object e.g. "myfolder/mysubfolder" * Notification Content * Based on the configured subscriptions, event notification * messages are published to the destination. * The event notification content is formatted in JSON according to this example. * If object operation happened in subtenant folder, both tenantId and subtenantId * will be part of the message. If object operation happened in tenant folder, only * tenantId will be part of the message.: * * @param {DataLakeModels.Subscription} subscription * @returns {Promise<DataLakeModels.Subscription>} * * @memberOf DataLakeClient */ PostObjectEventSubscriptions(subscription) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectEventSubscriptions`, body: subscription, })); }); } /** * * Object Event Subscription Operations * * List object event subscriptions for the tenant or subtenant. * * If requester is tenant, all the subscriptions for the tenant as well as its all * subtenants are returned. If requester is a subtenant, all the subscriptions for * the subtenant are returned. If tenant wants to filter results for a particular subtenant, * filter query parameter subtenantId can be used. This filter query parameter is applicable * only if the requester is tenant. * * @param {{ * page?: number; * size?: number; * filter?: string; * }} [params] * @param params.filter * JSON-based filter expression. Supported values: 'subtenantId'. Supported operations: 'eq'. * Decoded example value: * @example { "subtenantId": "204a896c-a23a-11e9-a2a3-2a2ae2dbcce4" } * * @returns {Promise<DataLakeModels.SubscriptionListResource>} * * @memberOf DataLakeClient */ GetObjectEventSubscriptions(params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectEventSubscriptions?${(0, utils_1.toQueryString)(params)}`, })); }); } /** * * Object Event Subscription Operations * * Read event subscription by id * * Read object event subscription for the tenant * * @param {string} id * @returns {Promise<DataLakeModels.SubscriptionResponse>} * * @memberOf DataLakeClient */ GetObjectEventSubscription(id) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectEventSubscriptions/${id}`, })); }); } /** * * Object Event Subscription Operations * * Update object event subscription by id * * @param {string} id * @param {DataLakeModels.SubscriptionUpdate} subscriptionUpdate * @param {{ ifMatch: number }} params * @returns {Promise<DataLakeModels.SubscriptionResponse>} * * @memberOf DataLakeClient */ PatchObjectEventSubscription(id, subscriptionUpdate, params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "PATCH", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectEventSubscriptions/${id}`, additionalHeaders: { "If-Match": params.ifMatch }, body: subscriptionUpdate, })); }); } /** * * Object Event Subscription Operations * * Delete object event subscription by id * * @param {string} id * @param {{ ifMatch: number }} params * @returns * * @memberOf DataLakeClient */ DeleteObjectEventSubscription(id, params) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "DELETE", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/objectEventSubscriptions/${id}`, additionalHeaders: { "If-Match": params.ifMatch }, noResponse: true, }); }); } /** * * Time Series Bulk Import Operations * * Creates a bulk import job of time series data into data * * Creates an asynchronous job to bulk import time series data into data lake. * The import takes into account time series data from the provided aspects associated to the provided assets, * in the given time range * * @param {DataLakeModels.ImportJobRequest} importJob * @returns {Promise<DataLakeModels.ImportJobResponse>} * * @memberOf DataLakeClient */ PostTimeSeriesImportJob(importJob) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/timeSeriesImportJobs`, body: importJob, })); }); } /** * * * Time Series Bulk Import Operations * * Query all time series bulk import jobs * * Query all time series bulk import jobs currently existing, * which are owned by the client's tenant or subtenant. * If requester is tenant, all the import jobs for the tenant as well as * its all subtenants are returned. If requester is a subtenant, * all the iport jobs for the subtenant are returned. If tenant wants to filter results * for a particular subtenant, filter query parameter subtenantId can be used. * This filter query parameter is applicable only if the requester is tenant. * * @param {{ * page?: number; * size?: number; * filter?: string; * }} [params] * @param params.filter * JSON-based filter expression. Supported values: 'subtenantId'. Supported operations: 'eq'. * Decoded example value: * @example { "subtenantId": "204a896c-a23a-11e9-a2a3-2a2ae2dbcce4" } * @returns {Promise<DataLakeModels.ImportJobListResource>} * * @memberOf DataLakeClient */ GetTimeSeriesImportJobs(params) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/timeSeriesImportJobs?${(0, utils_1.toQueryString)(params)}`, })); }); } /** * * Time Series Bulk Import Operations * * Retrieve status of time series bulk import job. * * @param {string} id * @returns {Promise<DataLakeModels.ImportJobResponse>} * * @memberOf DataLakeClient */ GetTimeSeriesImportJob(id) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/timeSeriesImportJobs/${id}`, })); }); } /** * * Time Series Bulk Import Operations * * Delete completed time series bulk import job. * * @param {string} id * @returns * * @memberOf DataLakeClient */ DeleteTimeSeriesImportJob(id) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "DELETE", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/timeSeriesImportJobs/${id}`, noResponse: true, }); }); } /** * * Time Series Bulk Import Operations * * Retreive details of a time series bulk import job. * * Details are only available once a job is not any longer in status PENDING. * * @param {string} id * @returns {Promise<DataLakeModels.ImportJobDetails>} * * @memberOf DataLakeClient */ GetTimeSeriesImportJobDetails(id) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/timeSeriesImportJobs/${id}/details`, })); }); } /** * * * Object Operations with Access Token * * Allows users to request temporary, limited-privilege AWS credentials to get read-only or write-only access on the URI returned in the response. * Read permission will always be on the root level. * Path field is optional for READ permission - If value for path is not provided then it will be considered on root level (/). * Ensure to enable write access on the path before requesting token with write permission. * Write access can be enabled using POST /accessTokenPermissions endpoint. * An access token requested for a given path also automatically gives access to all subpaths of the path. For example, if an access token is requested for path /a and there are subpaths /a/b and /a/b/c, the token allows to access those too. * An access token with write permissions can only be requested for the paths defined by resource accessTokenPermissions. An acecss token with read permissions can only be requested for the root path /. * * @param {DataLakeModels.GenerateSTSPayload} stsPayload * @returns {Promise<DataLakeModels.AccessTokens>} * * @memberOf DataLakeClient */ GenerateAccessToken(stsPayload) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/generateAccessToken`, body: stsPayload, })); }); } /** * * Object Operations with Access Token * * List all folders having write permission. * This API can be accessed by tenant admin, to list all write permission folders including of subtenants. * Subtenant can access this API, to get list write permission folders owned by subtenant. * * * Size parameter value should not be more than 1000. * @param {{ * page?: number; * size?: number; * }} [optional] * @returns {Promise<DataLakeModels.AccessTokenPermissionResources>} * * @memberOf DataLakeClient */ GetAccessTokenPermissions(optional) { return __awaiter(this, void 0, void 0, function* () { const qs = (0, utils_1.toQueryString)(optional); return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/accessTokenPermissions?${qs}`, })); }); } /** * * Object Operations with Access Token * * Details of the write folder request for the given id * * This API can be accessed by tenant admin, to get details of the request including for subtenants. * Subtenant can access this API, to get details of the request belongs to their write folder. * @param {string} id * @returns {Promise<DataLakeModels.AccessTokenPermissionResource>} * * @memberOf DataLakeClient */ GetAccessTokenPermission(id) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "GET", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/accessTokenPermissions/${id}`, })); }); } /** * * Object Operations with Access Token * * Delete write permission on folder for the given id * * @param {string} id Unique identifier of the write enabled folders * @returns {Promise<DataLakeModels.AccessTokenPermissionResource>} * * @memberOf DataLakeClient */ DeleteAccessTokenPermission(id) { return __awaiter(this, void 0, void 0, function* () { return yield this.HttpAction({ verb: "DELETE", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/accessTokenPermissions/${id}`, noResponse: true, }); }); } /** * * Object Operations with Access Token * * Allows to give write premission on folder/path * * @param {DataLakeModels.AccessTokenPermissionRequest} writePathPayload * @returns {Promise<DataLakeModels.AccessTokenPermissionResource>} * * @memberOf DataLakeClient */ PostAccessTokenPermissions(writePathPayload) { return __awaiter(this, void 0, void 0, function* () { return (yield this.HttpAction({ verb: "POST", gateway: this.GetGateway(), authorization: yield this.GetToken(), baseUrl: `${this._baseUrl}/accessTokenPermissions`, body: writePathPayload, })); }); } } exports.DataLakeClient = DataLakeClient; //# sourceMappingURL=data-lake.js.map