@ms-cloudpack/create-express-app 1.10.32 → 1.10.34

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.
@@ -42,6 +42,11 @@ export interface CreateExpressAppResult {
42
42
  /** Port the app is running on */
43
43
  port: number;
44
44
  }
45
+ /**
46
+ * Create an Express app with the given options.
47
+ *
48
+ * Note: If you update the errors thrown by this function, also update the ones in `handleKnownServerErrors.ts`.
49
+ */
45
50
  export declare function createExpressApp(options: CreateExpressAppOptions): Promise<CreateExpressAppResult>;
46
51
  export type { Express };
47
52
  //# sourceMappingURL=createExpressApp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createExpressApp.d.ts","sourceRoot":"","sources":["../src/createExpressApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAMnC,MAAM,WAAW,uBAAuB;IACtC,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,UAAU,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,qCAAqC;IACrC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,OAAO,CAAC;IACb,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAwGxG;AAED,YAAY,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"createExpressApp.d.ts","sourceRoot":"","sources":["../src/createExpressApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAMnC,MAAM,WAAW,uBAAuB;IACtC,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,UAAU,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,qCAAqC;IACrC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,OAAO,CAAC;IACb,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAwGxG;AAED,YAAY,EAAE,OAAO,EAAE,CAAC"}
@@ -5,6 +5,11 @@ import getPort from 'get-port';
5
5
  import https from 'https';
6
6
  import { parseHttpsConfig } from './parseHttpsConfig.js';
7
7
  import { getDomain } from './getDomain.js';
