Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2f5f8b3
Extract MoneyRequestReportEmptyStateView
sosek108 Sep 1, 2026
7bdea6f
Extract useMoneyRequestReportVisibleActions and adapt useMarkAsRead/u…
sosek108 Sep 1, 2026
d66bf4b
Extract useMoneyRequestReportPagination
sosek108 Sep 1, 2026
186db33
Extract useMoneyRequestReportScroll
sosek108 Sep 1, 2026
b752f34
Extract useMoneyRequestReportData
sosek108 Sep 1, 2026
ab54318
Extract MoneyRequestReportTransactionList presentational components
sosek108 Sep 1, 2026
37c6c57
Extract useMoneyRequestReportColumns and useMoneyRequestReportLayout
sosek108 Sep 1, 2026
dcbcf30
Extract the transaction data derivation chain
sosek108 Sep 1, 2026
8b435dc
Merge remote-tracking branch 'exfy/main' into decompose/money-request…
sosek108 Sep 8, 2026
35a4a88
Merge branch 'decompose/money-request-report-transactions-a1' into de…
sosek108 Sep 8, 2026
5afaa14
Merge branch 'decompose/money-request-report-transactions-a2' into de…
sosek108 Sep 8, 2026
7f9c555
Merge branch 'decompose/money-request-report-transactions-a3' into de…
sosek108 Sep 8, 2026
91bb3fe
Merge branch 'decompose/money-request-report-transactions-a4' into de…
sosek108 Sep 8, 2026
062a413
Drop unused guidedSetupAndTourStatusSelector import
sosek108 Sep 8, 2026
54f5231
Merge branch 'decompose/money-request-report-transactions-a4' into de…
sosek108 Sep 8, 2026
88ee30e
Merge branch 'decompose/money-request-report-transactions-a5' into de…
sosek108 Sep 8, 2026
ab78d66
Merge branch 'decompose/money-request-report-transactions-b1' into de…
sosek108 Sep 8, 2026
05637e5
Merge branch 'decompose/money-request-report-transactions-b2' into de…
sosek108 Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 5 additions & 250 deletions .github/actions/javascript/isDeployChecklistLocked/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3431,9 +3431,7 @@ var require_CONST = __commonJS({
REGISTER_AUTHENTICATION_KEY: "register_authentication_key",
REPLACE_CARD: "replace_card",
SHIP_CARD: "ship_card",
REPORT_CARD_FRAUD: "report_card_fraud",
ISSUE_CARD: "issue_card",
UPDATE_CARD: "update_card"
REPORT_CARD_FRAUD: "report_card_fraud"
},
EXPENSIFY_CARD: {
FEED_NAME: "Expensify Card",
Expand Down Expand Up @@ -23110,22 +23108,9 @@ var require_ExpensiMark = __commonJS({
var Logger_1 = __importDefault(require_Logger());
var Utils = __importStar(require_utils());
var EXTRAS_DEFAULT = {};
var ASCII_DIGIT_START = "0".charCodeAt(0);
var ASCII_DIGIT_END = "9".charCodeAt(0);
var ASCII_UPPERCASE_START = "A".charCodeAt(0);
var ASCII_UPPERCASE_END = "Z".charCodeAt(0);
var ASCII_LOWERCASE_START = "a".charCodeAt(0);
var ASCII_LOWERCASE_END = "z".charCodeAt(0);
var ASCII_WHITESPACE_END = " ".charCodeAt(0);
var NON_BREAKING_SPACE_CODE = 160;
var URL_PROTOCOLS = ["https://", "http://", "ftps://", "ftp://"];
var URL_CANDIDATE_PREFIX_CHARACTERS = "@_*~";
var PROTECTED_TAG_NAMES = /* @__PURE__ */ new Set(["a", "code", "pre", "video"]);
var MARKDOWN_LINK_REGEX = new RegExp(`\\[((?:[^\\[\\]\\r\\n]*(?:\\[[^\\[\\]\\r\\n]*][^\\[\\]\\r\\n]*)*))]\\(${UrlPatterns.MARKDOWN_URL_REGEX}\\)(?![^<]*(<\\/pre>|<\\/code>))`, "gi");
var MARKDOWN_IMAGE_REGEX = new RegExp(`\\!(?:\\[([^\\][]*(?:\\[[^\\][]*][^\\][]*)*)])?\\(${UrlPatterns.MARKDOWN_URL_REGEX}\\)(?![^<]*(<\\/pre>|<\\/code>))`, "gi");
var MARKDOWN_VIDEO_REGEX = new RegExp(`\\!(?:\\[([^\\][]*(?:\\[[^\\][]*][^\\][]*)*)])?\\(((${UrlPatterns.MARKDOWN_URL_REGEX})\\.(?:${Constants.CONST.VIDEO_EXTENSIONS.join("|")}))\\)(?![^<]*(<\\/pre>|<\\/code>))`, "gi");
var BOLD_MARKDOWN_REGEX = /(?<!<[^>]*)(\b_|\B)\*(?!(?:<\/em))(?![^<]*(?:<\/pre>|<\/code>|<\/a>|<\/video>))((?![\s*])[\s\S]*?[^\s*](?<!\s))\*\B(?![^<]*>)(?![^<]*(<\/pre>|<\/code>|<\/a>|<\/video>))/g;
var STRIKETHROUGH_MARKDOWN_REGEX = /(?<!<[^>]*)\B~((?![\s~])[\s\S]*?[^\s~](?<!\s))~\B(?![^<]*>)(?![^<]*(<\/pre>|<\/code>|<\/a>|<\/video>))/g;
var SLACK_SPAN_NEW_LINE_TAG = '<span class="c-mrkdwn__br" data-stringify-type="paragraph-break" style="box-sizing: inherit; display: block; height: unset;"></span>';
var VICTORY_CHART_REGEX = /<VictoryChart\b[^>]*\/>|<VictoryChart\b[^>]*>[\s\S]*?<\/VictoryChart>/gi;
var VICTORY_CHART_PLACEHOLDER_DELIMITER = String.fromCharCode(0);
Expand Down Expand Up @@ -23165,218 +23150,6 @@ var require_ExpensiMark = __commonJS({
}
return text.replace(regexp, replacement);
}
function isAsciiAlphaNumeric(character) {
if (!character) {
return false;
}
const code = character.charCodeAt(0);
return code >= ASCII_DIGIT_START && code <= ASCII_DIGIT_END || code >= ASCII_UPPERCASE_START && code <= ASCII_UPPERCASE_END || code >= ASCII_LOWERCASE_START && code <= ASCII_LOWERCASE_END;
}
function isWordCharacter(character) {
return character === "_" || isAsciiAlphaNumeric(character);
}
function canOpenBoldMarkdown(text, position, isProtected) {
if (isProtected) {
return false;
}
const nextCharacter = text[position + 1];
if (!nextCharacter || /\s|\*/.test(nextCharacter) || text.startsWith("</em", position + 1)) {
return false;
}
const previousCharacter = text[position - 1];
if (!isWordCharacter(previousCharacter)) {
return true;
}
return previousCharacter === "_" && !isWordCharacter(text[position - 2]);
}
function canOpenStrikethroughMarkdown(text, position) {
if (isWordCharacter(text[position - 1])) {
return false;
}
const nextCharacter = text[position + 1];
return !!nextCharacter && !/\s|~/.test(nextCharacter);
}
function canCloseMarkdown(text, position, marker) {
const previousCharacter = text[position - 1];
return !!previousCharacter && !/\s/.test(previousCharacter) && previousCharacter !== marker && !isWordCharacter(text[position + 1]);
}
function updateProtectedTagStack(text, tagStart, protectedTags) {
var _a, _b;
const tagEnd = text.indexOf(">", tagStart + 1);
if (tagEnd === -1) {
return void 0;
}
const tag = text.slice(tagStart + 1, tagEnd).trim();
const isClosingTag = tag.startsWith("/");
const tagName = (_b = (_a = tag.match(/^\/?\s*([a-z][a-z0-9-]*)/i)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
if (tagName && PROTECTED_TAG_NAMES.has(tagName)) {
if (isClosingTag) {
const matchingTagIndex = protectedTags.lastIndexOf(tagName);
if (matchingTagIndex !== -1) {
protectedTags.splice(matchingTagIndex, 1);
}
} else if (!tag.endsWith("/")) {
protectedTags.push(tagName);
}
}
return tagEnd + 1;
}
function isHostnameCharacter(character) {
return !!character && (isAsciiAlphaNumeric(character) || character === "-" || character === ".");
}
function isUrlBoundarySpace(character) {
const code = character.charCodeAt(0);
return code <= ASCII_WHITESPACE_END || code === NON_BREAKING_SPACE_CODE;
}
function getProtocolAt(text, position) {
var _a;
const firstCharacter = (_a = text[position]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
if (firstCharacter !== "h" && firstCharacter !== "f") {
return void 0;
}
return URL_PROTOCOLS.find((protocol) => text.slice(position, position + protocol.length).toLowerCase() === protocol);
}
function findHostnameEnd(text, hostnameStart, dotPosition) {
let hostnameEnd = dotPosition + 1;
while (hostnameEnd < text.length && (isAsciiAlphaNumeric(text[hostnameEnd]) || text[hostnameEnd] === "-")) {
hostnameEnd++;
}
if (hostnameStart === dotPosition || hostnameEnd === dotPosition + 1) {
return void 0;
}
return hostnameEnd;
}
function extendUrlCandidateBoundaries(text, start, end) {
let candidateStart = start;
while (candidateStart > 0 && URL_CANDIDATE_PREFIX_CHARACTERS.includes(text[candidateStart - 1])) {
candidateStart--;
}
let candidateEnd = end;
while (candidateEnd < text.length && !isUrlBoundarySpace(text[candidateEnd]) && text[candidateEnd] !== "<") {
candidateEnd++;
}
return { start: candidateStart, end: candidateEnd };
}
function findUrlCandidates(text) {
const candidates = [];
const protectedTags = [];
let index = 0;
let hostnameRunStart = 0;
while (index < text.length) {
if (text[index] === "<") {
const nextIndex = updateProtectedTagStack(text, index, protectedTags);
if (nextIndex === void 0) {
break;
}
index = nextIndex;
hostnameRunStart = index;
continue;
}
if (protectedTags.length > 0) {
index++;
hostnameRunStart = index;
continue;
}
const matchedProtocol = getProtocolAt(text, index);
if (matchedProtocol) {
const candidate2 = extendUrlCandidateBoundaries(text, index, index + matchedProtocol.length);
candidates.push(candidate2);
index = candidate2.end;
hostnameRunStart = candidate2.end;
continue;
}
if (!isHostnameCharacter(text[index])) {
hostnameRunStart = index + 1;
index++;
continue;
}
if (text[index] !== ".") {
index++;
continue;
}
const hostnameEnd = findHostnameEnd(text, hostnameRunStart, index);
if (hostnameEnd === void 0) {
index++;
continue;
}
const candidate = extendUrlCandidateBoundaries(text, hostnameRunStart, hostnameEnd);
candidates.push(candidate);
index = candidate.end;
hostnameRunStart = candidate.end;
}
return candidates;
}
function replaceMarkdownCandidates(text, regexp, replacement, marker, canOpen) {
if (!text.includes(marker)) {
return text;
}
const markers = [];
const protectedTags = [];
let index = 0;
while (index < text.length) {
if (text[index] === "<") {
const nextIndex = updateProtectedTagStack(text, index, protectedTags);
if (nextIndex === void 0) {
break;
}
index = nextIndex;
continue;
}
if (text[index] === marker) {
markers.push({ position: index, isProtected: protectedTags.length > 0 });
}
index++;
}
if (markers.length < 2) {
return text;
}
const output = [];
const candidateRegex = regexp;
let outputStart = 0;
let openingMarker;
for (const currentMarker of markers) {
const markerPosition = currentMarker.position;
if (openingMarker === void 0) {
openingMarker = canOpen(text, markerPosition, currentMarker.isProtected) ? currentMarker : void 0;
continue;
}
if (currentMarker.isProtected || !canCloseMarkdown(text, markerPosition, marker)) {
continue;
}
if (openingMarker.isProtected) {
openingMarker = void 0;
continue;
}
const openingPosition = openingMarker.position;
const prefixLength = openingPosition > 0 ? 1 : 0;
const suffixLength = markerPosition + 1 < text.length ? 1 : 0;
const candidateStart = openingPosition - prefixLength;
const candidateEnd = markerPosition + 1 + suffixLength;
const candidate = text.slice(candidateStart, candidateEnd);
candidateRegex.lastIndex = 0;
const candidateMatch = candidateRegex.exec(candidate);
if (!candidateMatch) {
openingMarker = canOpen(text, markerPosition, currentMarker.isProtected) ? currentMarker : void 0;
continue;
}
candidateRegex.lastIndex = 0;
const replacedCandidate = replaceTextWithExtras(candidate, candidateRegex, EXTRAS_DEFAULT, replacement);
if (replacedCandidate !== candidate) {
const replacedCoreEnd = suffixLength ? replacedCandidate.length - suffixLength : replacedCandidate.length;
output.push(text.slice(outputStart, openingPosition));
output.push(replacedCandidate.slice(prefixLength, replacedCoreEnd));
outputStart = markerPosition + 1;
openingMarker = void 0;
continue;
}
openingMarker = void 0;
}
if (output.length === 0) {
return text;
}
output.push(text.slice(outputStart));
return output.join("");
}
function replaceBlockElementWithNewLine(htmlString) {
let splitText = htmlString.replaceAll(/<blockquote>> (<div.*?>|<\/div>|<comment.*?>|\n<\/comment>|<\/comment>|<h1>|<\/h1>|<h2>|<\/h2>|<h3>|<\/h3>|<h4>|<\/h4>|<h5>|<\/h5>|<h6>|<\/h6>|<p>|<\/p>|<li>|<\/li>)/gi, "<blockquote>> ").split(/<div.*?>|<\/div>|<comment.*?>|\n<\/comment>|<\/comment>|<h1>|<\/h1>|<h2>|<\/h2>|<h3>|<\/h3>|<h4>|<\/h4>|<h5>|<\/h5>|<h6>|<\/h6>|<p>|<\/p>|<li>|<\/li>|<blockquote>|<\/blockquote>/);
const stripHTML = (text) => str_1.default.stripHTML(text);
Expand Down Expand Up @@ -23797,7 +23570,7 @@ var require_ExpensiMark = __commonJS({
name: "autolink",
process: (textToProcess, replacement) => {
const regex2 = new RegExp(`(?![^<]*>|[^<>]*<\\/(?!h1>))([_*~]*?)${UrlPatterns.MARKDOWN_URL_REGEX}\\1(?!((?:(?!<a).)+)?<\\/a>|[^<]*(<\\/pre>|<\\/code>))`, "gi");
return this.modifyTextForUrlLinks(regex2, textToProcess, replacement, true);
return this.modifyTextForUrlLinks(regex2, textToProcess, replacement);
},
replacement: (_extras, _match, g1, g2) => {
const href = str_1.default.sanitizeURL(g2);
Expand Down Expand Up @@ -23902,7 +23675,7 @@ ${"<blockquote>".repeat(i)}`, "\n");
// \B will match everything that \b doesn't, so it works
// for * and ~: https://www.rexegg.com/regex-boundaries.html#notb
name: "bold",
process: (textToProcess, replacement) => replaceMarkdownCandidates(textToProcess, BOLD_MARKDOWN_REGEX, replacement, "*", canOpenBoldMarkdown),
regex: /(?<!<[^>]*)(\b_|\B)\*(?!(?:<\/em))(?![^<]*(?:<\/pre>|<\/code>|<\/a>|<\/video>))((?![\s*])[\s\S]*?[^\s*](?<!\s))\*\B(?![^<]*>)(?![^<]*(<\/pre>|<\/code>|<\/a>|<\/video>))/g,
replacement: (_extras, match, g1, g2) => {
if (g1.includes("_")) {
return `${g1}<strong>${g2}</strong>`;
Expand All @@ -23912,7 +23685,7 @@ ${"<blockquote>".repeat(i)}`, "\n");
},
{
name: "strikethrough",
process: (textToProcess, replacement) => replaceMarkdownCandidates(textToProcess, STRIKETHROUGH_MARKDOWN_REGEX, replacement, "~", canOpenStrikethroughMarkdown),
regex: /(?<!<[^>]*)\B~((?![\s~])[\s\S]*?[^\s~](?<!\s))~\B(?![^<]*>)(?![^<]*(<\/pre>|<\/code>|<\/a>|<\/video>))/g,
replacement: (_extras, match, g1) => g1.includes("</pre>") || containsNonPairTag(g1) ? match : `<del>${g1}</del>`
},
{
Expand Down Expand Up @@ -24302,25 +24075,7 @@ ${g2}
/**
* Checks matched URLs for validity and replace valid links with html elements
*/
modifyTextForUrlLinks(regex2, textToCheck, replacement, shouldScanForUrls = false) {
if (shouldScanForUrls) {
const candidates = findUrlCandidates(textToCheck);
if (candidates.length === 0) {
return textToCheck;
}
const output = [];
const candidateRegex = regex2;
let outputStart = 0;
for (const { start, end } of candidates) {
const candidate = textToCheck.slice(start, end);
candidateRegex.lastIndex = 0;
output.push(textToCheck.slice(outputStart, start));
output.push(this.modifyTextForUrlLinks(candidateRegex, candidate, replacement));
outputStart = end;
}
output.push(textToCheck.slice(outputStart));
return output.join("");
}
modifyTextForUrlLinks(regex2, textToCheck, replacement) {
let match = regex2.exec(textToCheck);
let replacedText = "";
let startIndex = 0;
Expand Down
Loading
Loading