paperclip-github-plugin 0.4.1 → 0.4.2
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.
- package/README.md +14 -16
- package/dist/manifest.js +4 -4
- package/dist/ui/index.js +34 -104
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +405 -179
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -630,11 +630,13 @@ var COMMENT_ANNOTATION_ENTITY_TYPE = "paperclip-github-plugin.comment-annotation
|
|
|
630
630
|
var AI_AUTHORED_COMMENT_FOOTER_PREFIX = "Created by a Paperclip AI agent using ";
|
|
631
631
|
var HIDDEN_GITHUB_IMPORT_MARKER_PREFIX = "<!-- paperclip-github-plugin-imported-from: ";
|
|
632
632
|
var HIDDEN_GITHUB_IMPORT_MARKER_SUFFIX = " -->";
|
|
633
|
+
var EMPTY_GITHUB_ISSUE_DESCRIPTION_PLACEHOLDER = "_No description provided on GitHub._";
|
|
633
634
|
function normalizeCompanyId(value) {
|
|
634
635
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
635
636
|
}
|
|
636
637
|
var activeSyncPromise = null;
|
|
637
638
|
var activeRunningSyncState = null;
|
|
639
|
+
var activeRunningSyncCompanyId;
|
|
638
640
|
var activePaperclipApiAuthTokensByCompanyId = null;
|
|
639
641
|
var activeExternalConfigWarningKey = null;
|
|
640
642
|
var activeProjectPullRequestPageCache = /* @__PURE__ */ new Map();
|
|
@@ -710,6 +712,7 @@ var FAILED_STATUS_CONTEXT_STATES = /* @__PURE__ */ new Set(["ERROR", "FAILURE"])
|
|
|
710
712
|
var PENDING_STATUS_CONTEXT_STATES = /* @__PURE__ */ new Set(["EXPECTED", "PENDING"]);
|
|
711
713
|
var GITHUB_REPOSITORY_MAINTAINER_WARMUP_CONCURRENCY = 4;
|
|
712
714
|
var GITHUB_REPOSITORY_MAINTAINER_ROLE_NAMES = /* @__PURE__ */ new Set(["admin", "maintain"]);
|
|
715
|
+
var GITHUB_REPOSITORY_TRUSTED_AUTHOR_ASSOCIATIONS = /* @__PURE__ */ new Set(["collaborator", "member", "owner"]);
|
|
713
716
|
var GITHUB_ISSUE_STATUS_SNAPSHOT_QUERY = `
|
|
714
717
|
query GitHubIssueStatusSnapshot($owner: String!, $repo: String!, $issueNumber: Int!, $after: String) {
|
|
715
718
|
repository(owner: $owner, name: $repo) {
|
|
@@ -1613,6 +1616,20 @@ function normalizeGitHubUserLogin(value) {
|
|
|
1613
1616
|
function normalizeGitHubTokenRef(value) {
|
|
1614
1617
|
return normalizeSecretRef(value);
|
|
1615
1618
|
}
|
|
1619
|
+
function normalizeGitHubTokenRefs(value) {
|
|
1620
|
+
if (!value || typeof value !== "object") {
|
|
1621
|
+
return void 0;
|
|
1622
|
+
}
|
|
1623
|
+
const entries = Object.entries(value).map(([companyId, secretRef]) => {
|
|
1624
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
1625
|
+
const normalizedSecretRef = normalizeGitHubTokenRef(secretRef);
|
|
1626
|
+
return normalizedCompanyId && normalizedSecretRef ? [normalizedCompanyId, normalizedSecretRef] : null;
|
|
1627
|
+
}).filter((entry) => entry !== null);
|
|
1628
|
+
if (entries.length === 0) {
|
|
1629
|
+
return void 0;
|
|
1630
|
+
}
|
|
1631
|
+
return Object.fromEntries(entries);
|
|
1632
|
+
}
|
|
1616
1633
|
function formatUtcTimestamp(value) {
|
|
1617
1634
|
const parsed = new Date(value);
|
|
1618
1635
|
if (Number.isNaN(parsed.getTime())) {
|
|
@@ -2410,9 +2427,9 @@ function extractGitHubLinksFromCommentBody(body) {
|
|
|
2410
2427
|
return [...links.values()];
|
|
2411
2428
|
}
|
|
2412
2429
|
async function buildToolbarSyncState(ctx, input) {
|
|
2413
|
-
const settings = await getActiveOrCurrentSyncState(ctx);
|
|
2414
|
-
const config = await getResolvedConfig(ctx);
|
|
2415
2430
|
const companyId = typeof input.companyId === "string" && input.companyId.trim() ? input.companyId.trim() : void 0;
|
|
2431
|
+
const settings = await getActiveOrCurrentSyncState(ctx, companyId);
|
|
2432
|
+
const config = await getResolvedConfig(ctx);
|
|
2416
2433
|
const githubTokenConfigured = hasConfiguredGithubToken(settings, config, companyId);
|
|
2417
2434
|
const entityId = typeof input.entityId === "string" && input.entityId.trim() ? input.entityId.trim() : void 0;
|
|
2418
2435
|
const entityType = typeof input.entityType === "string" && input.entityType.trim() ? input.entityType.trim() : void 0;
|
|
@@ -2454,7 +2471,7 @@ async function buildToolbarSyncState(ctx, input) {
|
|
|
2454
2471
|
}) : [];
|
|
2455
2472
|
return {
|
|
2456
2473
|
kind: "issue",
|
|
2457
|
-
visible:
|
|
2474
|
+
visible: false,
|
|
2458
2475
|
canRun: githubTokenConfigured && mappings.length > 0,
|
|
2459
2476
|
label: link?.githubIssueNumber ? `Sync #${link.githubIssueNumber}` : "Sync issue",
|
|
2460
2477
|
message: link ? `Sync ${link.repositoryUrl.replace(/^https:\/\/github\.com\//, "")} issue #${link.githubIssueNumber}.` : "This Paperclip issue is not linked to GitHub yet.",
|
|
@@ -2626,15 +2643,25 @@ function sanitizeSettingsForCurrentSetup(settings, setup) {
|
|
|
2626
2643
|
function getPublicSettings(settings) {
|
|
2627
2644
|
const {
|
|
2628
2645
|
githubTokenRefs: _githubTokenRefs,
|
|
2629
|
-
|
|
2646
|
+
githubTokenLoginByCompanyId: _githubTokenLoginByCompanyId,
|
|
2630
2647
|
githubTokenRef: _githubTokenRef,
|
|
2631
2648
|
paperclipBoardApiTokenRefs: _paperclipBoardApiTokenRefs,
|
|
2632
2649
|
paperclipBoardAccessIdentityByCompanyId: _paperclipBoardAccessIdentityByCompanyId,
|
|
2633
2650
|
companyAdvancedSettingsByCompanyId: _companyAdvancedSettingsByCompanyId,
|
|
2651
|
+
syncStateByCompanyId: _syncStateByCompanyId,
|
|
2652
|
+
scheduleFrequencyMinutesByCompanyId: _scheduleFrequencyMinutesByCompanyId,
|
|
2653
|
+
paperclipApiBaseUrlByCompanyId: _paperclipApiBaseUrlByCompanyId,
|
|
2634
2654
|
...publicSettings
|
|
2635
2655
|
} = settings;
|
|
2636
2656
|
return publicSettings;
|
|
2637
2657
|
}
|
|
2658
|
+
function getGitHubTokenLogin(settings, companyId) {
|
|
2659
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2660
|
+
if (!normalizedCompanyId) {
|
|
2661
|
+
return void 0;
|
|
2662
|
+
}
|
|
2663
|
+
return normalizeOptionalString2(settings.githubTokenLoginByCompanyId?.[normalizedCompanyId]) ?? normalizeOptionalString2(settings.githubTokenLogin);
|
|
2664
|
+
}
|
|
2638
2665
|
function getPaperclipBoardAccessIdentity(settings, companyId) {
|
|
2639
2666
|
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2640
2667
|
if (!normalizedCompanyId) {
|
|
@@ -2644,34 +2671,16 @@ function getPaperclipBoardAccessIdentity(settings, companyId) {
|
|
|
2644
2671
|
}
|
|
2645
2672
|
function getPublicSettingsForScope(settings, companyId) {
|
|
2646
2673
|
const publicSettings = getPublicSettings(settings);
|
|
2674
|
+
const githubTokenLogin = getGitHubTokenLogin(settings, companyId);
|
|
2647
2675
|
const paperclipBoardAccessIdentity = getPaperclipBoardAccessIdentity(settings, companyId);
|
|
2648
2676
|
return {
|
|
2649
2677
|
...publicSettings,
|
|
2650
2678
|
mappings: filterMappingsByCompany(publicSettings.mappings, companyId),
|
|
2651
2679
|
advancedSettings: getCompanyAdvancedSettings(settings, companyId),
|
|
2680
|
+
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
2652
2681
|
...paperclipBoardAccessIdentity ? { paperclipBoardAccessIdentity } : {}
|
|
2653
2682
|
};
|
|
2654
2683
|
}
|
|
2655
|
-
function getSavedGitHubTokenRef(settings, companyId) {
|
|
2656
|
-
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2657
|
-
if (normalizedCompanyId) {
|
|
2658
|
-
const scopedSecretRef = normalizeSecretRef(settings?.githubTokenRefs?.[normalizedCompanyId]);
|
|
2659
|
-
if (scopedSecretRef) {
|
|
2660
|
-
return scopedSecretRef;
|
|
2661
|
-
}
|
|
2662
|
-
}
|
|
2663
|
-
return normalizeGitHubTokenRef(settings?.githubTokenRef);
|
|
2664
|
-
}
|
|
2665
|
-
function getSavedGitHubTokenLogin(settings, companyId) {
|
|
2666
|
-
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2667
|
-
if (normalizedCompanyId) {
|
|
2668
|
-
const scopedLogin = normalizeOptionalString2(settings?.githubTokenLoginsByCompanyId?.[normalizedCompanyId]);
|
|
2669
|
-
if (scopedLogin) {
|
|
2670
|
-
return scopedLogin;
|
|
2671
|
-
}
|
|
2672
|
-
}
|
|
2673
|
-
return normalizeOptionalString2(settings?.githubTokenLogin);
|
|
2674
|
-
}
|
|
2675
2684
|
async function listAvailableAssignees(ctx, companyId) {
|
|
2676
2685
|
try {
|
|
2677
2686
|
const agents = await ctx.agents.list({
|
|
@@ -2852,14 +2861,11 @@ function createSetupConfigurationErrorSyncState(issue, trigger) {
|
|
|
2852
2861
|
});
|
|
2853
2862
|
}
|
|
2854
2863
|
}
|
|
2855
|
-
async function saveSettingsSyncState(ctx, settings, syncState) {
|
|
2856
|
-
const next =
|
|
2857
|
-
...settings,
|
|
2858
|
-
syncState
|
|
2859
|
-
};
|
|
2864
|
+
async function saveSettingsSyncState(ctx, settings, syncState, companyId) {
|
|
2865
|
+
const next = upsertScopedSyncState(normalizeSettings(settings), syncState, companyId);
|
|
2860
2866
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
2861
|
-
await ctx.state.set(SYNC_STATE_SCOPE,
|
|
2862
|
-
return next;
|
|
2867
|
+
await ctx.state.set(SYNC_STATE_SCOPE, syncState);
|
|
2868
|
+
return materializeScopedSettings(next, null, companyId);
|
|
2863
2869
|
}
|
|
2864
2870
|
async function setSyncCancellationRequest(ctx, request) {
|
|
2865
2871
|
if (request) {
|
|
@@ -2884,8 +2890,8 @@ function buildCancelledSyncMessage(target, progress) {
|
|
|
2884
2890
|
const completionSummary = completedIssueCount !== void 0 && totalIssueCount !== void 0 ? ` Completed ${Math.min(completedIssueCount, totalIssueCount)} of ${totalIssueCount} issues before stopping.` : "";
|
|
2885
2891
|
return `${scopeLabel} was cancelled before it finished.${completionSummary}`;
|
|
2886
2892
|
}
|
|
2887
|
-
async function createUnexpectedSyncErrorResult(ctx, trigger, error) {
|
|
2888
|
-
const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
2893
|
+
async function createUnexpectedSyncErrorResult(ctx, trigger, error, companyId) {
|
|
2894
|
+
const settings = materializeScopedSettings(normalizeSettings(await ctx.state.get(SETTINGS_SCOPE)), null, companyId);
|
|
2889
2895
|
const errorDetails = buildSyncErrorDetails(error, {
|
|
2890
2896
|
phase: "configuration"
|
|
2891
2897
|
});
|
|
@@ -2910,7 +2916,8 @@ async function createUnexpectedSyncErrorResult(ctx, trigger, error) {
|
|
|
2910
2916
|
errorDetails
|
|
2911
2917
|
})
|
|
2912
2918
|
)
|
|
2913
|
-
})
|
|
2919
|
+
}),
|
|
2920
|
+
companyId
|
|
2914
2921
|
);
|
|
2915
2922
|
}
|
|
2916
2923
|
async function waitForSyncResultWithinGracePeriod(promise, timeoutMs) {
|
|
@@ -2928,15 +2935,13 @@ async function waitForSyncResultWithinGracePeriod(promise, timeoutMs) {
|
|
|
2928
2935
|
}
|
|
2929
2936
|
}
|
|
2930
2937
|
}
|
|
2931
|
-
async function getActiveOrCurrentSyncState(ctx) {
|
|
2932
|
-
|
|
2933
|
-
|
|
2938
|
+
async function getActiveOrCurrentSyncState(ctx, companyId) {
|
|
2939
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2940
|
+
if (activeRunningSyncState?.syncState.status === "running" && activeRunningSyncCompanyId === normalizedCompanyId) {
|
|
2941
|
+
return materializeScopedSettings(activeRunningSyncState, null, normalizedCompanyId);
|
|
2934
2942
|
}
|
|
2935
2943
|
const current = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
2936
|
-
|
|
2937
|
-
return current;
|
|
2938
|
-
}
|
|
2939
|
-
return current;
|
|
2944
|
+
return materializeScopedSettings(current, null, normalizedCompanyId);
|
|
2940
2945
|
}
|
|
2941
2946
|
function updateSyncFailureContext(current, next) {
|
|
2942
2947
|
if ("phase" in next) {
|
|
@@ -3060,12 +3065,6 @@ async function readExternalConfig(ctx) {
|
|
|
3060
3065
|
}
|
|
3061
3066
|
}
|
|
3062
3067
|
function normalizePaperclipBoardApiTokenRefs(value) {
|
|
3063
|
-
return normalizeCompanySecretRefs(value);
|
|
3064
|
-
}
|
|
3065
|
-
function normalizeGitHubTokenRefs(value) {
|
|
3066
|
-
return normalizeCompanySecretRefs(value);
|
|
3067
|
-
}
|
|
3068
|
-
function normalizeCompanySecretRefs(value) {
|
|
3069
3068
|
if (!value || typeof value !== "object") {
|
|
3070
3069
|
return void 0;
|
|
3071
3070
|
}
|
|
@@ -3079,7 +3078,7 @@ function normalizeCompanySecretRefs(value) {
|
|
|
3079
3078
|
}
|
|
3080
3079
|
return Object.fromEntries(entries);
|
|
3081
3080
|
}
|
|
3082
|
-
function
|
|
3081
|
+
function normalizeGitHubTokenLoginByCompanyId(value) {
|
|
3083
3082
|
if (!value || typeof value !== "object") {
|
|
3084
3083
|
return void 0;
|
|
3085
3084
|
}
|
|
@@ -3126,14 +3125,14 @@ function normalizeSyncState(value) {
|
|
|
3126
3125
|
const recentFailures = normalizeSyncFailureLogEntries(record.recentFailures);
|
|
3127
3126
|
return {
|
|
3128
3127
|
status: status === "running" || status === "success" || status === "error" || status === "cancelled" ? status : "idle",
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
lastRunTrigger
|
|
3136
|
-
|
|
3128
|
+
...typeof record.message === "string" ? { message: record.message } : {},
|
|
3129
|
+
...typeof record.checkedAt === "string" ? { checkedAt: record.checkedAt } : {},
|
|
3130
|
+
...typeof record.syncedIssuesCount === "number" ? { syncedIssuesCount: record.syncedIssuesCount } : {},
|
|
3131
|
+
...typeof record.createdIssuesCount === "number" ? { createdIssuesCount: record.createdIssuesCount } : {},
|
|
3132
|
+
...typeof record.skippedIssuesCount === "number" ? { skippedIssuesCount: record.skippedIssuesCount } : {},
|
|
3133
|
+
...typeof record.erroredIssuesCount === "number" ? { erroredIssuesCount: record.erroredIssuesCount } : {},
|
|
3134
|
+
...lastRunTrigger === "manual" || lastRunTrigger === "schedule" || lastRunTrigger === "retry" ? { lastRunTrigger } : {},
|
|
3135
|
+
...typeof record.cancelRequestedAt === "string" ? { cancelRequestedAt: record.cancelRequestedAt } : {},
|
|
3137
3136
|
...progress ? { progress } : {},
|
|
3138
3137
|
...errorDetails ? { errorDetails } : {},
|
|
3139
3138
|
...recentFailures ? { recentFailures } : {}
|
|
@@ -3243,6 +3242,26 @@ function normalizeScheduleFrequencyMinutes(value) {
|
|
|
3243
3242
|
}
|
|
3244
3243
|
return Math.floor(numericValue);
|
|
3245
3244
|
}
|
|
3245
|
+
function normalizeSyncStateByCompanyId(value) {
|
|
3246
|
+
if (!value || typeof value !== "object") {
|
|
3247
|
+
return void 0;
|
|
3248
|
+
}
|
|
3249
|
+
const entries = Object.entries(value).map(([companyId, syncState]) => {
|
|
3250
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3251
|
+
return normalizedCompanyId ? [normalizedCompanyId, normalizeSyncState(syncState)] : null;
|
|
3252
|
+
}).filter((entry) => entry !== null);
|
|
3253
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3254
|
+
}
|
|
3255
|
+
function normalizeScheduleFrequencyMinutesByCompanyId(value) {
|
|
3256
|
+
if (!value || typeof value !== "object") {
|
|
3257
|
+
return void 0;
|
|
3258
|
+
}
|
|
3259
|
+
const entries = Object.entries(value).map(([companyId, scheduleFrequencyMinutes]) => {
|
|
3260
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3261
|
+
return normalizedCompanyId ? [normalizedCompanyId, normalizeScheduleFrequencyMinutes(scheduleFrequencyMinutes)] : null;
|
|
3262
|
+
}).filter((entry) => entry !== null);
|
|
3263
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3264
|
+
}
|
|
3246
3265
|
function normalizePaperclipApiBaseUrl(value) {
|
|
3247
3266
|
if (typeof value !== "string") {
|
|
3248
3267
|
return void 0;
|
|
@@ -3257,6 +3276,17 @@ function normalizePaperclipApiBaseUrl(value) {
|
|
|
3257
3276
|
return void 0;
|
|
3258
3277
|
}
|
|
3259
3278
|
}
|
|
3279
|
+
function normalizePaperclipApiBaseUrlByCompanyId(value) {
|
|
3280
|
+
if (!value || typeof value !== "object") {
|
|
3281
|
+
return void 0;
|
|
3282
|
+
}
|
|
3283
|
+
const entries = Object.entries(value).map(([companyId, paperclipApiBaseUrl]) => {
|
|
3284
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3285
|
+
const normalizedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(paperclipApiBaseUrl);
|
|
3286
|
+
return normalizedCompanyId && normalizedPaperclipApiBaseUrl ? [normalizedCompanyId, normalizedPaperclipApiBaseUrl] : null;
|
|
3287
|
+
}).filter((entry) => entry !== null);
|
|
3288
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3289
|
+
}
|
|
3260
3290
|
function getRuntimePaperclipApiBaseUrl() {
|
|
3261
3291
|
if (typeof process === "undefined" || !process?.env) {
|
|
3262
3292
|
return void 0;
|
|
@@ -3276,19 +3306,26 @@ function resolvePaperclipApiBaseUrl(...values) {
|
|
|
3276
3306
|
}
|
|
3277
3307
|
return void 0;
|
|
3278
3308
|
}
|
|
3279
|
-
function getConfiguredPaperclipApiBaseUrl(settings, config) {
|
|
3280
|
-
|
|
3309
|
+
function getConfiguredPaperclipApiBaseUrl(settings, config, companyId) {
|
|
3310
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3311
|
+
return normalizedCompanyId ? resolvePaperclipApiBaseUrl(
|
|
3312
|
+
config?.paperclipApiBaseUrl,
|
|
3313
|
+
settings?.paperclipApiBaseUrlByCompanyId?.[normalizedCompanyId],
|
|
3314
|
+
settings?.paperclipApiBaseUrl
|
|
3315
|
+
) : resolvePaperclipApiBaseUrl(config?.paperclipApiBaseUrl, settings?.paperclipApiBaseUrl);
|
|
3281
3316
|
}
|
|
3282
|
-
function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config) {
|
|
3317
|
+
function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config, companyId) {
|
|
3283
3318
|
const runtimePaperclipApiBaseUrl = getRuntimePaperclipApiBaseUrl();
|
|
3284
3319
|
if (runtimePaperclipApiBaseUrl) {
|
|
3285
3320
|
return runtimePaperclipApiBaseUrl;
|
|
3286
3321
|
}
|
|
3287
3322
|
const requestedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(value);
|
|
3288
3323
|
const configuredPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(config?.paperclipApiBaseUrl);
|
|
3324
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3325
|
+
const savedCompanyPaperclipApiBaseUrl = normalizedCompanyId ? normalizePaperclipApiBaseUrl(settings?.paperclipApiBaseUrlByCompanyId?.[normalizedCompanyId]) : void 0;
|
|
3289
3326
|
const savedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(settings?.paperclipApiBaseUrl);
|
|
3290
3327
|
if (!requestedPaperclipApiBaseUrl) {
|
|
3291
|
-
return configuredPaperclipApiBaseUrl ?? savedPaperclipApiBaseUrl;
|
|
3328
|
+
return configuredPaperclipApiBaseUrl ?? savedCompanyPaperclipApiBaseUrl ?? savedPaperclipApiBaseUrl;
|
|
3292
3329
|
}
|
|
3293
3330
|
if (configuredPaperclipApiBaseUrl) {
|
|
3294
3331
|
if (requestedPaperclipApiBaseUrl !== configuredPaperclipApiBaseUrl) {
|
|
@@ -3298,6 +3335,9 @@ function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config) {
|
|
|
3298
3335
|
}
|
|
3299
3336
|
return configuredPaperclipApiBaseUrl;
|
|
3300
3337
|
}
|
|
3338
|
+
if (savedCompanyPaperclipApiBaseUrl && requestedPaperclipApiBaseUrl === savedCompanyPaperclipApiBaseUrl) {
|
|
3339
|
+
return savedCompanyPaperclipApiBaseUrl;
|
|
3340
|
+
}
|
|
3301
3341
|
if (savedPaperclipApiBaseUrl && requestedPaperclipApiBaseUrl === savedPaperclipApiBaseUrl) {
|
|
3302
3342
|
return savedPaperclipApiBaseUrl;
|
|
3303
3343
|
}
|
|
@@ -3310,9 +3350,14 @@ function normalizeSettings(value) {
|
|
|
3310
3350
|
return DEFAULT_SETTINGS;
|
|
3311
3351
|
}
|
|
3312
3352
|
const record = value;
|
|
3353
|
+
const syncStateByCompanyId = normalizeSyncStateByCompanyId(record.syncStateByCompanyId);
|
|
3354
|
+
const scheduleFrequencyMinutesByCompanyId = normalizeScheduleFrequencyMinutesByCompanyId(
|
|
3355
|
+
record.scheduleFrequencyMinutesByCompanyId
|
|
3356
|
+
);
|
|
3313
3357
|
const paperclipApiBaseUrl = resolvePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
|
|
3358
|
+
const paperclipApiBaseUrlByCompanyId = normalizePaperclipApiBaseUrlByCompanyId(record.paperclipApiBaseUrlByCompanyId);
|
|
3314
3359
|
const githubTokenRefs = normalizeGitHubTokenRefs(record.githubTokenRefs);
|
|
3315
|
-
const
|
|
3360
|
+
const githubTokenLoginByCompanyId = normalizeGitHubTokenLoginByCompanyId(record.githubTokenLoginByCompanyId);
|
|
3316
3361
|
const githubTokenRef = normalizeGitHubTokenRef(record.githubTokenRef);
|
|
3317
3362
|
const githubTokenLogin = normalizeOptionalString2(record.githubTokenLogin);
|
|
3318
3363
|
const paperclipBoardApiTokenRefs = normalizePaperclipBoardApiTokenRefs(record.paperclipBoardApiTokenRefs);
|
|
@@ -3323,10 +3368,13 @@ function normalizeSettings(value) {
|
|
|
3323
3368
|
return {
|
|
3324
3369
|
mappings: normalizeMappings(record.mappings),
|
|
3325
3370
|
syncState: normalizeSyncState(record.syncState),
|
|
3371
|
+
...syncStateByCompanyId ? { syncStateByCompanyId } : {},
|
|
3326
3372
|
scheduleFrequencyMinutes: normalizeScheduleFrequencyMinutes(record.scheduleFrequencyMinutes),
|
|
3373
|
+
...scheduleFrequencyMinutesByCompanyId ? { scheduleFrequencyMinutesByCompanyId } : {},
|
|
3327
3374
|
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {},
|
|
3375
|
+
...paperclipApiBaseUrlByCompanyId ? { paperclipApiBaseUrlByCompanyId } : {},
|
|
3328
3376
|
...githubTokenRefs ? { githubTokenRefs } : {},
|
|
3329
|
-
...
|
|
3377
|
+
...githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId } : {},
|
|
3330
3378
|
...githubTokenRef ? { githubTokenRef } : {},
|
|
3331
3379
|
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
3332
3380
|
...paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs } : {},
|
|
@@ -3335,6 +3383,103 @@ function normalizeSettings(value) {
|
|
|
3335
3383
|
updatedAt: typeof record.updatedAt === "string" ? record.updatedAt : void 0
|
|
3336
3384
|
};
|
|
3337
3385
|
}
|
|
3386
|
+
function getScopedSyncState(settings, companyId) {
|
|
3387
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3388
|
+
if (!normalizedCompanyId) {
|
|
3389
|
+
return normalizeSyncState(settings.syncState);
|
|
3390
|
+
}
|
|
3391
|
+
const scopedSyncState = settings.syncStateByCompanyId?.[normalizedCompanyId];
|
|
3392
|
+
return scopedSyncState ? normalizeSyncState(scopedSyncState) : normalizeSyncState(settings.syncState);
|
|
3393
|
+
}
|
|
3394
|
+
function getScopedScheduleFrequencyMinutes(settings, companyId) {
|
|
3395
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3396
|
+
if (!normalizedCompanyId) {
|
|
3397
|
+
return normalizeScheduleFrequencyMinutes(settings.scheduleFrequencyMinutes);
|
|
3398
|
+
}
|
|
3399
|
+
const scopedScheduleFrequencyMinutes = settings.scheduleFrequencyMinutesByCompanyId?.[normalizedCompanyId];
|
|
3400
|
+
return scopedScheduleFrequencyMinutes !== void 0 ? normalizeScheduleFrequencyMinutes(scopedScheduleFrequencyMinutes) : normalizeScheduleFrequencyMinutes(settings.scheduleFrequencyMinutes);
|
|
3401
|
+
}
|
|
3402
|
+
function materializeScopedSettings(settings, config, companyId) {
|
|
3403
|
+
const syncState = getScopedSyncState(settings, companyId);
|
|
3404
|
+
const scheduleFrequencyMinutes = getScopedScheduleFrequencyMinutes(settings, companyId);
|
|
3405
|
+
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(settings, config, companyId);
|
|
3406
|
+
return {
|
|
3407
|
+
...settings,
|
|
3408
|
+
syncState,
|
|
3409
|
+
scheduleFrequencyMinutes,
|
|
3410
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
|
|
3411
|
+
};
|
|
3412
|
+
}
|
|
3413
|
+
function upsertScopedSyncState(settings, syncState, companyId) {
|
|
3414
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3415
|
+
if (!normalizedCompanyId) {
|
|
3416
|
+
return {
|
|
3417
|
+
...settings,
|
|
3418
|
+
syncState
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
return {
|
|
3422
|
+
...settings,
|
|
3423
|
+
syncState,
|
|
3424
|
+
syncStateByCompanyId: {
|
|
3425
|
+
...settings.syncStateByCompanyId ?? {},
|
|
3426
|
+
[normalizedCompanyId]: syncState
|
|
3427
|
+
}
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
function upsertScopedScheduleFrequencyMinutes(settings, scheduleFrequencyMinutes, companyId) {
|
|
3431
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3432
|
+
if (!normalizedCompanyId) {
|
|
3433
|
+
return {
|
|
3434
|
+
...settings,
|
|
3435
|
+
scheduleFrequencyMinutes
|
|
3436
|
+
};
|
|
3437
|
+
}
|
|
3438
|
+
return {
|
|
3439
|
+
...settings,
|
|
3440
|
+
scheduleFrequencyMinutes,
|
|
3441
|
+
scheduleFrequencyMinutesByCompanyId: {
|
|
3442
|
+
...settings.scheduleFrequencyMinutesByCompanyId ?? {},
|
|
3443
|
+
[normalizedCompanyId]: scheduleFrequencyMinutes
|
|
3444
|
+
}
|
|
3445
|
+
};
|
|
3446
|
+
}
|
|
3447
|
+
function upsertScopedPaperclipApiBaseUrl(settings, paperclipApiBaseUrl, companyId) {
|
|
3448
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3449
|
+
if (!normalizedCompanyId) {
|
|
3450
|
+
return {
|
|
3451
|
+
...settings,
|
|
3452
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
|
|
3453
|
+
};
|
|
3454
|
+
}
|
|
3455
|
+
const nextPaperclipApiBaseUrlByCompanyId = {
|
|
3456
|
+
...settings.paperclipApiBaseUrlByCompanyId ?? {}
|
|
3457
|
+
};
|
|
3458
|
+
if (paperclipApiBaseUrl) {
|
|
3459
|
+
nextPaperclipApiBaseUrlByCompanyId[normalizedCompanyId] = paperclipApiBaseUrl;
|
|
3460
|
+
} else {
|
|
3461
|
+
delete nextPaperclipApiBaseUrlByCompanyId[normalizedCompanyId];
|
|
3462
|
+
}
|
|
3463
|
+
return {
|
|
3464
|
+
...settings,
|
|
3465
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {},
|
|
3466
|
+
...Object.keys(nextPaperclipApiBaseUrlByCompanyId).length > 0 ? { paperclipApiBaseUrlByCompanyId: nextPaperclipApiBaseUrlByCompanyId } : {}
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3469
|
+
function getScopedSyncTarget(companyId) {
|
|
3470
|
+
return {
|
|
3471
|
+
kind: "company",
|
|
3472
|
+
companyId,
|
|
3473
|
+
displayLabel: "this company"
|
|
3474
|
+
};
|
|
3475
|
+
}
|
|
3476
|
+
function getSyncableMappingsForScope(mappings, companyId) {
|
|
3477
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3478
|
+
return normalizedCompanyId ? getSyncableMappingsForTarget(mappings, getScopedSyncTarget(normalizedCompanyId)) : getSyncableMappings(mappings);
|
|
3479
|
+
}
|
|
3480
|
+
function hasAnyScopedValue(valueByCompanyId) {
|
|
3481
|
+
return Boolean(valueByCompanyId && Object.keys(valueByCompanyId).length > 0);
|
|
3482
|
+
}
|
|
3338
3483
|
function normalizeImportRegistry(value) {
|
|
3339
3484
|
if (!Array.isArray(value)) {
|
|
3340
3485
|
return [];
|
|
@@ -3494,6 +3639,7 @@ function normalizeGitHubIssueRecord(issue) {
|
|
|
3494
3639
|
body: typeof issue.body === "string" ? stripNullBytes(issue.body) : null,
|
|
3495
3640
|
htmlUrl: issue.html_url,
|
|
3496
3641
|
...normalizeGitHubUsername(issue.user?.login) ? { authorLogin: normalizeGitHubUsername(issue.user?.login) } : {},
|
|
3642
|
+
...normalizeGitHubLowercaseString(issue.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(issue.author_association) } : {},
|
|
3497
3643
|
labels: normalizeGitHubIssueLabels(issue.labels),
|
|
3498
3644
|
state: issue.state === "closed" ? "closed" : "open",
|
|
3499
3645
|
stateReason: normalizeGitHubIssueStateReason(issue.state_reason),
|
|
@@ -4274,6 +4420,22 @@ async function getGitHubIssueStatusSnapshot(octokit, repository, issueNumber, gi
|
|
|
4274
4420
|
function buildGitHubRepositoryActorCacheKey(repository, login) {
|
|
4275
4421
|
return `${repository.owner.toLowerCase()}/${repository.repo.toLowerCase()}:${login}`;
|
|
4276
4422
|
}
|
|
4423
|
+
function getGitHubRepositoryTrustedAuthorStatusFromAssociation(authorAssociation) {
|
|
4424
|
+
const normalizedAssociation = normalizeGitHubLowercaseString(authorAssociation);
|
|
4425
|
+
if (!normalizedAssociation) {
|
|
4426
|
+
return void 0;
|
|
4427
|
+
}
|
|
4428
|
+
return GITHUB_REPOSITORY_TRUSTED_AUTHOR_ASSOCIATIONS.has(normalizedAssociation);
|
|
4429
|
+
}
|
|
4430
|
+
function cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(repository, login, authorAssociation, cache) {
|
|
4431
|
+
const normalizedLogin = normalizeGitHubUserLogin(login);
|
|
4432
|
+
const trustedAuthorStatus = getGitHubRepositoryTrustedAuthorStatusFromAssociation(authorAssociation);
|
|
4433
|
+
if (!normalizedLogin || trustedAuthorStatus === void 0) {
|
|
4434
|
+
return trustedAuthorStatus;
|
|
4435
|
+
}
|
|
4436
|
+
cache.set(buildGitHubRepositoryActorCacheKey(repository, normalizedLogin), trustedAuthorStatus);
|
|
4437
|
+
return trustedAuthorStatus;
|
|
4438
|
+
}
|
|
4277
4439
|
async function isGitHubUserRepositoryMaintainer(octokit, repository, login, cache) {
|
|
4278
4440
|
const normalizedLogin = normalizeGitHubUserLogin(login);
|
|
4279
4441
|
if (!normalizedLogin) {
|
|
@@ -4339,6 +4501,7 @@ async function listNewGitHubIssueCommentsSinceCount(octokit, repository, issueNu
|
|
|
4339
4501
|
body: typeof comment.body === "string" ? stripNullBytes(comment.body) : "",
|
|
4340
4502
|
url: comment.html_url ?? void 0,
|
|
4341
4503
|
authorLogin: normalizeGitHubUserLogin(comment.user?.login),
|
|
4504
|
+
...normalizeGitHubLowercaseString(comment.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(comment.author_association) } : {},
|
|
4342
4505
|
createdAt: comment.created_at ?? void 0,
|
|
4343
4506
|
updatedAt: comment.updated_at ?? void 0
|
|
4344
4507
|
});
|
|
@@ -4380,6 +4543,18 @@ async function hasTrustedNewGitHubIssueComment(params) {
|
|
|
4380
4543
|
if (originalPosterLogin && authorLogin === originalPosterLogin) {
|
|
4381
4544
|
return true;
|
|
4382
4545
|
}
|
|
4546
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4547
|
+
params.repository,
|
|
4548
|
+
authorLogin,
|
|
4549
|
+
comment.authorAssociation,
|
|
4550
|
+
params.maintainerCache
|
|
4551
|
+
);
|
|
4552
|
+
if (trustedAuthorStatus === true) {
|
|
4553
|
+
return true;
|
|
4554
|
+
}
|
|
4555
|
+
if (trustedAuthorStatus === false) {
|
|
4556
|
+
continue;
|
|
4557
|
+
}
|
|
4383
4558
|
unseenAuthors.add(authorLogin);
|
|
4384
4559
|
}
|
|
4385
4560
|
for (const authorLogin of unseenAuthors) {
|
|
@@ -4399,6 +4574,15 @@ async function isMaintainerAuthoredGitHubIssue(params) {
|
|
|
4399
4574
|
if (!authorLogin) {
|
|
4400
4575
|
return false;
|
|
4401
4576
|
}
|
|
4577
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4578
|
+
params.repository,
|
|
4579
|
+
authorLogin,
|
|
4580
|
+
params.githubIssue.authorAssociation,
|
|
4581
|
+
params.maintainerCache
|
|
4582
|
+
);
|
|
4583
|
+
if (trustedAuthorStatus !== void 0) {
|
|
4584
|
+
return trustedAuthorStatus;
|
|
4585
|
+
}
|
|
4402
4586
|
return isGitHubUserRepositoryMaintainer(
|
|
4403
4587
|
params.octokit,
|
|
4404
4588
|
params.repository,
|
|
@@ -4408,7 +4592,19 @@ async function isMaintainerAuthoredGitHubIssue(params) {
|
|
|
4408
4592
|
}
|
|
4409
4593
|
async function warmGitHubRepositoryMaintainerCache(params) {
|
|
4410
4594
|
const uniqueAuthorLogins = [...new Set(
|
|
4411
|
-
params.githubIssues.
|
|
4595
|
+
params.githubIssues.flatMap((issue) => {
|
|
4596
|
+
const authorLogin = normalizeGitHubUserLogin(issue.authorLogin);
|
|
4597
|
+
if (!authorLogin) {
|
|
4598
|
+
return [];
|
|
4599
|
+
}
|
|
4600
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4601
|
+
params.repository,
|
|
4602
|
+
authorLogin,
|
|
4603
|
+
issue.authorAssociation,
|
|
4604
|
+
params.maintainerCache
|
|
4605
|
+
);
|
|
4606
|
+
return trustedAuthorStatus === void 0 ? [authorLogin] : [];
|
|
4607
|
+
})
|
|
4412
4608
|
)].filter((authorLogin) => !params.maintainerCache.has(buildGitHubRepositoryActorCacheKey(params.repository, authorLogin)));
|
|
4413
4609
|
if (uniqueAuthorLogins.length === 0) {
|
|
4414
4610
|
return;
|
|
@@ -4623,7 +4819,9 @@ function buildPaperclipIssueDescription(issue, linkedPullRequestNumbers = []) {
|
|
|
4623
4819
|
return normalizedBody ?? "";
|
|
4624
4820
|
}
|
|
4625
4821
|
if (!normalizedBody) {
|
|
4626
|
-
return
|
|
4822
|
+
return `${EMPTY_GITHUB_ISSUE_DESCRIPTION_PLACEHOLDER}
|
|
4823
|
+
|
|
4824
|
+
${hiddenImportMarker}`;
|
|
4627
4825
|
}
|
|
4628
4826
|
return `${normalizedBody}
|
|
4629
4827
|
|
|
@@ -6223,19 +6421,32 @@ async function getResolvedConfig(ctx) {
|
|
|
6223
6421
|
}
|
|
6224
6422
|
function getConfiguredGithubTokenSource(settings, config, companyId) {
|
|
6225
6423
|
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
6226
|
-
const
|
|
6424
|
+
const hasScopedGitHubTokenRefs = hasAnyScopedValue(settings?.githubTokenRefs) || hasAnyScopedValue(config.githubTokenRefs);
|
|
6425
|
+
const secretRef = normalizedCompanyId ? normalizeSecretRef(config.githubTokenRefs?.[normalizedCompanyId]) ?? normalizeSecretRef(settings?.githubTokenRefs?.[normalizedCompanyId]) ?? (!hasScopedGitHubTokenRefs ? normalizeGitHubTokenRef(config.githubTokenRef) ?? normalizeGitHubTokenRef(settings?.githubTokenRef) : void 0) : normalizeGitHubTokenRef(config.githubTokenRef) ?? normalizeGitHubTokenRef(settings?.githubTokenRef) ?? (() => {
|
|
6426
|
+
const configuredRefs = [
|
|
6427
|
+
...Object.values(config.githubTokenRefs ?? {}),
|
|
6428
|
+
...Object.values(settings?.githubTokenRefs ?? {})
|
|
6429
|
+
].map((value) => normalizeGitHubTokenRef(value)).filter((value) => Boolean(value));
|
|
6430
|
+
const uniqueRefs = [...new Set(configuredRefs)];
|
|
6431
|
+
return uniqueRefs.length === 1 ? uniqueRefs[0] : void 0;
|
|
6432
|
+
})();
|
|
6227
6433
|
if (secretRef) {
|
|
6228
6434
|
return { secretRef };
|
|
6229
6435
|
}
|
|
6230
|
-
const token = normalizeGitHubToken(config.githubToken);
|
|
6436
|
+
const token = !normalizedCompanyId || !hasScopedGitHubTokenRefs ? normalizeGitHubToken(config.githubToken) : void 0;
|
|
6231
6437
|
return token ? { token } : {};
|
|
6232
6438
|
}
|
|
6233
|
-
function getConfiguredGithubTokenRef(settings, config, companyId) {
|
|
6234
|
-
return getConfiguredGithubTokenSource(settings, config, companyId).secretRef;
|
|
6235
|
-
}
|
|
6236
6439
|
function hasConfiguredGithubToken(settings, config, companyId) {
|
|
6237
6440
|
const configuredTokenSource = getConfiguredGithubTokenSource(settings, config, companyId);
|
|
6238
|
-
|
|
6441
|
+
if (configuredTokenSource.secretRef ?? configuredTokenSource.token) {
|
|
6442
|
+
return true;
|
|
6443
|
+
}
|
|
6444
|
+
if (normalizeCompanyId(companyId)) {
|
|
6445
|
+
return false;
|
|
6446
|
+
}
|
|
6447
|
+
return Boolean(
|
|
6448
|
+
settings?.githubTokenRefs && Object.keys(settings.githubTokenRefs).length > 0 || config.githubTokenRefs && Object.keys(config.githubTokenRefs).length > 0
|
|
6449
|
+
);
|
|
6239
6450
|
}
|
|
6240
6451
|
function getSavedPaperclipBoardApiTokenRef(settings, companyId) {
|
|
6241
6452
|
if (!companyId) {
|
|
@@ -6937,6 +7148,7 @@ async function listAllGitHubIssueComments(octokit, repository, issueNumber) {
|
|
|
6937
7148
|
body: typeof comment.body === "string" ? stripNullBytes(comment.body) : "",
|
|
6938
7149
|
url: comment.html_url ?? void 0,
|
|
6939
7150
|
authorLogin: normalizeGitHubUserLogin(comment.user?.login),
|
|
7151
|
+
...normalizeGitHubLowercaseString(comment.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(comment.author_association) } : {},
|
|
6940
7152
|
authorUrl: comment.user?.html_url ?? void 0,
|
|
6941
7153
|
authorAvatarUrl: comment.user?.avatar_url ?? void 0,
|
|
6942
7154
|
createdAt: comment.created_at ?? void 0,
|
|
@@ -8079,7 +8291,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
|
|
|
8079
8291
|
}
|
|
8080
8292
|
const scope = await requireProjectPullRequestScope(ctx, input, projectMappings);
|
|
8081
8293
|
const config = await getResolvedConfig(ctx);
|
|
8082
|
-
if (!hasConfiguredGithubToken(settings, config, companyId)) {
|
|
8294
|
+
if (!hasConfiguredGithubToken(settings, config, scope.companyId)) {
|
|
8083
8295
|
return {
|
|
8084
8296
|
status: "missing_token",
|
|
8085
8297
|
projectId,
|
|
@@ -8098,7 +8310,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
|
|
|
8098
8310
|
};
|
|
8099
8311
|
}
|
|
8100
8312
|
try {
|
|
8101
|
-
const octokit = await createGitHubToolOctokit(ctx, companyId);
|
|
8313
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8102
8314
|
const pageCacheKey = buildProjectPullRequestPageCacheKey(scope, filter, pageIndex, cursor);
|
|
8103
8315
|
const cachedPage = getFreshCacheValue(activeProjectPullRequestPageCache, pageCacheKey);
|
|
8104
8316
|
if (cachedPage) {
|
|
@@ -9171,12 +9383,25 @@ function shouldRunScheduledSync(settings, scheduledAt) {
|
|
|
9171
9383
|
}
|
|
9172
9384
|
return now - lastCheckedAt >= settings.scheduleFrequencyMinutes * 6e4;
|
|
9173
9385
|
}
|
|
9386
|
+
function listScheduledSyncTargets(settings) {
|
|
9387
|
+
const companyIds = [
|
|
9388
|
+
...new Set(
|
|
9389
|
+
settings.mappings.map((mapping) => normalizeCompanyId(mapping.companyId)).filter((companyId) => Boolean(companyId))
|
|
9390
|
+
)
|
|
9391
|
+
];
|
|
9392
|
+
if (companyIds.length === 0) {
|
|
9393
|
+
return settings.mappings.length > 0 ? [void 0] : [];
|
|
9394
|
+
}
|
|
9395
|
+
return companyIds.map((companyId) => getScopedSyncTarget(companyId));
|
|
9396
|
+
}
|
|
9174
9397
|
async function performSync(ctx, trigger, options = {}) {
|
|
9175
|
-
const
|
|
9398
|
+
const targetCompanyId = normalizeCompanyId(options.target?.companyId);
|
|
9399
|
+
const baseSettings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
9176
9400
|
const config = await getResolvedConfig(ctx);
|
|
9401
|
+
const settings = materializeScopedSettings(baseSettings, config, targetCompanyId);
|
|
9177
9402
|
const importRegistry = normalizeImportRegistry(await ctx.state.get(IMPORT_REGISTRY_SCOPE));
|
|
9178
|
-
const token = typeof options.resolvedToken === "string" ? options.resolvedToken : await resolveGithubToken(ctx);
|
|
9179
|
-
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(
|
|
9403
|
+
const token = typeof options.resolvedToken === "string" ? options.resolvedToken : await resolveGithubToken(ctx, { companyId: targetCompanyId });
|
|
9404
|
+
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(baseSettings, config, targetCompanyId);
|
|
9180
9405
|
const mappings = getSyncableMappingsForTarget(settings.mappings, options.target);
|
|
9181
9406
|
activePaperclipApiAuthTokensByCompanyId = null;
|
|
9182
9407
|
const failureContext = {
|
|
@@ -9187,18 +9412,14 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9187
9412
|
...settings,
|
|
9188
9413
|
syncState: createSetupConfigurationErrorSyncState("missing_token", trigger)
|
|
9189
9414
|
};
|
|
9190
|
-
|
|
9191
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9192
|
-
return next;
|
|
9415
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9193
9416
|
}
|
|
9194
9417
|
if (mappings.length === 0) {
|
|
9195
9418
|
const next = {
|
|
9196
9419
|
...settings,
|
|
9197
9420
|
syncState: createSetupConfigurationErrorSyncState("missing_mapping", trigger)
|
|
9198
9421
|
};
|
|
9199
|
-
|
|
9200
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9201
|
-
return next;
|
|
9422
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9202
9423
|
}
|
|
9203
9424
|
const mappingsMissingBoardAccess = getMappingsMissingPaperclipBoardAccess(settings, config, mappings);
|
|
9204
9425
|
if (mappingsMissingBoardAccess.length > 0 && await detectPaperclipBoardAccessRequirement(paperclipApiBaseUrl)) {
|
|
@@ -9206,9 +9427,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9206
9427
|
...settings,
|
|
9207
9428
|
syncState: createSetupConfigurationErrorSyncState("missing_board_access", trigger)
|
|
9208
9429
|
};
|
|
9209
|
-
|
|
9210
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9211
|
-
return next;
|
|
9430
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9212
9431
|
}
|
|
9213
9432
|
if (!ctx.issues || typeof ctx.issues.create !== "function") {
|
|
9214
9433
|
const errorDetails = {
|
|
@@ -9234,9 +9453,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9234
9453
|
)
|
|
9235
9454
|
})
|
|
9236
9455
|
};
|
|
9237
|
-
|
|
9238
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9239
|
-
return next;
|
|
9456
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9240
9457
|
}
|
|
9241
9458
|
activePaperclipApiAuthTokensByCompanyId = await resolvePaperclipApiAuthTokens(ctx, settings, config, mappings);
|
|
9242
9459
|
const octokit = new Octokit({ auth: token });
|
|
@@ -9304,7 +9521,8 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9304
9521
|
erroredIssuesCount: recoverableFailures.length,
|
|
9305
9522
|
progress,
|
|
9306
9523
|
recentFailures
|
|
9307
|
-
})
|
|
9524
|
+
}),
|
|
9525
|
+
targetCompanyId
|
|
9308
9526
|
);
|
|
9309
9527
|
activeRunningSyncState = currentSettings;
|
|
9310
9528
|
lastProgressPersistedAt = now;
|
|
@@ -9641,10 +9859,9 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9641
9859
|
recentFailures: buildRecentSyncFailureLogEntries(recoverableFailures)
|
|
9642
9860
|
})
|
|
9643
9861
|
};
|
|
9644
|
-
await ctx.
|
|
9645
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next2.syncState);
|
|
9862
|
+
await saveSettingsSyncState(ctx, currentSettings, next2.syncState, targetCompanyId);
|
|
9646
9863
|
await ctx.state.set(IMPORT_REGISTRY_SCOPE, nextRegistry);
|
|
9647
|
-
return next2;
|
|
9864
|
+
return materializeScopedSettings(next2, config, targetCompanyId);
|
|
9648
9865
|
}
|
|
9649
9866
|
const next = {
|
|
9650
9867
|
...currentSettings,
|
|
@@ -9700,10 +9917,9 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9700
9917
|
)
|
|
9701
9918
|
})
|
|
9702
9919
|
};
|
|
9703
|
-
await ctx.
|
|
9704
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9920
|
+
await saveSettingsSyncState(ctx, currentSettings, next.syncState, targetCompanyId);
|
|
9705
9921
|
await ctx.state.set(IMPORT_REGISTRY_SCOPE, nextRegistry);
|
|
9706
|
-
return next;
|
|
9922
|
+
return materializeScopedSettings(next, config, targetCompanyId);
|
|
9707
9923
|
}
|
|
9708
9924
|
}
|
|
9709
9925
|
async function startSync(ctx, trigger, options = {}) {
|
|
@@ -9721,28 +9937,32 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9721
9937
|
getResolvedConfig(ctx),
|
|
9722
9938
|
ctx.state.get(SETTINGS_SCOPE).then((value) => normalizeSettings(value))
|
|
9723
9939
|
]);
|
|
9724
|
-
const targetCompanyId = options.target?.companyId;
|
|
9940
|
+
const targetCompanyId = normalizeCompanyId(options.target?.companyId);
|
|
9725
9941
|
const token = await resolveGithubToken(ctx, {
|
|
9942
|
+
companyId: targetCompanyId,
|
|
9726
9943
|
config,
|
|
9727
|
-
settings: persistedSettings
|
|
9728
|
-
companyId: targetCompanyId
|
|
9944
|
+
settings: persistedSettings
|
|
9729
9945
|
}).catch(() => "");
|
|
9730
|
-
let currentSettings = sanitizeSettingsForCurrentSetup(persistedSettings, {
|
|
9946
|
+
let currentSettings = sanitizeSettingsForCurrentSetup(materializeScopedSettings(persistedSettings, config, targetCompanyId), {
|
|
9731
9947
|
hasToken: Boolean(token.trim()),
|
|
9732
|
-
hasMappings:
|
|
9948
|
+
hasMappings: getSyncableMappingsForScope(persistedSettings.mappings, targetCompanyId).length > 0
|
|
9733
9949
|
});
|
|
9734
|
-
const nextPaperclipApiBaseUrl = trigger === "manual" ? resolveTrustedPaperclipApiBaseUrlInput(options.paperclipApiBaseUrl,
|
|
9950
|
+
const nextPaperclipApiBaseUrl = trigger === "manual" ? resolveTrustedPaperclipApiBaseUrlInput(options.paperclipApiBaseUrl, persistedSettings, config, targetCompanyId) : getConfiguredPaperclipApiBaseUrl(persistedSettings, config, targetCompanyId);
|
|
9735
9951
|
if (nextPaperclipApiBaseUrl !== currentSettings.paperclipApiBaseUrl) {
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9952
|
+
const nextPersistedSettings = upsertScopedPaperclipApiBaseUrl(
|
|
9953
|
+
{
|
|
9954
|
+
...persistedSettings,
|
|
9955
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9956
|
+
},
|
|
9957
|
+
nextPaperclipApiBaseUrl,
|
|
9958
|
+
targetCompanyId
|
|
9959
|
+
);
|
|
9960
|
+
await ctx.state.set(SETTINGS_SCOPE, nextPersistedSettings);
|
|
9742
9961
|
await ctx.state.set(SYNC_STATE_SCOPE, currentSettings.syncState);
|
|
9962
|
+
currentSettings = materializeScopedSettings(nextPersistedSettings, config, targetCompanyId);
|
|
9743
9963
|
}
|
|
9744
|
-
if (currentSettings !== persistedSettings) {
|
|
9745
|
-
await saveSettingsSyncState(ctx,
|
|
9964
|
+
if (JSON.stringify(currentSettings.syncState) !== JSON.stringify(getScopedSyncState(persistedSettings, targetCompanyId))) {
|
|
9965
|
+
await saveSettingsSyncState(ctx, persistedSettings, currentSettings.syncState, targetCompanyId);
|
|
9746
9966
|
}
|
|
9747
9967
|
if (getActiveGitHubRateLimitPause(currentSettings.syncState)) {
|
|
9748
9968
|
return currentSettings;
|
|
@@ -9771,7 +9991,8 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9771
9991
|
...currentSettings,
|
|
9772
9992
|
syncState
|
|
9773
9993
|
};
|
|
9774
|
-
|
|
9994
|
+
activeRunningSyncCompanyId = targetCompanyId;
|
|
9995
|
+
return saveSettingsSyncState(ctx, currentSettings, syncState, targetCompanyId);
|
|
9775
9996
|
})();
|
|
9776
9997
|
activeSyncPromise = (async () => {
|
|
9777
9998
|
try {
|
|
@@ -9781,11 +10002,12 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9781
10002
|
target: options.target
|
|
9782
10003
|
});
|
|
9783
10004
|
} catch (error) {
|
|
9784
|
-
return await createUnexpectedSyncErrorResult(ctx, trigger, error);
|
|
10005
|
+
return await createUnexpectedSyncErrorResult(ctx, trigger, error, targetCompanyId);
|
|
9785
10006
|
} finally {
|
|
9786
10007
|
await setSyncCancellationRequest(ctx, null);
|
|
9787
10008
|
activePaperclipApiAuthTokensByCompanyId = null;
|
|
9788
10009
|
activeRunningSyncState = null;
|
|
10010
|
+
activeRunningSyncCompanyId = void 0;
|
|
9789
10011
|
activeSyncPromise = null;
|
|
9790
10012
|
}
|
|
9791
10013
|
})();
|
|
@@ -10575,38 +10797,18 @@ var plugin = definePlugin({
|
|
|
10575
10797
|
const importRegistry = normalizeImportRegistry(await ctx.state.get(IMPORT_REGISTRY_SCOPE));
|
|
10576
10798
|
const normalizedSettings = normalizeSettings(saved);
|
|
10577
10799
|
const config = await getResolvedConfig(ctx);
|
|
10578
|
-
const configuredGitHubTokenRef = requestedCompanyId ? normalizeSecretRef(config.githubTokenRefs?.[requestedCompanyId]) : normalizeGitHubTokenRef(config.githubTokenRef);
|
|
10579
|
-
const savedGitHubTokenRef = getSavedGitHubTokenRef(normalizedSettings, requestedCompanyId);
|
|
10580
|
-
const githubTokenRef = getConfiguredGithubTokenRef(normalizedSettings, config, requestedCompanyId);
|
|
10581
|
-
const githubTokenLogin = getSavedGitHubTokenLogin(normalizedSettings, requestedCompanyId);
|
|
10582
|
-
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(normalizedSettings, config);
|
|
10583
10800
|
const githubTokenConfigured = hasConfiguredGithubToken(normalizedSettings, config, requestedCompanyId);
|
|
10584
10801
|
const configuredBoardTokenRef = getConfiguredPaperclipBoardApiTokenRef(config, requestedCompanyId);
|
|
10585
10802
|
const savedBoardTokenRef = getSavedPaperclipBoardApiTokenRef(normalizedSettings, requestedCompanyId);
|
|
10586
|
-
const
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
githubTokenLoginsByCompanyId: {
|
|
10596
|
-
...normalizedSettings.githubTokenLoginsByCompanyId ?? {},
|
|
10597
|
-
[requestedCompanyId]: githubTokenLogin
|
|
10598
|
-
}
|
|
10599
|
-
} : {},
|
|
10600
|
-
...!requestedCompanyId && githubTokenRef ? { githubTokenRef } : {},
|
|
10601
|
-
...!requestedCompanyId && githubTokenLogin ? { githubTokenLogin } : {},
|
|
10602
|
-
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
|
|
10603
|
-
};
|
|
10604
|
-
const settingsForResponse = sanitizeSettingsForCurrentSetup(settingsWithResolvedToken, {
|
|
10605
|
-
hasToken: githubTokenConfigured,
|
|
10606
|
-
hasMappings: getSyncableMappings(settingsWithResolvedToken.mappings).length > 0
|
|
10607
|
-
});
|
|
10608
|
-
if (settingsForResponse !== normalizedSettings) {
|
|
10609
|
-
await saveSettingsSyncState(ctx, settingsForResponse, settingsForResponse.syncState);
|
|
10803
|
+
const settingsForResponse = sanitizeSettingsForCurrentSetup(
|
|
10804
|
+
materializeScopedSettings(normalizedSettings, config, requestedCompanyId),
|
|
10805
|
+
{
|
|
10806
|
+
hasToken: githubTokenConfigured,
|
|
10807
|
+
hasMappings: getSyncableMappingsForScope(normalizedSettings.mappings, requestedCompanyId).length > 0
|
|
10808
|
+
}
|
|
10809
|
+
);
|
|
10810
|
+
if (JSON.stringify(settingsForResponse.syncState) !== JSON.stringify(getScopedSyncState(normalizedSettings, requestedCompanyId))) {
|
|
10811
|
+
await saveSettingsSyncState(ctx, normalizedSettings, settingsForResponse.syncState, requestedCompanyId);
|
|
10610
10812
|
}
|
|
10611
10813
|
const scopedMappings = filterMappingsByCompany(settingsForResponse.mappings, requestedCompanyId);
|
|
10612
10814
|
const availableAssignees = includeAssignees && requestedCompanyId ? await listAvailableAssignees(ctx, requestedCompanyId) : [];
|
|
@@ -10615,9 +10817,6 @@ var plugin = definePlugin({
|
|
|
10615
10817
|
...includeAssignees ? { availableAssignees } : {},
|
|
10616
10818
|
totalSyncedIssuesCount: countImportedIssuesForMappings(importRegistry, scopedMappings),
|
|
10617
10819
|
githubTokenConfigured,
|
|
10618
|
-
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
10619
|
-
...savedGitHubTokenRef ? { githubTokenConfigSyncRef: savedGitHubTokenRef } : {},
|
|
10620
|
-
githubTokenNeedsConfigSync: Boolean(requestedCompanyId && savedGitHubTokenRef && !configuredGitHubTokenRef),
|
|
10621
10820
|
paperclipBoardAccessConfigured: requestedCompanyId ? hasConfiguredPaperclipBoardAccess(settingsForResponse, config, requestedCompanyId) : hasConfiguredPaperclipBoardAccessForMappings(settingsForResponse, config, scopedMappings),
|
|
10622
10821
|
...savedBoardTokenRef ? { paperclipBoardAccessConfigSyncRef: savedBoardTokenRef } : {},
|
|
10623
10822
|
paperclipBoardAccessNeedsConfigSync: Boolean(savedBoardTokenRef && !configuredBoardTokenRef)
|
|
@@ -10668,34 +10867,38 @@ var plugin = definePlugin({
|
|
|
10668
10867
|
const config = await getResolvedConfig(ctx);
|
|
10669
10868
|
const record = input && typeof input === "object" ? input : {};
|
|
10670
10869
|
const requestedCompanyId = normalizeCompanyId(record.companyId);
|
|
10870
|
+
const requestedGitHubTokenLogin = "githubTokenLogin" in record ? normalizeOptionalString2(record.githubTokenLogin) : void 0;
|
|
10671
10871
|
const hasMappingsPatch = "mappings" in record;
|
|
10672
10872
|
const hasAdvancedSettingsPatch = "advancedSettings" in record;
|
|
10673
|
-
const
|
|
10674
|
-
const githubTokenLogin = "githubTokenLogin" in record ? normalizeOptionalString2(record.githubTokenLogin) : void 0;
|
|
10675
|
-
const inputMappings = hasMappingsPatch ? normalizeMappings(record.mappings) : previous.mappings;
|
|
10873
|
+
const previousScopedSettings = materializeScopedSettings(previous, config, requestedCompanyId);
|
|
10676
10874
|
const nextGitHubTokenRefs = {
|
|
10677
10875
|
...previous.githubTokenRefs ?? {}
|
|
10678
10876
|
};
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
...previous.companyAdvancedSettingsByCompanyId ?? {}
|
|
10684
|
-
};
|
|
10685
|
-
if (requestedCompanyId && "githubTokenRef" in record) {
|
|
10686
|
-
if (githubTokenRef) {
|
|
10687
|
-
nextGitHubTokenRefs[requestedCompanyId] = githubTokenRef;
|
|
10688
|
-
} else {
|
|
10689
|
-
delete nextGitHubTokenRefs[requestedCompanyId];
|
|
10877
|
+
if (requestedCompanyId) {
|
|
10878
|
+
const companyScopedGitHubTokenRef = normalizeGitHubTokenRefs(record.githubTokenRefs)?.[requestedCompanyId] ?? ("githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : void 0);
|
|
10879
|
+
if (companyScopedGitHubTokenRef) {
|
|
10880
|
+
nextGitHubTokenRefs[requestedCompanyId] = companyScopedGitHubTokenRef;
|
|
10690
10881
|
}
|
|
10691
10882
|
}
|
|
10883
|
+
const githubTokenRefs = Object.keys(nextGitHubTokenRefs).length > 0 ? nextGitHubTokenRefs : void 0;
|
|
10884
|
+
const githubTokenRef = !requestedCompanyId && "githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : normalizeGitHubTokenRef(previous.githubTokenRef) ?? normalizeGitHubTokenRef(config.githubTokenRef);
|
|
10885
|
+
const nextGitHubTokenLoginByCompanyId = {
|
|
10886
|
+
...previous.githubTokenLoginByCompanyId ?? {}
|
|
10887
|
+
};
|
|
10692
10888
|
if (requestedCompanyId && "githubTokenLogin" in record) {
|
|
10693
|
-
|
|
10694
|
-
|
|
10889
|
+
const companyScopedGitHubTokenLogin = requestedGitHubTokenLogin;
|
|
10890
|
+
if (companyScopedGitHubTokenLogin) {
|
|
10891
|
+
nextGitHubTokenLoginByCompanyId[requestedCompanyId] = companyScopedGitHubTokenLogin;
|
|
10695
10892
|
} else {
|
|
10696
|
-
delete
|
|
10893
|
+
delete nextGitHubTokenLoginByCompanyId[requestedCompanyId];
|
|
10697
10894
|
}
|
|
10698
10895
|
}
|
|
10896
|
+
const githubTokenLoginByCompanyId = Object.keys(nextGitHubTokenLoginByCompanyId).length > 0 ? nextGitHubTokenLoginByCompanyId : void 0;
|
|
10897
|
+
const githubTokenLogin = !requestedCompanyId && "githubTokenLogin" in record ? requestedGitHubTokenLogin : previous.githubTokenLogin;
|
|
10898
|
+
const inputMappings = hasMappingsPatch ? normalizeMappings(record.mappings) : previous.mappings;
|
|
10899
|
+
const nextCompanyAdvancedSettingsByCompanyId = {
|
|
10900
|
+
...previous.companyAdvancedSettingsByCompanyId ?? {}
|
|
10901
|
+
};
|
|
10699
10902
|
if (requestedCompanyId && hasAdvancedSettingsPatch) {
|
|
10700
10903
|
nextCompanyAdvancedSettingsByCompanyId[requestedCompanyId] = normalizeAdvancedSettings(record.advancedSettings);
|
|
10701
10904
|
}
|
|
@@ -10706,19 +10909,26 @@ var plugin = definePlugin({
|
|
|
10706
10909
|
companyId: requestedCompanyId
|
|
10707
10910
|
}))
|
|
10708
10911
|
] : inputMappings;
|
|
10709
|
-
|
|
10912
|
+
let current = normalizeSettings({
|
|
10710
10913
|
mappings: mergedMappings,
|
|
10711
10914
|
syncState: previous.syncState,
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
...
|
|
10715
|
-
...
|
|
10716
|
-
|
|
10915
|
+
...previous.syncStateByCompanyId ? { syncStateByCompanyId: previous.syncStateByCompanyId } : {},
|
|
10916
|
+
scheduleFrequencyMinutes: previous.scheduleFrequencyMinutes,
|
|
10917
|
+
...previous.scheduleFrequencyMinutesByCompanyId ? { scheduleFrequencyMinutesByCompanyId: previous.scheduleFrequencyMinutesByCompanyId } : {},
|
|
10918
|
+
...previous.paperclipApiBaseUrl ? { paperclipApiBaseUrl: previous.paperclipApiBaseUrl } : {},
|
|
10919
|
+
...previous.paperclipApiBaseUrlByCompanyId ? { paperclipApiBaseUrlByCompanyId: previous.paperclipApiBaseUrlByCompanyId } : {},
|
|
10920
|
+
...githubTokenRefs ? { githubTokenRefs } : {},
|
|
10921
|
+
...githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId } : {},
|
|
10922
|
+
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
10717
10923
|
paperclipBoardApiTokenRefs: previous.paperclipBoardApiTokenRefs,
|
|
10718
10924
|
paperclipBoardAccessIdentityByCompanyId: previous.paperclipBoardAccessIdentityByCompanyId,
|
|
10719
10925
|
...Object.keys(nextCompanyAdvancedSettingsByCompanyId).length > 0 ? { companyAdvancedSettingsByCompanyId: nextCompanyAdvancedSettingsByCompanyId } : {},
|
|
10720
|
-
|
|
10926
|
+
...githubTokenRef ? { githubTokenRef } : {}
|
|
10721
10927
|
});
|
|
10928
|
+
const nextScheduleFrequencyMinutes = "scheduleFrequencyMinutes" in record ? normalizeScheduleFrequencyMinutes(record.scheduleFrequencyMinutes) : getScopedScheduleFrequencyMinutes(previous, requestedCompanyId);
|
|
10929
|
+
current = upsertScopedScheduleFrequencyMinutes(current, nextScheduleFrequencyMinutes, requestedCompanyId);
|
|
10930
|
+
const nextPaperclipApiBaseUrl = "paperclipApiBaseUrl" in record ? resolveTrustedPaperclipApiBaseUrlInput(record.paperclipApiBaseUrl, previous, config, requestedCompanyId) : getConfiguredPaperclipApiBaseUrl(previous, config, requestedCompanyId);
|
|
10931
|
+
current = upsertScopedPaperclipApiBaseUrl(current, nextPaperclipApiBaseUrl, requestedCompanyId);
|
|
10722
10932
|
const nextMappings = current.mappings.map((mapping, index) => ({
|
|
10723
10933
|
id: mapping.id.trim() || createMappingId(index),
|
|
10724
10934
|
repositoryUrl: parseRepositoryReference(mapping.repositoryUrl)?.url ?? mapping.repositoryUrl.trim(),
|
|
@@ -10726,27 +10936,29 @@ var plugin = definePlugin({
|
|
|
10726
10936
|
paperclipProjectId: mapping.paperclipProjectId,
|
|
10727
10937
|
companyId: mapping.companyId
|
|
10728
10938
|
}));
|
|
10939
|
+
const materializedCurrent = materializeScopedSettings(current, config, requestedCompanyId);
|
|
10729
10940
|
const next = sanitizeSettingsForCurrentSetup({
|
|
10941
|
+
...current,
|
|
10730
10942
|
mappings: nextMappings,
|
|
10731
|
-
syncState:
|
|
10732
|
-
scheduleFrequencyMinutes:
|
|
10733
|
-
...
|
|
10943
|
+
syncState: materializedCurrent.syncState,
|
|
10944
|
+
scheduleFrequencyMinutes: materializedCurrent.scheduleFrequencyMinutes,
|
|
10945
|
+
...materializedCurrent.paperclipApiBaseUrl ? { paperclipApiBaseUrl: materializedCurrent.paperclipApiBaseUrl } : {},
|
|
10734
10946
|
...current.githubTokenRefs ? { githubTokenRefs: current.githubTokenRefs } : {},
|
|
10735
|
-
...current.
|
|
10947
|
+
...current.githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId: current.githubTokenLoginByCompanyId } : {},
|
|
10736
10948
|
...current.githubTokenLogin ? { githubTokenLogin: current.githubTokenLogin } : {},
|
|
10737
10949
|
...current.paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs: current.paperclipBoardApiTokenRefs } : {},
|
|
10738
10950
|
...current.paperclipBoardAccessIdentityByCompanyId ? { paperclipBoardAccessIdentityByCompanyId: current.paperclipBoardAccessIdentityByCompanyId } : {},
|
|
10739
10951
|
...current.companyAdvancedSettingsByCompanyId ? { companyAdvancedSettingsByCompanyId: current.companyAdvancedSettingsByCompanyId } : {},
|
|
10740
|
-
...
|
|
10952
|
+
...githubTokenRef ? { githubTokenRef } : {},
|
|
10741
10953
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10742
10954
|
}, {
|
|
10743
10955
|
hasToken: hasConfiguredGithubToken(current, config, requestedCompanyId),
|
|
10744
|
-
hasMappings:
|
|
10956
|
+
hasMappings: getSyncableMappingsForScope(nextMappings, requestedCompanyId).length > 0
|
|
10745
10957
|
});
|
|
10746
10958
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
10747
10959
|
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
10748
10960
|
clearGitHubRepositoryTokenCapabilityAudits();
|
|
10749
|
-
const scopedGitHubTokenLogin =
|
|
10961
|
+
const scopedGitHubTokenLogin = (requestedCompanyId && "githubTokenLogin" in record ? requestedGitHubTokenLogin : void 0) ?? getGitHubTokenLogin(next, requestedCompanyId);
|
|
10750
10962
|
return {
|
|
10751
10963
|
...getPublicSettingsForScope(next, requestedCompanyId),
|
|
10752
10964
|
...scopedGitHubTokenLogin ? { githubTokenLogin: scopedGitHubTokenLogin } : {},
|
|
@@ -10787,15 +10999,16 @@ var plugin = definePlugin({
|
|
|
10787
10999
|
paperclipBoardAccessIdentityByCompanyId: _previousPaperclipBoardAccessIdentityByCompanyId,
|
|
10788
11000
|
...previousWithoutBoardAccess
|
|
10789
11001
|
} = previous;
|
|
10790
|
-
const
|
|
11002
|
+
const nextBase = sanitizeSettingsForCurrentSetup({
|
|
10791
11003
|
...previousWithoutBoardAccess,
|
|
10792
11004
|
...Object.keys(nextPaperclipBoardApiTokenRefs).length > 0 ? { paperclipBoardApiTokenRefs: nextPaperclipBoardApiTokenRefs } : {},
|
|
10793
11005
|
...Object.keys(nextPaperclipBoardAccessIdentityByCompanyId).length > 0 ? { paperclipBoardAccessIdentityByCompanyId: nextPaperclipBoardAccessIdentityByCompanyId } : {},
|
|
10794
11006
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10795
11007
|
}, {
|
|
10796
11008
|
hasToken: hasConfiguredGithubToken(previous, config, companyId),
|
|
10797
|
-
hasMappings:
|
|
11009
|
+
hasMappings: getSyncableMappingsForScope(previous.mappings, companyId).length > 0
|
|
10798
11010
|
});
|
|
11011
|
+
const next = materializeScopedSettings(nextBase, config, companyId);
|
|
10799
11012
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
10800
11013
|
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
10801
11014
|
return {
|
|
@@ -10866,7 +11079,7 @@ var plugin = definePlugin({
|
|
|
10866
11079
|
});
|
|
10867
11080
|
});
|
|
10868
11081
|
ctx.actions.register("sync.cancel", async () => {
|
|
10869
|
-
const currentSettings = await getActiveOrCurrentSyncState(ctx);
|
|
11082
|
+
const currentSettings = await getActiveOrCurrentSyncState(ctx, activeRunningSyncCompanyId);
|
|
10870
11083
|
if (currentSettings.syncState.status !== "running") {
|
|
10871
11084
|
return currentSettings;
|
|
10872
11085
|
}
|
|
@@ -10886,7 +11099,8 @@ var plugin = definePlugin({
|
|
|
10886
11099
|
progress: currentSettings.syncState.progress,
|
|
10887
11100
|
message: CANCELLING_SYNC_MESSAGE,
|
|
10888
11101
|
cancelRequestedAt: cancellationRequest.requestedAt
|
|
10889
|
-
})
|
|
11102
|
+
}),
|
|
11103
|
+
activeRunningSyncCompanyId
|
|
10890
11104
|
);
|
|
10891
11105
|
activeRunningSyncState = next;
|
|
10892
11106
|
return next;
|
|
@@ -10894,10 +11108,22 @@ var plugin = definePlugin({
|
|
|
10894
11108
|
registerGitHubAgentTools(ctx);
|
|
10895
11109
|
ctx.jobs.register("sync.github-issues", async (job) => {
|
|
10896
11110
|
const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
10897
|
-
|
|
11111
|
+
const trigger = job.trigger === "retry" ? "retry" : "schedule";
|
|
11112
|
+
const scheduledTargets = listScheduledSyncTargets(settings);
|
|
11113
|
+
if (scheduledTargets.length === 0) {
|
|
11114
|
+
if (job.trigger === "schedule" && !shouldRunScheduledSync(settings, job.scheduledAt)) {
|
|
11115
|
+
return;
|
|
11116
|
+
}
|
|
11117
|
+
await startSync(ctx, trigger);
|
|
10898
11118
|
return;
|
|
10899
11119
|
}
|
|
10900
|
-
|
|
11120
|
+
for (const target of scheduledTargets) {
|
|
11121
|
+
const scopedSettings = materializeScopedSettings(settings, null, target?.companyId);
|
|
11122
|
+
if (job.trigger === "schedule" && !shouldRunScheduledSync(scopedSettings, job.scheduledAt)) {
|
|
11123
|
+
continue;
|
|
11124
|
+
}
|
|
11125
|
+
await startSync(ctx, trigger, target ? { target } : {});
|
|
11126
|
+
}
|
|
10901
11127
|
});
|
|
10902
11128
|
}
|
|
10903
11129
|
});
|