@ms-cloudpack/cli 0.74.2 → 0.74.4

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.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Creates API server URLs for remote connection
3
+ *
4
+ * Generates WebSocket URLs for connecting to remote API servers based on
5
+ * the provided remote host and available ports.
6
+ *
7
+ * If the remote host is not specified, it starts from 'localhost'.
8
+ * It accepts both HTTP and HTTPS protocols, and generates the appropriate
9
+ * WebSocket URLs based on the protocol of the remote host and known api server ports.
10
+ * It also accepts WS and WSS protocols based on the remote host's protocol and returns as is.
11
+ *
12
+ * When the protocol is undefined (not HTTP or HTTPS), it generates both secure (wss://)
13
+ * and non-secure (ws://) WebSocket URLs, with wss:// URLs listed first.
14
+ */
15
+ export declare function createRemoteApiUrls(params: {
16
+ remote: string | boolean;
17
+ apiServerUrl: string;
18
+ }): string[];
19
+ //# sourceMappingURL=createRemoteApiUrls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRemoteApiUrls.d.ts","sourceRoot":"","sources":["../../../src/commands/link/createRemoteApiUrls.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CA0CxG"}
@@ -0,0 +1,55 @@
1
+ import { makeUrl } from '@ms-cloudpack/path-string-parsing';
2
+ import { apiServerPort } from '@ms-cloudpack/api-server';
3
+ /**
4
+ * Creates API server URLs for remote connection
5
+ *
6
+ * Generates WebSocket URLs for connecting to remote API servers based on
7
+ * the provided remote host and available ports.
8
+ *
9
+ * If the remote host is not specified, it starts from 'localhost'.
10
+ * It accepts both HTTP and HTTPS protocols, and generates the appropriate
11
+ * WebSocket URLs based on the protocol of the remote host and known api server ports.
12
+ * It also accepts WS and WSS protocols based on the remote host's protocol and returns as is.
13
+ *
14
+ * When the protocol is undefined (not HTTP or HTTPS), it generates both secure (wss://)
15
+ * and non-secure (ws://) WebSocket URLs, with wss:// URLs listed first.
16
+ */
17
+ export function createRemoteApiUrls(params) {
18
+ const remote = typeof params.remote === 'string' ? params.remote : 'localhost';
19
+ // Extract the protocol from the remote if available
20
+ let remoteProtocol = undefined;
21
+ try {
22
+ remoteProtocol = makeUrl(remote).protocol;
23
+ }
24
+ catch (e) {
25
+ // Ignore error and proceed with undefined protocol
26
+ }
27
+ // Return as is if it is a WebSocket URL
28
+ if (remoteProtocol === 'ws:' || remoteProtocol === 'wss:') {
29
+ return [remote];
30
+ }
31
+ // Get the hostname (host without port, protocol, etc.). Use dummy protocol to extract the hostname if needed.
32
+ const hostname = remote.startsWith('http') ? makeUrl(remote).hostname : makeUrl(`http://${remote}`).hostname;
33
+ // Generate URLs based on protocol
34
+ let hostApiServerURLs = [];
35
+ if (remoteProtocol === 'https:') {
36
+ // For HTTPS, only use secure WebSockets
37
+ hostApiServerURLs = apiServerPort.map((port) => `wss://${hostname}:${port}`);
38
+ }
39
+ else if (remoteProtocol === 'http:') {
40
+ // For HTTP, only use non-secure WebSockets
41
+ hostApiServerURLs = apiServerPort.map((port) => `ws://${hostname}:${port}`);
42
+ }
43
+ else {
44
+ // For undefined protocol, generate both secure and non-secure URLs
45
+ // First add all wss:// URLs
46
+ const wssUrls = apiServerPort.map((port) => `wss://${hostname}:${port}`);
47
+ // Then add all ws:// URLs
48
+ const wsUrls = apiServerPort.map((port) => `ws://${hostname}:${port}`);
49
+ // Combine both sets of URLs with wss URLs first
50
+ hostApiServerURLs = [...wssUrls, ...wsUrls];
51
+ }
52
+ // Exclude the current api url from the list
53
+ return hostApiServerURLs.filter((url) => url !== params.apiServerUrl);
54
+ }
55
+ //# sourceMappingURL=createRemoteApiUrls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRemoteApiUrls.js","sourceRoot":"","sources":["../../../src/commands/link/createRemoteApiUrls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0D;IAC5F,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;IAE/E,oDAAoD;IACpD,IAAI,cAAc,GAAuB,SAAS,CAAC;IACnD,IAAI,CAAC;QACH,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC;IAC5C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,mDAAmD;IACrD,CAAC;IAED,wCAAwC;IACxC,IAAI,cAAc,KAAK,KAAK,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,8GAA8G;IAC9G,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC;IAE7G,kCAAkC;IAClC,IAAI,iBAAiB,GAAa,EAAE,CAAC;IAErC,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;QAChC,wCAAwC;QACxC,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QACtC,2CAA2C;QAC3C,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;SAAM,CAAC;QACN,mEAAmE;QACnE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;QAEzE,0BAA0B;QAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;QAEvE,gDAAgD;QAChD,iBAAiB,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,4CAA4C;IAC5C,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,YAAY,CAAC,CAAC;AACxE,CAAC","sourcesContent":["import { makeUrl } from '@ms-cloudpack/path-string-parsing';\nimport { apiServerPort } from '@ms-cloudpack/api-server';\n\n/**\n * Creates API server URLs for remote connection\n *\n * Generates WebSocket URLs for connecting to remote API servers based on\n * the provided remote host and available ports.\n *\n * If the remote host is not specified, it starts from 'localhost'.\n * It accepts both HTTP and HTTPS protocols, and generates the appropriate\n * WebSocket URLs based on the protocol of the remote host and known api server ports.\n * It also accepts WS and WSS protocols based on the remote host's protocol and returns as is.\n *\n * When the protocol is undefined (not HTTP or HTTPS), it generates both secure (wss://)\n * and non-secure (ws://) WebSocket URLs, with wss:// URLs listed first.\n */\nexport function createRemoteApiUrls(params: { remote: string | boolean; apiServerUrl: string }): string[] {\n const remote = typeof params.remote === 'string' ? params.remote : 'localhost';\n\n // Extract the protocol from the remote if available\n let remoteProtocol: string | undefined = undefined;\n try {\n remoteProtocol = makeUrl(remote).protocol;\n } catch (e) {\n // Ignore error and proceed with undefined protocol\n }\n\n // Return as is if it is a WebSocket URL\n if (remoteProtocol === 'ws:' || remoteProtocol === 'wss:') {\n return [remote];\n }\n\n // Get the hostname (host without port, protocol, etc.). Use dummy protocol to extract the hostname if needed.\n const hostname = remote.startsWith('http') ? makeUrl(remote).hostname : makeUrl(`http://${remote}`).hostname;\n\n // Generate URLs based on protocol\n let hostApiServerURLs: string[] = [];\n\n if (remoteProtocol === 'https:') {\n // For HTTPS, only use secure WebSockets\n hostApiServerURLs = apiServerPort.map((port) => `wss://${hostname}:${port}`);\n } else if (remoteProtocol === 'http:') {\n // For HTTP, only use non-secure WebSockets\n hostApiServerURLs = apiServerPort.map((port) => `ws://${hostname}:${port}`);\n } else {\n // For undefined protocol, generate both secure and non-secure URLs\n // First add all wss:// URLs\n const wssUrls = apiServerPort.map((port) => `wss://${hostname}:${port}`);\n\n // Then add all ws:// URLs\n const wsUrls = apiServerPort.map((port) => `ws://${hostname}:${port}`);\n\n // Combine both sets of URLs with wss URLs first\n hostApiServerURLs = [...wssUrls, ...wsUrls];\n }\n\n // Exclude the current api url from the list\n return hostApiServerURLs.filter((url) => url !== params.apiServerUrl);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/link/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO1D;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,WAAW,CAyD9C,CAAC"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/link/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ1D;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,WAAW,CA8D9C,CAAC"}
@@ -3,18 +3,24 @@ import { createCloudpackClient } from '@ms-cloudpack/api-server';
3
3
  import { formatLinkSummary } from './formatLinkSummary.js';
4
4
  import { writeJson } from '@ms-cloudpack/json-utilities';
5
5
  import path from 'path';
6
+ import { linkToRemoteSession } from './linkToRemoteSession.js';
6
7
  /**
7
8
  * Defines the "link" verb entry point.
8
9
  */
9
10
  export const execute = async (params) => {
10
11
  // Use the current directory as the default package path.
11
12
  const { options, appPath, reporter } = params;
12
- const { ignore: ignoredPackages, all: includeAll, ignoreResolutions, resolveStrategy, logResolveMap, cachePath, } = options;
13
+ const { remote, ignore: ignoredPackages, all: includeAll, ignoreResolutions, resolveStrategy, logResolveMap, cachePath, } = options;
13
14
  console.debug('Linking packages...');
14
15
  console.debug('Include all:', !!includeAll);
15
16
  console.debug('Ignored packages:', ignoredPackages?.join(', ') || 'none');
16
17
  console.debug('Apply host resolutions:', !ignoreResolutions);
17
18
  console.debug('Resolve strategy:', resolveStrategy);
19
+ console.debug('Remote:', remote);
20
+ // If we are linking to a remote session, we need to use the link proxy.
21
+ if (remote)
22
+ return linkToRemoteSession(params);
23
+ // If we are linking to a session on the same machine, we can access the paths directly.
18
24
  const sessionResult = await getSessionToLink({ reporter, cachePath });
19
25
  if (!sessionResult.session) {
20
26
  return sessionResult;
@@ -22,10 +28,10 @@ export const execute = async (params) => {
22
28
  const { session } = sessionResult;
23
29
  const client = await createCloudpackClient({ url: session.urls.apiServer, reporter });
24
30
  const includeMessage = includeAll ? ' including all internal paths' : '';
25
- const message = `Linking paths for ${session.projectName} at "${appPath}"${includeMessage}`;
31
+ const message = `Linking local paths for ${session.projectName} at "${appPath}"${includeMessage}`;
26
32
  const task = reporter.addTask(message);
27
33
  // Send request to api server to link paths.
28
- const { resolveMap, linkedPaths } = await client.linkPath.query({
34
+ const { resolveMap, linkedPaths } = await client.linkPath.mutate({
29
35
  linkedPath: {
30
36
  path: appPath,
31
37
  ignoredPackages,
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/link/execute.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandAction } from '../../types/CommandAction.js';\nimport type { LinkOptions } from './types/LinkOptions.js';\nimport { getSessionToLink } from './getSessionToLink.js';\nimport { createCloudpackClient } from '@ms-cloudpack/api-server';\nimport { formatLinkSummary } from './formatLinkSummary.js';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport path from 'path';\n\n/**\n * Defines the \"link\" verb entry point.\n */\nexport const execute: CommandAction<LinkOptions> = async (params) => {\n // Use the current directory as the default package path.\n const { options, appPath, reporter } = params;\n const {\n ignore: ignoredPackages,\n all: includeAll,\n ignoreResolutions,\n resolveStrategy,\n logResolveMap,\n cachePath,\n } = options;\n\n console.debug('Linking packages...');\n console.debug('Include all:', !!includeAll);\n console.debug('Ignored packages:', ignoredPackages?.join(', ') || 'none');\n console.debug('Apply host resolutions:', !ignoreResolutions);\n console.debug('Resolve strategy:', resolveStrategy);\n\n const sessionResult = await getSessionToLink({ reporter, cachePath });\n if (!sessionResult.session) {\n return sessionResult;\n }\n const { session } = sessionResult;\n const client = await createCloudpackClient({ url: session.urls.apiServer, reporter });\n\n const includeMessage = includeAll ? ' including all internal paths' : '';\n const message = `Linking paths for ${session.projectName} at \"${appPath}\"${includeMessage}`;\n const task = reporter.addTask(message);\n\n // Send request to api server to link paths.\n const { resolveMap, linkedPaths } = await client.linkPath.query({\n linkedPath: {\n path: appPath,\n ignoredPackages,\n includeAll,\n ignoreResolutions,\n resolveStrategy,\n },\n });\n await client.close();\n\n if (linkedPaths.find((p) => p.path === appPath) === undefined) {\n // Close down with an error.\n task.complete({ status: 'fail', message: `Failed to link paths.`, forceShow: true });\n return { hasErrors: true, message: 'Failed to link paths.' };\n }\n\n if (logResolveMap) {\n // Write the linked resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map-linked.json'), resolveMap);\n }\n\n // Close down successfully.\n task.complete({ status: 'complete', message: `Linked paths`, forceShow: true });\n const linkSummary = formatLinkSummary({ session, resolveMap, linkedPaths, resolveStrategy });\n\n return { message: linkSummary };\n};\n"]}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/link/execute.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandAction } from '../../types/CommandAction.js';\nimport type { LinkOptions } from './types/LinkOptions.js';\nimport { getSessionToLink } from './getSessionToLink.js';\nimport { createCloudpackClient } from '@ms-cloudpack/api-server';\nimport { formatLinkSummary } from './formatLinkSummary.js';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport path from 'path';\nimport { linkToRemoteSession } from './linkToRemoteSession.js';\n\n/**\n * Defines the \"link\" verb entry point.\n */\nexport const execute: CommandAction<LinkOptions> = async (params) => {\n // Use the current directory as the default package path.\n const { options, appPath, reporter } = params;\n const {\n remote,\n ignore: ignoredPackages,\n all: includeAll,\n ignoreResolutions,\n resolveStrategy,\n logResolveMap,\n cachePath,\n } = options;\n\n console.debug('Linking packages...');\n console.debug('Include all:', !!includeAll);\n console.debug('Ignored packages:', ignoredPackages?.join(', ') || 'none');\n console.debug('Apply host resolutions:', !ignoreResolutions);\n console.debug('Resolve strategy:', resolveStrategy);\n console.debug('Remote:', remote);\n\n // If we are linking to a remote session, we need to use the link proxy.\n if (remote) return linkToRemoteSession(params);\n\n // If we are linking to a session on the same machine, we can access the paths directly.\n const sessionResult = await getSessionToLink({ reporter, cachePath });\n if (!sessionResult.session) {\n return sessionResult;\n }\n const { session } = sessionResult;\n const client = await createCloudpackClient({ url: session.urls.apiServer, reporter });\n\n const includeMessage = includeAll ? ' including all internal paths' : '';\n const message = `Linking local paths for ${session.projectName} at \"${appPath}\"${includeMessage}`;\n const task = reporter.addTask(message);\n\n // Send request to api server to link paths.\n const { resolveMap, linkedPaths } = await client.linkPath.mutate({\n linkedPath: {\n path: appPath,\n ignoredPackages,\n includeAll,\n ignoreResolutions,\n resolveStrategy,\n },\n });\n await client.close();\n\n if (linkedPaths.find((p) => p.path === appPath) === undefined) {\n // Close down with an error.\n task.complete({ status: 'fail', message: `Failed to link paths.`, forceShow: true });\n return { hasErrors: true, message: 'Failed to link paths.' };\n }\n\n if (logResolveMap) {\n // Write the linked resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map-linked.json'), resolveMap);\n }\n\n // Close down successfully.\n task.complete({ status: 'complete', message: `Linked paths`, forceShow: true });\n const linkSummary = formatLinkSummary({ session, resolveMap, linkedPaths, resolveStrategy });\n return { message: linkSummary };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/link/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAI9E,+BAA+B;AAC/B,eAAO,MAAM,IAAI,EAAE,mBA4BlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/link/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAI9E,+BAA+B;AAC/B,eAAO,MAAM,IAAI,EAAE,mBAqClB,CAAC"}
@@ -6,6 +6,11 @@ export const init = (program) => {
6
6
  name: 'link',
7
7
  description: 'Links the package(s) found within the current folder to an existing cloudpack start session.',
8
8
  options: {
9
+ remote: new Option('--remote [remote]', 'Link to a remote session. Specify one of the following, listed in order of preference:\n' +
10
+ '- WebSocket URL: e.g., "wss://example.com:9890" or "ws://example.com:9890"\n' +
11
+ '- URL: e.g., "http://example.com" or "https://example.com"\n' +
12
+ '- hostname: e.g., "example.com" (attempts both wss:// and ws:// connections)\n' +
13
+ '- no value: Uses "localhost" (attempts both wss:// and ws:// connections)\n'),
9
14
  ignore: new Option('--ignore [packages...]', 'Ignore these packages when linking. This can be used for packages in the current repo ' +
10
15
  'that have issues being bundled.'),
11
16
  all: new Option('--all', "Link all internal packages discovered within the linked repo's graph."),
@@ -16,6 +21,7 @@ export const init = (program) => {
16
21
  `- "duplicate": Allow duplicates in the resolve map (don't bump dependencies).`)
17
22
  .choices(['dedupe', 'duplicate'])
18
23
  .default('dedupe'),
24
+ cache: reusedOptions.cache(),
19
25
  logResolveMap: reusedOptions.logResolveMap(),
20
26
  },
21
27
  getExecutor: () => import('./execute.js'),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/link/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEjE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,IAAI,GAAwB,CAAC,OAAO,EAAE,EAAE;IACnD,OAAO,CAAC,aAAa,CAAc;QACjC,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,8FAA8F;QAC3G,OAAO,EAAE;YACP,MAAM,EAAE,IAAI,MAAM,CAChB,wBAAwB,EACxB,wFAAwF;gBACtF,iCAAiC,CACpC;YACD,GAAG,EAAE,IAAI,MAAM,CAAC,OAAO,EAAE,uEAAuE,CAAC;YACjG,iBAAiB,EAAE,IAAI,MAAM,CAC3B,sBAAsB,EACtB,+EAA+E,CAChF;YACD,eAAe,EAAE,IAAI,MAAM,CACzB,+BAA+B,EAC/B,mDAAmD;gBACjD,sFAAsF;gBACtF,+EAA+E;gBAC/E,+EAA+E,CAClF;iBACE,OAAO,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;iBAChC,OAAO,CAAC,QAAQ,CAAC;YACpB,aAAa,EAAE,aAAa,CAAC,aAAa,EAAE;SAC7C;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC;KAC1C,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { Option } from 'commander';\nimport type { CommandInitFunction } from '../../types/CommandInitFunction.js';\nimport type { LinkOptions } from './types/LinkOptions.js';\nimport { reusedOptions } from '../../utilities/reusedOptions.js';\n\n/** Defines the \"link\" verb. */\nexport const init: CommandInitFunction = (program) => {\n program.addSubCommand<LinkOptions>({\n name: 'link',\n description: 'Links the package(s) found within the current folder to an existing cloudpack start session.',\n options: {\n ignore: new Option(\n '--ignore [packages...]',\n 'Ignore these packages when linking. This can be used for packages in the current repo ' +\n 'that have issues being bundled.',\n ),\n all: new Option('--all', \"Link all internal packages discovered within the linked repo's graph.\"),\n ignoreResolutions: new Option(\n '--ignore-resolutions',\n \"Don't apply resolutions from the host repo's package.json to linked packages.\",\n ),\n resolveStrategy: new Option(\n '--resolve-strategy <strategy>',\n 'Strategy to use when resolving linked packages.\\n' +\n '- \"dedupe\": Attempt to dedupe packages from the resolve map by removing all but the ' +\n 'highest version that satisfies semver requirements from all parent entries.\\n' +\n `- \"duplicate\": Allow duplicates in the resolve map (don't bump dependencies).`,\n )\n .choices(['dedupe', 'duplicate'])\n .default('dedupe'),\n logResolveMap: reusedOptions.logResolveMap(),\n },\n getExecutor: () => import('./execute.js'),\n });\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/link/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEjE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,IAAI,GAAwB,CAAC,OAAO,EAAE,EAAE;IACnD,OAAO,CAAC,aAAa,CAAc;QACjC,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,8FAA8F;QAC3G,OAAO,EAAE;YACP,MAAM,EAAE,IAAI,MAAM,CAChB,mBAAmB,EACnB,0FAA0F;gBACxF,8EAA8E;gBAC9E,8DAA8D;gBAC9D,gFAAgF;gBAChF,6EAA6E,CAChF;YACD,MAAM,EAAE,IAAI,MAAM,CAChB,wBAAwB,EACxB,wFAAwF;gBACtF,iCAAiC,CACpC;YACD,GAAG,EAAE,IAAI,MAAM,CAAC,OAAO,EAAE,uEAAuE,CAAC;YACjG,iBAAiB,EAAE,IAAI,MAAM,CAC3B,sBAAsB,EACtB,+EAA+E,CAChF;YACD,eAAe,EAAE,IAAI,MAAM,CACzB,+BAA+B,EAC/B,mDAAmD;gBACjD,sFAAsF;gBACtF,+EAA+E;gBAC/E,+EAA+E,CAClF;iBACE,OAAO,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;iBAChC,OAAO,CAAC,QAAQ,CAAC;YACpB,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE;YAC5B,aAAa,EAAE,aAAa,CAAC,aAAa,EAAE;SAC7C;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC;KAC1C,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { Option } from 'commander';\nimport type { CommandInitFunction } from '../../types/CommandInitFunction.js';\nimport type { LinkOptions } from './types/LinkOptions.js';\nimport { reusedOptions } from '../../utilities/reusedOptions.js';\n\n/** Defines the \"link\" verb. */\nexport const init: CommandInitFunction = (program) => {\n program.addSubCommand<LinkOptions>({\n name: 'link',\n description: 'Links the package(s) found within the current folder to an existing cloudpack start session.',\n options: {\n remote: new Option(\n '--remote [remote]',\n 'Link to a remote session. Specify one of the following, listed in order of preference:\\n' +\n '- WebSocket URL: e.g., \"wss://example.com:9890\" or \"ws://example.com:9890\"\\n' +\n '- URL: e.g., \"http://example.com\" or \"https://example.com\"\\n' +\n '- hostname: e.g., \"example.com\" (attempts both wss:// and ws:// connections)\\n' +\n '- no value: Uses \"localhost\" (attempts both wss:// and ws:// connections)\\n',\n ),\n ignore: new Option(\n '--ignore [packages...]',\n 'Ignore these packages when linking. This can be used for packages in the current repo ' +\n 'that have issues being bundled.',\n ),\n all: new Option('--all', \"Link all internal packages discovered within the linked repo's graph.\"),\n ignoreResolutions: new Option(\n '--ignore-resolutions',\n \"Don't apply resolutions from the host repo's package.json to linked packages.\",\n ),\n resolveStrategy: new Option(\n '--resolve-strategy <strategy>',\n 'Strategy to use when resolving linked packages.\\n' +\n '- \"dedupe\": Attempt to dedupe packages from the resolve map by removing all but the ' +\n 'highest version that satisfies semver requirements from all parent entries.\\n' +\n `- \"duplicate\": Allow duplicates in the resolve map (don't bump dependencies).`,\n )\n .choices(['dedupe', 'duplicate'])\n .default('dedupe'),\n cache: reusedOptions.cache(),\n logResolveMap: reusedOptions.logResolveMap(),\n },\n getExecutor: () => import('./execute.js'),\n });\n};\n"]}
@@ -0,0 +1,8 @@
1
+ import type { CommandActionParams, CommandExitParams } from '../../types/CommandAction.js';
2
+ import type { LinkOptions } from './types/LinkOptions.js';
3
+ import type { SharedOptions } from '../../types/SharedOptions.js';
4
+ /**
5
+ * Handles the remote linking process
6
+ */
7
+ export declare function linkToRemoteSession(params: CommandActionParams<LinkOptions & SharedOptions>): Promise<CommandExitParams>;
8
+ //# sourceMappingURL=linkToRemoteSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkToRemoteSession.d.ts","sourceRoot":"","sources":["../../../src/commands/link/linkToRemoteSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAoB3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,mBAAmB,CAAC,WAAW,GAAG,aAAa,CAAC,GACvD,OAAO,CAAC,iBAAiB,CAAC,CA6K5B"}
@@ -0,0 +1,179 @@
1
+ import { createApiContext, apiServerPort, waitForBusData, linkConfigSource, linkPathsSource, linkDoneSource, linkDisconnectedSource, } from '@ms-cloudpack/api-server';
2
+ import { writeJson } from '@ms-cloudpack/json-utilities';
3
+ import path from 'path';
4
+ import { filterInternalCapabilities } from '@ms-cloudpack/bundler-capabilities';
5
+ import { createLinkResolveMap, mergeObjects } from '@ms-cloudpack/package-utilities';
6
+ import { createApiServer } from '../../utilities/createApiServer.js';
7
+ import { openBrowser } from '../start/openBrowser.js';
8
+ import { resolveCloudpackInternalPath } from '../../utilities/resolveCloudpackInternalPath.js';
9
+ import { createRemoteApiUrls } from './createRemoteApiUrls.js';
10
+ /**
11
+ * Handles the remote linking process
12
+ */
13
+ export async function linkToRemoteSession(params) {
14
+ const { options, appPath, autoDispose } = params;
15
+ const { remote, ignore: ignoredPackages, all: includeAll, ignoreResolutions, resolveStrategy, logResolveMap, } = options;
16
+ const linkProxyPath = await resolveCloudpackInternalPath({
17
+ importMetaUrl: import.meta.url,
18
+ packageName: '@ms-cloudpack/link-proxy',
19
+ });
20
+ if (!linkProxyPath) {
21
+ return { hasErrors: true, message: 'Failed to resolve link proxy path' };
22
+ }
23
+ // Override routes to default to serve link proxy instead.
24
+ // TODO: Should this be done earlier to avoid the side effect that happens while reading the config?
25
+ delete params.config.routes;
26
+ const context = autoDispose(await createApiContext({
27
+ ...params,
28
+ // Load the link proxy to the resolve map to load it later.
29
+ additionalPaths: [linkProxyPath],
30
+ // Skip resolving dependencies, as we will load the resolve map later.
31
+ skipResolveDependencies: true,
32
+ }));
33
+ const { session, packages, packageHashes, bus } = context;
34
+ // Start api server for tracking status and handling remote requests.
35
+ const apiServerResult = await createApiServer(
36
+ // Create the api server at different ports to avoid conflicts.
37
+ { port: apiServerPort.map((p) => p + apiServerPort.length) }, context);
38
+ if (apiServerResult.hasErrors) {
39
+ return apiServerResult;
40
+ }
41
+ const { apiServer } = apiServerResult;
42
+ // Get possible host api server urls.
43
+ session.urls.hostApiServer = createRemoteApiUrls({ remote, apiServerUrl: apiServer.url });
44
+ // Then start bundle and app servers for hosting the app.
45
+ const { startServers } = await import('@ms-cloudpack/app-server');
46
+ const servers = await startServers({
47
+ // Start the app server with the link proxy.
48
+ definition: await packages.get(linkProxyPath),
49
+ bundleServerOptions: { disableCache: !options.cache },
50
+ }, context);
51
+ const cleanup = async () => {
52
+ await Promise.all(Object.entries({ apiServer, ...servers }).map(async ([name, server]) => {
53
+ if (!server)
54
+ return;
55
+ const desc = `${name} (${server.url})`;
56
+ console.info(`Closing ${desc}`);
57
+ try {
58
+ await server.close();
59
+ console.info(`Closed ${desc}`);
60
+ }
61
+ catch (err) {
62
+ console.warn(`Error closing ${desc}:`, err);
63
+ }
64
+ }));
65
+ };
66
+ autoDispose({ dispose: cleanup });
67
+ if (!session.urls.appServer || !session.urls.bundleServer) {
68
+ return { hasErrors: true, message: 'Failed to start app server' };
69
+ }
70
+ void openBrowser({ url: session.urls.appServer }, context).catch((err) => {
71
+ console.warn('Error opening browser:', err?.stack || err);
72
+ console.warn('Please open the browser manually to:', session.urls.appServer);
73
+ });
74
+ // Setup disconnection handling
75
+ const { disconnectionPromise, withDisconnectionHandling } = createDisconnectionHandler(bus);
76
+ // Get config from host api server.
77
+ console.debug('Attempting to fetch host config from the bus.');
78
+ const hostConfigResult = await withDisconnectionHandling(waitForBusData({ bus, source: linkConfigSource }));
79
+ // Check if disconnection happened
80
+ if (hostConfigResult.disconnected) {
81
+ return hostConfigResult.result;
82
+ }
83
+ const hostConfig = hostConfigResult.result;
84
+ hostConfig.packageSettings?.forEach((settings) => {
85
+ // We need to delete bundler capabilities that are not internal as they won't work.
86
+ // TODO: Figure out a way to support them.
87
+ if (settings.bundlerCapabilities) {
88
+ settings.bundlerCapabilities = filterInternalCapabilities(settings.bundlerCapabilities);
89
+ }
90
+ });
91
+ console.debug('Host config received:', hostConfig);
92
+ // Merge host config with local config.
93
+ const mergedConfig = mergeObjects([hostConfig, params.config]);
94
+ session.config = mergedConfig;
95
+ packages.reset({ newConfig: mergedConfig });
96
+ console.debug('Searching for packages from paths:', appPath);
97
+ // Use settings to find partial link app map.
98
+ // Update the resolve map with the linked packages.
99
+ context.session.resolveMap = await createLinkResolveMap({ appPath, additionalPaths: [linkProxyPath] }, context);
100
+ bus.publish(linkPathsSource, {
101
+ linkedPath: {
102
+ path: appPath,
103
+ ignoredPackages,
104
+ includeAll,
105
+ ignoreResolutions,
106
+ resolveStrategy,
107
+ remote: {
108
+ // Host app must route linked paths to the bundle server.
109
+ hostUrl: session.urls.bundleServer,
110
+ // Linked session resolve map to resolve dependencies on the host.
111
+ resolveMap: context.session.resolveMap,
112
+ // Send the package definitions to create the import map.
113
+ packages: packages.toSerializable(),
114
+ // We must send all external hashes for the linked packages and then update internal hashes on change.
115
+ packageHashes: packageHashes.toSerializable(),
116
+ },
117
+ },
118
+ });
119
+ // Get result from host.
120
+ console.debug('Waiting for host to link paths...');
121
+ const linkPathResult = await withDisconnectionHandling(waitForBusData({ bus, source: linkDoneSource }));
122
+ // Check if disconnection happened
123
+ if (linkPathResult.disconnected) {
124
+ return linkPathResult.result;
125
+ }
126
+ const result = linkPathResult.result;
127
+ console.debug('Host linked paths:', result.linkedPaths);
128
+ // Monitor client connections
129
+ const connectionMonitor = setupConnectionMonitor(apiServer, session.urls.appServer);
130
+ autoDispose({ dispose: () => clearInterval(connectionMonitor) });
131
+ // Wait for the host to send back the resolve map and linked paths.
132
+ if (logResolveMap) {
133
+ // Write the linked resolve map to disk.
134
+ await writeJson(path.join(appPath, 'resolve-map-linked.json'), result.resolveMap);
135
+ }
136
+ console.debug('Linked paths:', result.linkedPaths);
137
+ return disconnectionPromise;
138
+ }
139
+ /**
140
+ * Creates a disconnection handler that wraps promises
141
+ */
142
+ function createDisconnectionHandler(bus) {
143
+ // Create a promise that will resolve when host disconnection is detected
144
+ const disconnectionPromise = new Promise((res) => {
145
+ // Listen for host disconnection events
146
+ bus.subscribe(linkDisconnectedSource, ({ reason }) => {
147
+ res({ hasErrors: true, message: `Host connection ${reason}. Shutting down link session.` });
148
+ });
149
+ });
150
+ async function withDisconnectionHandling(operation) {
151
+ return await Promise.race([
152
+ operation.then((result) => ({ disconnected: false, result })),
153
+ disconnectionPromise.then((result) => ({
154
+ disconnected: true,
155
+ result,
156
+ })),
157
+ ]);
158
+ }
159
+ return { disconnectionPromise, withDisconnectionHandling };
160
+ }
161
+ /**
162
+ * Setup client connection monitoring
163
+ */
164
+ function setupConnectionMonitor(apiServer, appServerUrl) {
165
+ let hadConnections = false;
166
+ const connectionMonitor = setInterval(() => {
167
+ const connectedClients = apiServer.clients.size;
168
+ // If we previously had connections and now have none
169
+ if (hadConnections && connectedClients === 0) {
170
+ console.warn('Browser connection lost. Please reopen your browser to:', appServerUrl);
171
+ hadConnections = false;
172
+ }
173
+ else if (connectedClients > 0) {
174
+ hadConnections = true;
175
+ }
176
+ }, 5000); // Check every 5 seconds
177
+ return connectionMonitor;
178
+ }
179
+ //# sourceMappingURL=linkToRemoteSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkToRemoteSession.js","sourceRoot":"","sources":["../../../src/commands/link/linkToRemoteSession.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandActionParams, CommandExitParams } from '../../types/CommandAction.js';\nimport {\n createApiContext,\n apiServerPort,\n waitForBusData,\n linkConfigSource,\n linkPathsSource,\n linkDoneSource,\n linkDisconnectedSource,\n type LinkPathOutput,\n type Context,\n type CloudpackServer,\n} from '@ms-cloudpack/api-server';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport path from 'path';\nimport type { CloudpackConfig, CloudpackLinkConfig } from '@ms-cloudpack/common-types';\nimport { filterInternalCapabilities } from '@ms-cloudpack/bundler-capabilities';\nimport { createLinkResolveMap, mergeObjects } from '@ms-cloudpack/package-utilities';\nimport { createApiServer } from '../../utilities/createApiServer.js';\nimport { openBrowser } from '../start/openBrowser.js';\nimport type { LinkOptions } from './types/LinkOptions.js';\nimport type { SharedOptions } from '../../types/SharedOptions.js';\nimport { resolveCloudpackInternalPath } from '../../utilities/resolveCloudpackInternalPath.js';\nimport { createRemoteApiUrls } from './createRemoteApiUrls.js';\n\n/**\n * Handles the remote linking process\n */\nexport async function linkToRemoteSession(\n params: CommandActionParams<LinkOptions & SharedOptions>,\n): Promise<CommandExitParams> {\n const { options, appPath, autoDispose } = params;\n const {\n remote,\n ignore: ignoredPackages,\n all: includeAll,\n ignoreResolutions,\n resolveStrategy,\n logResolveMap,\n } = options;\n\n const linkProxyPath = await resolveCloudpackInternalPath({\n importMetaUrl: import.meta.url,\n packageName: '@ms-cloudpack/link-proxy',\n });\n if (!linkProxyPath) {\n return { hasErrors: true, message: 'Failed to resolve link proxy path' };\n }\n\n // Override routes to default to serve link proxy instead.\n // TODO: Should this be done earlier to avoid the side effect that happens while reading the config?\n delete params.config.routes;\n\n const context = autoDispose(\n await createApiContext({\n ...params,\n // Load the link proxy to the resolve map to load it later.\n additionalPaths: [linkProxyPath],\n // Skip resolving dependencies, as we will load the resolve map later.\n skipResolveDependencies: true,\n }),\n );\n\n const { session, packages, packageHashes, bus } = context;\n\n // Start api server for tracking status and handling remote requests.\n const apiServerResult = await createApiServer(\n // Create the api server at different ports to avoid conflicts.\n { port: apiServerPort.map((p) => p + apiServerPort.length) },\n context,\n );\n if (apiServerResult.hasErrors) {\n return apiServerResult;\n }\n\n const { apiServer } = apiServerResult;\n\n // Get possible host api server urls.\n session.urls.hostApiServer = createRemoteApiUrls({ remote, apiServerUrl: apiServer.url });\n\n // Then start bundle and app servers for hosting the app.\n const { startServers } = await import('@ms-cloudpack/app-server');\n const servers = await startServers(\n {\n // Start the app server with the link proxy.\n definition: await packages.get(linkProxyPath),\n bundleServerOptions: { disableCache: !options.cache },\n },\n context,\n );\n\n const cleanup = async () => {\n await Promise.all(\n Object.entries({ apiServer, ...servers }).map(async ([name, server]) => {\n if (!server) return;\n\n const desc = `${name} (${server.url})`;\n console.info(`Closing ${desc}`);\n try {\n await server.close();\n console.info(`Closed ${desc}`);\n } catch (err) {\n console.warn(`Error closing ${desc}:`, err);\n }\n }),\n );\n };\n\n autoDispose({ dispose: cleanup });\n\n if (!session.urls.appServer || !session.urls.bundleServer) {\n return { hasErrors: true, message: 'Failed to start app server' };\n }\n\n void openBrowser({ url: session.urls.appServer }, context).catch((err: unknown) => {\n console.warn('Error opening browser:', (err as Error | undefined)?.stack || err);\n console.warn('Please open the browser manually to:', session.urls.appServer);\n });\n\n // Setup disconnection handling\n const { disconnectionPromise, withDisconnectionHandling } = createDisconnectionHandler(bus);\n\n // Get config from host api server.\n console.debug('Attempting to fetch host config from the bus.');\n const hostConfigResult = await withDisconnectionHandling(\n waitForBusData<CloudpackLinkConfig>({ bus, source: linkConfigSource }),\n );\n\n // Check if disconnection happened\n if (hostConfigResult.disconnected) {\n return hostConfigResult.result;\n }\n\n const hostConfig = hostConfigResult.result as CloudpackConfig;\n\n hostConfig.packageSettings?.forEach((settings) => {\n // We need to delete bundler capabilities that are not internal as they won't work.\n // TODO: Figure out a way to support them.\n if (settings.bundlerCapabilities) {\n settings.bundlerCapabilities = filterInternalCapabilities(settings.bundlerCapabilities);\n }\n });\n\n console.debug('Host config received:', hostConfig);\n // Merge host config with local config.\n const mergedConfig = mergeObjects([hostConfig, params.config]);\n session.config = mergedConfig;\n\n packages.reset({ newConfig: mergedConfig });\n\n console.debug('Searching for packages from paths:', appPath);\n\n // Use settings to find partial link app map.\n // Update the resolve map with the linked packages.\n context.session.resolveMap = await createLinkResolveMap({ appPath, additionalPaths: [linkProxyPath] }, context);\n\n bus.publish(linkPathsSource, {\n linkedPath: {\n path: appPath,\n ignoredPackages,\n includeAll,\n ignoreResolutions,\n resolveStrategy,\n remote: {\n // Host app must route linked paths to the bundle server.\n hostUrl: session.urls.bundleServer,\n // Linked session resolve map to resolve dependencies on the host.\n resolveMap: context.session.resolveMap,\n // Send the package definitions to create the import map.\n packages: packages.toSerializable(),\n // We must send all external hashes for the linked packages and then update internal hashes on change.\n packageHashes: packageHashes.toSerializable(),\n },\n },\n });\n\n // Get result from host.\n console.debug('Waiting for host to link paths...');\n const linkPathResult = await withDisconnectionHandling(\n waitForBusData<LinkPathOutput>({ bus, source: linkDoneSource }),\n );\n\n // Check if disconnection happened\n if (linkPathResult.disconnected) {\n return linkPathResult.result;\n }\n\n const result = linkPathResult.result;\n console.debug('Host linked paths:', result.linkedPaths);\n\n // Monitor client connections\n const connectionMonitor = setupConnectionMonitor(apiServer, session.urls.appServer);\n autoDispose({ dispose: () => clearInterval(connectionMonitor) });\n\n // Wait for the host to send back the resolve map and linked paths.\n if (logResolveMap) {\n // Write the linked resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map-linked.json'), result.resolveMap);\n }\n\n console.debug('Linked paths:', result.linkedPaths);\n\n return disconnectionPromise;\n}\n\n/**\n * Creates a disconnection handler that wraps promises\n */\nfunction createDisconnectionHandler(bus: Context['bus']) {\n // Create a promise that will resolve when host disconnection is detected\n const disconnectionPromise = new Promise<CommandExitParams>((res) => {\n // Listen for host disconnection events\n bus.subscribe(linkDisconnectedSource, ({ reason }: { reason: string }) => {\n res({ hasErrors: true, message: `Host connection ${reason}. Shutting down link session.` });\n });\n });\n\n async function withDisconnectionHandling<T>(\n operation: Promise<T>,\n ): Promise<{ disconnected: false; result: T } | { disconnected: true; result: CommandExitParams }> {\n return await Promise.race([\n operation.then((result): { disconnected: false; result: T } => ({ disconnected: false, result })),\n disconnectionPromise.then((result): { disconnected: true; result: CommandExitParams } => ({\n disconnected: true,\n result,\n })),\n ]);\n }\n\n return { disconnectionPromise, withDisconnectionHandling };\n}\n\n/**\n * Setup client connection monitoring\n */\nfunction setupConnectionMonitor(apiServer: CloudpackServer, appServerUrl: string) {\n let hadConnections = false;\n const connectionMonitor = setInterval(() => {\n const connectedClients = apiServer.clients.size;\n\n // If we previously had connections and now have none\n if (hadConnections && connectedClients === 0) {\n console.warn('Browser connection lost. Please reopen your browser to:', appServerUrl);\n hadConnections = false;\n } else if (connectedClients > 0) {\n hadConnections = true;\n }\n }, 5000); // Check every 5 seconds\n\n return connectionMonitor;\n}\n"]}
@@ -1,5 +1,9 @@
1
1
  import type { ReusedOptions } from '../../../types/ReusedOptions.js';
2
- export interface LinkOptions extends Pick<ReusedOptions, 'logResolveMap'> {
2
+ export interface LinkOptions extends Pick<ReusedOptions, 'cache' | 'logResolveMap'> {
3
+ /**
4
+ * Url to link to a remote session. See ../createRemoteApiUrls.ts for details.
5
+ */
6
+ remote: string | boolean;
3
7
  /**
4
8
  * Ignore these packages when linking.
5
9
  * This can be used for packages in the current repo that have issues being bundled.
@@ -1 +1 @@
1
- {"version":3,"file":"LinkOptions.d.ts","sourceRoot":"","sources":["../../../../src/commands/link/types/LinkOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC;IACvE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,CAAC;IAEd,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,eAAe,EAAE,QAAQ,GAAG,WAAW,CAAC;CACzC"}
1
+ {"version":3,"file":"LinkOptions.d.ts","sourceRoot":"","sources":["../../../../src/commands/link/types/LinkOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,eAAe,CAAC;IACjF;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,CAAC;IAEd,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,eAAe,EAAE,QAAQ,GAAG,WAAW,CAAC;CACzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"LinkOptions.js","sourceRoot":"","sources":["../../../../src/commands/link/types/LinkOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { ReusedOptions } from '../../../types/ReusedOptions.js';\n\nexport interface LinkOptions extends Pick<ReusedOptions, 'logResolveMap'> {\n /**\n * Ignore these packages when linking.\n * This can be used for packages in the current repo that have issues being bundled.\n */\n ignore?: string[];\n\n /** Link all internal packages discovered within the linked repo's graph. */\n all?: boolean;\n\n /** Don't apply resolutions from the host repo's package.json to linked packages. */\n ignoreResolutions?: boolean;\n\n /**\n * Strategy to use when resolving linked packages.\n * - `\"dedupe\"`: Attempt to dedupe packages from the resolve map by removing all but the\n * highest version that satisfies semver requirements from all parent entries.\n * - `\"duplicate\"`: Allow duplicates in the resolve map (don't bump dependencies).\n * @default \"dedupe\"\n */\n resolveStrategy: 'dedupe' | 'duplicate';\n}\n"]}
1
+ {"version":3,"file":"LinkOptions.js","sourceRoot":"","sources":["../../../../src/commands/link/types/LinkOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { ReusedOptions } from '../../../types/ReusedOptions.js';\n\nexport interface LinkOptions extends Pick<ReusedOptions, 'cache' | 'logResolveMap'> {\n /**\n * Url to link to a remote session. See ../createRemoteApiUrls.ts for details.\n */\n remote: string | boolean;\n\n /**\n * Ignore these packages when linking.\n * This can be used for packages in the current repo that have issues being bundled.\n */\n ignore?: string[];\n\n /** Link all internal packages discovered within the linked repo's graph. */\n all?: boolean;\n\n /** Don't apply resolutions from the host repo's package.json to linked packages. */\n ignoreResolutions?: boolean;\n\n /**\n * Strategy to use when resolving linked packages.\n * - `\"dedupe\"`: Attempt to dedupe packages from the resolve map by removing all but the\n * highest version that satisfies semver requirements from all parent entries.\n * - `\"duplicate\"`: Allow duplicates in the resolve map (don't bump dependencies).\n * @default \"dedupe\"\n */\n resolveStrategy: 'dedupe' | 'duplicate';\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/start/execute.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAI5D;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,YAAY,CAwH/C,CAAC"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/start/execute.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAK5D;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,YAAY,CAmH/C,CAAC"}
@@ -1,15 +1,14 @@
1
1
  import { createApiContext, ensurePackageBundled } from '@ms-cloudpack/api-server';
2
2
  import { writeJson } from '@ms-cloudpack/json-utilities';
3
- import { isExternalPackage, resolve } from '@ms-cloudpack/path-utilities';
4
3
  import { makeUrl } from '@ms-cloudpack/path-string-parsing';
5
4
  import { yellow } from '@ms-cloudpack/task-reporter';
6
5
  import path from 'path';
7
- import { fileURLToPath } from 'url';
8
6
  import { runPrerequisites } from '../../utilities/runPrerequisites.js';
9
7
  import { openBrowser } from './openBrowser.js';
10
8
  import { trackSession } from './trackSession.js';
11
9
  import { getCliStartTime } from '../../utilities/getCliStartTime.js';
12
10
  import { createApiServer } from '../../utilities/createApiServer.js';
11
+ import { resolveCloudpackInternalPath } from '../../utilities/resolveCloudpackInternalPath.js';
13
12
  /**
14
13
  * Defines the "start" verb entry point.
15
14
  */
@@ -18,19 +17,15 @@ export const execute = async (params) => {
18
17
  console.log('App path:', yellow(appPath));
19
18
  console.log('Bundle mode:', yellow(options.mode));
20
19
  await runPrerequisites(params);
21
- const currentDir = path.dirname(fileURLToPath(import.meta.url));
22
- let overlayPath = await resolve('@ms-cloudpack/overlay', currentDir);
23
- // If overlay is an internal package, resolve the overlay from the current package's linked node modules
24
- // to "externalize" it, so that we always use the bundled version of the overlay instead of the source.
25
- if (overlayPath && !isExternalPackage(overlayPath)) {
26
- const cliPath = await resolve('@ms-cloudpack/cli', currentDir);
27
- overlayPath = cliPath ? path.join(cliPath, 'node_modules', '@ms-cloudpack/overlay') : undefined;
28
- }
20
+ const overlayPath = await resolveCloudpackInternalPath({
21
+ packageName: '@ms-cloudpack/overlay',
22
+ importMetaUrl: import.meta.url,
23
+ });
29
24
  const shouldUseRemoteCache = config.features?.enableCloudHosted || config.features?.enableRemoteCacheDownloads;
30
25
  const apiContext = autoDispose(await createApiContext({
31
26
  ...params,
32
27
  remoteCacheClientLoginMethod: shouldUseRemoteCache ? options.login : undefined,
33
- overlayPath,
28
+ additionalPaths: overlayPath ? [overlayPath] : undefined,
34
29
  }));
35
30
  const { packages, session, telemetryClient } = apiContext;
36
31
  // Increment the session version if caching is disabled.
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/start/execute.ts"],"names":[],"mappings":"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","sourcesContent":["import { createApiContext, ensurePackageBundled } from '@ms-cloudpack/api-server';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport { isExternalPackage, resolve } from '@ms-cloudpack/path-utilities';\nimport { makeUrl } from '@ms-cloudpack/path-string-parsing';\nimport { yellow } from '@ms-cloudpack/task-reporter';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { CommandAction } from '../../types/CommandAction.js';\nimport { runPrerequisites } from '../../utilities/runPrerequisites.js';\nimport { openBrowser } from './openBrowser.js';\nimport { trackSession } from './trackSession.js';\nimport type { StartOptions } from './types/StartOptions.js';\nimport { getCliStartTime } from '../../utilities/getCliStartTime.js';\nimport { createApiServer } from '../../utilities/createApiServer.js';\n\n/**\n * Defines the \"start\" verb entry point.\n */\nexport const execute: CommandAction<StartOptions> = async (params) => {\n const { appPath, config, options, autoDispose } = params;\n\n console.log('App path:', yellow(appPath));\n console.log('Bundle mode:', yellow(options.mode));\n\n await runPrerequisites(params);\n\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n let overlayPath = await resolve('@ms-cloudpack/overlay', currentDir);\n\n // If overlay is an internal package, resolve the overlay from the current package's linked node modules\n // to \"externalize\" it, so that we always use the bundled version of the overlay instead of the source.\n if (overlayPath && !isExternalPackage(overlayPath)) {\n const cliPath = await resolve('@ms-cloudpack/cli', currentDir);\n overlayPath = cliPath ? path.join(cliPath, 'node_modules', '@ms-cloudpack/overlay') : undefined;\n }\n\n const shouldUseRemoteCache = config.features?.enableCloudHosted || config.features?.enableRemoteCacheDownloads;\n const apiContext = autoDispose(\n await createApiContext({\n ...params,\n remoteCacheClientLoginMethod: shouldUseRemoteCache ? options.login : undefined,\n overlayPath,\n }),\n );\n const { packages, session, telemetryClient } = apiContext;\n\n // Increment the session version if caching is disabled.\n if (options.cache === false) {\n session.incrementSessionVersion();\n }\n\n // Make sure the package has a valid definition.\n const definition = await packages.get(appPath);\n\n if (options.logResolveMap) {\n // Write the resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map.json'), session.resolveMap);\n }\n\n // Start api server for tracking status and handling remote requests.\n const apiServerResult = await createApiServer({ port: options.apiServerPort }, apiContext);\n if (apiServerResult.hasErrors) {\n return apiServerResult;\n }\n const { apiServer } = apiServerResult;\n\n // Kick off bundling app package as soon as api server is ready.\n void ensurePackageBundled({ name: definition.name, version: definition.version }, apiContext);\n\n // Then start bundle and app servers for hosting the app.\n const { startServers } = await import('@ms-cloudpack/app-server');\n const servers = await startServers(\n {\n definition,\n bundleServerOptions: { disableCache: !options.cache, port: options.bundleServerPort },\n port: options.appServerPort,\n },\n apiContext,\n );\n\n // Save the session to active sessions.\n const sessionTracker = await trackSession(session);\n\n const cleanup = async () => {\n // Stop tracking the session.\n await sessionTracker.close();\n\n await Promise.all(\n Object.entries({ apiServer, ...servers }).map(async ([name, server]) => {\n if (!server) return;\n\n const desc = `${name} (${server.url})`;\n console.info(`Closing ${desc}`);\n try {\n await server.close();\n console.info(`Closed ${desc}`);\n } catch (err) {\n console.warn(`Error closing ${desc}:`, err);\n }\n }),\n );\n };\n\n autoDispose({ dispose: cleanup });\n\n const defaultUrl = makeUrl(config.server?.defaultPath || '', session.urls.appServer).href;\n\n // Log the time elapsed from when the CLI started until the browser is ready to be opened.\n await telemetryClient.tracer.startActiveSpan(\n 'TIME_TO_OPEN_BROWSER',\n { startTime: getCliStartTime(), attributes: { open: options.open } },\n () => {\n // Open the browser.\n if (options.open === false) {\n console.log('Please open the browser manually to:', defaultUrl);\n } else {\n let urlToOpen: string;\n if (typeof options.open === 'string') {\n // If the string doesn't start with http or https, pick a protocol based on config.server.https\n if (!options.open.startsWith('http://') && !options.open.startsWith('https://')) {\n urlToOpen = `${config.server?.https ? 'https' : 'http'}://${options.open}`;\n } else {\n urlToOpen = options.open;\n }\n } else {\n // Use the default path from the config with the first domain.\n urlToOpen = defaultUrl;\n }\n\n void openBrowser({ url: urlToOpen }, apiContext).catch((err: unknown) => {\n console.warn('Error opening browser:', (err as Error | undefined)?.stack || err);\n console.warn('Please open the browser manually to:', defaultUrl);\n });\n }\n },\n );\n\n return null; // the command should keep running\n};\n\n// cspell:ignore Prereqs\n"]}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/start/execute.ts"],"names":[],"mappings":"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","sourcesContent":["import { createApiContext, ensurePackageBundled } from '@ms-cloudpack/api-server';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport { makeUrl } from '@ms-cloudpack/path-string-parsing';\nimport { yellow } from '@ms-cloudpack/task-reporter';\nimport path from 'path';\nimport type { CommandAction } from '../../types/CommandAction.js';\nimport { runPrerequisites } from '../../utilities/runPrerequisites.js';\nimport { openBrowser } from './openBrowser.js';\nimport { trackSession } from './trackSession.js';\nimport type { StartOptions } from './types/StartOptions.js';\nimport { getCliStartTime } from '../../utilities/getCliStartTime.js';\nimport { createApiServer } from '../../utilities/createApiServer.js';\nimport { resolveCloudpackInternalPath } from '../../utilities/resolveCloudpackInternalPath.js';\n\n/**\n * Defines the \"start\" verb entry point.\n */\nexport const execute: CommandAction<StartOptions> = async (params) => {\n const { appPath, config, options, autoDispose } = params;\n\n console.log('App path:', yellow(appPath));\n console.log('Bundle mode:', yellow(options.mode));\n\n await runPrerequisites(params);\n\n const overlayPath = await resolveCloudpackInternalPath({\n packageName: '@ms-cloudpack/overlay',\n importMetaUrl: import.meta.url,\n });\n\n const shouldUseRemoteCache = config.features?.enableCloudHosted || config.features?.enableRemoteCacheDownloads;\n const apiContext = autoDispose(\n await createApiContext({\n ...params,\n remoteCacheClientLoginMethod: shouldUseRemoteCache ? options.login : undefined,\n additionalPaths: overlayPath ? [overlayPath] : undefined,\n }),\n );\n const { packages, session, telemetryClient } = apiContext;\n\n // Increment the session version if caching is disabled.\n if (options.cache === false) {\n session.incrementSessionVersion();\n }\n\n // Make sure the package has a valid definition.\n const definition = await packages.get(appPath);\n\n if (options.logResolveMap) {\n // Write the resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map.json'), session.resolveMap);\n }\n\n // Start api server for tracking status and handling remote requests.\n const apiServerResult = await createApiServer({ port: options.apiServerPort }, apiContext);\n if (apiServerResult.hasErrors) {\n return apiServerResult;\n }\n const { apiServer } = apiServerResult;\n\n // Kick off bundling app package as soon as api server is ready.\n void ensurePackageBundled({ name: definition.name, version: definition.version }, apiContext);\n\n // Then start bundle and app servers for hosting the app.\n const { startServers } = await import('@ms-cloudpack/app-server');\n const servers = await startServers(\n {\n definition,\n bundleServerOptions: { disableCache: !options.cache, port: options.bundleServerPort },\n port: options.appServerPort,\n },\n apiContext,\n );\n\n // Save the session to active sessions.\n const sessionTracker = await trackSession(session);\n\n const cleanup = async () => {\n // Stop tracking the session.\n await sessionTracker.close();\n\n await Promise.all(\n Object.entries({ apiServer, ...servers }).map(async ([name, server]) => {\n if (!server) return;\n\n const desc = `${name} (${server.url})`;\n console.info(`Closing ${desc}`);\n try {\n await server.close();\n console.info(`Closed ${desc}`);\n } catch (err) {\n console.warn(`Error closing ${desc}:`, err);\n }\n }),\n );\n };\n\n autoDispose({ dispose: cleanup });\n\n const defaultUrl = makeUrl(config.server?.defaultPath || '', session.urls.appServer).href;\n\n // Log the time elapsed from when the CLI started until the browser is ready to be opened.\n await telemetryClient.tracer.startActiveSpan(\n 'TIME_TO_OPEN_BROWSER',\n { startTime: getCliStartTime(), attributes: { open: options.open } },\n () => {\n // Open the browser.\n if (options.open === false) {\n console.log('Please open the browser manually to:', defaultUrl);\n } else {\n let urlToOpen: string;\n if (typeof options.open === 'string') {\n // If the string doesn't start with http or https, pick a protocol based on config.server.https\n if (!options.open.startsWith('http://') && !options.open.startsWith('https://')) {\n urlToOpen = `${config.server?.https ? 'https' : 'http'}://${options.open}`;\n } else {\n urlToOpen = options.open;\n }\n } else {\n // Use the default path from the config with the first domain.\n urlToOpen = defaultUrl;\n }\n\n void openBrowser({ url: urlToOpen }, apiContext).catch((err: unknown) => {\n console.warn('Error opening browser:', (err as Error | undefined)?.stack || err);\n console.warn('Please open the browser manually to:', defaultUrl);\n });\n }\n },\n );\n\n return null; // the command should keep running\n};\n\n// cspell:ignore Prereqs\n"]}
@@ -20,7 +20,7 @@ export const execute = async (params) => {
20
20
  const message = `Unlinking paths for ${session.projectName} at "${appPath}"`;
21
21
  const task = reporter.addTask(message);
22
22
  // Send request to api server to link paths.
23
- const { resolveMap, linkedPaths } = await client.unlinkPath.query({
23
+ const { resolveMap, linkedPaths } = await client.unlinkPath.mutate({
24
24
  linkedPath: {
25
25
  path: appPath,
26
26
  },
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/unlink/execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAiC,KAAK,EAAE,MAAM,EAAE,EAAE;IACpE,yDAAyD;IACzD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC9C,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE7C,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEvC,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEtF,MAAM,OAAO,GAAG,uBAAuB,OAAO,CAAC,WAAW,QAAQ,OAAO,GAAG,CAAC;IAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC,4CAA4C;IAC5C,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;QAChE,UAAU,EAAE;YACV,IAAI,EAAE,OAAO;SACd;KACF,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;QAChD,4BAA4B;QAC5B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,0CAA0C;QAC1C,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAAE,UAAU,CAAC,CAAC;IAC/E,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAE5E,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC,CAAC","sourcesContent":["import type { CommandAction } from '../../types/CommandAction.js';\nimport type { UnlinkOptions } from './types/UnlinkOptions.js';\nimport { getSessionToLink } from '../link/getSessionToLink.js';\nimport { createCloudpackClient } from '@ms-cloudpack/api-server';\nimport { formatLinkSummary } from '../link/formatLinkSummary.js';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport path from 'path';\n\n/**\n * Defines the \"unlink\" verb entry point.\n */\nexport const execute: CommandAction<UnlinkOptions> = async (params) => {\n // Use the current directory as the default package path.\n const { options, appPath, reporter } = params;\n const { logResolveMap, cachePath } = options;\n\n console.debug('Unlinking packages...');\n\n const sessionResult = await getSessionToLink({ reporter, cachePath });\n if (!sessionResult.session) {\n return sessionResult;\n }\n const { session } = sessionResult;\n const client = await createCloudpackClient({ url: session.urls.apiServer, reporter });\n\n const message = `Unlinking paths for ${session.projectName} at \"${appPath}\"`;\n const task = reporter.addTask(message);\n\n // Send request to api server to link paths.\n const { resolveMap, linkedPaths } = await client.unlinkPath.query({\n linkedPath: {\n path: appPath,\n },\n });\n await client.close();\n\n if (linkedPaths.some((p) => p.path === appPath)) {\n // Close down with an error.\n task.complete({ status: 'fail', message: `Failed to unlink paths.`, forceShow: true });\n return { hasErrors: true, message: 'Failed to unlink paths.' };\n }\n\n if (logResolveMap) {\n // Write the unlinked resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map-unlinked.json'), resolveMap);\n }\n\n // Close down successfully.\n task.complete({ status: 'complete', message: `Unlinked paths`, forceShow: true });\n const linkSummary = formatLinkSummary({ session, resolveMap, linkedPaths });\n\n return { message: linkSummary };\n};\n"]}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/commands/unlink/execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAiC,KAAK,EAAE,MAAM,EAAE,EAAE;IACpE,yDAAyD;IACzD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC9C,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE7C,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEvC,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEtF,MAAM,OAAO,GAAG,uBAAuB,OAAO,CAAC,WAAW,QAAQ,OAAO,GAAG,CAAC;IAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC,4CAA4C;IAC5C,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QACjE,UAAU,EAAE;YACV,IAAI,EAAE,OAAO;SACd;KACF,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;QAChD,4BAA4B;QAC5B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,0CAA0C;QAC1C,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAAE,UAAU,CAAC,CAAC;IAC/E,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAE5E,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC,CAAC","sourcesContent":["import type { CommandAction } from '../../types/CommandAction.js';\nimport type { UnlinkOptions } from './types/UnlinkOptions.js';\nimport { getSessionToLink } from '../link/getSessionToLink.js';\nimport { createCloudpackClient } from '@ms-cloudpack/api-server';\nimport { formatLinkSummary } from '../link/formatLinkSummary.js';\nimport { writeJson } from '@ms-cloudpack/json-utilities';\nimport path from 'path';\n\n/**\n * Defines the \"unlink\" verb entry point.\n */\nexport const execute: CommandAction<UnlinkOptions> = async (params) => {\n // Use the current directory as the default package path.\n const { options, appPath, reporter } = params;\n const { logResolveMap, cachePath } = options;\n\n console.debug('Unlinking packages...');\n\n const sessionResult = await getSessionToLink({ reporter, cachePath });\n if (!sessionResult.session) {\n return sessionResult;\n }\n const { session } = sessionResult;\n const client = await createCloudpackClient({ url: session.urls.apiServer, reporter });\n\n const message = `Unlinking paths for ${session.projectName} at \"${appPath}\"`;\n const task = reporter.addTask(message);\n\n // Send request to api server to link paths.\n const { resolveMap, linkedPaths } = await client.unlinkPath.mutate({\n linkedPath: {\n path: appPath,\n },\n });\n await client.close();\n\n if (linkedPaths.some((p) => p.path === appPath)) {\n // Close down with an error.\n task.complete({ status: 'fail', message: `Failed to unlink paths.`, forceShow: true });\n return { hasErrors: true, message: 'Failed to unlink paths.' };\n }\n\n if (logResolveMap) {\n // Write the unlinked resolve map to disk.\n await writeJson(path.join(appPath, 'resolve-map-unlinked.json'), resolveMap);\n }\n\n // Close down successfully.\n task.complete({ status: 'complete', message: `Unlinked paths`, forceShow: true });\n const linkSummary = formatLinkSummary({ session, resolveMap, linkedPaths });\n\n return { message: linkSummary };\n};\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resolves an internal Cloudpack package path, ensuring we use the bundled version when available.
3
+ *
4
+ */
5
+ export declare function resolveCloudpackInternalPath(params: {
6
+ packageName: string;
7
+ importMetaUrl: string;
8
+ }): Promise<string | undefined>;
9
+ //# sourceMappingURL=resolveCloudpackInternalPath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveCloudpackInternalPath.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveCloudpackInternalPath.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAa9B"}
@@ -0,0 +1,20 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { isExternalPackage, resolve } from '@ms-cloudpack/path-utilities';
4
+ /**
5
+ * Resolves an internal Cloudpack package path, ensuring we use the bundled version when available.
6
+ *
7
+ */
8
+ export async function resolveCloudpackInternalPath(params) {
9
+ const { packageName, importMetaUrl } = params;
10
+ const currentDir = path.dirname(fileURLToPath(importMetaUrl));
11
+ let packagePath = await resolve(packageName, currentDir);
12
+ // If the package is internal, resolve it from the CLI's node_modules
13
+ // to "externalize" it, so that we always use the bundled version instead of the source.
14
+ if (packagePath && !isExternalPackage(packagePath)) {
15
+ const cliPath = await resolve('@ms-cloudpack/cli', currentDir);
16
+ packagePath = cliPath ? path.join(cliPath, 'node_modules', packageName) : undefined;
17
+ }
18
+ return packagePath;
19
+ }
20
+ //# sourceMappingURL=resolveCloudpackInternalPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveCloudpackInternalPath.js","sourceRoot":"","sources":["../../src/utilities/resolveCloudpackInternalPath.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,MAGlD;IACC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAC9D,IAAI,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAEzD,qEAAqE;IACrE,wFAAwF;IACxF,IAAI,WAAW,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;QAC/D,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\nimport { isExternalPackage, resolve } from '@ms-cloudpack/path-utilities';\n\n/**\n * Resolves an internal Cloudpack package path, ensuring we use the bundled version when available.\n *\n */\nexport async function resolveCloudpackInternalPath(params: {\n packageName: string;\n importMetaUrl: string;\n}): Promise<string | undefined> {\n const { packageName, importMetaUrl } = params;\n const currentDir = path.dirname(fileURLToPath(importMetaUrl));\n let packagePath = await resolve(packageName, currentDir);\n\n // If the package is internal, resolve it from the CLI's node_modules\n // to \"externalize\" it, so that we always use the bundled version instead of the source.\n if (packagePath && !isExternalPackage(packagePath)) {\n const cliPath = await resolve('@ms-cloudpack/cli', currentDir);\n packagePath = cliPath ? path.join(cliPath, 'node_modules', packageName) : undefined;\n }\n\n return packagePath;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/cli",
3
- "version": "0.74.2",
3
+ "version": "0.74.4",
4
4
  "description": "The Cloudpack command line interface - a tool for managing fast inner and outer looping in web apps.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,22 +10,23 @@
10
10
  "cloudpack": "./bin/cloudpack.js"
11
11
  },
12
12
  "dependencies": {
13
- "@ms-cloudpack/api-server": "^0.62.1",
14
- "@ms-cloudpack/app-server": "^0.18.2",
15
- "@ms-cloudpack/bundler": "^0.25.1",
13
+ "@ms-cloudpack/api-server": "^0.63.1",
14
+ "@ms-cloudpack/app-server": "^0.18.4",
15
+ "@ms-cloudpack/bundler": "^0.25.3",
16
+ "@ms-cloudpack/bundler-capabilities": "^0.2.23",
16
17
  "@ms-cloudpack/common-types": "^0.24.17",
17
- "@ms-cloudpack/config": "^0.35.3",
18
+ "@ms-cloudpack/config": "^0.35.4",
18
19
  "@ms-cloudpack/environment": "^0.1.1",
19
20
  "@ms-cloudpack/json-utilities": "^0.1.10",
20
- "@ms-cloudpack/link-proxy": "^0.2.1",
21
- "@ms-cloudpack/overlay": "^0.18.1",
22
- "@ms-cloudpack/package-utilities": "^12.3.5",
21
+ "@ms-cloudpack/link-proxy": "^0.2.3",
22
+ "@ms-cloudpack/overlay": "^0.18.3",
23
+ "@ms-cloudpack/package-utilities": "^12.3.6",
23
24
  "@ms-cloudpack/path-string-parsing": "^1.2.7",
24
25
  "@ms-cloudpack/path-utilities": "^3.1.2",
25
- "@ms-cloudpack/remote-cache": "^0.11.14",
26
+ "@ms-cloudpack/remote-cache": "^0.11.15",
26
27
  "@ms-cloudpack/setup-utilities": "^0.5.24",
27
- "@ms-cloudpack/task-reporter": "^0.16.2",
28
- "@ms-cloudpack/telemetry": "^0.11.17",
28
+ "@ms-cloudpack/task-reporter": "^0.16.3",
29
+ "@ms-cloudpack/telemetry": "^0.11.18",
29
30
  "@yarnpkg/lockfile": "^1.1.0",
30
31
  "commander": "^13.0.0",
31
32
  "cross-spawn": "^7.0.3",