Skip to content

Commit 9a2a436

Browse files
committed
Merge branch 'main' of https://github.com/Expensify/App into ikevin127-proposalPoliceDupe
2 parents d3f914b + 8b943bb commit 9a2a436

553 files changed

Lines changed: 15346 additions & 7512 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ module.exports = {
230230
'rulesdir/no-multiple-onyx-in-file': 'off',
231231
'rulesdir/prefer-underscore-method': 'off',
232232
'rulesdir/prefer-import-module-contents': 'off',
233+
'rulesdir/no-beta-handler': 'error',
233234

234235
// React and React Native specific rules
235236
'react-native-a11y/has-accessibility-hint': ['off'],
@@ -276,6 +277,14 @@ module.exports = {
276277
property: 'isHybridApp',
277278
message: 'Use CONFIG.IS_HYBRID_APP instead.',
278279
},
280+
// Prevent direct use of HybridAppModule.closeReactNativeApp().
281+
// Instead, use the `closeReactNativeApp` action from `@userActions/HybridApp`,
282+
// which correctly updates `hybridApp.closingReactNativeApp` when closing NewDot
283+
{
284+
object: 'HybridAppModule',
285+
property: 'closeReactNativeApp',
286+
message: 'Use `closeReactNativeApp` from `@userActions/HybridApp` instead.',
287+
},
279288
],
280289
'no-restricted-imports': [
281290
'error',

.github/.eslintrc.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ module.exports = {
77
'no-await-in-loop': 'off',
88
'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
99
'no-continue': 'off',
10-
'no-restricted-imports': 'off',
10+
'no-restricted-imports': [
11+
'error',
12+
{
13+
patterns: [
14+
{
15+
group: ['@src/**'],
16+
message: 'Do not import files from src/ directory as they can break the GH Actions build script.',
17+
},
18+
],
19+
},
20+
],
1121
},
1222
};

.github/actions/javascript/authorChecklist/index.js

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15545,8 +15545,8 @@ exports["default"] = newComponentCategory;
1554515545
Object.defineProperty(exports, "__esModule", ({ value: true }));
1554615546
const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)');
1554715547
const GIT_CONST = {
15548-
GITHUB_OWNER: process.env.GITHUB_REPOSITORY_OWNER,
15549-
APP_REPO: process.env.GITHUB_REPOSITORY.split('/').at(1) ?? '',
15548+
GITHUB_OWNER: process.env.GITHUB_REPOSITORY_OWNER ?? 'Expensify',
15549+
APP_REPO: (process.env.GITHUB_REPOSITORY ?? 'Expensify/App').split('/').at(1) ?? '',
1555015550
MOBILE_EXPENSIFY_REPO: 'Mobile-Expensify',
1555115551
};
1555215552
const CONST = {
@@ -15630,9 +15630,9 @@ const utils_1 = __nccwpck_require__(3030);
1563015630
const plugin_paginate_rest_1 = __nccwpck_require__(4193);
1563115631
const plugin_throttling_1 = __nccwpck_require__(9968);
1563215632
const request_error_1 = __nccwpck_require__(537);
15633-
const EmptyObject_1 = __nccwpck_require__(8227);
15634-
const arrayDifference_1 = __importDefault(__nccwpck_require__(7034));
15633+
const arrayDifference_1 = __importDefault(__nccwpck_require__(7532));
1563515634
const CONST_1 = __importDefault(__nccwpck_require__(9873));
15635+
const isEmptyObject_1 = __nccwpck_require__(6497);
1563615636
class GithubUtils {
1563715637
static internalOctokit;
1563815638
/**
@@ -15823,7 +15823,7 @@ class GithubUtils {
1582315823
static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isFirebaseChecked = false, isGHStatusChecked = false) {
1582415824
return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr)))
1582515825
.then((data) => {
15826-
const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : [];
15826+
const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, isEmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : [];
1582715827
return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => {
1582815828
// The format of this map is following:
1582915829
// {
@@ -15853,7 +15853,7 @@ class GithubUtils {
1585315853
issueBody += '\r\n\r\n';
1585415854
}
1585515855
// Internal QA PR list
15856-
if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) {
15856+
if (!(0, isEmptyObject_1.isEmptyObject)(internalQAPRMap)) {
1585715857
console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs);
1585815858
issueBody += '**Internal QA:**\r\n';
1585915859
Object.keys(internalQAPRMap).forEach((URL) => {
@@ -16061,6 +16061,24 @@ class GithubUtils {
1606116061
})
1606216062
.then((response) => response.url);
1606316063
}
16064+
/**
16065+
* Get the contents of a file from the API at a given ref as a string.
16066+
*/
16067+
static async getFileContents(path, ref = 'main') {
16068+
const { data } = await this.octokit.repos.getContent({
16069+
owner: CONST_1.default.GITHUB_OWNER,
16070+
repo: CONST_1.default.APP_REPO,
16071+
path,
16072+
ref,
16073+
});
16074+
if (Array.isArray(data)) {
16075+
throw new Error(`Provided path ${path} refers to a directory, not a file`);
16076+
}
16077+
if (!('content' in data)) {
16078+
throw new Error(`Provided path ${path} is invalid`);
16079+
}
16080+
return Buffer.from(data.content, 'base64').toString('utf8');
16081+
}
1606416082
/**
1606516083
* Get commits between two tags via the GitHub API
1606616084
*/
@@ -16125,38 +16143,25 @@ exports["default"] = GithubUtils;
1612516143

1612616144
/***/ }),
1612716145

