@azure/api-management-custom-widgets-scaffolder 1.0.0-beta.3 → 1.0.0-beta.5

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.
Files changed (88) hide show
  1. package/LICENSE +17 -17
  2. package/README.md +2 -2
  3. package/bin/{execute.js → execute.cjs} +120 -494
  4. package/bin/execute.cjs.map +1 -0
  5. package/bin/templates/react/package.json.mustache +1 -1
  6. package/bin/templates/typescript/package.json.mustache +1 -1
  7. package/bin/templates/vue/package.json.mustache +1 -1
  8. package/dist/commonjs/bin/execute-configs.d.ts +15 -0
  9. package/dist/commonjs/bin/execute-configs.d.ts.map +1 -0
  10. package/dist/commonjs/bin/execute-configs.js +157 -0
  11. package/dist/commonjs/bin/execute-configs.js.map +1 -0
  12. package/dist/commonjs/bin/execute-helpers.d.ts +12 -0
  13. package/dist/commonjs/bin/execute-helpers.d.ts.map +1 -0
  14. package/dist/commonjs/bin/execute-helpers.js +50 -0
  15. package/dist/commonjs/bin/execute-helpers.js.map +1 -0
  16. package/dist/commonjs/bin/execute.d.ts +3 -0
  17. package/dist/commonjs/bin/execute.d.ts.map +1 -0
  18. package/dist/commonjs/bin/execute.js +48 -0
  19. package/dist/commonjs/bin/execute.js.map +1 -0
  20. package/dist/commonjs/generateProject.d.ts +10 -0
  21. package/dist/commonjs/generateProject.d.ts.map +1 -0
  22. package/dist/commonjs/generateProject.js +74 -0
  23. package/dist/commonjs/generateProject.js.map +1 -0
  24. package/dist/commonjs/getTemplates.d.ts +3 -0
  25. package/dist/commonjs/getTemplates.d.ts.map +1 -0
  26. package/dist/commonjs/getTemplates.js +21 -0
  27. package/dist/commonjs/getTemplates.js.map +1 -0
  28. package/dist/commonjs/index.d.ts +7 -0
  29. package/dist/commonjs/index.d.ts.map +1 -0
  30. package/dist/commonjs/index.js +17 -0
  31. package/dist/commonjs/index.js.map +1 -0
  32. package/dist/commonjs/package.json +3 -0
  33. package/{types/latest/api-management-custom-widgets-scaffolder.d.ts → dist/commonjs/scaffolding.d.ts} +54 -74
  34. package/dist/commonjs/scaffolding.d.ts.map +1 -0
  35. package/dist/commonjs/scaffolding.js +35 -0
  36. package/dist/commonjs/scaffolding.js.map +1 -0
  37. package/dist/commonjs/sourceDir-cjs.cjs.map +1 -0
  38. package/dist/commonjs/sourceDir-cjs.d.cts.map +1 -0
  39. package/dist/commonjs/sourceDir.d.ts +2 -0
  40. package/dist/commonjs/sourceDir.js +7 -0
  41. package/dist/commonjs/tsdoc-metadata.json +11 -0
  42. package/dist/esm/bin/execute-configs.d.ts +15 -0
  43. package/dist/esm/bin/execute-configs.d.ts.map +1 -0
  44. package/dist/esm/bin/execute-configs.js +150 -0
  45. package/dist/esm/bin/execute-configs.js.map +1 -0
  46. package/dist/esm/bin/execute-helpers.d.ts +12 -0
  47. package/dist/esm/bin/execute-helpers.d.ts.map +1 -0
  48. package/{dist-esm/src → dist/esm}/bin/execute-helpers.js +3 -3
  49. package/dist/esm/bin/execute-helpers.js.map +1 -0
  50. package/dist/esm/bin/execute.d.ts +3 -0
  51. package/dist/esm/bin/execute.d.ts.map +1 -0
  52. package/{dist-esm/src → dist/esm}/bin/execute.js +4 -4
  53. package/dist/esm/bin/execute.js.map +1 -0
  54. package/dist/esm/generateProject.d.ts +10 -0
  55. package/dist/esm/generateProject.d.ts.map +1 -0
  56. package/{dist-esm/src → dist/esm}/generateProject.js +10 -9
  57. package/dist/esm/generateProject.js.map +1 -0
  58. package/dist/esm/getTemplates.d.ts +3 -0
  59. package/dist/esm/getTemplates.d.ts.map +1 -0
  60. package/{dist-esm/src → dist/esm}/getTemplates.js +5 -4
  61. package/dist/esm/getTemplates.js.map +1 -0
  62. package/dist/esm/index.d.ts +7 -0
  63. package/dist/esm/index.d.ts.map +1 -0
  64. package/dist/esm/index.js +8 -0
  65. package/dist/esm/index.js.map +1 -0
  66. package/dist/esm/package.json +3 -0
  67. package/dist/esm/scaffolding.d.ts +54 -0
  68. package/dist/esm/scaffolding.d.ts.map +1 -0
  69. package/{dist-esm/src → dist/esm}/scaffolding.js +3 -2
  70. package/dist/esm/scaffolding.js.map +1 -0
  71. package/dist/esm/sourceDir.d.ts +2 -0
  72. package/dist/esm/sourceDir.d.ts.map +1 -0
  73. package/dist/esm/sourceDir.js +8 -0
  74. package/dist/esm/sourceDir.js.map +1 -0
  75. package/package.json +70 -72
  76. package/dist/index.js +0 -122
  77. package/dist/index.js.map +0 -1
  78. package/dist-esm/src/bin/execute-configs.js +0 -139
  79. package/dist-esm/src/bin/execute-configs.js.map +0 -1
  80. package/dist-esm/src/bin/execute-helpers.js.map +0 -1
  81. package/dist-esm/src/bin/execute.js.map +0 -1
  82. package/dist-esm/src/generateProject.browser.js +0 -6
  83. package/dist-esm/src/generateProject.browser.js.map +0 -1
  84. package/dist-esm/src/generateProject.js.map +0 -1
  85. package/dist-esm/src/getTemplates.js.map +0 -1
  86. package/dist-esm/src/index.js +0 -8
  87. package/dist-esm/src/index.js.map +0 -1
  88. package/dist-esm/src/scaffolding.js.map +0 -1
