@forge/bundler

7.1.1-next.17.1.1-next.1-experimental-0b00ed8
~

Modified (7 files)

Index: package/out/config/common.js
===================================================================
--- package/out/config/common.js
+++ package/out/config/common.js
@@ -74,9 +74,8 @@
         resolveLoader: {
             modules: require.resolve.paths('babel-loader') || undefined
         },
         plugins: [
-            new webpack_1.default.IgnorePlugin({ resourceRegExp: /^encoding$/, contextRegExp: /node-fetch/ }),
             new webpack_1.default.IgnorePlugin({ resourceRegExp: /^(bufferutil|utf-8-validate)$/, contextRegExp: /ws\/lib$/ }),
             new webpack_1.default.IgnorePlugin({ resourceRegExp: /^dtrace-provider$/, contextRegExp: /bunyan$/ })
         ],
         module: {
Index: package/out/wrapper-provider.js
===================================================================
--- package/out/wrapper-provider.js
+++ package/out/wrapper-provider.js
@@ -2,10 +2,12 @@
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.getWrapperProvider = exports.NetworkWrapperProvider = exports.LocalWrapperProvider = exports.ParseWrapperCDNIndexError = exports.WrapperNetworkError = exports.LocalWrapperNotFoundError = void 0;
 const tslib_1 = require("tslib");
 const path_1 = tslib_1.__importDefault(require("path"));
+const http_1 = tslib_1.__importDefault(require("http"));
+const https_1 = tslib_1.__importDefault(require("https"));
+const url_1 = require("url");
 const cheerio_1 = require("cheerio");
-const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
 const cli_shared_1 = require("@forge/cli-shared");
 var RuntimeCDN;
 (function (RuntimeCDN) {
     RuntimeCDN["DEV"] = "https://forge-node-runtime.stg-east.frontend.public.atl-paas.net/";
@@ -36,8 +38,32 @@
 (function (ScriptType) {
     ScriptType["WRAPPER"] = "wrapper";
     ScriptType["LOADER"] = "loader";
 })(ScriptType || (ScriptType = {}));
+const NODE_REQUEST_TIMEOUT_MS = 30_000;
+const DEFAULT_HTTP_ERROR_STATUS = 500;
+const toHeaders = (rawHeaders) => {
+    const responseHeaders = new Headers();
+    Object.entries(rawHeaders).forEach(([key, value]) => {
+        if (Array.isArray(value)) {
+            value.forEach((headerValue) => responseHeaders.append(key, headerValue));
+            return;
+        }
+        if (typeof value === 'string') {
+            responseHeaders.set(key, value);
+        }
+    });
+    return responseHeaders;
+};
+const toRuntimeFetchResponse = (response, chunks, headers) => {
+    const status = response.statusCode ?? DEFAULT_HTTP_ERROR_STATUS;
+    return {
+        ok: status >= 200 && status < 300,
+        status,
+        headers,
+        text: async () => Buffer.concat(chunks).toString('utf8')
+    };
+};
 class LocalWrapperProvider {
     filesystemReader;
     runtimePath;
     constructor(filesystemReader, runtimePath) {
@@ -72,34 +98,51 @@
     constructor(statsigService) {
         this.statsigService = statsigService;
         this.cdnUrl = (0, cli_shared_1.getEnvironmentConfig)(RuntimeCDN);
     }
+    getFromNodeRequest = async (url) => {
+        return await new Promise((resolve, reject) => {
+            const parsedUrl = new url_1.URL(url);
+            const requestClient = parsedUrl.protocol === 'https:' ? https_1.default : http_1.default;
+            const request = requestClient.get(parsedUrl, (response) => {
+                const body = [];
+                response.on('data', (chunk) => body.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
+                response.on('end', () => {
+                    resolve(toRuntimeFetchResponse(response, body, toHeaders(response.headers)));
+                });
+            });
+            request.setTimeout(NODE_REQUEST_TIMEOUT_MS, () => {
+                request.destroy(new Error(`Request timed out after ${NODE_REQUEST_TIMEOUT_MS}ms`));
+            });
+            request.on('error', reject);
+        });
+    };
     async getScriptPathFromIndex(htmlContent, requestId, scriptType) {
         const html = (0, cheerio_1.load)(htmlContent, { xml: { xmlMode: false } });
         const scriptPath = html('script')
             ?.get()
             ?.find((asset) => asset.attribs['src']?.includes(scriptType))?.attribs['src'];
         if (typeof scriptPath !== 'string') {
             throw new ParseWrapperCDNIndexError(`Unable to parse source of runtime ${scriptType}.`, requestId);
         }
-        return new URL(scriptPath, this.cdnUrl).toString();
+        return new url_1.URL(scriptPath, this.cdnUrl).toString();
     }
     getFileFromCDN = async (scriptType) => {
         try {
-            const indexResponse = await (0, node_fetch_1.default)(this.cdnUrl);
+            const indexResponse = await this.getFromNodeRequest(this.cdnUrl);
             if (!indexResponse.ok) {
                 throw new WrapperNetworkError(`Failed to fetch runtime component: ${this.cdnUrl} ${indexResponse.status}.`, (0, cli_shared_1.getAtlassianTraceId)(indexResponse.headers));
             }
             const source = await this.getScriptPathFromIndex(await indexResponse.text(), (0, cli_shared_1.getAtlassianTraceId)(indexResponse.headers), scriptType);
-            const response = await (0, node_fetch_1.default)(source);
+            const response = await this.getFromNodeRequest(source);
             if (!response.ok) {
                 throw new WrapperNetworkError(`Failed to fetch runtime component: ${source.toString()} ${response.status}.`, (0, cli_shared_1.getAtlassianTraceId)(response.headers));
             }
             const script = await response.text();
             return {
                 script,
                 source,
-                version: new URL(source).pathname
+                version: new url_1.URL(source).pathname
             };
         }
         catch (e) {
             if (e instanceof ParseWrapperCDNIndexError) {
Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@forge/bundler",
-  "version": "7.1.1-next.1",
+  "version": "7.1.1-next.1-experimental-0b00ed8",
   "description": "Default bundler for Forge apps",
   "license": "SEE LICENSE IN LICENSE.txt",
   "author": "Atlassian",
   "main": "out/index.js",
@@ -20,21 +20,20 @@
     "@babel/plugin-transform-optional-chaining": "^7.23.4",
     "@babel/plugin-transform-react-jsx": "^7.23.4",
     "@babel/traverse": "^7.24.0",
     "@babel/types": "^7.24.0",
-    "@forge/cli-shared": "9.3.1-next.1",
+    "@forge/cli-shared": "9.3.1-next.1-experimental-0b00ed8",
     "@forge/i18n": "1.0.0",
-    "@forge/lint": "6.1.1-next.1",
-    "@forge/manifest": "13.3.0",
+    "@forge/lint": "6.1.1-next.1-experimental-0b00ed8",
+    "@forge/manifest": "13.3.0-experimental-0b00ed8",
     "babel-loader": "^8.3.0",
     "cheerio": "^1.2.0",
     "chokidar": "^4.0.3",
     "cross-spawn": "^7.0.6",
     "debounce": "^2.2.0",
     "fs-extra": "^11.2.0",
     "html-webpack-plugin": "^5.6.3",
     "nock": "13.5.6",
-    "node-fetch": "2.7.0",
     "tmp": "^0.2.3",
     "ts-loader": "^9.5.2",
     "type-fest": "4.10.2",
     "typescript": "5.9.2",
Index: package/out/config/common.d.ts.map
===================================================================
--- package/out/config/common.d.ts.map
+++ package/out/config/common.d.ts.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/config/common.ts"],"names":[],"mappings":"AAEA,OAAgB,EAAE,aAAa,IAAI,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIjF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,MAEtD,CAAC;AAEF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAe,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,KAAG,MAShF,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAC5F,KAAK,mBAAmB,GAAG,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpD,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC,GACnF,MAAM,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GACrC,MAAM,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GACrC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AAElC,eAAO,MAAM,WAAW,GAAI,YAAY,YAAY;;;;;+DAIe;YAAE,MAAM,EAAE;gBAAE,QAAQ,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;;CAalG,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,WAAW,KAAG,mBA2F1D,CAAC"}
\ No newline at end of file
+{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/config/common.ts"],"names":[],"mappings":"AAEA,OAAgB,EAAE,aAAa,IAAI,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIjF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,MAEtD,CAAC;AAEF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAe,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,KAAG,MAShF,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAC5F,KAAK,mBAAmB,GAAG,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpD,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC,GACnF,MAAM,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GACrC,MAAM,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GACrC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AAElC,eAAO,MAAM,WAAW,GAAI,YAAY,YAAY;;;;;+DAIe;YAAE,MAAM,EAAE;gBAAE,QAAQ,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;;CAalG,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,WAAW,KAAG,mBA0F1D,CAAC"}
\ No newline at end of file
Index: package/out/wrapper-provider.d.ts.map
===================================================================
--- package/out/wrapper-provider.d.ts.map
+++ package/out/wrapper-provider.d.ts.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"wrapper-provider.d.ts","sourceRoot":"","sources":["../src/wrapper-provider.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,SAAS,EAGT,cAAc,EACf,MAAM,mBAAmB,CAAC;AAW3B,qBAAa,yBAA0B,SAAQ,SAAS;;CAIvD;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAGhD;AAED,qBAAa,yBAA0B,SAAQ,SAAS;gBAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS;CAG3D;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAChD,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;CAC5D;AAOD,qBAAa,oBAAqB,YAAW,eAAe;IAExD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADX,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,MAAM;YAExB,cAAc;IAatB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC;IAI/C,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAGjE;AAED,qBAAa,sBAAuB,YAAW,eAAe;IAKhD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc;IAJ7D,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEM,cAAc,EAAE,cAAc;YAI/C,sBAAsB;IAgBpC,OAAO,CAAC,cAAc,CAuCpB;IAEI,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC;IAO/C,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAQjE;AAED,eAAO,MAAM,kBAAkB,GAAI,sCAGhC;IACD,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;CAChC,kDAQA,CAAC"}
\ No newline at end of file
+{"version":3,"file":"wrapper-provider.d.ts","sourceRoot":"","sources":["../src/wrapper-provider.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,SAAS,EAGT,cAAc,EACf,MAAM,mBAAmB,CAAC;AAW3B,qBAAa,yBAA0B,SAAQ,SAAS;;CAIvD;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAGhD;AAED,qBAAa,yBAA0B,SAAQ,SAAS;gBAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS;CAG3D;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAChD,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;CAC5D;AAOD,KAAK,oBAAoB,GAAG;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAiCF,qBAAa,oBAAqB,YAAW,eAAe;IAExD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADX,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,MAAM;YAExB,cAAc;IAatB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC;IAI/C,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAGjE;AAED,qBAAa,sBAAuB,YAAW,eAAe;IAKhD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc;IAJ7D,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEM,cAAc,EAAE,cAAc;IAI7D,SAAS,CAAC,kBAAkB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,oBAAoB,CAAC,CAqB/E;YAEY,sBAAsB;IAgBpC,OAAO,CAAC,cAAc,CAyCpB;IAEI,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC;IAO/C,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAQjE;AAED,eAAO,MAAM,kBAAkB,GAAI,sCAGhC;IACD,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;CAChC,kDAQA,CAAC"}
\ No newline at end of file
File too large for inline diff
Index: package/out/wrapper-provider.d.ts
===================================================================
--- package/out/wrapper-provider.d.ts
+++ package/out/wrapper-provider.d.ts
@@ -16,8 +16,14 @@
 export interface WrapperProvider {
     getNodeRuntimeWrapper(): Promise<RuntimeScript>;
     getNodeRuntimeLoader(): Promise<RuntimeScript | undefined>;
 }
+type RuntimeFetchResponse = {
+    ok: boolean;
+    status: number;
+    headers: Headers;
+    text: () => Promise<string>;
+};
 export declare class LocalWrapperProvider implements WrapperProvider {
     private readonly filesystemReader;
     private readonly runtimePath;
     constructor(filesystemReader: FileSystemReader, runtimePath: string);
@@ -30,8 +36,9 @@
     private wrapper;
     private loader;
     protected cdnUrl: string;
     constructor(statsigService: StatsigService);
+    protected getFromNodeRequest: (url: string) => Promise<RuntimeFetchResponse>;
     private getScriptPathFromIndex;
     private getFileFromCDN;
     getNodeRuntimeWrapper(): Promise<RuntimeScript>;
     getNodeRuntimeLoader(): Promise<RuntimeScript | undefined>;
@@ -39,5 +46,6 @@
 export declare const getWrapperProvider: ({ fileSystemReader, statsigService }: {
     fileSystemReader: FileSystemReader;
     statsigService: StatsigService;
 }) => LocalWrapperProvider | NetworkWrapperProvider;
+export {};
 //# sourceMappingURL=wrapper-provider.d.ts.map
\ No newline at end of file