16128-
/***/ 8534:
16146+
/***/ 7532:
1612916147
/***/ ((__unused_webpack_module, exports) => {
1613016148

1613116149
"use strict";
1613216150

1613316151
Object.defineProperty(exports, "__esModule", ({ value: true }));
1613416152
/**
16135-
* Like _.some but for promises. It short-circuts after a promise fulfills with a value that passes the test implemented by provided function.
16136-
* It does not wait for the other promises to complete once it finds one.
16137-
* If no promise passes the provided test, it rejects.
16153+
* This function is an equivalent of _.difference, it takes two arrays and returns the difference between them.
16154+
* It returns an array of items that are in the first array but not in the second array.
1613816155
*/
16139-
function promiseSome(promises, callbackFn) {
16140-
return new Promise((resolve, reject) => {
16141-
for (const p of promises) {
16142-
Promise.resolve(p)
16143-
.then((res) => {
16144-
if (!callbackFn(res)) {
16145-
return;
16146-
}
16147-
resolve(true);
16148-
})
16149-
.catch(() => { });
16150-
}
16151-
Promise.allSettled(promises).then(() => reject());
16152-
});
16156+
function arrayDifference(array1, array2) {
16157+
return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c)));
1615316158
}
16154-
exports["default"] = promiseSome;
16159+
exports["default"] = arrayDifference;
1615516160

1615616161

1615716162
/***/ }),
1615816163

16159-
/***/ 8227:
16164+
/***/ 6497:
1616016165
/***/ ((__unused_webpack_module, exports) => {
1616116166

1616216167
"use strict";
@@ -16171,20 +16176,33 @@ exports.isEmptyObject = isEmptyObject;
1617116176

1617216177
/***/ }),
1617316178

16174-
/***/ 7034:
16179+
/***/ 8534:
1617516180
/***/ ((__unused_webpack_module, exports) => {
1617616181

1617716182
"use strict";
1617816183

1617916184
Object.defineProperty(exports, "__esModule", ({ value: true }));
1618016185
/**
16181-
* This function is an equivalent of _.difference, it takes two arrays and returns the difference between them.
16182-
* It returns an array of items that are in the first array but not in the second array.
16186+
* Like _.some but for promises. It short-circuts after a promise fulfills with a value that passes the test implemented by provided function.
16187+
* It does not wait for the other promises to complete once it finds one.
16188+
* If no promise passes the provided test, it rejects.
1618316189
*/
16184-
function arrayDifference(array1, array2) {
16185-
return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c)));
16190+
function promiseSome(promises, callbackFn) {
16191+
return new Promise((resolve, reject) => {
16192+
for (const p of promises) {
16193+
Promise.resolve(p)
16194+
.then((res) => {
16195+
if (!callbackFn(res)) {
16196+
return;
16197+
}
16198+
resolve(true);
16199+
})
16200+
.catch(() => { });
16201+
}
16202+
Promise.allSettled(promises).then(() => reject());
16203+
});
1618616204
}
16187-
exports["default"] = arrayDifference;
16205+
exports["default"] = promiseSome;
1618816206

1618916207

1619016208
/***/ }),

