@azure/api-management-custom-widgets-tools 1.0.0-beta.1 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ the [official Azure documentation](https://aka.ms/apimdocs/portal/customwidgets)
12
12
 
13
13
  ### Currently supported environments
14
14
 
15
- - [LTS versions of Node.js](https://nodejs.org/about/releases/)
15
+ - [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule)
16
16
  - Latest versions of Safari, Chrome, Edge, and Firefox
17
17
 
18
18
  ### Prerequisites
package/dist/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var tslib = require('tslib');
6
4
  var storageBlob = require('@azure/storage-blob');
7
5
  var mime = require('mime');
@@ -10,12 +8,6 @@ var identity = require('@azure/identity');
10
8
  var coreClient = require('@azure-rest/core-client');
11
9
  var path = require('path');
12
10
 
13
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
14
-
15
- var mime__default = /*#__PURE__*/_interopDefaultLegacy(mime);
16
- var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
17
- var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
18
-
19
11
  // Copyright (c) Microsoft Corporation.
20
12
  // Licensed under the MIT license.
21
13
  /**
@@ -71,7 +63,7 @@ function getValuesPure(valuesDefault, urlSearchParams) {
71
63
  const urlValues = parseWidgetData(urlSearchParams).values;
72
64
  Object.keys(values).forEach((key) => {
73
65
  const value = urlValues[key];
74
- if (value != null && value !== "")
66
+ if (value != null)
75
67
  values[key] = value; // if value is specified in the URL, replace the default value
76
68
  });
77
69
  return values;
@@ -167,6 +159,7 @@ function buildBlobConfigPath(name) {
167
159
  }
168
160
 
169
161
  // Copyright (c) Microsoft Corporation.
162
+ // Licensed under the MIT license.
170
163
  /**
171
164
  * A service wrapping ContainerClient class to simplify blob handling
172
165
  */
@@ -191,7 +184,7 @@ class CustomWidgetBlobService {
191
184
  if (!fileName)
192
185
  throw new Error("a fileName was not found in the absolutePath");
193
186
  return this.containerClient.getBlockBlobClient(absolutePath).upload(content, content.length, {
194
- blobHTTPHeaders: { blobContentType: mime__default["default"].getType(fileName) || "application/octet-stream" },
187
+ blobHTTPHeaders: { blobContentType: mime.getType(fileName) || "application/octet-stream" },
195
188
  });
196
189
  }
197
190
  async jsonUpload(absolutePath, json) {
@@ -201,17 +194,24 @@ class CustomWidgetBlobService {
201
194
  return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();
202
195
  }
203
196
  async dirDelete(absolutePath) {
204
- var e_1, _a;
197
+ var _a, e_1, _b, _c;
205
198
  try {
206
- for (var _b = tslib.__asyncValues(await this.containerClient.listBlobsFlat({ prefix: absolutePath })), _c; _c = await _b.next(), !_c.done;) {
207
- const blob = _c.value;
208
- await this.containerClient.deleteBlob(blob.name);
199
+ for (var _d = true, _e = tslib.__asyncValues(await this.containerClient.listBlobsFlat({ prefix: absolutePath })), _f; _f = await _e.next(), _a = _f.done, !_a;) {
200
+ _c = _f.value;
201
+ _d = false;
202
+ try {
203
+ const blob = _c;
204
+ await this.containerClient.deleteBlob(blob.name);
205
+ }
206
+ finally {
207
+ _d = true;
208
+ }
209
209
  }
210
210
  }
211
211
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
212
212
  finally {
213
213
  try {
214
- if (_c && !_c.done && (_a = _b.return)) await _a.call(_b);
214
+ if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
215
215
  }
216
216
  finally { if (e_1) throw e_1.error; }
217
217
  }
@@ -233,8 +233,9 @@ class CustomWidgetBlobService {
233
233
  var CustomWidgetBlobService$1 = CustomWidgetBlobService;
234
234
 
235
235
  // Copyright (c) Microsoft Corporation.
236
- async function getAccessToken(managementApiEndpoint) {
237
- const credentials = new identity.InteractiveBrowserCredential();
236
+ // Licensed under the MIT license.
237
+ async function getAccessToken(managementApiEndpoint, options) {
238
+ const credentials = new identity.InteractiveBrowserCredential(options);
238
239
  const scope = `${managementApiEndpoint}/user_impersonation`;
239
240
  const { token } = await credentials.getToken(scope);
240
241
  return `Bearer ${token}`;
@@ -244,7 +245,7 @@ async function getAccessToken(managementApiEndpoint) {
244
245
  *
245
246
  * @returns storage SAS URL
246
247
  */
247
- async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion = "2019-01-01", tokenOverride, }) {
248
+ async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion = "2019-01-01", tokenOverride, }, interactiveBrowserCredentialOptions) {
248
249
  var _a;
249
250
  const httpClient = coreClient.getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });
250
251
  const response = await httpClient
@@ -253,7 +254,7 @@ async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion
253
254
  headers: {
254
255
  "If-Match": "*",
255
256
  "Content-Type": "application/json",
256
- Authorization: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : (await getAccessToken(managementApiEndpoint)),
257
+ Authorization: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : (await getAccessToken(managementApiEndpoint, interactiveBrowserCredentialOptions)),
257
258
  },
258
259
  });
259
260
  if (!((_a = response === null || response === void 0 ? void 0 : response.body) === null || _a === void 0 ? void 0 : _a.containerSasUrl))
@@ -262,12 +263,13 @@ async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion
262
263
  }
263
264
 
264
265
  // Copyright (c) Microsoft Corporation.
266
+ // Licensed under the MIT license.
265
267
  function readdir(dir, root) {
266
268
  const results = [];
267
- fs__default["default"].readdirSync(root + dir).forEach((file) => {
268
- const stat = fs__default["default"].statSync(root + dir + path__default["default"].sep + file);
269
+ fs.readdirSync(root + dir).forEach((file) => {
270
+ const stat = fs.statSync(root + dir + path.sep + file);
269
271
  if (stat && stat.isDirectory()) {
270
- results.push(...readdir(dir + file + path__default["default"].sep, root));
272
+ results.push(...readdir(dir + file + path.sep, root));
271
273
  }
272
274
  else {
273
275
  results.push(dir + file);
@@ -277,19 +279,20 @@ function readdir(dir, root) {
277
279
  }
278
280
 
279
281
  // Copyright (c) Microsoft Corporation.
282
+ // Licensed under the MIT license.
280
283
  /**
281
284
  * Deploys everything from /dist folder to the API Management DevPortals' blob storage.
282
285
  *
283
286
  * @param serviceInformation - service information for deployment
284
287
  * @param name - name of the widget to be deployed
285
288
  * @param fallbackConfigPath - local path to the config file (by default "./static/config.msapim.json")
286
- * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default "./dist")
289
+ * @param config - optional config object
287
290
  */
288
- async function deploy(serviceInformation, name, fallbackConfigPath = "./static/" + APIM_CONFIG_FILE_NAME, rootLocal = "./dist/") {
291
+ async function deploy(serviceInformation, name, fallbackConfigPath = "./static/" + APIM_CONFIG_FILE_NAME, { rootLocal = "./dist/", interactiveBrowserCredentialOptions = { redirectUri: "http://localhost:1337" }, } = {}) {
289
292
  console.log("\n\n");
290
293
  console.log("Starting deploy process of custom widget: " + name);
291
294
  console.log("Please, sign in to your Azure account when prompted\n");
292
- const blobStorageUrl = await getStorageSasUrl(serviceInformation);
295
+ const blobStorageUrl = await getStorageSasUrl(serviceInformation, interactiveBrowserCredentialOptions);
293
296
  const customWidgetBlobService = new CustomWidgetBlobService$1(blobStorageUrl, name);
294
297
  let config;
295
298
  try {
@@ -301,7 +304,7 @@ async function deploy(serviceInformation, name, fallbackConfigPath = "./static/"
301
304
  }
302
305
  if (!config) {
303
306
  console.log("Looking for a local config file in: " + fallbackConfigPath);
304
- config = JSON.parse(fs__default["default"].readFileSync(fallbackConfigPath).toString());
307
+ config = JSON.parse(fs.readFileSync(fallbackConfigPath).toString());
305
308
  }
306
309
  if (!config) {
307
310
  throw new Error("Config file could not be loaded.");
@@ -312,7 +315,7 @@ async function deploy(serviceInformation, name, fallbackConfigPath = "./static/"
312
315
  await customWidgetBlobService.cleanDataDir();
313
316
  const promises = [];
314
317
  files.forEach((file) => {
315
- const content = fs__default["default"].readFileSync(rootLocal + file);
318
+ const content = fs.readFileSync(rootLocal + file);
316
319
  const promise = customWidgetBlobService
317
320
  .uploadWidgetDataFile(file, content)
318
321
  .then(() => console.log("Uploaded file: " + file));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/paths.ts","../src/node/CustomWidgetBlobService.ts","../src/node/getStorageSasUrl.ts","../src/node/readdir.ts","../src/node/deploy.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Key for a search param, from which editor data will be loaded from.\n */\nexport const APIM_EDITOR_DATA_KEY = \"editorData\";\n/**\n * Key for a post message object, it's used to propagate changes from editor to the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ON_CHANGE_MESSAGE_KEY = \"customInputValueChangedMSAPIM\";\n/**\n * Key for a post message object, it's used to request and send secrets - token and user id, from the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ASK_FOR_SECRETS_MESSAGE_KEY = \"askForSecretsMSAPIM\";\n\n/**\n * Base of a values obj\n */\nexport type ValuesCommon = Record<string, unknown>;\n/**\n * All possible runtime environments\n */\nexport type Environment = \"development\" | \"publishing\" | \"runtime\" | \"error\";\n\n/** Information about the widget instance received from the Dev Portal */\nexport interface PortalData {\n // /** web content's origin (URL) of your Dev Portal */\n // origin: string;\n /** current runtime environment */\n environment: Environment;\n /** ID of this particular instance of the widget */\n instanceId: string;\n}\n\n/** JSON object with all the data you'll receive from the Dev Portal */\nexport interface EditorData<Values extends ValuesCommon> extends PortalData {\n /** values you've set in the admin editor window */\n values: Partial<Values>;\n}\n\nfunction parseWidgetData<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n try {\n const urlEditorParams: EditorData<Values> = JSON.parse(\n decodeURIComponent(urlSearchParams.get(APIM_EDITOR_DATA_KEY) ?? \"\")\n );\n\n // if (!(\"origin\" in urlEditorParams)) {\n // console.error(\n // \"Could not get 'origin' from the search params of the URL:\\n\" + self.location.href\n // );\n // }\n return urlEditorParams;\n } catch (e) {\n console.error(\n `Could not get '${APIM_EDITOR_DATA_KEY}' from the search params of the URL:\\n` +\n self.location,\n e\n );\n return { values: {}, environment: \"error\", instanceId: \"error\" };\n }\n}\n\nexport function getWidgetDataPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n return parseWidgetData<Values>(urlSearchParams);\n}\n\n/**\n * Function to get all data related to the widget including technical values not expected to be needed in most cases.\n * Intended mostly for internal use, API might change. Consider using getValues or getEditorValues instead.\n */\nexport function getWidgetData<Values extends ValuesCommon>(): EditorData<Values> {\n return getWidgetDataPure(new URLSearchParams(self.location.search));\n}\n\nexport function getEditorValuesPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): Partial<Values> {\n return getWidgetDataPure<Values>(urlSearchParams).values;\n}\n\n/**\n * Function to get values you've set in the admin editor window.\n */\nexport function getEditorValues<Values extends ValuesCommon>(): Partial<Values> {\n return getEditorValuesPure<Values>(new URLSearchParams(self.location.search));\n}\n\nexport function getValuesPure<Values extends ValuesCommon>(\n valuesDefault: Values,\n urlSearchParams: URLSearchParams\n): Values {\n const values = { ...valuesDefault }; // set Obj to contain all possible values and prefill default value\n const urlValues = parseWidgetData<Values>(urlSearchParams).values;\n\n Object.keys(values).forEach((key: keyof Values) => {\n const value = urlValues[key];\n if (value != null && value !== \"\") values[key] = value as Values[typeof key]; // if value is specified in the URL, replace the default value\n });\n return values;\n}\n\n/**\n * Function to get values you've set in the admin editor window. Undefined/empty values are replaced with default values.\n *\n * @param valuesDefault - object with your default values to use, just import valuesDefault object from values.ts folder\n */\nexport function getValues<Values extends ValuesCommon>(valuesDefault: Values): Values {\n return getValuesPure(valuesDefault, new URLSearchParams(self.location.search));\n}\n\n/**\n * Type of the onChange function.\n */\nexport type OnChange<Values extends ValuesCommon> = (values: Partial<Values>) => void;\n\n/**\n * The onChange function itself with 'origin' provided as a param.\n *\n * @param origin - web content's origin (URL) of your Dev Portal to send changes to\n * @param instanceId - ID of this particular instance of the widget\n * @param values - values that changed\n */\nexport function onChangeWithOrigin<Values extends ValuesCommon>(\n origin: string,\n instanceId: string,\n values: Values\n): void {\n Object.entries(values).forEach(([key, value]) => {\n self.parent.postMessage({ [APIM_ON_CHANGE_MESSAGE_KEY]: { key, value, instanceId } }, origin);\n });\n}\n\n/**\n * Build onChange function, which you can use, to send changed data from the editor.\n */\nexport function buildOnChange<Values extends ValuesCommon>(): OnChange<Values> {\n const { instanceId } = getWidgetData();\n return (values: Partial<Values>) => onChangeWithOrigin(\"*\", instanceId, values);\n}\n\n/**\n * Possible target modules\n * \"app\" for main application which is embedded in your Dev Portal\n * \"editor\" for form in admin panel\n */\nexport type TargetModule = \"app\" | \"editor\";\n/**\n * Secrets needed for communication with Dev Portal back-end\n */\nexport type Secrets = {\n managementApiUrl: string;\n apiVersion: string;\n userId?: string;\n token?: string;\n};\n\n/**\n * Request secrets - token & userId, from the Dev portal parent window.\n *\n * @param targetModule - is the function invoke from the main \"app\" window or the admin \"editor\"?\n */\nexport async function askForSecrets(targetModule: TargetModule): Promise<Secrets> {\n let receiveSecrets: (e: MessageEvent) => void;\n\n const promise = new Promise<Secrets>((resolve, reject) => {\n const { instanceId, environment }: PortalData = getWidgetData();\n\n receiveSecrets = ({ data }) => {\n if (!(APIM_ASK_FOR_SECRETS_MESSAGE_KEY in data)) return;\n\n const secrets = data[APIM_ASK_FOR_SECRETS_MESSAGE_KEY];\n if (typeof secrets !== \"object\" || !(\"managementApiUrl\" in secrets)) {\n reject(\"Secrets send by Dev Portal are invalid\");\n }\n\n resolve(secrets);\n };\n\n self.addEventListener(\"message\", receiveSecrets);\n\n const message = {\n [APIM_ASK_FOR_SECRETS_MESSAGE_KEY]: {\n instanceId,\n origin: self.location.origin,\n targetModule,\n },\n };\n\n if (targetModule === \"app\" && environment === \"development\") {\n self.parent.parent.postMessage(message, \"*\");\n } else {\n self.parent.postMessage(message, \"*\");\n }\n });\n\n return promise.finally(() => self.removeEventListener(\"message\", receiveSecrets));\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/** root of the blob storage folder */\nexport const BLOB_ROOT = \"custom-widgets\";\n/** name of the blob storage folder with widget implementation */\nexport const BLOB_DATA_FOLDER = \"data\";\n/** name of the blob storage folder with widget configs */\nexport const BLOB_CONFIGS_FOLDER = \"configs\";\n/** name of the configuration file */\nexport const APIM_CONFIG_FILE_NAME = \"config.msapim.json\";\n\n/**\n * Generate relative path for widgets' data on the blob storage\n *\n * @param name - name of the widget\n */\nexport function buildBlobDataPath(name: string): string {\n return `${BLOB_ROOT}/${BLOB_DATA_FOLDER}/${name}/`;\n}\n\n/**\n * Generate relative path for widgets' config on the blob storage\n *\n * @param name - name of the widget\n */\nexport function buildBlobConfigPath(name: string): string {\n return `${BLOB_ROOT}/${BLOB_CONFIGS_FOLDER}/${name}/${APIM_CONFIG_FILE_NAME}`;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { BlobServiceClient, BlockBlobUploadResponse } from \"@azure/storage-blob\";\nimport { buildBlobConfigPath, buildBlobDataPath } from \"../paths\";\nimport mime from \"mime\";\n\nexport type Config = Record<string, unknown>;\n\n/**\n * A service wrapping ContainerClient class to simplify blob handling\n */\nexport class CustomWidgetBlobService {\n readonly containerClient;\n readonly name;\n readonly pathWidget;\n readonly pathConfig;\n\n /**\n * @param blobStorageUrl - blob storage SAS URL\n * @param name - name of the custom widget to be taken care of\n */\n constructor(blobStorageUrl: string, name: string) {\n const container = \"content\";\n const blobServiceClient = new BlobServiceClient(blobStorageUrl.replace(`/${container}`, \"\"));\n this.containerClient = blobServiceClient.getContainerClient(container);\n this.name = name;\n this.pathWidget = buildBlobDataPath(name);\n this.pathConfig = buildBlobConfigPath(name);\n }\n\n private extractFileName(path: string): string | undefined {\n return path.split(\"/\").pop();\n }\n\n async blobUpload(absolutePath: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n const fileName = this.extractFileName(absolutePath);\n if (!fileName) throw new Error(\"a fileName was not found in the absolutePath\");\n return this.containerClient.getBlockBlobClient(absolutePath).upload(content, content.length, {\n blobHTTPHeaders: { blobContentType: mime.getType(fileName) || \"application/octet-stream\" },\n });\n }\n\n async jsonUpload(\n absolutePath: string,\n json: Record<string, unknown>\n ): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(absolutePath, Buffer.from(JSON.stringify(json)));\n }\n\n async blobDownload(absolutePath: string): Promise<Buffer> {\n return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();\n }\n\n async dirDelete(absolutePath: string): Promise<void> {\n for await (const blob of await this.containerClient.listBlobsFlat({ prefix: absolutePath })) {\n await this.containerClient.deleteBlob(blob.name);\n }\n }\n\n async uploadWidgetDataFile(file: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(this.pathWidget + file, content);\n }\n\n async cleanDataDir(): Promise<void> {\n return this.dirDelete(this.pathWidget);\n }\n\n async getConfig(): Promise<Config> {\n const buffer = await this.blobDownload(this.pathConfig);\n return JSON.parse(buffer.toString());\n }\n\n async uploadConfig(config: Config): Promise<BlockBlobUploadResponse> {\n return this.jsonUpload(this.pathConfig, config);\n }\n}\n\nexport default CustomWidgetBlobService;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveBrowserCredential } from \"@azure/identity\";\nimport { ServiceInformation } from \"./deploy\";\nimport { getClient } from \"@azure-rest/core-client\";\n\nasync function getAccessToken(managementApiEndpoint: string): Promise<string> {\n const credentials = new InteractiveBrowserCredential();\n const scope = `${managementApiEndpoint}/user_impersonation`;\n const { token } = await credentials.getToken(scope);\n return `Bearer ${token}`;\n}\n\n/**\n * Function to get storage SAS URL.\n *\n * @returns storage SAS URL\n */\nasync function getStorageSasUrl({\n managementApiEndpoint,\n resourceId,\n apiVersion = \"2019-01-01\",\n tokenOverride,\n}: ServiceInformation): Promise<string> {\n const httpClient = getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });\n const response = await httpClient\n .pathUnchecked(`/portalSettings/mediaContent/listSecrets?apiVersion=${apiVersion}`) // TODO\n .post({\n headers: {\n \"If-Match\": \"*\",\n \"Content-Type\": \"application/json\",\n Authorization: tokenOverride ?? (await getAccessToken(managementApiEndpoint)),\n },\n });\n\n if (!response?.body?.containerSasUrl) throw new Error(\"Could not get storage SAS URL\");\n return response.body.containerSasUrl;\n}\n\nexport default getStorageSasUrl;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport fs from \"fs\";\nimport path from \"path\";\n\nfunction readdir(dir: string, root: string): string[] {\n const results: string[] = [];\n\n fs.readdirSync(root + dir).forEach((file) => {\n const stat = fs.statSync(root + dir + path.sep + file);\n if (stat && stat.isDirectory()) {\n results.push(...readdir(dir + file + path.sep, root));\n } else {\n results.push(dir + file);\n }\n });\n\n return results;\n}\n\nexport default readdir;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport CustomWidgetBlobService, { Config } from \"./CustomWidgetBlobService\";\nimport { APIM_CONFIG_FILE_NAME } from \"../paths\";\nimport fs from \"fs\";\nimport getStorageSasUrl from \"./getStorageSasUrl\";\nimport readdir from \"./readdir\";\n\n/**\n * resourceId - resource ID of API Management service \"subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.ApiManagement/service/[service-name]\"\n * managementApiEndpoint - URL with protocol (e.g. https://management.azure.com)\n * apiVersion - optional to override default (e.g. \"2019-01-01\")\n * tokenOverride - optional, provides token to use for auth, instead of 'az login' approach\n */\nexport type ServiceInformation = {\n resourceId: string;\n managementApiEndpoint: string;\n apiVersion?: string;\n tokenOverride?: string;\n};\n\n/**\n * Deploys everything from /dist folder to the API Management DevPortals' blob storage.\n *\n * @param serviceInformation - service information for deployment\n * @param name - name of the widget to be deployed\n * @param fallbackConfigPath - local path to the config file (by default \"./static/config.msapim.json\")\n * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default \"./dist\")\n */\nasync function deploy(\n serviceInformation: ServiceInformation,\n name: string,\n fallbackConfigPath = \"./static/\" + APIM_CONFIG_FILE_NAME,\n rootLocal: string = \"./dist/\"\n): Promise<void> {\n console.log(\"\\n\\n\");\n console.log(\"Starting deploy process of custom widget: \" + name);\n console.log(\"Please, sign in to your Azure account when prompted\\n\");\n\n const blobStorageUrl = await getStorageSasUrl(serviceInformation);\n const customWidgetBlobService = new CustomWidgetBlobService(blobStorageUrl, name);\n\n let config: Config | undefined;\n try {\n console.log(\"Looking for config file in the Azure blob storage\");\n config = await customWidgetBlobService.getConfig();\n } catch (e) {\n console.log(\"Config not found.\");\n }\n if (!config) {\n console.log(\"Looking for a local config file in: \" + fallbackConfigPath);\n config = JSON.parse(fs.readFileSync(fallbackConfigPath).toString());\n }\n if (!config) {\n throw new Error(\"Config file could not be loaded.\");\n }\n\n console.log(\"Config file loaded\\n\");\n\n const files = readdir(\"\", rootLocal);\n\n console.log(\"Starting upload of data files from the '\" + rootLocal + \"' folder\\n\");\n\n await customWidgetBlobService.cleanDataDir();\n\n const promises: Promise<void>[] = [];\n files.forEach((file) => {\n const content = fs.readFileSync(rootLocal + file);\n const promise = customWidgetBlobService\n .uploadWidgetDataFile(file, content)\n .then(() => console.log(\"Uploaded file: \" + file));\n promises.push(promise);\n });\n await Promise.all(promises);\n\n console.log(files.length + \" files has been uploaded\\n\");\n\n config.deployedOn = new Date();\n await customWidgetBlobService.uploadConfig(config);\n console.log(\"Uploaded updated config\");\n}\n\nexport default deploy;\n"],"names":["BlobServiceClient","mime","__asyncValues","InteractiveBrowserCredential","getClient","fs","path","CustomWidgetBlobService"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/paths.ts","../src/node/CustomWidgetBlobService.ts","../src/node/getStorageSasUrl.ts","../src/node/readdir.ts","../src/node/deploy.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Key for a search param, from which editor data will be loaded from.\n */\nexport const APIM_EDITOR_DATA_KEY = \"editorData\";\n/**\n * Key for a post message object, it's used to propagate changes from editor to the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ON_CHANGE_MESSAGE_KEY = \"customInputValueChangedMSAPIM\";\n/**\n * Key for a post message object, it's used to request and send secrets - token and user id, from the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ASK_FOR_SECRETS_MESSAGE_KEY = \"askForSecretsMSAPIM\";\n\n/**\n * Base of a values obj\n */\nexport type ValuesCommon = Record<string, unknown>;\n/**\n * All possible runtime environments\n */\nexport type Environment = \"development\" | \"publishing\" | \"runtime\" | \"error\";\n\n/** Information about the widget instance received from the Dev Portal */\nexport interface PortalData {\n // /** web content's origin (URL) of your Dev Portal */\n // origin: string;\n /** current runtime environment */\n environment: Environment;\n /** ID of this particular instance of the widget */\n instanceId: string;\n}\n\n/** JSON object with all the data you'll receive from the Dev Portal */\nexport interface EditorData<Values extends ValuesCommon> extends PortalData {\n /** values you've set in the admin editor window */\n values: Partial<Values>;\n}\n\nfunction parseWidgetData<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n try {\n const urlEditorParams: EditorData<Values> = JSON.parse(\n decodeURIComponent(urlSearchParams.get(APIM_EDITOR_DATA_KEY) ?? \"\")\n );\n\n // if (!(\"origin\" in urlEditorParams)) {\n // console.error(\n // \"Could not get 'origin' from the search params of the URL:\\n\" + self.location.href\n // );\n // }\n return urlEditorParams;\n } catch (e) {\n console.error(\n `Could not get '${APIM_EDITOR_DATA_KEY}' from the search params of the URL:\\n` +\n self.location,\n e\n );\n return { values: {}, environment: \"error\", instanceId: \"error\" };\n }\n}\n\nexport function getWidgetDataPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n return parseWidgetData<Values>(urlSearchParams);\n}\n\n/**\n * Function to get all data related to the widget including technical values not expected to be needed in most cases.\n * Intended mostly for internal use, API might change. Consider using getValues or getEditorValues instead.\n */\nexport function getWidgetData<Values extends ValuesCommon>(): EditorData<Values> {\n return getWidgetDataPure(new URLSearchParams(self.location.search));\n}\n\nexport function getEditorValuesPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): Partial<Values> {\n return getWidgetDataPure<Values>(urlSearchParams).values;\n}\n\n/**\n * Function to get values you've set in the admin editor window.\n */\nexport function getEditorValues<Values extends ValuesCommon>(): Partial<Values> {\n return getEditorValuesPure<Values>(new URLSearchParams(self.location.search));\n}\n\nexport function getValuesPure<Values extends ValuesCommon>(\n valuesDefault: Values,\n urlSearchParams: URLSearchParams\n): Values {\n const values = { ...valuesDefault }; // set Obj to contain all possible values and prefill default value\n const urlValues = parseWidgetData<Values>(urlSearchParams).values;\n\n Object.keys(values).forEach((key: keyof Values) => {\n const value = urlValues[key];\n if (value != null) values[key] = value as Values[typeof key]; // if value is specified in the URL, replace the default value\n });\n return values;\n}\n\n/**\n * Function to get values you've set in the admin editor window. Undefined/empty values are replaced with default values.\n *\n * @param valuesDefault - object with your default values to use, just import valuesDefault object from values.ts folder\n */\nexport function getValues<Values extends ValuesCommon>(valuesDefault: Values): Values {\n return getValuesPure(valuesDefault, new URLSearchParams(self.location.search));\n}\n\n/**\n * Type of the onChange function.\n */\nexport type OnChange<Values extends ValuesCommon> = (values: Partial<Values>) => void;\n\n/**\n * The onChange function itself with 'origin' provided as a param.\n *\n * @param origin - web content's origin (URL) of your Dev Portal to send changes to\n * @param instanceId - ID of this particular instance of the widget\n * @param values - values that changed\n */\nexport function onChangeWithOrigin<Values extends ValuesCommon>(\n origin: string,\n instanceId: string,\n values: Values\n): void {\n Object.entries(values).forEach(([key, value]) => {\n self.parent.postMessage({ [APIM_ON_CHANGE_MESSAGE_KEY]: { key, value, instanceId } }, origin);\n });\n}\n\n/**\n * Build onChange function, which you can use, to send changed data from the editor.\n */\nexport function buildOnChange<Values extends ValuesCommon>(): OnChange<Values> {\n const { instanceId } = getWidgetData();\n return (values: Partial<Values>) => onChangeWithOrigin(\"*\", instanceId, values);\n}\n\n/**\n * Possible target modules\n * \"app\" for main application which is embedded in your Dev Portal\n * \"editor\" for form in admin panel\n */\nexport type TargetModule = \"app\" | \"editor\";\n/**\n * Secrets needed for communication with Dev Portal back-end and other runtime data\n */\nexport type Secrets = {\n managementApiUrl: string;\n apiVersion: string;\n userId?: string;\n token?: string;\n parentLocation: {\n host: string;\n hostname: string;\n href: string;\n origin: string;\n pathname: string;\n port: string;\n protocol: string;\n search: string;\n };\n};\n\n/**\n * Request secrets - token & userId, from the Dev portal parent window.\n *\n * @param targetModule - is the function invoke from the main \"app\" window or the admin \"editor\"?\n */\nexport async function askForSecrets(targetModule: TargetModule): Promise<Secrets> {\n let receiveSecrets: (e: MessageEvent) => void;\n\n const promise = new Promise<Secrets>((resolve, reject) => {\n const { instanceId, environment }: PortalData = getWidgetData();\n\n receiveSecrets = ({ data }) => {\n if (!(APIM_ASK_FOR_SECRETS_MESSAGE_KEY in data)) return;\n\n const secrets = data[APIM_ASK_FOR_SECRETS_MESSAGE_KEY];\n if (typeof secrets !== \"object\" || !(\"managementApiUrl\" in secrets)) {\n reject(\"Secrets send by Dev Portal are invalid\");\n }\n\n resolve(secrets);\n };\n\n self.addEventListener(\"message\", receiveSecrets);\n\n const message = {\n [APIM_ASK_FOR_SECRETS_MESSAGE_KEY]: {\n instanceId,\n origin: self.location.origin,\n targetModule,\n },\n };\n\n if (targetModule === \"app\" && environment === \"development\") {\n self.parent.parent.postMessage(message, \"*\");\n } else {\n self.parent.postMessage(message, \"*\");\n }\n });\n\n return promise.finally(() => self.removeEventListener(\"message\", receiveSecrets));\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/** root of the blob storage folder */\nexport const BLOB_ROOT = \"custom-widgets\";\n/** name of the blob storage folder with widget implementation */\nexport const BLOB_DATA_FOLDER = \"data\";\n/** name of the blob storage folder with widget configs */\nexport const BLOB_CONFIGS_FOLDER = \"configs\";\n/** name of the configuration file */\nexport const APIM_CONFIG_FILE_NAME = \"config.msapim.json\";\n\n/**\n * Generate relative path for widgets' data on the blob storage\n *\n * @param name - name of the widget\n */\nexport function buildBlobDataPath(name: string): string {\n return `${BLOB_ROOT}/${BLOB_DATA_FOLDER}/${name}/`;\n}\n\n/**\n * Generate relative path for widgets' config on the blob storage\n *\n * @param name - name of the widget\n */\nexport function buildBlobConfigPath(name: string): string {\n return `${BLOB_ROOT}/${BLOB_CONFIGS_FOLDER}/${name}/${APIM_CONFIG_FILE_NAME}`;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { BlobServiceClient, BlockBlobUploadResponse } from \"@azure/storage-blob\";\nimport { buildBlobConfigPath, buildBlobDataPath } from \"../paths\";\nimport mime from \"mime\";\n\nexport type Config = Record<string, unknown>;\n\n/**\n * A service wrapping ContainerClient class to simplify blob handling\n */\nexport class CustomWidgetBlobService {\n readonly containerClient;\n readonly name;\n readonly pathWidget;\n readonly pathConfig;\n\n /**\n * @param blobStorageUrl - blob storage SAS URL\n * @param name - name of the custom widget to be taken care of\n */\n constructor(blobStorageUrl: string, name: string) {\n const container = \"content\";\n const blobServiceClient = new BlobServiceClient(blobStorageUrl.replace(`/${container}`, \"\"));\n this.containerClient = blobServiceClient.getContainerClient(container);\n this.name = name;\n this.pathWidget = buildBlobDataPath(name);\n this.pathConfig = buildBlobConfigPath(name);\n }\n\n private extractFileName(path: string): string | undefined {\n return path.split(\"/\").pop();\n }\n\n async blobUpload(absolutePath: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n const fileName = this.extractFileName(absolutePath);\n if (!fileName) throw new Error(\"a fileName was not found in the absolutePath\");\n return this.containerClient.getBlockBlobClient(absolutePath).upload(content, content.length, {\n blobHTTPHeaders: { blobContentType: mime.getType(fileName) || \"application/octet-stream\" },\n });\n }\n\n async jsonUpload(\n absolutePath: string,\n json: Record<string, unknown>\n ): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(absolutePath, Buffer.from(JSON.stringify(json)));\n }\n\n async blobDownload(absolutePath: string): Promise<Buffer> {\n return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();\n }\n\n async dirDelete(absolutePath: string): Promise<void> {\n for await (const blob of await this.containerClient.listBlobsFlat({ prefix: absolutePath })) {\n await this.containerClient.deleteBlob(blob.name);\n }\n }\n\n async uploadWidgetDataFile(file: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(this.pathWidget + file, content);\n }\n\n async cleanDataDir(): Promise<void> {\n return this.dirDelete(this.pathWidget);\n }\n\n async getConfig(): Promise<Config> {\n const buffer = await this.blobDownload(this.pathConfig);\n return JSON.parse(buffer.toString());\n }\n\n async uploadConfig(config: Config): Promise<BlockBlobUploadResponse> {\n return this.jsonUpload(this.pathConfig, config);\n }\n}\n\nexport default CustomWidgetBlobService;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n InteractiveBrowserCredential,\n InteractiveBrowserCredentialNodeOptions as IBCNOptions,\n} from \"@azure/identity\";\nimport { ServiceInformation } from \"./deploy\";\nimport { getClient } from \"@azure-rest/core-client\";\n\nasync function getAccessToken(\n managementApiEndpoint: string,\n options?: IBCNOptions\n): Promise<string> {\n const credentials = new InteractiveBrowserCredential(options);\n const scope = `${managementApiEndpoint}/user_impersonation`;\n const { token } = await credentials.getToken(scope);\n return `Bearer ${token}`;\n}\n\n/**\n * Function to get storage SAS URL.\n *\n * @returns storage SAS URL\n */\nasync function getStorageSasUrl(\n {\n managementApiEndpoint,\n resourceId,\n apiVersion = \"2019-01-01\",\n tokenOverride,\n }: ServiceInformation,\n interactiveBrowserCredentialOptions?: IBCNOptions\n): Promise<string> {\n const httpClient = getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });\n const response = await httpClient\n .pathUnchecked(`/portalSettings/mediaContent/listSecrets?apiVersion=${apiVersion}`) // TODO\n .post({\n headers: {\n \"If-Match\": \"*\",\n \"Content-Type\": \"application/json\",\n Authorization:\n tokenOverride ??\n (await getAccessToken(managementApiEndpoint, interactiveBrowserCredentialOptions)),\n },\n });\n\n if (!response?.body?.containerSasUrl) throw new Error(\"Could not get storage SAS URL\");\n return response.body.containerSasUrl;\n}\n\nexport default getStorageSasUrl;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport fs from \"fs\";\nimport path from \"path\";\n\nfunction readdir(dir: string, root: string): string[] {\n const results: string[] = [];\n\n fs.readdirSync(root + dir).forEach((file) => {\n const stat = fs.statSync(root + dir + path.sep + file);\n if (stat && stat.isDirectory()) {\n results.push(...readdir(dir + file + path.sep, root));\n } else {\n results.push(dir + file);\n }\n });\n\n return results;\n}\n\nexport default readdir;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport CustomWidgetBlobService, { Config } from \"./CustomWidgetBlobService\";\nimport { InteractiveBrowserCredentialNodeOptions } from \"@azure/identity\";\nimport { APIM_CONFIG_FILE_NAME } from \"../paths\";\nimport fs from \"fs\";\nimport getStorageSasUrl from \"./getStorageSasUrl\";\nimport readdir from \"./readdir\";\n\n/**\n * resourceId - resource ID of API Management service \"subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.ApiManagement/service/[service-name]\"\n * managementApiEndpoint - URL with protocol (e.g. https://management.azure.com)\n * apiVersion - optional to override default (e.g. \"2019-01-01\")\n * tokenOverride - optional, provides token to use for auth, instead of 'az login' approach\n */\nexport type ServiceInformation = {\n resourceId: string;\n managementApiEndpoint: string;\n apiVersion?: string;\n tokenOverride?: string;\n};\n\n/**\n * Optional options object for configuring the deployment function.\n *\n * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default \"./dist\")\n * @param interactiveBrowserCredentialOptions - options for InteractiveBrowserCredential for Node or InBrowser from \\@azure/identity\n */\nexport type DeployConfig = {\n rootLocal?: string;\n interactiveBrowserCredentialOptions?: InteractiveBrowserCredentialNodeOptions;\n};\n\n/**\n * Deploys everything from /dist folder to the API Management DevPortals' blob storage.\n *\n * @param serviceInformation - service information for deployment\n * @param name - name of the widget to be deployed\n * @param fallbackConfigPath - local path to the config file (by default \"./static/config.msapim.json\")\n * @param config - optional config object\n */\nasync function deploy(\n serviceInformation: ServiceInformation,\n name: string,\n fallbackConfigPath = \"./static/\" + APIM_CONFIG_FILE_NAME,\n {\n rootLocal = \"./dist/\",\n interactiveBrowserCredentialOptions = { redirectUri: \"http://localhost:1337\" },\n }: DeployConfig = {}\n): Promise<void> {\n console.log(\"\\n\\n\");\n console.log(\"Starting deploy process of custom widget: \" + name);\n console.log(\"Please, sign in to your Azure account when prompted\\n\");\n\n const blobStorageUrl = await getStorageSasUrl(\n serviceInformation,\n interactiveBrowserCredentialOptions\n );\n const customWidgetBlobService = new CustomWidgetBlobService(blobStorageUrl, name);\n\n let config: Config | undefined;\n try {\n console.log(\"Looking for config file in the Azure blob storage\");\n config = await customWidgetBlobService.getConfig();\n } catch (e) {\n console.log(\"Config not found.\");\n }\n if (!config) {\n console.log(\"Looking for a local config file in: \" + fallbackConfigPath);\n config = JSON.parse(fs.readFileSync(fallbackConfigPath).toString());\n }\n if (!config) {\n throw new Error(\"Config file could not be loaded.\");\n }\n\n console.log(\"Config file loaded\\n\");\n\n const files = readdir(\"\", rootLocal);\n\n console.log(\"Starting upload of data files from the '\" + rootLocal + \"' folder\\n\");\n\n await customWidgetBlobService.cleanDataDir();\n\n const promises: Promise<void>[] = [];\n files.forEach((file) => {\n const content = fs.readFileSync(rootLocal + file);\n const promise = customWidgetBlobService\n .uploadWidgetDataFile(file, content)\n .then(() => console.log(\"Uploaded file: \" + file));\n promises.push(promise);\n });\n await Promise.all(promises);\n\n console.log(files.length + \" files has been uploaded\\n\");\n\n config.deployedOn = new Date();\n await customWidgetBlobService.uploadConfig(config);\n console.log(\"Uploaded updated config\");\n}\n\nexport default deploy;\n"],"names":["BlobServiceClient","__asyncValues","InteractiveBrowserCredential","getClient","CustomWidgetBlobService"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,gCAAgC,EAChC,aAAa,EACb,eAAe,EACf,SAAS,EACT,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAUjB,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * @packageDocumentation https://aka.ms/apimdocs/portal/customwidgets\n */\n\nexport {\n APIM_EDITOR_DATA_KEY,\n APIM_ON_CHANGE_MESSAGE_KEY,\n APIM_ASK_FOR_SECRETS_MESSAGE_KEY,\n getWidgetData,\n getEditorValues,\n getValues,\n askForSecrets,\n buildOnChange,\n onChangeWithOrigin,\n} from \"./utils\";\nexport type {\n PortalData,\n EditorData,\n OnChange,\n Secrets,\n TargetModule,\n ValuesCommon,\n Environment,\n} from \"./utils\";\nexport {\n BLOB_ROOT,\n APIM_CONFIG_FILE_NAME,\n BLOB_DATA_FOLDER,\n BLOB_CONFIGS_FOLDER,\n buildBlobDataPath,\n buildBlobConfigPath,\n} from \"./paths\";\n\nimport deployNodeJS from \"./node/deploy\";\nexport { deployNodeJS };\nexport type { ServiceInformation } from \"./node/deploy\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,gCAAgC,EAChC,aAAa,EACb,eAAe,EACf,SAAS,EACT,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAUjB,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * @packageDocumentation https://aka.ms/apimdocs/portal/customwidgets\n */\n\nexport {\n APIM_EDITOR_DATA_KEY,\n APIM_ON_CHANGE_MESSAGE_KEY,\n APIM_ASK_FOR_SECRETS_MESSAGE_KEY,\n getWidgetData,\n getEditorValues,\n getValues,\n askForSecrets,\n buildOnChange,\n onChangeWithOrigin,\n} from \"./utils\";\nexport type {\n PortalData,\n EditorData,\n OnChange,\n Secrets,\n TargetModule,\n ValuesCommon,\n Environment,\n} from \"./utils\";\nexport {\n BLOB_ROOT,\n APIM_CONFIG_FILE_NAME,\n BLOB_DATA_FOLDER,\n BLOB_CONFIGS_FOLDER,\n buildBlobDataPath,\n buildBlobConfigPath,\n} from \"./paths\";\n\nimport deployNodeJS from \"./node/deploy\";\nexport { deployNodeJS };\nexport type { ServiceInformation, DeployConfig } from \"./node/deploy\";\n"]}
@@ -38,17 +38,24 @@ export class CustomWidgetBlobService {
38
38
  return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();
39
39
  }
40
40
  async dirDelete(absolutePath) {
41
- var e_1, _a;
41
+ var _a, e_1, _b, _c;
42
42
  try {
43
- for (var _b = __asyncValues(await this.containerClient.listBlobsFlat({ prefix: absolutePath })), _c; _c = await _b.next(), !_c.done;) {
44
- const blob = _c.value;
45
- await this.containerClient.deleteBlob(blob.name);
43
+ for (var _d = true, _e = __asyncValues(await this.containerClient.listBlobsFlat({ prefix: absolutePath })), _f; _f = await _e.next(), _a = _f.done, !_a;) {
44
+ _c = _f.value;
45
+ _d = false;
46
+ try {
47
+ const blob = _c;
48
+ await this.containerClient.deleteBlob(blob.name);
49
+ }
50
+ finally {
51
+ _d = true;
52
+ }
46
53
  }
47
54
  }
48
55
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
49
56
  finally {
50
57
  try {
51
- if (_c && !_c.done && (_a = _b.return)) await _a.call(_b);
58
+ if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
52
59
  }
53
60
  finally { if (e_1) throw e_1.error; }
54
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CustomWidgetBlobService.js","sourceRoot":"","sources":["../../../src/node/CustomWidgetBlobService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { BlobServiceClient, BlockBlobUploadResponse } from \"@azure/storage-blob\";\nimport { buildBlobConfigPath, buildBlobDataPath } from \"../paths\";\nimport mime from \"mime\";\n\nexport type Config = Record<string, unknown>;\n\n/**\n * A service wrapping ContainerClient class to simplify blob handling\n */\nexport class CustomWidgetBlobService {\n readonly containerClient;\n readonly name;\n readonly pathWidget;\n readonly pathConfig;\n\n /**\n * @param blobStorageUrl - blob storage SAS URL\n * @param name - name of the custom widget to be taken care of\n */\n constructor(blobStorageUrl: string, name: string) {\n const container = \"content\";\n const blobServiceClient = new BlobServiceClient(blobStorageUrl.replace(`/${container}`, \"\"));\n this.containerClient = blobServiceClient.getContainerClient(container);\n this.name = name;\n this.pathWidget = buildBlobDataPath(name);\n this.pathConfig = buildBlobConfigPath(name);\n }\n\n private extractFileName(path: string): string | undefined {\n return path.split(\"/\").pop();\n }\n\n async blobUpload(absolutePath: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n const fileName = this.extractFileName(absolutePath);\n if (!fileName) throw new Error(\"a fileName was not found in the absolutePath\");\n return this.containerClient.getBlockBlobClient(absolutePath).upload(content, content.length, {\n blobHTTPHeaders: { blobContentType: mime.getType(fileName) || \"application/octet-stream\" },\n });\n }\n\n async jsonUpload(\n absolutePath: string,\n json: Record<string, unknown>\n ): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(absolutePath, Buffer.from(JSON.stringify(json)));\n }\n\n async blobDownload(absolutePath: string): Promise<Buffer> {\n return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();\n }\n\n async dirDelete(absolutePath: string): Promise<void> {\n for await (const blob of await this.containerClient.listBlobsFlat({ prefix: absolutePath })) {\n await this.containerClient.deleteBlob(blob.name);\n }\n }\n\n async uploadWidgetDataFile(file: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(this.pathWidget + file, content);\n }\n\n async cleanDataDir(): Promise<void> {\n return this.dirDelete(this.pathWidget);\n }\n\n async getConfig(): Promise<Config> {\n const buffer = await this.blobDownload(this.pathConfig);\n return JSON.parse(buffer.toString());\n }\n\n async uploadConfig(config: Config): Promise<BlockBlobUploadResponse> {\n return this.jsonUpload(this.pathConfig, config);\n }\n}\n\nexport default CustomWidgetBlobService;\n"]}
1
+ {"version":3,"file":"CustomWidgetBlobService.js","sourceRoot":"","sources":["../../../src/node/CustomWidgetBlobService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { BlobServiceClient, BlockBlobUploadResponse } from \"@azure/storage-blob\";\nimport { buildBlobConfigPath, buildBlobDataPath } from \"../paths\";\nimport mime from \"mime\";\n\nexport type Config = Record<string, unknown>;\n\n/**\n * A service wrapping ContainerClient class to simplify blob handling\n */\nexport class CustomWidgetBlobService {\n readonly containerClient;\n readonly name;\n readonly pathWidget;\n readonly pathConfig;\n\n /**\n * @param blobStorageUrl - blob storage SAS URL\n * @param name - name of the custom widget to be taken care of\n */\n constructor(blobStorageUrl: string, name: string) {\n const container = \"content\";\n const blobServiceClient = new BlobServiceClient(blobStorageUrl.replace(`/${container}`, \"\"));\n this.containerClient = blobServiceClient.getContainerClient(container);\n this.name = name;\n this.pathWidget = buildBlobDataPath(name);\n this.pathConfig = buildBlobConfigPath(name);\n }\n\n private extractFileName(path: string): string | undefined {\n return path.split(\"/\").pop();\n }\n\n async blobUpload(absolutePath: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n const fileName = this.extractFileName(absolutePath);\n if (!fileName) throw new Error(\"a fileName was not found in the absolutePath\");\n return this.containerClient.getBlockBlobClient(absolutePath).upload(content, content.length, {\n blobHTTPHeaders: { blobContentType: mime.getType(fileName) || \"application/octet-stream\" },\n });\n }\n\n async jsonUpload(\n absolutePath: string,\n json: Record<string, unknown>\n ): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(absolutePath, Buffer.from(JSON.stringify(json)));\n }\n\n async blobDownload(absolutePath: string): Promise<Buffer> {\n return this.containerClient.getBlockBlobClient(absolutePath).downloadToBuffer();\n }\n\n async dirDelete(absolutePath: string): Promise<void> {\n for await (const blob of await this.containerClient.listBlobsFlat({ prefix: absolutePath })) {\n await this.containerClient.deleteBlob(blob.name);\n }\n }\n\n async uploadWidgetDataFile(file: string, content: Buffer): Promise<BlockBlobUploadResponse> {\n return this.blobUpload(this.pathWidget + file, content);\n }\n\n async cleanDataDir(): Promise<void> {\n return this.dirDelete(this.pathWidget);\n }\n\n async getConfig(): Promise<Config> {\n const buffer = await this.blobDownload(this.pathConfig);\n return JSON.parse(buffer.toString());\n }\n\n async uploadConfig(config: Config): Promise<BlockBlobUploadResponse> {\n return this.jsonUpload(this.pathConfig, config);\n }\n}\n\nexport default CustomWidgetBlobService;\n"]}
@@ -11,13 +11,13 @@ import readdir from "./readdir";
11
11
  * @param serviceInformation - service information for deployment
12
12
  * @param name - name of the widget to be deployed
13
13
  * @param fallbackConfigPath - local path to the config file (by default "./static/config.msapim.json")
14
- * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default "./dist")
14
+ * @param config - optional config object
15
15
  */
16
- async function deploy(serviceInformation, name, fallbackConfigPath = "./static/" + APIM_CONFIG_FILE_NAME, rootLocal = "./dist/") {
16
+ async function deploy(serviceInformation, name, fallbackConfigPath = "./static/" + APIM_CONFIG_FILE_NAME, { rootLocal = "./dist/", interactiveBrowserCredentialOptions = { redirectUri: "http://localhost:1337" }, } = {}) {
17
17
  console.log("\n\n");
18
18
  console.log("Starting deploy process of custom widget: " + name);
19
19
  console.log("Please, sign in to your Azure account when prompted\n");
20
- const blobStorageUrl = await getStorageSasUrl(serviceInformation);
20
+ const blobStorageUrl = await getStorageSasUrl(serviceInformation, interactiveBrowserCredentialOptions);
21
21
  const customWidgetBlobService = new CustomWidgetBlobService(blobStorageUrl, name);
22
22
  let config;
23
23
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/node/deploy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,uBAAmC,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,OAAO,MAAM,WAAW,CAAC;AAehC;;;;;;;GAOG;AACH,KAAK,UAAU,MAAM,CACnB,kBAAsC,EACtC,IAAY,EACZ,kBAAkB,GAAG,WAAW,GAAG,qBAAqB,EACxD,YAAoB,SAAS;IAE7B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,4CAA4C,GAAG,IAAI,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IAErE,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAClE,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAElF,IAAI,MAA0B,CAAC;IAC/B,IAAI;QACF,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,MAAM,GAAG,MAAM,uBAAuB,CAAC,SAAS,EAAE,CAAC;KACpD;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;KAClC;IACD,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,kBAAkB,CAAC,CAAC;QACzE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;KACrE;IACD,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;KACrD;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAErC,OAAO,CAAC,GAAG,CAAC,0CAA0C,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;IAEnF,MAAM,uBAAuB,CAAC,YAAY,EAAE,CAAC;IAE7C,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,uBAAuB;aACpC,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC;aACnC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,4BAA4B,CAAC,CAAC;IAEzD,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;IAC/B,MAAM,uBAAuB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AACzC,CAAC;AAED,eAAe,MAAM,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport CustomWidgetBlobService, { Config } from \"./CustomWidgetBlobService\";\nimport { APIM_CONFIG_FILE_NAME } from \"../paths\";\nimport fs from \"fs\";\nimport getStorageSasUrl from \"./getStorageSasUrl\";\nimport readdir from \"./readdir\";\n\n/**\n * resourceId - resource ID of API Management service \"subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.ApiManagement/service/[service-name]\"\n * managementApiEndpoint - URL with protocol (e.g. https://management.azure.com)\n * apiVersion - optional to override default (e.g. \"2019-01-01\")\n * tokenOverride - optional, provides token to use for auth, instead of 'az login' approach\n */\nexport type ServiceInformation = {\n resourceId: string;\n managementApiEndpoint: string;\n apiVersion?: string;\n tokenOverride?: string;\n};\n\n/**\n * Deploys everything from /dist folder to the API Management DevPortals' blob storage.\n *\n * @param serviceInformation - service information for deployment\n * @param name - name of the widget to be deployed\n * @param fallbackConfigPath - local path to the config file (by default \"./static/config.msapim.json\")\n * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default \"./dist\")\n */\nasync function deploy(\n serviceInformation: ServiceInformation,\n name: string,\n fallbackConfigPath = \"./static/\" + APIM_CONFIG_FILE_NAME,\n rootLocal: string = \"./dist/\"\n): Promise<void> {\n console.log(\"\\n\\n\");\n console.log(\"Starting deploy process of custom widget: \" + name);\n console.log(\"Please, sign in to your Azure account when prompted\\n\");\n\n const blobStorageUrl = await getStorageSasUrl(serviceInformation);\n const customWidgetBlobService = new CustomWidgetBlobService(blobStorageUrl, name);\n\n let config: Config | undefined;\n try {\n console.log(\"Looking for config file in the Azure blob storage\");\n config = await customWidgetBlobService.getConfig();\n } catch (e) {\n console.log(\"Config not found.\");\n }\n if (!config) {\n console.log(\"Looking for a local config file in: \" + fallbackConfigPath);\n config = JSON.parse(fs.readFileSync(fallbackConfigPath).toString());\n }\n if (!config) {\n throw new Error(\"Config file could not be loaded.\");\n }\n\n console.log(\"Config file loaded\\n\");\n\n const files = readdir(\"\", rootLocal);\n\n console.log(\"Starting upload of data files from the '\" + rootLocal + \"' folder\\n\");\n\n await customWidgetBlobService.cleanDataDir();\n\n const promises: Promise<void>[] = [];\n files.forEach((file) => {\n const content = fs.readFileSync(rootLocal + file);\n const promise = customWidgetBlobService\n .uploadWidgetDataFile(file, content)\n .then(() => console.log(\"Uploaded file: \" + file));\n promises.push(promise);\n });\n await Promise.all(promises);\n\n console.log(files.length + \" files has been uploaded\\n\");\n\n config.deployedOn = new Date();\n await customWidgetBlobService.uploadConfig(config);\n console.log(\"Uploaded updated config\");\n}\n\nexport default deploy;\n"]}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/node/deploy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,uBAAmC,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,OAAO,MAAM,WAAW,CAAC;AA0BhC;;;;;;;GAOG;AACH,KAAK,UAAU,MAAM,CACnB,kBAAsC,EACtC,IAAY,EACZ,kBAAkB,GAAG,WAAW,GAAG,qBAAqB,EACxD,EACE,SAAS,GAAG,SAAS,EACrB,mCAAmC,GAAG,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAC9D,EAAE;IAEpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,4CAA4C,GAAG,IAAI,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IAErE,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAC3C,kBAAkB,EAClB,mCAAmC,CACpC,CAAC;IACF,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAElF,IAAI,MAA0B,CAAC;IAC/B,IAAI;QACF,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,MAAM,GAAG,MAAM,uBAAuB,CAAC,SAAS,EAAE,CAAC;KACpD;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;KAClC;IACD,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,kBAAkB,CAAC,CAAC;QACzE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;KACrE;IACD,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;KACrD;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAErC,OAAO,CAAC,GAAG,CAAC,0CAA0C,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;IAEnF,MAAM,uBAAuB,CAAC,YAAY,EAAE,CAAC;IAE7C,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,uBAAuB;aACpC,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC;aACnC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,4BAA4B,CAAC,CAAC;IAEzD,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;IAC/B,MAAM,uBAAuB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AACzC,CAAC;AAED,eAAe,MAAM,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport CustomWidgetBlobService, { Config } from \"./CustomWidgetBlobService\";\nimport { InteractiveBrowserCredentialNodeOptions } from \"@azure/identity\";\nimport { APIM_CONFIG_FILE_NAME } from \"../paths\";\nimport fs from \"fs\";\nimport getStorageSasUrl from \"./getStorageSasUrl\";\nimport readdir from \"./readdir\";\n\n/**\n * resourceId - resource ID of API Management service \"subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.ApiManagement/service/[service-name]\"\n * managementApiEndpoint - URL with protocol (e.g. https://management.azure.com)\n * apiVersion - optional to override default (e.g. \"2019-01-01\")\n * tokenOverride - optional, provides token to use for auth, instead of 'az login' approach\n */\nexport type ServiceInformation = {\n resourceId: string;\n managementApiEndpoint: string;\n apiVersion?: string;\n tokenOverride?: string;\n};\n\n/**\n * Optional options object for configuring the deployment function.\n *\n * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default \"./dist\")\n * @param interactiveBrowserCredentialOptions - options for InteractiveBrowserCredential for Node or InBrowser from \\@azure/identity\n */\nexport type DeployConfig = {\n rootLocal?: string;\n interactiveBrowserCredentialOptions?: InteractiveBrowserCredentialNodeOptions;\n};\n\n/**\n * Deploys everything from /dist folder to the API Management DevPortals' blob storage.\n *\n * @param serviceInformation - service information for deployment\n * @param name - name of the widget to be deployed\n * @param fallbackConfigPath - local path to the config file (by default \"./static/config.msapim.json\")\n * @param config - optional config object\n */\nasync function deploy(\n serviceInformation: ServiceInformation,\n name: string,\n fallbackConfigPath = \"./static/\" + APIM_CONFIG_FILE_NAME,\n {\n rootLocal = \"./dist/\",\n interactiveBrowserCredentialOptions = { redirectUri: \"http://localhost:1337\" },\n }: DeployConfig = {}\n): Promise<void> {\n console.log(\"\\n\\n\");\n console.log(\"Starting deploy process of custom widget: \" + name);\n console.log(\"Please, sign in to your Azure account when prompted\\n\");\n\n const blobStorageUrl = await getStorageSasUrl(\n serviceInformation,\n interactiveBrowserCredentialOptions\n );\n const customWidgetBlobService = new CustomWidgetBlobService(blobStorageUrl, name);\n\n let config: Config | undefined;\n try {\n console.log(\"Looking for config file in the Azure blob storage\");\n config = await customWidgetBlobService.getConfig();\n } catch (e) {\n console.log(\"Config not found.\");\n }\n if (!config) {\n console.log(\"Looking for a local config file in: \" + fallbackConfigPath);\n config = JSON.parse(fs.readFileSync(fallbackConfigPath).toString());\n }\n if (!config) {\n throw new Error(\"Config file could not be loaded.\");\n }\n\n console.log(\"Config file loaded\\n\");\n\n const files = readdir(\"\", rootLocal);\n\n console.log(\"Starting upload of data files from the '\" + rootLocal + \"' folder\\n\");\n\n await customWidgetBlobService.cleanDataDir();\n\n const promises: Promise<void>[] = [];\n files.forEach((file) => {\n const content = fs.readFileSync(rootLocal + file);\n const promise = customWidgetBlobService\n .uploadWidgetDataFile(file, content)\n .then(() => console.log(\"Uploaded file: \" + file));\n promises.push(promise);\n });\n await Promise.all(promises);\n\n console.log(files.length + \" files has been uploaded\\n\");\n\n config.deployedOn = new Date();\n await customWidgetBlobService.uploadConfig(config);\n console.log(\"Uploaded updated config\");\n}\n\nexport default deploy;\n"]}
@@ -1,9 +1,9 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { InteractiveBrowserCredential } from "@azure/identity";
3
+ import { InteractiveBrowserCredential, } from "@azure/identity";
4
4
  import { getClient } from "@azure-rest/core-client";
5
- async function getAccessToken(managementApiEndpoint) {
6
- const credentials = new InteractiveBrowserCredential();
5
+ async function getAccessToken(managementApiEndpoint, options) {
6
+ const credentials = new InteractiveBrowserCredential(options);
7
7
  const scope = `${managementApiEndpoint}/user_impersonation`;
8
8
  const { token } = await credentials.getToken(scope);
9
9
  return `Bearer ${token}`;
@@ -13,7 +13,7 @@ async function getAccessToken(managementApiEndpoint) {
13
13
  *
14
14
  * @returns storage SAS URL
15
15
  */
16
- async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion = "2019-01-01", tokenOverride, }) {
16
+ async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion = "2019-01-01", tokenOverride, }, interactiveBrowserCredentialOptions) {
17
17
  var _a;
18
18
  const httpClient = getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });
19
19
  const response = await httpClient
@@ -22,7 +22,7 @@ async function getStorageSasUrl({ managementApiEndpoint, resourceId, apiVersion
22
22
  headers: {
23
23
  "If-Match": "*",
24
24
  "Content-Type": "application/json",
25
- Authorization: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : (await getAccessToken(managementApiEndpoint)),
25
+ Authorization: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : (await getAccessToken(managementApiEndpoint, interactiveBrowserCredentialOptions)),
26
26
  },
27
27
  });
28
28
  if (!((_a = response === null || response === void 0 ? void 0 : response.body) === null || _a === void 0 ? void 0 : _a.containerSasUrl))
@@ -1 +1 @@
1
- {"version":3,"file":"getStorageSasUrl.js","sourceRoot":"","sources":["../../../src/node/getStorageSasUrl.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,KAAK,UAAU,cAAc,CAAC,qBAA6B;IACzD,MAAM,WAAW,GAAG,IAAI,4BAA4B,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,GAAG,qBAAqB,qBAAqB,CAAC;IAC5D,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,UAAU,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAAC,EAC9B,qBAAqB,EACrB,UAAU,EACV,UAAU,GAAG,YAAY,EACzB,aAAa,GACM;;IACnB,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,qBAAqB,IAAI,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACvF,MAAM,QAAQ,GAAG,MAAM,UAAU;SAC9B,aAAa,CAAC,uDAAuD,UAAU,EAAE,CAAC,CAAC,OAAO;SAC1F,IAAI,CAAC;QACJ,OAAO,EAAE;YACP,UAAU,EAAE,GAAG;YACf,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,CAAC,MAAM,cAAc,CAAC,qBAAqB,CAAC,CAAC;SAC9E;KACF,CAAC,CAAC;IAEL,IAAI,CAAC,CAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,0CAAE,eAAe,CAAA;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACvF,OAAO,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;AACvC,CAAC;AAED,eAAe,gBAAgB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveBrowserCredential } from \"@azure/identity\";\nimport { ServiceInformation } from \"./deploy\";\nimport { getClient } from \"@azure-rest/core-client\";\n\nasync function getAccessToken(managementApiEndpoint: string): Promise<string> {\n const credentials = new InteractiveBrowserCredential();\n const scope = `${managementApiEndpoint}/user_impersonation`;\n const { token } = await credentials.getToken(scope);\n return `Bearer ${token}`;\n}\n\n/**\n * Function to get storage SAS URL.\n *\n * @returns storage SAS URL\n */\nasync function getStorageSasUrl({\n managementApiEndpoint,\n resourceId,\n apiVersion = \"2019-01-01\",\n tokenOverride,\n}: ServiceInformation): Promise<string> {\n const httpClient = getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });\n const response = await httpClient\n .pathUnchecked(`/portalSettings/mediaContent/listSecrets?apiVersion=${apiVersion}`) // TODO\n .post({\n headers: {\n \"If-Match\": \"*\",\n \"Content-Type\": \"application/json\",\n Authorization: tokenOverride ?? (await getAccessToken(managementApiEndpoint)),\n },\n });\n\n if (!response?.body?.containerSasUrl) throw new Error(\"Could not get storage SAS URL\");\n return response.body.containerSasUrl;\n}\n\nexport default getStorageSasUrl;\n"]}
1
+ {"version":3,"file":"getStorageSasUrl.js","sourceRoot":"","sources":["../../../src/node/getStorageSasUrl.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EACL,4BAA4B,GAE7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,KAAK,UAAU,cAAc,CAC3B,qBAA6B,EAC7B,OAAqB;IAErB,MAAM,WAAW,GAAG,IAAI,4BAA4B,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,GAAG,qBAAqB,qBAAqB,CAAC;IAC5D,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,UAAU,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAC7B,EACE,qBAAqB,EACrB,UAAU,EACV,UAAU,GAAG,YAAY,EACzB,aAAa,GACM,EACrB,mCAAiD;;IAEjD,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,qBAAqB,IAAI,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACvF,MAAM,QAAQ,GAAG,MAAM,UAAU;SAC9B,aAAa,CAAC,uDAAuD,UAAU,EAAE,CAAC,CAAC,OAAO;SAC1F,IAAI,CAAC;QACJ,OAAO,EAAE;YACP,UAAU,EAAE,GAAG;YACf,cAAc,EAAE,kBAAkB;YAClC,aAAa,EACX,aAAa,aAAb,aAAa,cAAb,aAAa,GACb,CAAC,MAAM,cAAc,CAAC,qBAAqB,EAAE,mCAAmC,CAAC,CAAC;SACrF;KACF,CAAC,CAAC;IAEL,IAAI,CAAC,CAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,0CAAE,eAAe,CAAA;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACvF,OAAO,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;AACvC,CAAC;AAED,eAAe,gBAAgB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n InteractiveBrowserCredential,\n InteractiveBrowserCredentialNodeOptions as IBCNOptions,\n} from \"@azure/identity\";\nimport { ServiceInformation } from \"./deploy\";\nimport { getClient } from \"@azure-rest/core-client\";\n\nasync function getAccessToken(\n managementApiEndpoint: string,\n options?: IBCNOptions\n): Promise<string> {\n const credentials = new InteractiveBrowserCredential(options);\n const scope = `${managementApiEndpoint}/user_impersonation`;\n const { token } = await credentials.getToken(scope);\n return `Bearer ${token}`;\n}\n\n/**\n * Function to get storage SAS URL.\n *\n * @returns storage SAS URL\n */\nasync function getStorageSasUrl(\n {\n managementApiEndpoint,\n resourceId,\n apiVersion = \"2019-01-01\",\n tokenOverride,\n }: ServiceInformation,\n interactiveBrowserCredentialOptions?: IBCNOptions\n): Promise<string> {\n const httpClient = getClient(`${managementApiEndpoint}/${resourceId}`, { apiVersion });\n const response = await httpClient\n .pathUnchecked(`/portalSettings/mediaContent/listSecrets?apiVersion=${apiVersion}`) // TODO\n .post({\n headers: {\n \"If-Match\": \"*\",\n \"Content-Type\": \"application/json\",\n Authorization:\n tokenOverride ??\n (await getAccessToken(managementApiEndpoint, interactiveBrowserCredentialOptions)),\n },\n });\n\n if (!response?.body?.containerSasUrl) throw new Error(\"Could not get storage SAS URL\");\n return response.body.containerSasUrl;\n}\n\nexport default getStorageSasUrl;\n"]}
@@ -53,7 +53,7 @@ export function getValuesPure(valuesDefault, urlSearchParams) {
53
53
  const urlValues = parseWidgetData(urlSearchParams).values;
54
54
  Object.keys(values).forEach((key) => {
55
55
  const value = urlValues[key];
56
- if (value != null && value !== "")
56
+ if (value != null)
57
57
  values[key] = value; // if value is specified in the URL, replace the default value
58
58
  });
59
59
  return values;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AACjD;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,CAAC;AAC1E;;GAEG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,qBAAqB,CAAC;AA2BtE,SAAS,eAAe,CACtB,eAAgC;;IAEhC,IAAI;QACF,MAAM,eAAe,GAAuB,IAAI,CAAC,KAAK,CACpD,kBAAkB,CAAC,MAAA,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,mCAAI,EAAE,CAAC,CACpE,CAAC;QAEF,wCAAwC;QACxC,mBAAmB;QACnB,yFAAyF;QACzF,OAAO;QACP,IAAI;QACJ,OAAO,eAAe,CAAC;KACxB;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CACX,kBAAkB,oBAAoB,wCAAwC;YAC5E,IAAI,CAAC,QAAQ,EACf,CAAC,CACF,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;KAClE;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,eAAgC;IAEhC,OAAO,eAAe,CAAS,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,eAAgC;IAEhC,OAAO,iBAAiB,CAAS,eAAe,CAAC,CAAC,MAAM,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,mBAAmB,CAAS,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,aAAqB,EACrB,eAAgC;IAEhC,MAAM,MAAM,qBAAQ,aAAa,CAAE,CAAC,CAAC,mEAAmE;IACxG,MAAM,SAAS,GAAG,eAAe,CAAS,eAAe,CAAC,CAAC,MAAM,CAAC;IAElE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAiB,EAAE,EAAE;QAChD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAA2B,CAAC,CAAC,8DAA8D;IAC9I,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAA8B,aAAqB;IAC1E,OAAO,aAAa,CAAC,aAAa,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACjF,CAAC;AAOD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,UAAkB,EAClB,MAAc;IAEd,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC9C,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAAC;IACvC,OAAO,CAAC,MAAuB,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAClF,CAAC;AAkBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAA0B;IAC5D,IAAI,cAAyC,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACvD,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAe,aAAa,EAAE,CAAC;QAEhE,cAAc,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YAC5B,IAAI,CAAC,CAAC,gCAAgC,IAAI,IAAI,CAAC;gBAAE,OAAO;YAExD,MAAM,OAAO,GAAG,IAAI,CAAC,gCAAgC,CAAC,CAAC;YACvD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,kBAAkB,IAAI,OAAO,CAAC,EAAE;gBACnE,MAAM,CAAC,wCAAwC,CAAC,CAAC;aAClD;YAED,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC,CAAC;QAEF,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG;YACd,CAAC,gCAAgC,CAAC,EAAE;gBAClC,UAAU;gBACV,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAC5B,YAAY;aACb;SACF,CAAC;QAEF,IAAI,YAAY,KAAK,KAAK,IAAI,WAAW,KAAK,aAAa,EAAE;YAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;SAC9C;aAAM;YACL,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;SACvC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;AACpF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Key for a search param, from which editor data will be loaded from.\n */\nexport const APIM_EDITOR_DATA_KEY = \"editorData\";\n/**\n * Key for a post message object, it's used to propagate changes from editor to the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ON_CHANGE_MESSAGE_KEY = \"customInputValueChangedMSAPIM\";\n/**\n * Key for a post message object, it's used to request and send secrets - token and user id, from the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ASK_FOR_SECRETS_MESSAGE_KEY = \"askForSecretsMSAPIM\";\n\n/**\n * Base of a values obj\n */\nexport type ValuesCommon = Record<string, unknown>;\n/**\n * All possible runtime environments\n */\nexport type Environment = \"development\" | \"publishing\" | \"runtime\" | \"error\";\n\n/** Information about the widget instance received from the Dev Portal */\nexport interface PortalData {\n // /** web content's origin (URL) of your Dev Portal */\n // origin: string;\n /** current runtime environment */\n environment: Environment;\n /** ID of this particular instance of the widget */\n instanceId: string;\n}\n\n/** JSON object with all the data you'll receive from the Dev Portal */\nexport interface EditorData<Values extends ValuesCommon> extends PortalData {\n /** values you've set in the admin editor window */\n values: Partial<Values>;\n}\n\nfunction parseWidgetData<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n try {\n const urlEditorParams: EditorData<Values> = JSON.parse(\n decodeURIComponent(urlSearchParams.get(APIM_EDITOR_DATA_KEY) ?? \"\")\n );\n\n // if (!(\"origin\" in urlEditorParams)) {\n // console.error(\n // \"Could not get 'origin' from the search params of the URL:\\n\" + self.location.href\n // );\n // }\n return urlEditorParams;\n } catch (e) {\n console.error(\n `Could not get '${APIM_EDITOR_DATA_KEY}' from the search params of the URL:\\n` +\n self.location,\n e\n );\n return { values: {}, environment: \"error\", instanceId: \"error\" };\n }\n}\n\nexport function getWidgetDataPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n return parseWidgetData<Values>(urlSearchParams);\n}\n\n/**\n * Function to get all data related to the widget including technical values not expected to be needed in most cases.\n * Intended mostly for internal use, API might change. Consider using getValues or getEditorValues instead.\n */\nexport function getWidgetData<Values extends ValuesCommon>(): EditorData<Values> {\n return getWidgetDataPure(new URLSearchParams(self.location.search));\n}\n\nexport function getEditorValuesPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): Partial<Values> {\n return getWidgetDataPure<Values>(urlSearchParams).values;\n}\n\n/**\n * Function to get values you've set in the admin editor window.\n */\nexport function getEditorValues<Values extends ValuesCommon>(): Partial<Values> {\n return getEditorValuesPure<Values>(new URLSearchParams(self.location.search));\n}\n\nexport function getValuesPure<Values extends ValuesCommon>(\n valuesDefault: Values,\n urlSearchParams: URLSearchParams\n): Values {\n const values = { ...valuesDefault }; // set Obj to contain all possible values and prefill default value\n const urlValues = parseWidgetData<Values>(urlSearchParams).values;\n\n Object.keys(values).forEach((key: keyof Values) => {\n const value = urlValues[key];\n if (value != null && value !== \"\") values[key] = value as Values[typeof key]; // if value is specified in the URL, replace the default value\n });\n return values;\n}\n\n/**\n * Function to get values you've set in the admin editor window. Undefined/empty values are replaced with default values.\n *\n * @param valuesDefault - object with your default values to use, just import valuesDefault object from values.ts folder\n */\nexport function getValues<Values extends ValuesCommon>(valuesDefault: Values): Values {\n return getValuesPure(valuesDefault, new URLSearchParams(self.location.search));\n}\n\n/**\n * Type of the onChange function.\n */\nexport type OnChange<Values extends ValuesCommon> = (values: Partial<Values>) => void;\n\n/**\n * The onChange function itself with 'origin' provided as a param.\n *\n * @param origin - web content's origin (URL) of your Dev Portal to send changes to\n * @param instanceId - ID of this particular instance of the widget\n * @param values - values that changed\n */\nexport function onChangeWithOrigin<Values extends ValuesCommon>(\n origin: string,\n instanceId: string,\n values: Values\n): void {\n Object.entries(values).forEach(([key, value]) => {\n self.parent.postMessage({ [APIM_ON_CHANGE_MESSAGE_KEY]: { key, value, instanceId } }, origin);\n });\n}\n\n/**\n * Build onChange function, which you can use, to send changed data from the editor.\n */\nexport function buildOnChange<Values extends ValuesCommon>(): OnChange<Values> {\n const { instanceId } = getWidgetData();\n return (values: Partial<Values>) => onChangeWithOrigin(\"*\", instanceId, values);\n}\n\n/**\n * Possible target modules\n * \"app\" for main application which is embedded in your Dev Portal\n * \"editor\" for form in admin panel\n */\nexport type TargetModule = \"app\" | \"editor\";\n/**\n * Secrets needed for communication with Dev Portal back-end\n */\nexport type Secrets = {\n managementApiUrl: string;\n apiVersion: string;\n userId?: string;\n token?: string;\n};\n\n/**\n * Request secrets - token & userId, from the Dev portal parent window.\n *\n * @param targetModule - is the function invoke from the main \"app\" window or the admin \"editor\"?\n */\nexport async function askForSecrets(targetModule: TargetModule): Promise<Secrets> {\n let receiveSecrets: (e: MessageEvent) => void;\n\n const promise = new Promise<Secrets>((resolve, reject) => {\n const { instanceId, environment }: PortalData = getWidgetData();\n\n receiveSecrets = ({ data }) => {\n if (!(APIM_ASK_FOR_SECRETS_MESSAGE_KEY in data)) return;\n\n const secrets = data[APIM_ASK_FOR_SECRETS_MESSAGE_KEY];\n if (typeof secrets !== \"object\" || !(\"managementApiUrl\" in secrets)) {\n reject(\"Secrets send by Dev Portal are invalid\");\n }\n\n resolve(secrets);\n };\n\n self.addEventListener(\"message\", receiveSecrets);\n\n const message = {\n [APIM_ASK_FOR_SECRETS_MESSAGE_KEY]: {\n instanceId,\n origin: self.location.origin,\n targetModule,\n },\n };\n\n if (targetModule === \"app\" && environment === \"development\") {\n self.parent.parent.postMessage(message, \"*\");\n } else {\n self.parent.postMessage(message, \"*\");\n }\n });\n\n return promise.finally(() => self.removeEventListener(\"message\", receiveSecrets));\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Key for a search param, from which editor data will be loaded from.\n */\nexport const APIM_EDITOR_DATA_KEY = \"editorData\";\n/**\n * Key for a post message object, it's used to propagate changes from editor to the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ON_CHANGE_MESSAGE_KEY = \"customInputValueChangedMSAPIM\";\n/**\n * Key for a post message object, it's used to request and send secrets - token and user id, from the DevPortal. Used to prevent interference with other applications.\n */\nexport const APIM_ASK_FOR_SECRETS_MESSAGE_KEY = \"askForSecretsMSAPIM\";\n\n/**\n * Base of a values obj\n */\nexport type ValuesCommon = Record<string, unknown>;\n/**\n * All possible runtime environments\n */\nexport type Environment = \"development\" | \"publishing\" | \"runtime\" | \"error\";\n\n/** Information about the widget instance received from the Dev Portal */\nexport interface PortalData {\n // /** web content's origin (URL) of your Dev Portal */\n // origin: string;\n /** current runtime environment */\n environment: Environment;\n /** ID of this particular instance of the widget */\n instanceId: string;\n}\n\n/** JSON object with all the data you'll receive from the Dev Portal */\nexport interface EditorData<Values extends ValuesCommon> extends PortalData {\n /** values you've set in the admin editor window */\n values: Partial<Values>;\n}\n\nfunction parseWidgetData<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n try {\n const urlEditorParams: EditorData<Values> = JSON.parse(\n decodeURIComponent(urlSearchParams.get(APIM_EDITOR_DATA_KEY) ?? \"\")\n );\n\n // if (!(\"origin\" in urlEditorParams)) {\n // console.error(\n // \"Could not get 'origin' from the search params of the URL:\\n\" + self.location.href\n // );\n // }\n return urlEditorParams;\n } catch (e) {\n console.error(\n `Could not get '${APIM_EDITOR_DATA_KEY}' from the search params of the URL:\\n` +\n self.location,\n e\n );\n return { values: {}, environment: \"error\", instanceId: \"error\" };\n }\n}\n\nexport function getWidgetDataPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): EditorData<Values> {\n return parseWidgetData<Values>(urlSearchParams);\n}\n\n/**\n * Function to get all data related to the widget including technical values not expected to be needed in most cases.\n * Intended mostly for internal use, API might change. Consider using getValues or getEditorValues instead.\n */\nexport function getWidgetData<Values extends ValuesCommon>(): EditorData<Values> {\n return getWidgetDataPure(new URLSearchParams(self.location.search));\n}\n\nexport function getEditorValuesPure<Values extends ValuesCommon>(\n urlSearchParams: URLSearchParams\n): Partial<Values> {\n return getWidgetDataPure<Values>(urlSearchParams).values;\n}\n\n/**\n * Function to get values you've set in the admin editor window.\n */\nexport function getEditorValues<Values extends ValuesCommon>(): Partial<Values> {\n return getEditorValuesPure<Values>(new URLSearchParams(self.location.search));\n}\n\nexport function getValuesPure<Values extends ValuesCommon>(\n valuesDefault: Values,\n urlSearchParams: URLSearchParams\n): Values {\n const values = { ...valuesDefault }; // set Obj to contain all possible values and prefill default value\n const urlValues = parseWidgetData<Values>(urlSearchParams).values;\n\n Object.keys(values).forEach((key: keyof Values) => {\n const value = urlValues[key];\n if (value != null) values[key] = value as Values[typeof key]; // if value is specified in the URL, replace the default value\n });\n return values;\n}\n\n/**\n * Function to get values you've set in the admin editor window. Undefined/empty values are replaced with default values.\n *\n * @param valuesDefault - object with your default values to use, just import valuesDefault object from values.ts folder\n */\nexport function getValues<Values extends ValuesCommon>(valuesDefault: Values): Values {\n return getValuesPure(valuesDefault, new URLSearchParams(self.location.search));\n}\n\n/**\n * Type of the onChange function.\n */\nexport type OnChange<Values extends ValuesCommon> = (values: Partial<Values>) => void;\n\n/**\n * The onChange function itself with 'origin' provided as a param.\n *\n * @param origin - web content's origin (URL) of your Dev Portal to send changes to\n * @param instanceId - ID of this particular instance of the widget\n * @param values - values that changed\n */\nexport function onChangeWithOrigin<Values extends ValuesCommon>(\n origin: string,\n instanceId: string,\n values: Values\n): void {\n Object.entries(values).forEach(([key, value]) => {\n self.parent.postMessage({ [APIM_ON_CHANGE_MESSAGE_KEY]: { key, value, instanceId } }, origin);\n });\n}\n\n/**\n * Build onChange function, which you can use, to send changed data from the editor.\n */\nexport function buildOnChange<Values extends ValuesCommon>(): OnChange<Values> {\n const { instanceId } = getWidgetData();\n return (values: Partial<Values>) => onChangeWithOrigin(\"*\", instanceId, values);\n}\n\n/**\n * Possible target modules\n * \"app\" for main application which is embedded in your Dev Portal\n * \"editor\" for form in admin panel\n */\nexport type TargetModule = \"app\" | \"editor\";\n/**\n * Secrets needed for communication with Dev Portal back-end and other runtime data\n */\nexport type Secrets = {\n managementApiUrl: string;\n apiVersion: string;\n userId?: string;\n token?: string;\n parentLocation: {\n host: string;\n hostname: string;\n href: string;\n origin: string;\n pathname: string;\n port: string;\n protocol: string;\n search: string;\n };\n};\n\n/**\n * Request secrets - token & userId, from the Dev portal parent window.\n *\n * @param targetModule - is the function invoke from the main \"app\" window or the admin \"editor\"?\n */\nexport async function askForSecrets(targetModule: TargetModule): Promise<Secrets> {\n let receiveSecrets: (e: MessageEvent) => void;\n\n const promise = new Promise<Secrets>((resolve, reject) => {\n const { instanceId, environment }: PortalData = getWidgetData();\n\n receiveSecrets = ({ data }) => {\n if (!(APIM_ASK_FOR_SECRETS_MESSAGE_KEY in data)) return;\n\n const secrets = data[APIM_ASK_FOR_SECRETS_MESSAGE_KEY];\n if (typeof secrets !== \"object\" || !(\"managementApiUrl\" in secrets)) {\n reject(\"Secrets send by Dev Portal are invalid\");\n }\n\n resolve(secrets);\n };\n\n self.addEventListener(\"message\", receiveSecrets);\n\n const message = {\n [APIM_ASK_FOR_SECRETS_MESSAGE_KEY]: {\n instanceId,\n origin: self.location.origin,\n targetModule,\n },\n };\n\n if (targetModule === \"app\" && environment === \"development\") {\n self.parent.parent.postMessage(message, \"*\");\n } else {\n self.parent.postMessage(message, \"*\");\n }\n });\n\n return promise.finally(() => self.removeEventListener(\"message\", receiveSecrets));\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure/api-management-custom-widgets-tools",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.2",
4
4
  "author": "Microsoft Corporation",
5
5
  "license": "MIT",
6
6
  "sdk-type": "client",
@@ -13,7 +13,7 @@
13
13
  "url": "https://github.com/Azure/azure-sdk-for-js/issues"
14
14
  },
15
15
  "engines": {
16
- "node": ">=12.0.0"
16
+ "node": ">=14.0.0"
17
17
  },
18
18
  "keywords": [
19
19
  "azure",
@@ -58,56 +58,51 @@
58
58
  },
59
59
  "devDependencies": {
60
60
  "@azure/dev-tool": "^1.0.0",
61
- "@azure-tools/test-recorder": "^2.0.0",
62
- "@microsoft/api-extractor": "7.18.11",
61
+ "@azure-tools/test-recorder": "^3.0.0",
62
+ "@microsoft/api-extractor": "^7.31.1",
63
63
  "@types/chai": "^4.1.6",
64
- "@types/mocha": "^7.0.2",
65
- "@types/mime": "~2.0.3",
66
- "@types/node": "^12.0.0",
67
- "@types/glob": "^7.1.1",
68
- "@types/inquirer": "^8.2.1",
64
+ "@types/mocha": "^10.0.0",
65
+ "@types/mime": "^3.0.1",
66
+ "@types/node": "^14.0.0",
69
67
  "@types/yargs": "^17.0.10",
70
68
  "@types/yargs-parser": "^21.0.0",
71
69
  "@azure/eslint-plugin-azure-sdk": "^3.0.0",
72
70
  "chai": "^4.2.0",
73
71
  "cross-env": "^7.0.2",
74
- "eslint": "^7.15.0",
75
- "mocha": "^7.1.1",
72
+ "eslint": "^8.0.0",
73
+ "mocha": "^10.0.0",
76
74
  "mocha-junit-reporter": "^2.0.0",
77
75
  "prettier": "^2.5.1",
78
76
  "nyc": "^15.0.0",
79
77
  "rimraf": "^3.0.0",
80
- "typescript": "~4.6.0",
78
+ "typescript": "~5.0.0",
81
79
  "util": "^0.12.1",
82
- "dotenv": "^8.2.0",
80
+ "dotenv": "^16.0.0",
83
81
  "@azure/test-utils": "^1.0.0",
84
- "@types/mustache": "4.1.2",
85
- "sinon": "^9.0.4",
82
+ "@types/mustache": "^4.2.1",
83
+ "sinon": "^15.0.0",
86
84
  "karma": "^6.2.0",
87
85
  "karma-chrome-launcher": "^3.0.0",
88
86
  "karma-coverage": "^2.0.0",
89
- "karma-edge-launcher": "^0.4.2",
90
87
  "karma-env-preprocessor": "^0.1.1",
91
88
  "karma-firefox-launcher": "^1.1.0",
92
- "karma-ie-launcher": "^1.0.0",
93
89
  "karma-json-preprocessor": "^0.3.3",
94
90
  "karma-json-to-file-reporter": "^1.0.1",
95
91
  "karma-junit-reporter": "^2.0.1",
96
92
  "karma-mocha": "^2.0.1",
97
93
  "karma-mocha-reporter": "^2.2.5",
98
- "@types/sinon": "^9.0.4"
94
+ "@types/sinon": "^10.0.0",
95
+ "ts-node": "^10.0.0"
99
96
  },
100
97
  "dependencies": {
101
- "@azure/identity": "^2.1.0",
98
+ "@azure/identity": "^3.3.0",
102
99
  "@azure-rest/core-client": "^1.0.0-beta.10",
103
100
  "@azure/storage-blob": "^12.9.0",
104
101
  "mime": "^3.0.0",
105
102
  "mustache": "^4.2.0",
106
103
  "prettier": "^2.5.1",
107
- "glob": "^7.1.2",
108
104
  "tslib": "^2.2.0",
109
- "typescript": "~4.6.4",
110
- "rollup": "~2.75.5",
111
- "@rollup/plugin-node-resolve": "~13.3.0"
105
+ "rollup": "^2.66.1",
106
+ "@rollup/plugin-node-resolve": "^13.1.3"
112
107
  }
113
108
  }
@@ -2,6 +2,8 @@
2
2
  * @packageDocumentation https://aka.ms/apimdocs/portal/customwidgets
3
3
  */
4
4
 
5
+ import { InteractiveBrowserCredentialNodeOptions } from '@azure/identity';
6
+
5
7
  /**
6
8
  * Key for a post message object, it's used to request and send secrets - token and user id, from the DevPortal. Used to prevent interference with other applications.
7
9
  */
@@ -55,15 +57,26 @@ export declare function buildBlobDataPath(name: string): string;
55
57
  */
56
58
  export declare function buildOnChange<Values extends ValuesCommon>(): OnChange<Values>;
57
59
 
60
+ /**
61
+ * Optional options object for configuring the deployment function.
62
+ *
63
+ * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default "./dist")
64
+ * @param interactiveBrowserCredentialOptions - options for InteractiveBrowserCredential for Node or InBrowser from \@azure/identity
65
+ */
66
+ export declare type DeployConfig = {
67
+ rootLocal?: string;
68
+ interactiveBrowserCredentialOptions?: InteractiveBrowserCredentialNodeOptions;
69
+ };
70
+
58
71
  /**
59
72
  * Deploys everything from /dist folder to the API Management DevPortals' blob storage.
60
73
  *
61
74
  * @param serviceInformation - service information for deployment
62
75
  * @param name - name of the widget to be deployed
63
76
  * @param fallbackConfigPath - local path to the config file (by default "./static/config.msapim.json")
64
- * @param rootLocal - optional, root of the local folder with compiled project to be exported (by default "./dist")
77
+ * @param config - optional config object
65
78
  */
66
- export declare function deployNodeJS(serviceInformation: ServiceInformation, name: string, fallbackConfigPath?: string, rootLocal?: string): Promise<void>;
79
+ export declare function deployNodeJS(serviceInformation: ServiceInformation, name: string, fallbackConfigPath?: string, { rootLocal, interactiveBrowserCredentialOptions, }?: DeployConfig): Promise<void>;
67
80
 
68
81
  /** JSON object with all the data you'll receive from the Dev Portal */
69
82
  export declare interface EditorData<Values extends ValuesCommon> extends PortalData {
@@ -117,13 +130,23 @@ export declare interface PortalData {
117
130
  }
118
131
 
119
132
  /**
120
- * Secrets needed for communication with Dev Portal back-end
133
+ * Secrets needed for communication with Dev Portal back-end and other runtime data
121
134
  */
122
135
  export declare type Secrets = {
123
136
  managementApiUrl: string;
124
137
  apiVersion: string;
125
138
  userId?: string;
126
139
  token?: string;
140
+ parentLocation: {
141
+ host: string;
142
+ hostname: string;
143
+ href: string;
144
+ origin: string;
145
+ pathname: string;
146
+ port: string;
147
+ protocol: string;
148
+ search: string;
149
+ };
127
150
  };
128
151
 
129
152
  /**