@forge/cli-shared 9.8.0-next.0 → 9.8.0-next.10

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.
@@ -2,6 +2,7 @@ export { graphql } from './gql/gql';
2
2
  export * from './app-environment-graphql-client';
3
3
  export * from './debugging-graphql-runner';
4
4
  export * from './gateway';
5
+ export * from './path-based-graphql-client-resolver';
5
6
  export * from './graphql-client';
6
7
  export * from './graphql-runtime-enums';
7
8
  export * from './graphql-domain-types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,WAAW,CAAC;AAC1B,cAAc,sCAAsC,CAAC;AACrD,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,sCAAsC,CAAC"}
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "graphql", { enumerable: true, get: function () {
7
7
  tslib_1.__exportStar(require("./app-environment-graphql-client"), exports);
8
8
  tslib_1.__exportStar(require("./debugging-graphql-runner"), exports);
9
9
  tslib_1.__exportStar(require("./gateway"), exports);
10
+ tslib_1.__exportStar(require("./path-based-graphql-client-resolver"), exports);
10
11
  tslib_1.__exportStar(require("./graphql-client"), exports);
11
12
  tslib_1.__exportStar(require("./graphql-runtime-enums"), exports);
12
13
  tslib_1.__exportStar(require("./graphql-domain-types"), exports);
@@ -0,0 +1,10 @@
1
+ import { GraphQLClient } from './graphql-client';
2
+ export type GraphQLClientFactory = (endpoint: string) => GraphQLClient;
3
+ export declare class PathBasedGraphQLClientResolver {
4
+ private readonly defaultClient;
5
+ private readonly createGraphQLClient;
6
+ private readonly siteClients;
7
+ constructor(defaultClient: GraphQLClient, createGraphQLClient: GraphQLClientFactory);
8
+ resolve(site?: string): GraphQLClient;
9
+ }
10
+ //# sourceMappingURL=path-based-graphql-client-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-based-graphql-client-resolver.d.ts","sourceRoot":"","sources":["../../src/graphql/path-based-graphql-client-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;AAgBvE,qBAAa,8BAA8B;IAIvC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;gBAG7C,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,oBAAoB;IAGrD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa;CAc7C"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathBasedGraphQLClientResolver = void 0;
4
+ const gateway_1 = require("./gateway");
5
+ const SITE_GRAPHQL_GATEWAY_PATH = '/gateway/api/graphql';
6
+ const HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
7
+ class PathBasedGraphQLClientResolver {
8
+ defaultClient;
9
+ createGraphQLClient;
10
+ siteClients = new Map();
11
+ constructor(defaultClient, createGraphQLClient) {
12
+ this.defaultClient = defaultClient;
13
+ this.createGraphQLClient = createGraphQLClient;
14
+ }
15
+ resolve(site) {
16
+ const hostname = site?.trim().toLowerCase();
17
+ if (!hostname || !HOSTNAME_PATTERN.test(hostname) || !(0, gateway_1.isPathBasedRoutingEnabled)()) {
18
+ return this.defaultClient;
19
+ }
20
+ const endpoint = `https://${hostname}${SITE_GRAPHQL_GATEWAY_PATH}`;
21
+ let client = this.siteClients.get(endpoint);
22
+ if (!client) {
23
+ client = this.createGraphQLClient(endpoint);
24
+ this.siteClients.set(endpoint, client);
25
+ }
26
+ return client;
27
+ }
28
+ }
29
+ exports.PathBasedGraphQLClientResolver = PathBasedGraphQLClientResolver;
@@ -4,7 +4,7 @@ import { Logger } from '../ui/logger';
4
4
  import { Services } from '@forge/manifest';
5
5
  import { ChildProcess } from 'child_process';
6
6
  export declare const PROXY_SIDECAR_VOLUME_DIR = "/forge/container";
7
- export declare const CONTAINER_SERVICE_ASSETS = ".container-service-assets";
7
+ export declare const CONTAINER_SERVICE_ASSETS: string;
8
8
  export declare const K8S_AUTH_TOKEN_FILENAME = "local-account";
9
9
  export declare const STARTUP_TIMER_MS: number;
10
10
  export declare const STARTUP_TIMER_BUFFER_MS: number;
@@ -1 +1 @@
1
- {"version":3,"file":"docker-compose-lifecycle.d.ts","sourceRoot":"","sources":["../../src/tunnel/docker-compose-lifecycle.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,8BAA8B,CAAC;AACpE,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAgCvD,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAC1C,eAAO,MAAM,uBAAuB,QAAW,CAAC;AAEhD,qBAAa,2BAA4B,SAAQ,SAAS;gBAC5C,UAAU,EAAE,MAAM;CAG/B;AAED,qBAAa,mCAAoC,SAAQ,SAAS;gBACpD,GAAG,CAAC,EAAE,KAAK;CAGxB;AAED,qBAAa,wBAAyB,SAAQ,SAAS;gBACzC,GAAG,CAAC,EAAE,KAAK;CAGxB;AAED,qBAAa,mCAAoC,SAAQ,SAAS;gBACpD,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK;CAG5C;AAED,qBAAa,+BAAgC,SAAQ,SAAS;gBAChD,YAAY,EAAE,MAAM;CAGjC;AAED,qBAAa,sCAAuC,SAAQ,SAAS;gBACvD,YAAY,EAAE,MAAM;CAGjC;AAED,qBAAa,yBAA0B,SAAQ,SAAS;gBAC1C,OAAO,EAAE,MAAM;CAG5B;AAMD,eAAO,MAAM,mCAAmC,GAAU,UAAU,QAAQ,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,oCAgFzG,CAAC;AAsFF,eAAO,MAAM,uBAAuB,GAAU,aAAa,MAAM,kBAYhE,CAAC;AAOF,eAAO,MAAM,uBAAuB,GAAU,uBAAuB,MAAM,EAAE,YAAY,MAAM,EAAE,QAAQ,MAAM,kBA8B9G,CAAC;AA6BF,eAAO,MAAM,qBAAqB,GAChC,uBAAuB,MAAM,EAC7B,YAAY,MAAM,EAClB,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,EAAE,CAgBlB,CAAC;AA2LF,eAAO,MAAM,sBAAsB,GACjC,YAAY,UAAU,EACtB,QAAQ,MAAM,EACd,eAAe,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,kBAmCtC,CAAC;AAgCF,eAAO,MAAM,2BAA2B,GAAU,cAAc,YAAY,kBAW3E,CAAC"}
1
+ {"version":3,"file":"docker-compose-lifecycle.d.ts","sourceRoot":"","sources":["../../src/tunnel/docker-compose-lifecycle.ts"],"names":[],"mappings":"AAUA,OAAO,EAAmB,SAAS,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM7C,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAE3D,eAAO,MAAM,wBAAwB,QAAgE,CAAC;AACtG,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAwBvD,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAC1C,eAAO,MAAM,uBAAuB,QAAW,CAAC;AAEhD,qBAAa,2BAA4B,SAAQ,SAAS;gBAC5C,UAAU,EAAE,MAAM;CAG/B;AAED,qBAAa,mCAAoC,SAAQ,SAAS;gBACpD,GAAG,CAAC,EAAE,KAAK;CAGxB;AAED,qBAAa,wBAAyB,SAAQ,SAAS;gBACzC,GAAG,CAAC,EAAE,KAAK;CAGxB;AAED,qBAAa,mCAAoC,SAAQ,SAAS;gBACpD,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK;CAG5C;AAED,qBAAa,+BAAgC,SAAQ,SAAS;gBAChD,YAAY,EAAE,MAAM;CAGjC;AAED,qBAAa,sCAAuC,SAAQ,SAAS;gBACvD,YAAY,EAAE,MAAM;CAGjC;AAED,qBAAa,yBAA0B,SAAQ,SAAS;gBAC1C,OAAO,EAAE,MAAM;CAG5B;AAMD,eAAO,MAAM,mCAAmC,GAAU,UAAU,QAAQ,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,oCAgFzG,CAAC;AAyFF,eAAO,MAAM,uBAAuB,GAAU,aAAa,MAAM,kBAYhE,CAAC;AAOF,eAAO,MAAM,uBAAuB,GAAU,uBAAuB,MAAM,EAAE,YAAY,MAAM,EAAE,QAAQ,MAAM,kBAc9G,CAAC;AAiBF,eAAO,MAAM,qBAAqB,GAChC,uBAAuB,MAAM,EAC7B,YAAY,MAAM,EAClB,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,EAAE,CAgBlB,CAAC;AA2LF,eAAO,MAAM,sBAAsB,GACjC,YAAY,UAAU,EACtB,QAAQ,MAAM,EACd,eAAe,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,kBAmCtC,CAAC;AAgCF,eAAO,MAAM,2BAA2B,GAAU,cAAc,YAAY,kBAW3E,CAAC"}
@@ -10,24 +10,20 @@ const docker_compose_1 = require("docker-compose");
10
10
  const shared_1 = require("../shared");
11
11
  const text_1 = require("../ui/text");
12
12
  const tunnel_options_1 = require("./tunnel-options");
13
- const HIDDEN_DIR = '.services';
13
+ const SERVICES_DIR_NAME = 'services';
14
+ const HIDDEN_DIR = path.join(shared_1.FORGE_DIRECTORY, SERVICES_DIR_NAME);
14
15
  exports.PROXY_SIDECAR_VOLUME_DIR = '/forge/container';
15
- exports.CONTAINER_SERVICE_ASSETS = '.container-service-assets';
16
+ const CONTAINER_SERVICE_ASSETS_DIR_NAME = 'container-service-assets';
17
+ exports.CONTAINER_SERVICE_ASSETS = path.join(shared_1.FORGE_DIRECTORY, CONTAINER_SERVICE_ASSETS_DIR_NAME);
16
18
  exports.K8S_AUTH_TOKEN_FILENAME = 'local-account';
17
19
  const PROXY_SIDECAR_SERVICE_NAME = 'proxy-sidecar';
18
20
  const PROXY_SIDECAR_IMAGE_PATH = 'forge-platform/proxy-sidecar:latest';
19
21
  const PROXY_SIDECAR_REGISTRIES = {
20
- portable: {
21
- production: 'forge-registry.services.atlassian.com',
22
- staging: 'forge-registry.stg.services.atlassian.com'
23
- },
24
- ecr: {
25
- production: 'forge-ecr.services.atlassian.com',
26
- staging: 'forge-ecr.stg.services.atlassian.com'
27
- }
22
+ production: 'forge-registry.services.atlassian.com',
23
+ staging: 'forge-registry.stg.services.atlassian.com'
28
24
  };
29
25
  const isStagingEnvironment = () => process.env.FORGE_GRAPHQL_GATEWAY?.startsWith('https://api-private.stg.atlassian.com/graphql') ?? false;
30
- const getProxySidecarRegistry = (registryType) => PROXY_SIDECAR_REGISTRIES[registryType][isStagingEnvironment() ? 'staging' : 'production'];
26
+ const getProxySidecarRegistry = () => PROXY_SIDECAR_REGISTRIES[isStagingEnvironment() ? 'staging' : 'production'];
31
27
  const LIFECYCLE_PATTERNS = [
32
28
  /Container .* (Starting|Started|Stopping|Stopped|Creating|Created|Recreated)/,
33
29
  /Network .* (Creating|Created|Removing|Removed)/,
@@ -134,20 +130,19 @@ const generateContainersDockerComposeFile = async (services, appId, envId) => {
134
130
  return filesGenerated;
135
131
  };
136
132
  exports.generateContainersDockerComposeFile = generateContainersDockerComposeFile;
133
+ const relativeComposePath = (from, to) => path.relative(from, to).split(path.sep).join('/');
137
134
  const adjustFilePath = (filePath) => {
138
135
  if (path.isAbsolute(filePath)) {
139
136
  return filePath;
140
137
  }
141
- let adjusted = filePath;
142
- if (adjusted.startsWith('./')) {
143
- adjusted = adjusted.slice(2);
144
- }
145
- return path.join('..', adjusted);
138
+ const composeFileDir = path.join(process.cwd(), HIDDEN_DIR);
139
+ const absoluteTarget = path.resolve(process.cwd(), filePath);
140
+ return relativeComposePath(composeFileDir, absoluteTarget);
146
141
  };
147
142
  const getProxySidecarConfig = async (serviceKey, containerKeys, port, appId, envId, serviceIndex, healthEndpointPath) => {
148
143
  let fopBaseUrl = 'https://forge-outbound-proxy.services.atlassian.com';
149
144
  let jwksUrl = 'https://forge.cdn.prod.atlassian-dev.net/.well-known/jwks.json';
150
- const proxySidecarRegistry = getProxySidecarRegistry('portable');
145
+ const proxySidecarRegistry = getProxySidecarRegistry();
151
146
  if (isStagingEnvironment()) {
152
147
  fopBaseUrl = 'https://forge-outbound-proxy.stg.services.atlassian.com';
153
148
  jwksUrl = 'https://forge.cdn.stg.atlassian-dev.net/.well-known/jwks.json';
@@ -170,7 +165,7 @@ const getProxySidecarConfig = async (serviceKey, containerKeys, port, appId, env
170
165
  `K8S_AUTH_TOKEN_PATH=${exports.PROXY_SIDECAR_VOLUME_DIR}/${exports.K8S_AUTH_TOKEN_FILENAME}`,
171
166
  `${containerKeys[0]}_CONTAINER_HEALTHCHECK=http://${containerKeys[0]}:8080${healthEndpointPath}`
172
167
  ],
173
- volumes: [`../${exports.CONTAINER_SERVICE_ASSETS}:${exports.PROXY_SIDECAR_VOLUME_DIR}:ro`],
168
+ volumes: [`${adjustFilePath(exports.CONTAINER_SERVICE_ASSETS)}:${exports.PROXY_SIDECAR_VOLUME_DIR}:ro`],
174
169
  ports: [
175
170
  `${port}:${tunnel_options_1.DEFAULT_PROXY_INGRESS_PORT}`,
176
171
  `${tunnel_options_1.DEFAULT_PROXY_HEALTHCHECK_PORT_HOST_MACHINE + serviceIndex}:${tunnel_options_1.DEFAULT_PROXY_HEALTHCHECK_PORT}`
@@ -210,15 +205,8 @@ const startDockerComposeStack = async (dockerComposeFilePath, serviceKey, logger
210
205
  try {
211
206
  await (0, docker_compose_1.pullOne)(PROXY_SIDECAR_SERVICE_NAME, pullOptions);
212
207
  }
213
- catch (portableRegistryError) {
214
- logger.warn('Unable to pull the proxy sidecar image. Retrying from an alternate source...');
215
- useEcrProxySidecarImage(dockerComposeFilePath);
216
- try {
217
- await (0, docker_compose_1.pullOne)(PROXY_SIDECAR_SERVICE_NAME, pullOptions);
218
- }
219
- catch (ecrRegistryError) {
220
- throw new DockerUnableToPullProxySidecarImage(new Error(`Initial pull error: ${getDockerComposeErrorMessage(portableRegistryError)}. Retry error: ${getDockerComposeErrorMessage(ecrRegistryError)}`));
221
- }
208
+ catch (pullError) {
209
+ throw new DockerUnableToPullProxySidecarImage(new Error(getDockerComposeErrorMessage(pullError)));
222
210
  }
223
211
  await waitForContainersToStart(dockerComposeFilePath, serviceKey, logger);
224
212
  };
@@ -230,16 +218,6 @@ const getDockerComposeErrorMessage = (error) => {
230
218
  }
231
219
  return error != null ? String(error) : 'Unknown Error Occurred.';
232
220
  };
233
- const useEcrProxySidecarImage = (dockerComposeFilePath) => {
234
- const composeConfig = yaml.parse(fs.readFileSync(dockerComposeFilePath, 'utf8'));
235
- const proxySidecar = composeConfig?.services?.[PROXY_SIDECAR_SERVICE_NAME];
236
- if (!proxySidecar) {
237
- throw new Error(`The Docker Compose file does not contain the ${PROXY_SIDECAR_SERVICE_NAME} service.`);
238
- }
239
- const ecrRegistry = getProxySidecarRegistry('ecr');
240
- proxySidecar.image = `${ecrRegistry}/${PROXY_SIDECAR_IMAGE_PATH}`;
241
- fs.writeFileSync(dockerComposeFilePath, yaml.stringify(composeConfig));
242
- };
243
221
  const determineComposeFlags = async (dockerComposeFilePath, serviceKey, logger) => {
244
222
  const flags = ['--build', '--quiet-pull'];
245
223
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/cli-shared",
3
- "version": "9.8.0-next.0",
3
+ "version": "9.8.0-next.10",
4
4
  "description": "Common functionality for Forge CLI",
5
5
  "author": "Atlassian",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -13,12 +13,12 @@
13
13
  "prebuild": "yarn generate-graphql-types"
14
14
  },
15
15
  "dependencies": {
16
- "@forge/manifest": "13.7.0-next.0",
16
+ "@forge/manifest": "13.7.0-next.6",
17
17
  "@forge/util": "3.0.0",
18
18
  "@forge/i18n": "1.0.0",
19
19
  "@sentry/node": "7.106.0",
20
20
  "@vercel/detect-agent": "^1.2.3",
21
- "adm-zip": "^0.6.0",
21
+ "adm-zip": "^0.6.1",
22
22
  "archiver": "^8.0.0",
23
23
  "array.prototype.flatmap": "^1.3.3",
24
24
  "case": "^1.6.3",
@@ -58,7 +58,7 @@
58
58
  "@graphql-codegen/typescript-operations": "^4.6.0",
59
59
  "@graphql-tools/schema": "^10.1.1",
60
60
  "@graphql-typed-document-node/core": "^3.2.0",
61
- "@types/adm-zip": "^0.5.5",
61
+ "@types/adm-zip": "^0.5.8",
62
62
  "@types/array.prototype.flatmap": "^1.2.6",
63
63
  "@types/cross-spawn": "^6.0.6",
64
64
  "@types/fs-extra": "^11.0.4",