.github/actions/javascript/awaitStagingDeploys/index.js

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12336,8 +12336,8 @@ exports.convertToNumber = convertToNumber;
1233612336
Object.defineProperty(exports, "__esModule", ({ value: true }));
1233712337
const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)');
1233812338
const GIT_CONST = {
12339-
GITHUB_OWNER: process.env.GITHUB_REPOSITORY_OWNER,
12340-
APP_REPO: process.env.GITHUB_REPOSITORY.split('/').at(1) ?? '',
12339+
GITHUB_OWNER: process.env.GITHUB_REPOSITORY_OWNER ?? 'Expensify',
12340+
APP_REPO: (process.env.GITHUB_REPOSITORY ?? 'Expensify/App').split('/').at(1) ?? '',
1234112341
MOBILE_EXPENSIFY_REPO: 'Mobile-Expensify',
1234212342
};
1234312343
const CONST = {
@@ -12421,9 +12421,9 @@ const utils_1 = __nccwpck_require__(3030);
1242112421
const plugin_paginate_rest_1 = __nccwpck_require__(4193);
1242212422
const plugin_throttling_1 = __nccwpck_require__(9968);
1242312423
const request_error_1 = __nccwpck_require__(537);
12424-
const EmptyObject_1 = __nccwpck_require__(8227);
12425-
const arrayDifference_1 = __importDefault(__nccwpck_require__(7034));
12424+
const arrayDifference_1 = __importDefault(__nccwpck_require__(7532));
1242612425
const CONST_1 = __importDefault(__nccwpck_require__(9873));
12426+
const isEmptyObject_1 = __nccwpck_require__(6497);
1242712427
class GithubUtils {
1242812428
static internalOctokit;
1242912429
/**
@@ -12614,7 +12614,7 @@ class GithubUtils {
1261412614
static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isFirebaseChecked = false, isGHStatusChecked = false) {
1261512615
return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr)))
1261612616
.then((data) => {
12617-
const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : [];
12617+
const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, isEmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : [];
1261812618
return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => {
1261912619
// The format of this map is following:
1262012620
// {
@@ -12644,7 +12644,7 @@ class GithubUtils {
1264412644
issueBody += '\r\n\r\n';
1264512645
}
1264612646
// Internal QA PR list
12647-
if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) {
12647+
if (!(0, isEmptyObject_1.isEmptyObject)(internalQAPRMap)) {
1264812648
console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs);
1264912649
issueBody += '**Internal QA:**\r\n';
1265012650
Object.keys(internalQAPRMap).forEach((URL) => {
@@ -12852,6 +12852,24 @@ class GithubUtils {
1285212852
})
1285312853
.then((response) => response.url);
1285412854
}
12855+
/**
12856+
* Get the contents of a file from the API at a given ref as a string.
12857+
*/
12858+
static async getFileContents(path, ref = 'main') {
12859+
const { data } = await this.octokit.repos.getContent({
12860+
owner: CONST_1.default.GITHUB_OWNER,
12861+
repo: CONST_1.default.APP_REPO,
12862+
path,
12863+
ref,
12864+
});
12865+
if (Array.isArray(data)) {
12866+
throw new Error(`Provided path ${path} refers to a directory, not a file`);
12867+
}
12868+
if (!('content' in data)) {
12869+
throw new Error(`Provided path ${path} is invalid`);
12870+
}
12871+
return Buffer.from(data.content, 'base64').toString('utf8');
12872+
}
1285512873
/**
1285612874
* Get commits between two tags via the GitHub API
1285712875
*/
@@ -12914,6 +12932,39 @@ class GithubUtils {
1291412932
exports["default"] = GithubUtils;
1291512933

1291612934

12935+
/***/ }),
12936+
12937+
/***/ 7532:
12938+
/***/ ((__unused_webpack_module, exports) => {
12939+
12940+
"use strict";
12941+
12942+
Object.defineProperty(exports, "__esModule", ({ value: true }));
12943+
/**
12944+
* This function is an equivalent of _.difference, it takes two arrays and returns the difference between them.
12945+
* It returns an array of items that are in the first array but not in the second array.
12946+
*/
12947+
function arrayDifference(array1, array2) {
12948+
return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c)));
12949+
}
12950+
exports["default"] = arrayDifference;
12951+
12952+
12953+
/***/ }),
12954+
12955+
/***/ 6497:
12956+
/***/ ((__unused_webpack_module, exports) => {
12957+
12958+
"use strict";
12959+
12960+
Object.defineProperty(exports, "__esModule", ({ value: true }));
12961+
exports.isEmptyObject = void 0;
12962+
function isEmptyObject(obj) {
12963+
return Object.keys(obj ?? {}).length === 0;
12964+
}
12965+
exports.isEmptyObject = isEmptyObject;
12966+
12967+
1291712968
/***/ }),
1291812969

1291912970
/***/ 9438:
@@ -12969,39 +13020,6 @@ function promiseDoWhile(condition, action) {
1296913020
exports.promiseDoWhile = promiseDoWhile;
1297013021

1297113022

12972-
/***/ }),
12973-
12974-
/***/ 8227:
12975-
/***/ ((__unused_webpack_module, exports) => {
12976-
12977-
"use strict";
12978-
12979-
Object.defineProperty(exports, "__esModule", ({ value: true }));
12980-
exports.isEmptyObject = void 0;
12981-
function isEmptyObject(obj) {
12982-
return Object.keys(obj ?? {}).length === 0;
12983-
}
12984-
exports.isEmptyObject = isEmptyObject;
12985-
12986-
12987-
/***/ }),
12988-
12989-
/***/ 7034:
12990-
/***/ ((__unused_webpack_module, exports) => {
12991-
12992-
"use strict";
12993-
12994-
Object.defineProperty(exports, "__esModule", ({ value: true }));
12995-
/**
12996-
* This function is an equivalent of _.difference, it takes two arrays and returns the difference between them.
12997-
* It returns an array of items that are in the first array but not in the second array.
12998-
*/
12999-
function arrayDifference(array1, array2) {
13000-
return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c)));
13001-
}
13002-
exports["default"] = arrayDifference;
13003-
13004-
1300513023
/***/ }),
1300613024

1300713025
/***/ 9491:

0 commit comments

Comments
 (0)