package/package.json CHANGED
@@ -1,22 +1,19 @@
1
1
  {
2
2
  "name": "@azure/api-management-custom-widgets-scaffolder",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
4
4
  "author": "Microsoft Corporation",
5
5
  "license": "MIT",
6
6
  "sdk-type": "client",
7
7
  "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/apimanagement/api-management-custom-widgets-scaffolder/README.md",
8
8
  "repository": "github:Azure/azure-sdk-for-js",
9
- "browser": {
10
- "./dist-esm/src/generateProject.js": "./dist-esm/src/generateProject.browser.js"
11
- },
12
9
  "bugs": {
13
10
  "url": "https://github.com/Azure/azure-sdk-for-js/issues"
14
11
  },
15
12
  "bin": {
16
- "create-apimanagement-widget": "bin/execute.js"
13
+ "create-apimanagement-widget": "bin/execute.cjs"
17
14
  },
18
15
  "engines": {
19
- "node": ">=14.0.0"
16
+ "node": ">=20.0.0"
20
17
  },
21
18
  "keywords": [
22
19
  "azure",
@@ -29,77 +26,78 @@
29
26
  "files": [
30
27
  "dist/",
31
28
  "bin/",
32
- "dist-esm/src/",
33
- "types/latest/api-management-custom-widgets-scaffolder.d.ts",
34
29
  "LICENSE"
35
30
  ],
36
- "main": "dist/index.js",
37
- "module": "dist-esm/src/index.js",
38
- "types": "types/latest/api-management-custom-widgets-scaffolder.d.ts",
39
- "scripts": {
40
- "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit",
41
- "build:browser": "tsc -p . && dev-tool run bundle --browser-test=false",
42
- "build:node": "tsc -p . && dev-tool run bundle",
43
- "build:test": "echo skip",
44
- "bundle:bin": "rollup -c rollup.config.bin.js",
45
- "build:samples": "echo skip",
46
- "build": "npm run clean && tsc -p . && dev-tool run bundle --browser-test=false && npm run bundle:bin && api-extractor run --local",
47
- "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore --ignore-path ./.prettierignore \"src/templates/**\" \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
48
- "clean": "rimraf dist dist-* types *.tgz *.log",
49
- "extract-api": "tsc -p . && api-extractor run --local",
50
- "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore --ignore-path ./.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
51
- "integration-test:browser": "echo skip",
52
- "integration-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true",
53
- "integration-test": "npm run integration-test:node && npm run integration-test:browser",
54
- "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion] --ignore-pattern src/templates",
55
- "lint": "eslint package.json api-extractor.json src test --ext .ts --ignore-pattern src/templates",
56
- "pack": "npm pack 2>&1",
57
- "test:browser": "echo skip",
58
- "test:node": "npm run build:test && npm run unit-test:node && npm run integration-test:node",
59
- "test": "npm run clean && npm run build:test && npm run unit-test",
60
- "unit-test:browser": "echo skip",
61
- "unit-test:node": "npm run integration-test:node",
62
- "unit-test": "npm run unit-test:node && npm run unit-test:browser"
63
- },
31
+ "type": "module",
64
32
  "devDependencies": {
65
- "@azure/dev-tool": "^1.0.0",
66
- "@microsoft/api-extractor": "^7.31.1",
67
- "@types/chai": "^4.1.6",
68
- "@types/mocha": "^10.0.0",
69
- "@types/node": "^14.0.0",
70
- "@types/inquirer": "^8.2.1",
71
- "@types/yargs": "^17.0.10",
72
- "@types/yargs-parser": "^21.0.0",
73
- "@azure/eslint-plugin-azure-sdk": "^3.0.0",
74
- "chai": "^4.2.0",
75
- "cross-env": "^7.0.2",
76
- "eslint": "^8.0.0",
77
- "magic-string": "~0.27.0",
78
- "mocha": "^10.0.0",
79
- "mocha-junit-reporter": "^2.0.0",
80
- "prettier": "^2.5.1",
81
- "nyc": "^15.0.0",
82
- "rimraf": "^3.0.0",
83
- "ts-node": "^10.0.0",
84
- "typescript": "~5.0.0",
85
- "util": "^0.12.1",
86
- "dotenv": "^16.0.0",
87
- "@azure/test-utils": "^1.0.0",
33
+ "@rollup/plugin-node-resolve": "^15.2.3",
34
+ "@types/inquirer": "^9.0.7",
88
35
  "@types/mustache": "^4.2.1",
89
- "sinon": "^15.0.0",
90
- "@types/sinon": "^10.0.0"
36
+ "@types/node": "^20.19.0",
37
+ "@types/yargs": "^17.0.32",
38
+ "@types/yargs-parser": "^21.0.3",
39
+ "@vitest/coverage-istanbul": "^3.2.3",
40
+ "eslint": "^9.33.0",
41
+ "magic-string": "^0.30.8",
42
+ "prettier": "^3.3.3",
43
+ "rollup": "^4.14.0",
44
+ "typescript": "~5.8.3",
45
+ "vitest": "^3.2.3",
46
+ "@azure/dev-tool": "^1.0.0",
47
+ "@azure/eslint-plugin-azure-sdk": "^3.0.0"
91
48
  },
92
49
  "dependencies": {
93
- "mustache": "^4.2.0",
94
- "prettier": "^2.5.1",
95
- "glob": "^9.0.0",
96
- "tslib": "^2.2.0",
97
- "typescript": "~5.0.0",
98
50
  "chalk": "^4.1.2",
99
- "inquirer": "^8.2.4",
100
- "yargs": "^17.0.1",
101
- "yargs-parser": "^21.0.1",
102
- "rollup": "^2.66.1",
103
- "@rollup/plugin-node-resolve": "^13.1.3"
51
+ "glob": "^10.3.12",
52
+ "inquirer": "^9.2.17",
53
+ "mustache": "^4.2.0",
54
+ "tslib": "^2.6.2",
55
+ "yargs": "^17.2.2",
56
+ "yargs-parser": "^21.1.1"
57
+ },
58
+ "tshy": {
59
+ "exports": {
60
+ "./package.json": "./package.json",
61
+ ".": "./src/index.ts"
62
+ },
63
+ "dialects": [
64
+ "esm",
65
+ "commonjs"
66
+ ],
67
+ "selfLink": false,
68
+ "project": "./tsconfig.src.build.json"
69
+ },
70
+ "exports": {
71
+ "./package.json": "./package.json",
72
+ ".": {
73
+ "import": {
74
+ "types": "./dist/esm/index.d.ts",
75
+ "default": "./dist/esm/index.js"
76
+ },
77
+ "require": {
78
+ "types": "./dist/commonjs/index.d.ts",
79
+ "default": "./dist/commonjs/index.js"
80
+ }
81
+ }
82
+ },
83
+ "main": "./dist/commonjs/index.js",
84
+ "types": "./dist/commonjs/index.d.ts",
85
+ "module": "./dist/esm/index.js",
86
+ "scripts": {
87
+ "build": "npm run clean && dev-tool run build-package && npm run bundle:bin && dev-tool run extract-api",
88
+ "build:samples": "echo Skipped.",
89
+ "bundle:bin": "rollup -c rollup.config.bin.mjs 2>&1",
90
+ "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore --ignore-path ./.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
91
+ "clean": "dev-tool run vendored rimraf --glob dist dist-* types *.tgz *.log",
92
+ "extract-api": "tsc -p . && dev-tool run extract-api",
93
+ "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore --ignore-path ./.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
94
+ "lint": "eslint package.json src test --ignore-pattern templates",
95
+ "lint:fix": "eslint package.json src test --fix --fix-type [problem,suggestion] --ignore-pattern templates",
96
+ "pack": "pnpm pack 2>&1",
97
+ "test": "npm run test:node && npm run test:browser",
98
+ "test:browser": "echo skipped",
99
+ "test:node": "dev-tool run test:vitest --no-test-proxy",
100
+ "test:node:esm": "dev-tool run test:vitest --esm --no-test-proxy",
101
+ "update-snippets": "dev-tool run update-snippets"
104
102
  }
105
- }
103
+ }
package/dist/index.js DELETED
@@ -1,122 +0,0 @@
1
- 'use strict';
2
-
3
- var path = require('path');
4
- var fs = require('fs');
5
- var glob = require('glob');
6
- var mustache = require('mustache');
7
-
8
- // Copyright (c) Microsoft Corporation.
9
- // Licensed under the MIT license.
10
- /**
11
- * Unique identifier under which is specified which port to use for injecting locally hosted custom widget to a running DevPortal instance.
12
- */
13
- const OVERRIDE_PORT_KEY = "MS_APIM_CW_localhost_port";
14
- /**
15
- * Default port for running local dev server on.
16
- */
17
- const OVERRIDE_DEFAULT_PORT = 3000;
18
- /** List of all supported technologies to scaffold a widget in. */
19
- const TECHNOLOGIES = ["typescript", "react", "vue"];
20
- /**
21
- * Converts user defined name of a custom widget to a unique ID, which is in context of Dev Portal known as "name".
22
- *
23
- * @param displayName - User defined name of the custom widget.
24
- */
25
- const displayNameToName = (displayName) => encodeURIComponent(displayName
26
- .normalize("NFD")
27
- .toLowerCase()
28
- .replace(/[\u0300-\u036f]/g, "")
29
- .replace(/[^a-z0-9-]/g, "-"));
30
- /**
31
- * Returns name of the folder for widget project.
32
- *
33
- * @param name - name of the widget
34
- */
35
- const widgetFolderName = (name) => `azure-api-management-widget-${name}`;
36
-
37
- // Copyright (c) Microsoft Corporation.
38
- // Licensed under the MIT license.
39
- async function getTemplates(template) {
40
- const sharedFiles = await getFiles(path.join(__dirname, "templates", "_shared", "**", "**", "*.*"));
41
- const templateFiles = await getFiles(path.join(__dirname, "templates", template, "**", "**", "*.*"));
42
- return [...sharedFiles, ...templateFiles];
43
- }
44
- async function getFiles(path) {
45
- // Starting from glob v8 `\` is only used as an escape character, and never as a path separator in glob patterns.
46
- // Glob pattern paths must use forward-slashes as path separators.
47
- // See https://github.com/isaacs/node-glob/blob/af57da21c7722bb6edb687ccd4ad3b99d3e7a333/changelog.md#80
48
- const normalizedPath = path.replace(/\\/g, "/");
49
- return glob.glob(normalizedPath, { dot: true });
50
- }
51
-
52
- // Copyright (c) Microsoft Corporation.
53
- // Licensed under the MIT license.
54
- const templateSuffix = ".mustache";
55
- /**
56
- * Generates a scaffold project of Custom widget for API Managements' Dev Portal.
57
- *
58
- * @param widgetConfig - JSON object with data required by DevPortal to handle a widget integration.
59
- * @param deploymentConfig - JSON object with data for deployment.
60
- * @param options - JSON object with other data, which will not be stored in the DevPortal.
61
- */
62
- async function generateProject(widgetConfig, deploymentConfig, options = {}) {
63
- const { openUrl, configAdvancedTenantId, configAdvancedRedirectUri } = options;
64
- const openUrlParsed = openUrl ? new URL(openUrl) : null;
65
- if (openUrlParsed) {
66
- openUrlParsed.searchParams.append(OVERRIDE_PORT_KEY, String(OVERRIDE_DEFAULT_PORT));
67
- }
68
- const name = displayNameToName(widgetConfig.displayName);
69
- const serverSettings = {
70
- port: OVERRIDE_DEFAULT_PORT,
71
- open: openUrlParsed ? openUrlParsed.toString() : true,
72
- };
73
- const configAdditional = {
74
- interactiveBrowserCredentialOptions: { redirectUri: "http://localhost:1337" },
75
- };
76
- if (configAdvancedTenantId) {
77
- configAdditional.interactiveBrowserCredentialOptions.tenantId = configAdvancedTenantId;
78
- }
79
- if (configAdvancedRedirectUri) {
80
- configAdditional.interactiveBrowserCredentialOptions.redirectUri = configAdvancedRedirectUri;
81
- }
82
- const renderTemplate = async (file) => {
83
- const isTemplate = file.endsWith(templateSuffix);
84
- const encoding = file.endsWith(".ttf") ? "binary" : "utf8";
85
- let fileData = await fs.promises.readFile(file, { encoding });
86
- if (isTemplate) {
87
- fileData = mustache.render(fileData, {
88
- name,
89
- displayName: widgetConfig.displayName,
90
- config: JSON.stringify(Object.assign(Object.assign({}, widgetConfig), { name }), null, "\t"),
91
- configDeploy: JSON.stringify(deploymentConfig, null, "\t"),
92
- configAdditional: JSON.stringify(configAdditional, null, "\t"),
93
- serverSettings: JSON.stringify(serverSettings, null, "\t"),
94
- });
95
- }
96
- let relativePath = file;
97
- if (__dirname.includes("\\")) {
98
- relativePath = relativePath.replace(/\//g, "\\");
99
- }
100
- relativePath = relativePath
101
- .replace(path.join(__dirname, "templates", "_shared"), "")
102
- .replace(path.join(__dirname, "templates", widgetConfig.technology), "")
103
- .replace(templateSuffix, "");
104
- const newFilePath = path.join(process.cwd(), widgetFolderName(name), relativePath);
105
- const dir = path.parse(newFilePath).dir;
106
- await fs.promises.mkdir(dir, { recursive: true });
107
- await fs.promises.writeFile(newFilePath, fileData, { encoding });
108
- };
109
- const templates = await getTemplates(widgetConfig.technology);
110
- for (const file of Object.values(templates)) {
111
- await renderTemplate(file);
112
- }
113
- return;
114
- }
115
-
116
- exports.OVERRIDE_DEFAULT_PORT = OVERRIDE_DEFAULT_PORT;
117
- exports.OVERRIDE_PORT_KEY = OVERRIDE_PORT_KEY;
118
- exports.TECHNOLOGIES = TECHNOLOGIES;
119
- exports.displayNameToName = displayNameToName;
120
- exports.generateProject = generateProject;
121
- exports.widgetFolderName = widgetFolderName;
122
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../src/scaffolding.ts","../src/getTemplates.ts","../src/generateProject.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Unique identifier under which is specified which port to use for injecting locally hosted custom widget to a running DevPortal instance.\n */\nexport const OVERRIDE_PORT_KEY = \"MS_APIM_CW_localhost_port\";\n/**\n * Default port for running local dev server on.\n */\nexport const OVERRIDE_DEFAULT_PORT = 3000;\n\n/** All supported technologies to scaffold a widget in. */\nexport type ScaffoldTech = \"typescript\" | \"react\" | \"vue\";\n\n/** List of all supported technologies to scaffold a widget in. */\nexport const TECHNOLOGIES: ScaffoldTech[] = [\"typescript\", \"react\", \"vue\"];\n\n/** Main data which DevPortal needs for every custom widget. */\nexport interface WidgetConfig {\n /** Name of the custom widget which is displayed in DevPortal. */\n displayName: string;\n /** Technology to use to scaffold the widget. */\n technology: ScaffoldTech;\n /** Optional URL for a custom icon, which will be displayed in DevPortal widget list. */\n iconUrl?: string;\n}\n\n/** Data needed for deployment. */\nexport interface ServiceInformation {\n /** Management API endpoint to use (e.g. management.azure.com). */\n managementApiEndpoint: string;\n /** resourceId of your APIM service, must be in this format: subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.ApiManagement/service/<service-name> */\n resourceId: string;\n /** optional override which API version to use during deployment */\n apiVersion?: string;\n}\n\n/** Miscellaneous data for scaffolding of a custom widget which will not be stored in DevPortal. */\nexport interface Options {\n /** The URL to open after development server of the widget is started (URL of your Developer Portal). If you don't want to use this feature, set it to `false`. If you want to open just the widget page, set it to `true`. */\n openUrl?: string;\n /** advance configuration option for the deploy function - tenant ID for InteractiveBrowserCredentialNodeOptions */\n configAdvancedTenantId?: string;\n /** advance configuration option for the deploy function - redirect URI for InteractiveBrowserCredentialNodeOptions */\n configAdvancedRedirectUri?: string;\n}\n\nexport type Configs = WidgetConfig | ServiceInformation | Options;\n\n/**\n * Converts user defined name of a custom widget to a unique ID, which is in context of Dev Portal known as \"name\".\n *\n * @param displayName - User defined name of the custom widget.\n */\nexport const displayNameToName = (displayName: string): string =>\n encodeURIComponent(\n displayName\n .normalize(\"NFD\")\n .toLowerCase()\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n );\n\n/**\n * Returns name of the folder for widget project.\n *\n * @param name - name of the widget\n */\nexport const widgetFolderName = (name: string): string => `azure-api-management-widget-${name}`;\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { ScaffoldTech } from \"./scaffolding\";\nimport { glob } from \"glob\";\nimport { join as pathJoin } from \"path\";\n\nexport async function getTemplates(template: ScaffoldTech): Promise<string[]> {\n const sharedFiles = await getFiles(\n pathJoin(__dirname, \"templates\", \"_shared\", \"**\", \"**\", \"*.*\")\n );\n const templateFiles = await getFiles(\n pathJoin(__dirname, \"templates\", template, \"**\", \"**\", \"*.*\")\n );\n return [...sharedFiles, ...templateFiles];\n}\n\nasync function getFiles(path: string): Promise<string[]> {\n // Starting from glob v8 `\\` is only used as an escape character, and never as a path separator in glob patterns.\n // Glob pattern paths must use forward-slashes as path separators.\n // See https://github.com/isaacs/node-glob/blob/af57da21c7722bb6edb687ccd4ad3b99d3e7a333/changelog.md#80\n const normalizedPath = path.replace(/\\\\/g, \"/\");\n return glob(normalizedPath, { dot: true });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n ServiceInformation,\n OVERRIDE_DEFAULT_PORT,\n OVERRIDE_PORT_KEY,\n Options,\n WidgetConfig,\n displayNameToName,\n widgetFolderName,\n} from \"./scaffolding\";\nimport { join as joinPath, parse as parsePath } from \"path\";\nimport { promises as fs } from \"fs\";\nimport { getTemplates } from \"./getTemplates\";\nimport mustache from \"mustache\";\n\nconst templateSuffix = \".mustache\";\n\n/**\n * Generates a scaffold project of Custom widget for API Managements' Dev Portal.\n *\n * @param widgetConfig - JSON object with data required by DevPortal to handle a widget integration.\n * @param deploymentConfig - JSON object with data for deployment.\n * @param options - JSON object with other data, which will not be stored in the DevPortal.\n */\nexport async function generateProject(\n widgetConfig: WidgetConfig,\n deploymentConfig: ServiceInformation,\n options: Options = {}\n): Promise<void> {\n const { openUrl, configAdvancedTenantId, configAdvancedRedirectUri } = options;\n const openUrlParsed = openUrl ? new URL(openUrl) : null;\n if (openUrlParsed) {\n openUrlParsed.searchParams.append(OVERRIDE_PORT_KEY, String(OVERRIDE_DEFAULT_PORT));\n }\n\n const name = displayNameToName(widgetConfig.displayName);\n const serverSettings = {\n port: OVERRIDE_DEFAULT_PORT,\n open: openUrlParsed ? openUrlParsed.toString() : true,\n };\n\n const configAdditional = {\n interactiveBrowserCredentialOptions: { redirectUri: \"http://localhost:1337\" } as {\n redirectUri: string;\n tenantId?: string;\n },\n };\n if (configAdvancedTenantId) {\n configAdditional.interactiveBrowserCredentialOptions.tenantId = configAdvancedTenantId;\n }\n if (configAdvancedRedirectUri) {\n configAdditional.interactiveBrowserCredentialOptions.redirectUri = configAdvancedRedirectUri;\n }\n\n const renderTemplate = async (file: string): Promise<void> => {\n const isTemplate = file.endsWith(templateSuffix);\n const encoding = file.endsWith(\".ttf\") ? \"binary\" : \"utf8\";\n let fileData = await fs.readFile(file, { encoding });\n if (isTemplate) {\n fileData = mustache.render(fileData, {\n name,\n displayName: widgetConfig.displayName,\n config: JSON.stringify({ ...widgetConfig, name }, null, \"\\t\"),\n configDeploy: JSON.stringify(deploymentConfig, null, \"\\t\"),\n configAdditional: JSON.stringify(configAdditional, null, \"\\t\"),\n serverSettings: JSON.stringify(serverSettings, null, \"\\t\"),\n });\n }\n\n let relativePath = file;\n if (__dirname.includes(\"\\\\\")) {\n relativePath = relativePath.replace(/\\//g, \"\\\\\");\n }\n relativePath = relativePath\n .replace(joinPath(__dirname, \"templates\", \"_shared\"), \"\")\n .replace(joinPath(__dirname, \"templates\", widgetConfig.technology), \"\")\n .replace(templateSuffix, \"\");\n const newFilePath = joinPath(process.cwd(), widgetFolderName(name), relativePath);\n const dir = parsePath(newFilePath).dir;\n\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(newFilePath, fileData, { encoding });\n };\n\n const templates = await getTemplates(widgetConfig.technology);\n for (const file of Object.values(templates)) {\n await renderTemplate(file);\n }\n\n return;\n}\n"],"names":["pathJoin","glob","fs","joinPath","parsePath"],"mappings":"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"}
@@ -1,139 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT license.
3
- import { TECHNOLOGIES } from "../scaffolding";
4
- import inquirer from "inquirer";
5
- export const fieldIdToName = {
6
- displayName: "Widget display name",
7
- technology: "Technology",
8
- iconUrl: "iconUrl",
9
- resourceId: "Azure API Management resource ID (following format: subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.ApiManagement/service/<api-management service-name>)",
10
- managementApiEndpoint: "Management API hostname",
11
- apiVersion: "Management API version",
12
- openUrl: "Developer portal URL",
13
- configAdvancedTenantId: "Tenant ID",
14
- configAdvancedRedirectUri: "Redirect URI",
15
- };
16
- export const prefixUrlProtocol = (value) => /https?:\/\//.test(value) ? value : `https://${value}`;
17
- const validateRequired = (name, msg = `The “${name}” parameter is required.`) => (input) => (input != null && input !== "") || msg;
18
- const validateUrl = (name, msg = (input) => `Provided “${name}” parameter value (“${prefixUrlProtocol(input)}”) isn’t a valid URL. Use the correct URL format, e.g., https://contoso.com.`) => (input) => {
19
- try {
20
- new URL(prefixUrlProtocol(input));
21
- return true;
22
- }
23
- catch (e) {
24
- return msg(prefixUrlProtocol(input));
25
- }
26
- };
27
- export const validateWidgetConfig = {
28
- displayName: validateRequired(fieldIdToName.displayName),
29
- technology: (input) => {
30
- const required = validateRequired(fieldIdToName.technology)(input);
31
- if (required !== true)
32
- return required;
33
- if (TECHNOLOGIES.includes(input)) {
34
- return true;
35
- }
36
- else {
37
- return ("Provided “technology” parameter value isn’t correct. Use one of the following: " +
38
- TECHNOLOGIES.join(", "));
39
- }
40
- },
41
- };
42
- export const validateDeployConfig = {
43
- resourceId: (input) => {
44
- const required = validateRequired(fieldIdToName.resourceId)(input);
45
- if (required !== true)
46
- return required;
47
- const regex = /^\/?subscriptions\/[^/]+\/resourceGroups\/[^/]+\/providers\/Microsoft\.ApiManagement\/service\/[^/]+\/?$/;
48
- return input === "test" || regex.test(input)
49
- ? true
50
- : "Resource ID needs to be a valid Azure resource ID. For example, subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso-group/providers/Microsoft.ApiManagement/service/contoso-apis.";
51
- },
52
- managementApiEndpoint: (input) => validateRequired(fieldIdToName.managementApiEndpoint)(input),
53
- };
54
- export const validateMiscConfig = {
55
- openUrl: (input) => {
56
- if (!input)
57
- return true;
58
- return validateUrl(fieldIdToName.openUrl)(input);
59
- },
60
- configAdvancedTenantId: () => {
61
- return true;
62
- },
63
- configAdvancedRedirectUri: (input) => {
64
- if (!input)
65
- return true;
66
- return validateUrl(fieldIdToName.openUrl)(input);
67
- },
68
- };
69
- export const promptWidgetConfig = (partial) => inquirer.prompt([
70
- {
71
- name: "displayName",
72
- type: "input",
73
- message: fieldIdToName.displayName,
74
- validate: validateWidgetConfig.displayName,
75
- },
76
- {
77
- name: "technology",
78
- type: "list",
79
- message: fieldIdToName.technology,
80
- choices: [
81
- { name: "React", value: "react" },
82
- { name: "Vue", value: "vue" },
83
- { name: "TypeScript", value: "typescript" },
84
- ],
85
- },
86
- ], partial);
87
- export const promptServiceInformation = (partial) => inquirer.prompt([
88
- {
89
- name: "resourceId",
90
- type: "input",
91
- message: fieldIdToName.resourceId,
92
- validate: validateDeployConfig.resourceId,
93
- },
94
- {
95
- name: "managementApiEndpoint",
96
- type: "list",
97
- message: fieldIdToName.managementApiEndpoint,
98
- choices: [
99
- {
100
- name: "management.azure.com (if you're not sure what to select, use this option)",
101
- value: "management.azure.com",
102
- },
103
- { name: "management.usgovcloudapi.net", value: "management.usgovcloudapi.net" },
104
- { name: "management.chinacloudapi.cn", value: "management.chinacloudapi.cn" },
105
- ],
106
- transformer: prefixUrlProtocol,
107
- validate: validateDeployConfig.managementApiEndpoint,
108
- },
109
- {
110
- name: "apiVersion",
111
- type: "input",
112
- message: fieldIdToName.apiVersion + " (optional; e.g., 2021-08-01)",
113
- },
114
- ], partial);
115
- export const promptMiscConfig = (partial) => inquirer.prompt([
116
- {
117
- name: "openUrl",
118
- type: "input",
119
- message: fieldIdToName.openUrl +
120
- " for widget development and testing (optional; e.g., https://contoso.developer.azure-api.net/ or http://localhost:8080)",
121
- transformer: prefixUrlProtocol,
122
- validate: validateMiscConfig.openUrl,
123
- },
124
- {
125
- name: "configAdvancedTenantId",
126
- type: "input",
127
- message: fieldIdToName.configAdvancedTenantId +
128
- " to be used in Azure Identity InteractiveBrowserCredential class (optional)",
129
- validate: validateMiscConfig.openUrl,
130
- },
131
- {
132
- name: "configAdvancedRedirectUri",
133
- type: "input",
134
- message: fieldIdToName.configAdvancedRedirectUri +
135
- " to be used in Azure Identity InteractiveBrowserCredential class (optional; default is http://localhost:1337)",
136
- validate: validateMiscConfig.openUrl,
137
- },
138
- ], partial);
139
- //# sourceMappingURL=execute-configs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"execute-configs.js","sourceRoot":"","sources":["../../../src/bin/execute-configs.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { Configs, ServiceInformation, Options, TECHNOLOGIES, WidgetConfig } from \"../scaffolding\";\n\nimport inquirer from \"inquirer\";\n\nexport const fieldIdToName: Record<\n keyof (WidgetConfig & ServiceInformation & Options) | string,\n string\n> = {\n displayName: \"Widget display name\",\n technology: \"Technology\",\n iconUrl: \"iconUrl\",\n\n resourceId:\n \"Azure API Management resource ID (following format: subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.ApiManagement/service/<api-management service-name>)\",\n managementApiEndpoint: \"Management API hostname\",\n apiVersion: \"Management API version\",\n\n openUrl: \"Developer portal URL\",\n configAdvancedTenantId: \"Tenant ID\",\n configAdvancedRedirectUri: \"Redirect URI\",\n};\n\nexport const prefixUrlProtocol = (value: string): string =>\n /https?:\\/\\//.test(value) ? value : `https://${value}`;\n\nconst validateRequired =\n (name: string, msg: string = `The “${name}” parameter is required.`) =>\n (input: unknown) =>\n (input != null && input !== \"\") || msg;\n\nconst validateUrl =\n (\n name: string,\n msg = (input: string) =>\n `Provided “${name}” parameter value (“${prefixUrlProtocol(\n input\n )}”) isn’t a valid URL. Use the correct URL format, e.g., https://contoso.com.`\n ) =>\n (input: string) => {\n try {\n new URL(prefixUrlProtocol(input));\n return true;\n } catch (e) {\n return msg(prefixUrlProtocol(input));\n }\n };\n\nexport type ReplaceTypesPreserveOptional<T extends Record<any, any>, V> = {\n [Key in keyof T]: T[Key] extends undefined ? V | undefined : V;\n};\n\nexport type ValidateFnc = (input: string) => boolean | string;\nexport type Validate<C extends Configs> = ReplaceTypesPreserveOptional<C, ValidateFnc>;\n\nexport const validateWidgetConfig: Validate<WidgetConfig> = {\n displayName: validateRequired(fieldIdToName.displayName),\n technology: (input) => {\n const required = validateRequired(fieldIdToName.technology)(input);\n if (required !== true) return required;\n\n if (TECHNOLOGIES.includes(input as any)) {\n return true;\n } else {\n return (\n \"Provided “technology” parameter value isn’t correct. Use one of the following: \" +\n TECHNOLOGIES.join(\", \")\n );\n }\n },\n};\n\nexport const validateDeployConfig: Validate<ServiceInformation> = {\n resourceId: (input) => {\n const required = validateRequired(fieldIdToName.resourceId)(input);\n if (required !== true) return required;\n\n const regex =\n /^\\/?subscriptions\\/[^/]+\\/resourceGroups\\/[^/]+\\/providers\\/Microsoft\\.ApiManagement\\/service\\/[^/]+\\/?$/;\n return input === \"test\" || regex.test(input)\n ? true\n : \"Resource ID needs to be a valid Azure resource ID. For example, subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso-group/providers/Microsoft.ApiManagement/service/contoso-apis.\";\n },\n managementApiEndpoint: (input) => validateRequired(fieldIdToName.managementApiEndpoint)(input),\n};\n\nexport const validateMiscConfig: Validate<Options> = {\n openUrl: (input) => {\n if (!input) return true;\n return validateUrl(fieldIdToName.openUrl)(input);\n },\n configAdvancedTenantId: () => {\n return true;\n },\n configAdvancedRedirectUri: (input) => {\n if (!input) return true;\n return validateUrl(fieldIdToName.openUrl)(input);\n },\n};\n\nexport const promptWidgetConfig = (partial: Partial<WidgetConfig>): Promise<WidgetConfig> =>\n inquirer.prompt(\n [\n {\n name: \"displayName\",\n type: \"input\",\n message: fieldIdToName.displayName,\n validate: validateWidgetConfig.displayName,\n },\n {\n name: \"technology\",\n type: \"list\",\n message: fieldIdToName.technology,\n choices: [\n { name: \"React\", value: \"react\" },\n { name: \"Vue\", value: \"vue\" },\n { name: \"TypeScript\", value: \"typescript\" },\n ],\n },\n ],\n partial\n );\n\nexport const promptServiceInformation = (\n partial: Partial<ServiceInformation>\n): Promise<ServiceInformation> =>\n inquirer.prompt(\n [\n {\n name: \"resourceId\",\n type: \"input\",\n message: fieldIdToName.resourceId,\n validate: validateDeployConfig.resourceId,\n },\n {\n name: \"managementApiEndpoint\",\n type: \"list\",\n message: fieldIdToName.managementApiEndpoint,\n choices: [\n {\n name: \"management.azure.com (if you're not sure what to select, use this option)\",\n value: \"management.azure.com\",\n },\n { name: \"management.usgovcloudapi.net\", value: \"management.usgovcloudapi.net\" },\n { name: \"management.chinacloudapi.cn\", value: \"management.chinacloudapi.cn\" },\n ],\n transformer: prefixUrlProtocol,\n validate: validateDeployConfig.managementApiEndpoint,\n },\n {\n name: \"apiVersion\",\n type: \"input\",\n message: fieldIdToName.apiVersion + \" (optional; e.g., 2021-08-01)\",\n },\n ],\n partial\n );\n\nexport const promptMiscConfig = (partial: Partial<Options>): Promise<Options> =>\n inquirer.prompt(\n [\n {\n name: \"openUrl\",\n type: \"input\",\n message:\n fieldIdToName.openUrl +\n \" for widget development and testing (optional; e.g., https://contoso.developer.azure-api.net/ or http://localhost:8080)\",\n transformer: prefixUrlProtocol,\n validate: validateMiscConfig.openUrl,\n },\n {\n name: \"configAdvancedTenantId\",\n type: \"input\",\n message:\n fieldIdToName.configAdvancedTenantId +\n \" to be used in Azure Identity InteractiveBrowserCredential class (optional)\",\n validate: validateMiscConfig.openUrl,\n },\n {\n name: \"configAdvancedRedirectUri\",\n type: \"input\",\n message:\n fieldIdToName.configAdvancedRedirectUri +\n \" to be used in Azure Identity InteractiveBrowserCredential class (optional; default is http://localhost:1337)\",\n validate: validateMiscConfig.openUrl,\n },\n ],\n partial\n );\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"execute-helpers.js","sourceRoot":"","sources":["../../../src/bin/execute-helpers.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAIL,aAAa,GACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,IAA2B,EAC3B,cAAiC,EACjC,GAA0B,EAC6B,EAAE;IACzD,MAAM,aAAa,GAAqB,EAAE,CAAC;IAC3C,IAAI,OAAO,GAAY,KAAK,CAAC;IAE7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;QAClD,MAAM,QAAQ,GAAG,CAAgB,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEjC,IAAI,QAAQ,KAAK,IAAI,EAAE;YACrB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;gBACzC,aAAa,CAAC,GAAkC,CAAC,GAAG,KAAK,CAAC;aAC3D;SACF;aAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;YAChD,OAAO,GAAG,IAAI,CAAC;SAChB;aAAM;YACL,OAAO,GAAG,IAAI,CAAC;YACf,GAAG,CAAC,IAAI,KAAK,+BAA+B,GAAG,GAAG,CAAC,CAAC;YACpD,IAAI,OAAO,QAAQ,KAAK,QAAQ;gBAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;SACjD;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC,CAAC;AAQF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAS,EAAE,GAAQ,EAAU,EAAE;IAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,OAAO,KAAK,EACV,eAAoD,EACpD,cAA2B,EAC3B,EAAE;QACF,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;QAEpF,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE;YACnD,OAAO,eAAe,CAAC,aAAa,CAAC,CAAC;SACvC;aAAM;YACL,IAAI,CAAC,uCAAuC,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,CACnC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,WAAC,OAAA,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,MAAA,aAAa,CAAC,GAAG,CAAC,mCAAI,GAAG,KAAK,KAAK,EAAE,CAAC,CAAA,EAAA,CAClF,CAAC;YACF,OAAO,aAAkB,CAAC;SAC3B;IACH,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n ReplaceTypesPreserveOptional,\n Validate,\n ValidateFnc,\n fieldIdToName,\n} from \"./execute-configs\";\n\nimport { Configs } from \"../scaffolding\";\nimport { hideBin } from \"yargs/helpers\";\nimport yargsParser from \"yargs-parser\";\n\nexport const extractConfigFromArgs = <TConfig extends Configs>(\n argv: yargsParser.Arguments,\n validateConfig: Validate<TConfig>,\n red: (msg: string) => void\n): { configPartial: Partial<TConfig>; missing: boolean } => {\n const configPartial: Partial<TConfig> = {};\n let missing: boolean = false;\n\n Object.entries(validateConfig).forEach(([key, v]) => {\n const validate = v as ValidateFnc;\n const value = argv[key];\n const response = validate(value);\n\n if (response === true) {\n if (value !== null && value !== undefined) {\n configPartial[key as keyof typeof validateConfig] = value;\n }\n } else if (value === null || value === undefined) {\n missing = true;\n } else {\n missing = true;\n red(`\"${value}\" is not a valid value for \"${key}\"`);\n if (typeof response === \"string\") red(response);\n }\n });\n\n return { configPartial, missing };\n};\n\nexport type Log = (msg: string) => void;\ntype Config = <C extends Configs>(\n promptForConfig: (partial: Partial<C>) => Promise<C>,\n validateConfig: ReplaceTypesPreserveOptional<C, ValidateFnc>\n) => Promise<C>;\n\nexport const buildGetConfig = (gray: Log, red: Log): Config => {\n const argv = yargsParser(hideBin(process.argv));\n return async <C extends Configs>(\n promptForConfig: (partial: Partial<C>) => Promise<C>,\n validateConfig: Validate<C>\n ) => {\n const { configPartial, missing } = extractConfigFromArgs(argv, validateConfig, red);\n\n if (missing || !Object.values(configPartial).length) {\n return promptForConfig(configPartial);\n } else {\n gray(\"Retrieved from the command parameters\");\n Object.entries(configPartial).forEach(\n ([key, value]) => value != null && gray(`${fieldIdToName[key] ?? key}: ${value}`)\n );\n return configPartial as C;\n }\n };\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/bin/execute.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { Log, buildGetConfig } from \"./execute-helpers\";\nimport {\n prefixUrlProtocol,\n promptServiceInformation,\n promptMiscConfig,\n promptWidgetConfig,\n validateDeployConfig,\n validateMiscConfig,\n validateWidgetConfig,\n} from \"./execute-configs\";\n\nimport chalk from \"chalk\";\nimport { generateProject } from \"../generateProject\";\n\nconst log = console.log;\nconst white: Log = (msg) => log(chalk.white(msg));\nconst green: Log = (msg) => log(chalk.green(msg));\nconst red: Log = (msg) => log(chalk.red(msg));\nconst gray: Log = (msg) => log(chalk.gray(msg));\n\nasync function main(): Promise<void> {\n green(\n \"\\nThis tool generates code scaffold for custom widgets in the Azure API Management’s developer portal. Learn more at https://aka.ms/apimdocs/portal/customwidgets.\\n\"\n );\n\n const getConfig = buildGetConfig(gray, red);\n\n white(\"Specify the custom widget configuration.\");\n const widgetConfig = await getConfig(promptWidgetConfig, validateWidgetConfig);\n white(\"Specify the Azure API Management service configuration.\");\n const serviceInformation = await getConfig(promptServiceInformation, validateDeployConfig);\n white(\"Specify other options\");\n const miscConfig = await getConfig(promptMiscConfig, validateMiscConfig);\n\n if (serviceInformation.resourceId[0] === \"/\") {\n serviceInformation.resourceId = serviceInformation.resourceId.slice(1);\n }\n if (serviceInformation.resourceId.slice(-1) === \"/\") {\n serviceInformation.resourceId = serviceInformation.resourceId.slice(0, -1);\n }\n if (serviceInformation.apiVersion === \"\") {\n delete serviceInformation.apiVersion;\n }\n\n serviceInformation.managementApiEndpoint = prefixUrlProtocol(\n serviceInformation.managementApiEndpoint\n );\n\n miscConfig.openUrl = miscConfig.openUrl\n ? prefixUrlProtocol(miscConfig.openUrl)\n : miscConfig.openUrl;\n\n return generateProject(widgetConfig, serviceInformation, miscConfig)\n .then(() => green(\"\\nThe custom widget’s code scaffold has been successfully generated.\\n\"))\n .catch(console.error);\n}\n\nmain()\n .then(() => process.exit(0))\n .catch((err) => {\n console.error(err);\n process.exit(1);\n });\n"]}
@@ -1,6 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT license.
3
- export async function generateProject(_widgetConfig, _deployConfig, _miscConfig = {}) {
4
- throw new Error("Only for Node.js");
5
- }
6
- //# sourceMappingURL=generateProject.browser.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generateProject.browser.js","sourceRoot":"","sources":["../../src/generateProject.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,aAA2B,EAC3B,aAAiC,EACjC,cAAuB,EAAE;IAEzB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACtC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { ServiceInformation, Options, WidgetConfig } from \"./scaffolding\";\n\nexport async function generateProject(\n _widgetConfig: WidgetConfig,\n _deployConfig: ServiceInformation,\n _miscConfig: Options = {}\n): Promise<void> {\n throw new Error(\"Only for Node.js\");\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"generateProject.js","sourceRoot":"","sources":["../../src/generateProject.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n ServiceInformation,\n OVERRIDE_DEFAULT_PORT,\n OVERRIDE_PORT_KEY,\n Options,\n WidgetConfig,\n displayNameToName,\n widgetFolderName,\n} from \"./scaffolding\";\nimport { join as joinPath, parse as parsePath } from \"path\";\nimport { promises as fs } from \"fs\";\nimport { getTemplates } from \"./getTemplates\";\nimport mustache from \"mustache\";\n\nconst templateSuffix = \".mustache\";\n\n/**\n * Generates a scaffold project of Custom widget for API Managements' Dev Portal.\n *\n * @param widgetConfig - JSON object with data required by DevPortal to handle a widget integration.\n * @param deploymentConfig - JSON object with data for deployment.\n * @param options - JSON object with other data, which will not be stored in the DevPortal.\n */\nexport async function generateProject(\n widgetConfig: WidgetConfig,\n deploymentConfig: ServiceInformation,\n options: Options = {}\n): Promise<void> {\n const { openUrl, configAdvancedTenantId, configAdvancedRedirectUri } = options;\n const openUrlParsed = openUrl ? new URL(openUrl) : null;\n if (openUrlParsed) {\n openUrlParsed.searchParams.append(OVERRIDE_PORT_KEY, String(OVERRIDE_DEFAULT_PORT));\n }\n\n const name = displayNameToName(widgetConfig.displayName);\n const serverSettings = {\n port: OVERRIDE_DEFAULT_PORT,\n open: openUrlParsed ? openUrlParsed.toString() : true,\n };\n\n const configAdditional = {\n interactiveBrowserCredentialOptions: { redirectUri: \"http://localhost:1337\" } as {\n redirectUri: string;\n tenantId?: string;\n },\n };\n if (configAdvancedTenantId) {\n configAdditional.interactiveBrowserCredentialOptions.tenantId = configAdvancedTenantId;\n }\n if (configAdvancedRedirectUri) {\n configAdditional.interactiveBrowserCredentialOptions.redirectUri = configAdvancedRedirectUri;\n }\n\n const renderTemplate = async (file: string): Promise<void> => {\n const isTemplate = file.endsWith(templateSuffix);\n const encoding = file.endsWith(\".ttf\") ? \"binary\" : \"utf8\";\n let fileData = await fs.readFile(file, { encoding });\n if (isTemplate) {\n fileData = mustache.render(fileData, {\n name,\n displayName: widgetConfig.displayName,\n config: JSON.stringify({ ...widgetConfig, name }, null, \"\\t\"),\n configDeploy: JSON.stringify(deploymentConfig, null, \"\\t\"),\n configAdditional: JSON.stringify(configAdditional, null, \"\\t\"),\n serverSettings: JSON.stringify(serverSettings, null, \"\\t\"),\n });\n }\n\n let relativePath = file;\n if (__dirname.includes(\"\\\\\")) {\n relativePath = relativePath.replace(/\\//g, \"\\\\\");\n }\n relativePath = relativePath\n .replace(joinPath(__dirname, \"templates\", \"_shared\"), \"\")\n .replace(joinPath(__dirname, \"templates\", widgetConfig.technology), \"\")\n .replace(templateSuffix, \"\");\n const newFilePath = joinPath(process.cwd(), widgetFolderName(name), relativePath);\n const dir = parsePath(newFilePath).dir;\n\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(newFilePath, fileData, { encoding });\n };\n\n const templates = await getTemplates(widgetConfig.technology);\n for (const file of Object.values(templates)) {\n await renderTemplate(file);\n }\n\n return;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"getTemplates.js","sourceRoot":"","sources":["../../src/getTemplates.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,MAAM,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAsB;IACvD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAChC,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAC/D,CAAC;IACF,MAAM,aAAa,GAAG,MAAM,QAAQ,CAClC,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAC9D,CAAC;IACF,OAAO,CAAC,GAAG,WAAW,EAAE,GAAG,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,iHAAiH;IACjH,kEAAkE;IAClE,wGAAwG;IACxG,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { ScaffoldTech } from \"./scaffolding\";\nimport { glob } from \"glob\";\nimport { join as pathJoin } from \"path\";\n\nexport async function getTemplates(template: ScaffoldTech): Promise<string[]> {\n const sharedFiles = await getFiles(\n pathJoin(__dirname, \"templates\", \"_shared\", \"**\", \"**\", \"*.*\")\n );\n const templateFiles = await getFiles(\n pathJoin(__dirname, \"templates\", template, \"**\", \"**\", \"*.*\")\n );\n return [...sharedFiles, ...templateFiles];\n}\n\nasync function getFiles(path: string): Promise<string[]> {\n // Starting from glob v8 `\\` is only used as an escape character, and never as a path separator in glob patterns.\n // Glob pattern paths must use forward-slashes as path separators.\n // See https://github.com/isaacs/node-glob/blob/af57da21c7722bb6edb687ccd4ad3b99d3e7a333/changelog.md#80\n const normalizedPath = path.replace(/\\\\/g, \"/\");\n return glob(normalizedPath, { dot: true });\n}\n"]}
@@ -1,8 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT license.
3
- /**
4
- * @packageDocumentation https://aka.ms/apimdocs/portal/customwidgets
5
- */
6
- export { OVERRIDE_PORT_KEY, OVERRIDE_DEFAULT_PORT, TECHNOLOGIES, displayNameToName, widgetFolderName, } from "./scaffolding";
7
- export { generateProject } from "./generateProject";
8
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,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 OVERRIDE_PORT_KEY,\n OVERRIDE_DEFAULT_PORT,\n TECHNOLOGIES,\n displayNameToName,\n widgetFolderName,\n} from \"./scaffolding\";\nexport { generateProject } from \"./generateProject\";\nexport type {\n WidgetConfig as CustomWidgetCommonConfig,\n ServiceInformation as DeploymentConfig,\n Options,\n ScaffoldTech,\n} from \"./scaffolding\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scaffolding.js","sourceRoot":"","sources":["../../src/scaffolding.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAC7D;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAK1C,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAmB,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAkC3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAU,EAAE,CAC/D,kBAAkB,CAChB,WAAW;KACR,SAAS,CAAC,KAAK,CAAC;KAChB,WAAW,EAAE;KACb,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;KAC/B,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAC/B,CAAC;AAEJ;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,+BAA+B,IAAI,EAAE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Unique identifier under which is specified which port to use for injecting locally hosted custom widget to a running DevPortal instance.\n */\nexport const OVERRIDE_PORT_KEY = \"MS_APIM_CW_localhost_port\";\n/**\n * Default port for running local dev server on.\n */\nexport const OVERRIDE_DEFAULT_PORT = 3000;\n\n/** All supported technologies to scaffold a widget in. */\nexport type ScaffoldTech = \"typescript\" | \"react\" | \"vue\";\n\n/** List of all supported technologies to scaffold a widget in. */\nexport const TECHNOLOGIES: ScaffoldTech[] = [\"typescript\", \"react\", \"vue\"];\n\n/** Main data which DevPortal needs for every custom widget. */\nexport interface WidgetConfig {\n /** Name of the custom widget which is displayed in DevPortal. */\n displayName: string;\n /** Technology to use to scaffold the widget. */\n technology: ScaffoldTech;\n /** Optional URL for a custom icon, which will be displayed in DevPortal widget list. */\n iconUrl?: string;\n}\n\n/** Data needed for deployment. */\nexport interface ServiceInformation {\n /** Management API endpoint to use (e.g. management.azure.com). */\n managementApiEndpoint: string;\n /** resourceId of your APIM service, must be in this format: subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.ApiManagement/service/<service-name> */\n resourceId: string;\n /** optional override which API version to use during deployment */\n apiVersion?: string;\n}\n\n/** Miscellaneous data for scaffolding of a custom widget which will not be stored in DevPortal. */\nexport interface Options {\n /** The URL to open after development server of the widget is started (URL of your Developer Portal). If you don't want to use this feature, set it to `false`. If you want to open just the widget page, set it to `true`. */\n openUrl?: string;\n /** advance configuration option for the deploy function - tenant ID for InteractiveBrowserCredentialNodeOptions */\n configAdvancedTenantId?: string;\n /** advance configuration option for the deploy function - redirect URI for InteractiveBrowserCredentialNodeOptions */\n configAdvancedRedirectUri?: string;\n}\n\nexport type Configs = WidgetConfig | ServiceInformation | Options;\n\n/**\n * Converts user defined name of a custom widget to a unique ID, which is in context of Dev Portal known as \"name\".\n *\n * @param displayName - User defined name of the custom widget.\n */\nexport const displayNameToName = (displayName: string): string =>\n encodeURIComponent(\n displayName\n .normalize(\"NFD\")\n .toLowerCase()\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n );\n\n/**\n * Returns name of the folder for widget project.\n *\n * @param name - name of the widget\n */\nexport const widgetFolderName = (name: string): string => `azure-api-management-widget-${name}`;\n"]}