iframe-coordinator-cli 6.0.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -6,8 +6,8 @@
6
6
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
7
7
  <link rel="icon" href="/favicon.ico" />
8
8
  <title>ifc-wrapper</title>
9
- <script type="module" crossorigin src="/assets/index-CArHK_XP.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-D3hBVT7E.css">
9
+ <script type="module" crossorigin src="/assets/index-CLBM4aoB.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-BACxQIa4.css">
11
11
  </head>
12
12
  <body>
13
13
  <noscript>
package/ifc-cli.js CHANGED
@@ -19,9 +19,26 @@ main();
19
19
  function main() {
20
20
  const opts = parseProgramOptions();
21
21
  const indexContent = generateIndex(appPath, opts.clientConfigFile);
22
+ const configuredProxies = loadProxyConfig(opts.proxyConfigFile);
22
23
 
23
24
  app = express();
25
+ // Serve our custom index file with injected frame-router config
24
26
  app.use(/^\/$/, serveIndex(indexContent));
27
+
28
+ // Set up user configured proxies
29
+ configuredProxies.forEach((proxy) => {
30
+ app.use(
31
+ proxy.path,
32
+ createProxyMiddleware({
33
+ target: proxy.target,
34
+ ws: true, // proxy websockets too
35
+ changeOrigin: true, // rewrite the origin header to avoid any potential CORS issues
36
+ followRedirects: true, // ensure redirects from the server will also be proxied
37
+ }),
38
+ );
39
+ });
40
+
41
+ // Deprecated path-based dynamic proxy - to be removed in next major release
25
42
  app.use(
26
43
  "/proxy",
27
44
  createProxyMiddleware({
@@ -35,6 +52,8 @@ function main() {
35
52
  target: `http://localhost:${opts.port}`, //Required by middleware, but should be always overriden by the previous options
36
53
  }),
37
54
  );
55
+
56
+ // Server the static Vue App assets
38
57
  app.use(express.static(appPath));
39
58
 
40
59
  if (opts.ssl) {
@@ -55,6 +74,7 @@ function main() {
55
74
  function parseProgramOptions() {
56
75
  const projRoot = findRoot(process.cwd());
57
76
  const defaultJsConfig = path.join(projRoot, "ifc-cli.config.js");
77
+ const defaultProxyConfig = path.join(projRoot, "ifc-proxy.config.json");
58
78
 
59
79
  program
60
80
  .option(
@@ -62,6 +82,7 @@ function parseProgramOptions() {
62
82
  "iframe client configuration file",
63
83
  defaultJsConfig,
64
84
  )
85
+ .option("-x -proxy-config <proxy_config_file>")
65
86
  .option("-p, --port <port_num>", "port number to host on", 3000)
66
87
  .option("-s, --ssl", "serve over https")
67
88
  .option("--ssl-cert <cert_path>", "certificate file to use for https")
@@ -72,17 +93,29 @@ function parseProgramOptions() {
72
93
 
73
94
  const options = program.opts();
74
95
 
75
- return {
96
+ // Use a proxy config file from the default location as our fallback if needed
97
+ let proxyConfigPath = null;
98
+ if (options.proxyConfig) {
99
+ proxyConfigPath = findConfigFile(options.proxyConfig);
100
+ } else if (fs.existsSync(defaultProxyConfig)) {
101
+ proxyConfigPath = defaultProxyConfig;
102
+ }
103
+
104
+ parsedOpts = {
76
105
  clientConfigFile: findConfigFile(options.configFile),
106
+ proxyConfigFile: proxyConfigPath,
77
107
  port: options.port,
78
108
  ssl: options.ssl,
79
109
  sslCert: options.sslCert,
80
110
  sslKey: options.sslKey,
81
111
  };
112
+
113
+ return parsedOpts;
82
114
  }
83
115
 
84
116
  function showHelpText() {
85
117
  const configExample = path.join(__dirname, "example-ifc.config.js");
118
+ const configContent = fs.readFileSync(configExample).toString();
86
119
  console.log(`
87
120
  This program will start a server for a basic iframe-coordinator host app. In
88
121
  order to configure the frame-router element and any other custom logic needed
@@ -98,8 +131,19 @@ function showHelpText() {
98
131
  function expression.
99
132
 
100
133
  Here is an example config file:
134
+
135
+ ${configContent}
136
+
137
+ ifc-cli can also be configured to proxy requests to a local dev server or
138
+ other server so that embedded apps appear on the same origin as the host.
139
+ That configuration should be a json file mapping server paths to upstream
140
+ targets, e.g.:
141
+
142
+ {
143
+ "/my/app/": "http://localhost:8000/",
144
+ "/another/app/": "http://localhost:9000/"
145
+ }
101
146
  `);
102
- console.log(fs.readFileSync(configExample).toString());
103
147
  }
104
148
 
105
149
  function serveIndex(indexContent) {
@@ -108,6 +152,10 @@ function serveIndex(indexContent) {
108
152
  };
109
153
  }
110
154
 
155
+ /**
156
+ * Build the index file served to clients. This is the `index.html` from this project with the
157
+ * user's configuration file injected into a script tag to enable frame router setup.
158
+ */
111
159
  function generateIndex(appPath, clientConfigFile) {
112
160
  const baseIndex = fs
113
161
  .readFileSync(path.join(appPath, "index.html"))
@@ -117,6 +165,11 @@ function generateIndex(appPath, clientConfigFile) {
117
165
  return $.html();
118
166
  }
119
167
 
168
+ /**
169
+ * Generate a script tag that exports the frame router setup function from the user's config file
170
+ * as a global variable so that ifc-cli's host app can call it when creating the frame-router elemen
171
+ * in the DOM
172
+ */
120
173
  function configScript(scriptFile) {
121
174
  const scriptContents = fs.readFileSync(scriptFile).toString();
122
175
  // This is a bit of a kludge but it should suffice for now.
@@ -142,6 +195,14 @@ function findConfigFile(cliPath) {
142
195
  }
143
196
  }
144
197
 
198
+ function relativizePath(inPath) {
199
+ let outPath = path.relative(process.cwd(), inPath);
200
+ if (!outPath.startsWith(".")) {
201
+ outPath = "./" + outPath;
202
+ }
203
+ return outPath;
204
+ }
205
+
145
206
  function getSslOpts(certPath, keyPath) {
146
207
  if (!certPath || !keyPath) {
147
208
  return devCertAuthority("localhost");
@@ -157,13 +218,18 @@ function getSslOpts(certPath, keyPath) {
157
218
  }
158
219
  }
159
220
 
160
- // Make sure a path isn't interpreted as a module when required.
161
- function relativizePath(inPath) {
162
- let outPath = path.relative(process.cwd(), inPath);
163
- if (!outPath.startsWith(".")) {
164
- outPath = "./" + outPath;
221
+ function loadProxyConfig(path) {
222
+ if (!path) {
223
+ return [];
165
224
  }
166
- return outPath;
225
+
226
+ const proxyConfig = JSON.parse(fs.readFileSync(path).toString());
227
+ return Object.entries(proxyConfig).map(([path, target]) => {
228
+ return {
229
+ path,
230
+ target,
231
+ };
232
+ });
167
233
  }
168
234
 
169
235
  function extractTargetHost(req) {
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "iframe-coordinator-cli",
3
- "version": "6.0.1",
3
+ "version": "6.1.0",
4
4
  "description": "CLI for local iframe-coordinator development",
5
5
  "dependencies": {
6
6
  "cheerio": "1.0.0-rc.12",
7
7
  "commander": "^12.1.0",
8
8
  "custom-event-polyfill": "^1.0.7",
9
9
  "dev-cert-authority": "^1.1.1",
10
- "express": "^4.19.2",
10
+ "express": "^4.21.1",
11
11
  "find-root": "^1.1.0",
12
- "http-proxy-middleware": "^2.0.6",
12
+ "http-proxy-middleware": "^3.0.3",
13
13
  "iframe-coordinator": "6.0.0",
14
14
  "vue": "^2.7.16",
15
15
  "vue-class-component": "^7.2.6",