8
+ /**
9
+ * Create an Express app with the given options.
10
+ *
11
+ * Note: If you update the errors thrown by this function, also update the ones in `handleKnownServerErrors.ts`.
12
+ */
8
13
  export async function createExpressApp(options) {
9
14
  const {
10
15
  // eslint-disable-next-line etc/no-deprecated
@@ -1 +1 @@
1
- {"version":3,"file":"createExpressApp.js","sourceRoot":"","sources":["../src/createExpressApp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HttpsConfig } from '@ms-cloudpack/common-types';\nimport compression from 'compression';\nimport cors from 'cors';\nimport express, { type Express } from 'express';\nimport getPort from 'get-port';\nimport type { Server } from 'http';\nimport https from 'https';\nimport type { Socket } from 'net';\nimport { parseHttpsConfig } from './parseHttpsConfig.js';\nimport { getDomain } from './getDomain.js';\n\nexport interface CreateExpressAppOptions {\n /** Port(s) to try */\n portRange?: number | number[];\n /** Throw an error if none of the ports specified in `portRange` are available. */\n requireSpecifiedPort?: boolean;\n /**\n * Hostname to use for the server. Supports replacement `{ip}` for the current IP address.\n * @default 'localhost'\n */\n hostname?: string;\n /** Include these headers with all responses */\n requestHeaders?: Record<string, string>;\n /** cwd for resolving any relative paths in `sslOptions` */\n cwd?: string;\n /** Options for an HTTPS server. Certificate paths support tokens `{homedir}` and `{tmpdir}`. */\n sslOptions?: HttpsConfig | true;\n /** @deprecated use returned `app` */\n setupCallback?: (app: Express, baseUrl: string) => void | Promise<void>;\n /** Path of any static assets */\n publicDir?: string;\n /** @deprecated Inferred based on presence of `server` */\n middlewareMode?: boolean;\n /** If provided, act as a middleware on this server, rather than starting a new server */\n server?: Server;\n}\n\nexport interface CreateExpressAppResult {\n app: Express;\n /** http or https server */\n server: Server;\n /** Close the server */\n close: () => Promise<void>;\n /** Base URL of the app */\n url: string;\n /** @deprecated use `url` */\n baseUrl: string;\n protocol: 'http' | 'https';\n /** Domain (no protocol or port) the app is running on */\n domain: string;\n /** Port the app is running on */\n port: number;\n}\n\nexport async function createExpressApp(options: CreateExpressAppOptions): Promise<CreateExpressAppResult> {\n const {\n // eslint-disable-next-line etc/no-deprecated\n setupCallback,\n hostname,\n requestHeaders = {},\n cwd = '',\n sslOptions,\n requireSpecifiedPort,\n publicDir,\n portRange: ports,\n } = options;\n\n if (sslOptions && !cwd) {\n throw new Error('Must provide `cwd` when `sslOptions` are provided');\n }\n\n const portRange = typeof ports === 'number' ? [ports] : ports;\n\n if (requireSpecifiedPort && !portRange?.length) {\n throw new Error('Must specify a portRange when requireSpecifiedPort is true');\n }\n\n // Get the available port.\n const port = await getPort({\n port: portRange,\n });\n\n if (requireSpecifiedPort && !portRange?.includes(port)) {\n throw new Error(`No ports from portRange ${JSON.stringify(portRange)} are available`);\n }\n\n const app = express();\n\n // Use cors.\n app.use(cors());\n\n // Use compression.\n app.use(compression());\n\n app.use((_, res, next) => {\n for (const [headerName, headerValue] of Object.entries(requestHeaders)) {\n res.setHeader(headerName, headerValue);\n }\n next();\n });\n\n if (publicDir !== undefined) {\n app.use(express.static(publicDir, { index: false }));\n }\n\n const domain = getDomain(hostname);\n let server = options.server;\n const isHttps = !!sslOptions;\n const protocol = isHttps ? 'https' : 'http';\n let url = `${protocol}://${domain}`;\n\n if ((isHttps && port !== 443) || (!isHttps && port !== 80)) {\n url += `:${port}`;\n }\n // Call setup callback with the app.\n await setupCallback?.(app, url);\n\n if (!server) {\n if (isHttps) {\n // Create an HTTPS server.\n const httpsServer = https.createServer(await parseHttpsConfig({ domain, https: sslOptions, cwd }), app);\n // The 0.0.0.0 ip filter is needed for the server to be accessible from outside the container (e.g. WSL case)\n server = httpsServer.listen(port, '0.0.0.0');\n } else {\n // Create an HTTP server.\n server = app.listen(port, '0.0.0.0');\n }\n }\n\n // Track new connections so that we can close them and exit cleanly on ctrl+C.\n // (Calling close() on an express server simply stops it from accepting new connections;\n // it doesn't close existing keep-alive connections, which makes the CLI hang on exit.)\n const sockets = new Set<Socket>();\n server.on('connection', (socket) => {\n sockets.add(socket);\n socket.on('close', () => {\n sockets.delete(socket);\n });\n });\n\n return {\n app,\n server,\n async close() {\n for (const socket of sockets) {\n socket.destroy();\n }\n sockets.clear();\n await new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()));\n });\n },\n url,\n baseUrl: url,\n protocol,\n domain,\n port,\n };\n}\n\nexport type { Express };\n"]}
1
+ {"version":3,"file":"createExpressApp.js","sourceRoot":"","sources":["../src/createExpressApp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HttpsConfig } from '@ms-cloudpack/common-types';\nimport compression from 'compression';\nimport cors from 'cors';\nimport express, { type Express } from 'express';\nimport getPort from 'get-port';\nimport type { Server } from 'http';\nimport https from 'https';\nimport type { Socket } from 'net';\nimport { parseHttpsConfig } from './parseHttpsConfig.js';\nimport { getDomain } from './getDomain.js';\n\nexport interface CreateExpressAppOptions {\n /** Port(s) to try */\n portRange?: number | number[];\n /** Throw an error if none of the ports specified in `portRange` are available. */\n requireSpecifiedPort?: boolean;\n /**\n * Hostname to use for the server. Supports replacement `{ip}` for the current IP address.\n * @default 'localhost'\n */\n hostname?: string;\n /** Include these headers with all responses */\n requestHeaders?: Record<string, string>;\n /** cwd for resolving any relative paths in `sslOptions` */\n cwd?: string;\n /** Options for an HTTPS server. Certificate paths support tokens `{homedir}` and `{tmpdir}`. */\n sslOptions?: HttpsConfig | true;\n /** @deprecated use returned `app` */\n setupCallback?: (app: Express, baseUrl: string) => void | Promise<void>;\n /** Path of any static assets */\n publicDir?: string;\n /** @deprecated Inferred based on presence of `server` */\n middlewareMode?: boolean;\n /** If provided, act as a middleware on this server, rather than starting a new server */\n server?: Server;\n}\n\nexport interface CreateExpressAppResult {\n app: Express;\n /** http or https server */\n server: Server;\n /** Close the server */\n close: () => Promise<void>;\n /** Base URL of the app */\n url: string;\n /** @deprecated use `url` */\n baseUrl: string;\n protocol: 'http' | 'https';\n /** Domain (no protocol or port) the app is running on */\n domain: string;\n /** Port the app is running on */\n port: number;\n}\n\n/**\n * Create an Express app with the given options.\n *\n * Note: If you update the errors thrown by this function, also update the ones in `handleKnownServerErrors.ts`.\n */\nexport async function createExpressApp(options: CreateExpressAppOptions): Promise<CreateExpressAppResult> {\n const {\n // eslint-disable-next-line etc/no-deprecated\n setupCallback,\n hostname,\n requestHeaders = {},\n cwd = '',\n sslOptions,\n requireSpecifiedPort,\n publicDir,\n portRange: ports,\n } = options;\n\n if (sslOptions && !cwd) {\n throw new Error('Must provide `cwd` when `sslOptions` are provided');\n }\n\n const portRange = typeof ports === 'number' ? [ports] : ports;\n\n if (requireSpecifiedPort && !portRange?.length) {\n throw new Error('Must specify a portRange when requireSpecifiedPort is true');\n }\n\n // Get the available port.\n const port = await getPort({\n port: portRange,\n });\n\n if (requireSpecifiedPort && !portRange?.includes(port)) {\n throw new Error(`No ports from portRange ${JSON.stringify(portRange)} are available`);\n }\n\n const app = express();\n\n // Use cors.\n app.use(cors());\n\n // Use compression.\n app.use(compression());\n\n app.use((_, res, next) => {\n for (const [headerName, headerValue] of Object.entries(requestHeaders)) {\n res.setHeader(headerName, headerValue);\n }\n next();\n });\n\n if (publicDir !== undefined) {\n app.use(express.static(publicDir, { index: false }));\n }\n\n const domain = getDomain(hostname);\n let server = options.server;\n const isHttps = !!sslOptions;\n const protocol = isHttps ? 'https' : 'http';\n let url = `${protocol}://${domain}`;\n\n if ((isHttps && port !== 443) || (!isHttps && port !== 80)) {\n url += `:${port}`;\n }\n // Call setup callback with the app.\n await setupCallback?.(app, url);\n\n if (!server) {\n if (isHttps) {\n // Create an HTTPS server.\n const httpsServer = https.createServer(await parseHttpsConfig({ domain, https: sslOptions, cwd }), app);\n // The 0.0.0.0 ip filter is needed for the server to be accessible from outside the container (e.g. WSL case)\n server = httpsServer.listen(port, '0.0.0.0');\n } else {\n // Create an HTTP server.\n server = app.listen(port, '0.0.0.0');\n }\n }\n\n // Track new connections so that we can close them and exit cleanly on ctrl+C.\n // (Calling close() on an express server simply stops it from accepting new connections;\n // it doesn't close existing keep-alive connections, which makes the CLI hang on exit.)\n const sockets = new Set<Socket>();\n server.on('connection', (socket) => {\n sockets.add(socket);\n socket.on('close', () => {\n sockets.delete(socket);\n });\n });\n\n return {\n app,\n server,\n async close() {\n for (const socket of sockets) {\n socket.destroy();\n }\n sockets.clear();\n await new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()));\n });\n },\n url,\n baseUrl: url,\n protocol,\n domain,\n port,\n };\n}\n\nexport type { Express };\n"]}
@@ -1,4 +1,9 @@
1
1
  import type { HttpsConfig } from '@ms-cloudpack/common-types';
2
+ /**
3
+ * Read certificates files in Https Config and return the contents.
4
+ *
5
+ * Note: If you update the errors thrown by this function, also update the ones in `handleKnownParseHttpsErrors.ts`.
6
+ */
2
7
  export declare function parseHttpsConfig(options: {
3
8
  domain?: string;
4
9
  https: true | HttpsConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"parseHttpsConfig.d.ts","sourceRoot":"","sources":["../src/parseHttpsConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAU9D,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,GAAG,WAAW,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,WAAW,CAAC,CAoCvB"}
1
+ {"version":3,"file":"parseHttpsConfig.d.ts","sourceRoot":"","sources":["../src/parseHttpsConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAO9D;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,GAAG,WAAW,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,WAAW,CAAC,CAqCvB"}
@@ -3,8 +3,10 @@ import fs from 'fs';
3
3
  import { pathSymbolReplacement } from '@ms-cloudpack/path-utilities';
4
4
  import { slash } from '@ms-cloudpack/path-string-parsing';
5
5
  import { getCertificate } from '@ms-cloudpack/setup-utilities';
6
- /*
6
+ /**
7
7
  * Read certificates files in Https Config and return the contents.
8
+ *
9
+ * Note: If you update the errors thrown by this function, also update the ones in `handleKnownParseHttpsErrors.ts`.
8
10
  */
9
11
  export async function parseHttpsConfig(options) {
10
12
  const { https, cwd } = options;
@@ -25,7 +27,8 @@ export async function parseHttpsConfig(options) {
25
27
  sslOptions[key] = fs.readFileSync(certFilePath);
26
28
  }
27
29
  else {
28
- throw new Error(`The specified certificate to be used for the web server is missing at "${certFilePath}". Make sure the path is correct, the file exists, and try starting again.`);
30
+ throw new Error(`The specified certificate to be used for the web server is missing at "${certFilePath}".\n\n` +
31
+ 'Make sure the path is correct, the necessary setup to install the certificate has been done, the file exists, and try starting again.');
29
32
  }
30
33
  }
31
34
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"parseHttpsConfig.js","sourceRoot":"","sources":["../src/parseHttpsConfig.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAI/D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAItC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAE/B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAElD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,wCAAwC,OAAO,CAAC,MAAM,8EAA8E,CACrI,CAAC;QACJ,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,UAAU,GAAyC,EAAE,CAAC;IAE5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,+CAA+C;QAC/C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5E,kDAAkD;YAClD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAE5E,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,0EAA0E,YAAY,4EAA4E,CACnK,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,4CAA4C;YAC5C,UAAU,CAAC,GAAG,CAAC,GAAG,KAA6B,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { HttpsConfig } from '@ms-cloudpack/common-types';\nimport { pathSymbolReplacement } from '@ms-cloudpack/path-utilities';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport { getCertificate } from '@ms-cloudpack/setup-utilities';\n\ntype ValueOf<T> = T[keyof T];\n\n/*\n * Read certificates files in Https Config and return the contents.\n */\nexport async function parseHttpsConfig(options: {\n domain?: string;\n https: true | HttpsConfig;\n cwd: string;\n}): Promise<HttpsConfig> {\n const { https, cwd } = options;\n\n if (https === true) {\n const httpsConfig = await getCertificate(options);\n\n if (!httpsConfig) {\n throw new Error(\n `No certificate found for the domain \"${options.domain}\". Make sure you have a valid certificate in the cloudpack.config.json file.`,\n );\n }\n\n return httpsConfig;\n }\n\n const sslOptions: Record<string, ValueOf<HttpsConfig>> = {};\n\n for (const [key, value] of Object.entries(https)) {\n // Read the file contents for the certificates.\n if (['ca', 'cert', 'key', 'pfx'].includes(key) && typeof value === 'string') {\n // Get a standard path with expanded path symbols.\n const certFilePath = slash(path.resolve(cwd, pathSymbolReplacement(value)));\n\n if (fs.existsSync(certFilePath)) {\n sslOptions[key] = fs.readFileSync(certFilePath);\n } else {\n throw new Error(\n `The specified certificate to be used for the web server is missing at \"${certFilePath}\". Make sure the path is correct, the file exists, and try starting again.`,\n );\n }\n } else {\n // If not a certificate, just use the value.\n sslOptions[key] = value as ValueOf<HttpsConfig>;\n }\n }\n return sslOptions;\n}\n"]}
1
+ {"version":3,"file":"parseHttpsConfig.js","sourceRoot":"","sources":["../src/parseHttpsConfig.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAI/D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAItC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAE/B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAElD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,wCAAwC,OAAO,CAAC,MAAM,8EAA8E,CACrI,CAAC;QACJ,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,UAAU,GAAyC,EAAE,CAAC;IAE5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,+CAA+C;QAC/C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5E,kDAAkD;YAClD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAE5E,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,0EAA0E,YAAY,QAAQ;oBAC5F,uIAAuI,CAC1I,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,4CAA4C;YAC5C,UAAU,CAAC,GAAG,CAAC,GAAG,KAA6B,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { HttpsConfig } from '@ms-cloudpack/common-types';\nimport { pathSymbolReplacement } from '@ms-cloudpack/path-utilities';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport { getCertificate } from '@ms-cloudpack/setup-utilities';\n\ntype ValueOf<T> = T[keyof T];\n\n/**\n * Read certificates files in Https Config and return the contents.\n *\n * Note: If you update the errors thrown by this function, also update the ones in `handleKnownParseHttpsErrors.ts`.\n */\nexport async function parseHttpsConfig(options: {\n domain?: string;\n https: true | HttpsConfig;\n cwd: string;\n}): Promise<HttpsConfig> {\n const { https, cwd } = options;\n\n if (https === true) {\n const httpsConfig = await getCertificate(options);\n\n if (!httpsConfig) {\n throw new Error(\n `No certificate found for the domain \"${options.domain}\". Make sure you have a valid certificate in the cloudpack.config.json file.`,\n );\n }\n\n return httpsConfig;\n }\n\n const sslOptions: Record<string, ValueOf<HttpsConfig>> = {};\n\n for (const [key, value] of Object.entries(https)) {\n // Read the file contents for the certificates.\n if (['ca', 'cert', 'key', 'pfx'].includes(key) && typeof value === 'string') {\n // Get a standard path with expanded path symbols.\n const certFilePath = slash(path.resolve(cwd, pathSymbolReplacement(value)));\n\n if (fs.existsSync(certFilePath)) {\n sslOptions[key] = fs.readFileSync(certFilePath);\n } else {\n throw new Error(\n `The specified certificate to be used for the web server is missing at \"${certFilePath}\".\\n\\n` +\n 'Make sure the path is correct, the necessary setup to install the certificate has been done, the file exists, and try starting again.',\n );\n }\n } else {\n // If not a certificate, just use the value.\n sslOptions[key] = value as ValueOf<HttpsConfig>;\n }\n }\n return sslOptions;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/create-express-app",
3
- "version": "1.10.32",
3
+ "version": "1.10.34",
4
4
  "description": "Helper for creating an express app server, abstracting a common plugin setup.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,10 +14,10 @@
14
14
  }
15
15
  },
16
16
  "dependencies": {
17
- "@ms-cloudpack/common-types": "^0.24.18",
17
+ "@ms-cloudpack/common-types": "^0.24.20",
18
18
  "@ms-cloudpack/path-string-parsing": "^1.2.7",
19
- "@ms-cloudpack/path-utilities": "^3.1.3",
20
- "@ms-cloudpack/setup-utilities": "^0.5.25",
19
+ "@ms-cloudpack/path-utilities": "^3.1.5",
20
+ "@ms-cloudpack/setup-utilities": "^0.5.27",
21
21
  "@types/express": "^4.17.16",
22
22
  "compression": "^1.7.4",
23
23
  "cors": "^2.8.5",