deepline 0.3.423 → 0.3.424
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/dist/bundling-sources/sdk/src/client.ts +13 -6
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/fleets/verdict.ts +11 -1
- package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +38 -4
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +12 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-control-plane-capability.ts +25 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +201 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +42 -5
- package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +5 -0
- package/dist/cli/auth-MN7MWTFR.js +40 -0
- package/dist/cli/{auth-L7Q53QKK.mjs → auth-QITAQMHF.mjs} +4 -4
- package/dist/cli/{billing-QNP6YGI2.js → billing-N5AOFDSU.js} +73 -73
- package/dist/cli/{billing-IH7AKDR2.mjs → billing-UX2GH5L2.mjs} +4 -4
- package/dist/cli/{chunk-2U3AMRHF.js → chunk-22XGRO2M.js} +8 -8
- package/dist/cli/{chunk-ARTGL3FM.mjs → chunk-3FQUUVN2.mjs} +1 -1
- package/dist/cli/{chunk-QWJJMQNE.mjs → chunk-3O7KATMQ.mjs} +1 -1
- package/dist/cli/{chunk-4WT5RISA.js → chunk-3VB5DQ7Y.js} +20 -20
- package/dist/cli/{chunk-JDAXVQV7.mjs → chunk-5MD5I4MM.mjs} +1 -1
- package/dist/cli/{chunk-PH4BP6KM.mjs → chunk-5OBCPN2C.mjs} +2 -2
- package/dist/cli/{chunk-MMI2DXCW.js → chunk-5YLEB4CL.js} +8 -8
- package/dist/cli/{chunk-6FFORGD2.mjs → chunk-7KNBC4RJ.mjs} +1 -1
- package/dist/cli/{chunk-FJRFSBWO.mjs → chunk-7VC7STG5.mjs} +4 -4
- package/dist/cli/{chunk-YCHR57TD.js → chunk-7W4N6VRE.js} +35 -35
- package/dist/cli/{chunk-QN6DG4JO.mjs → chunk-7Y5M5YE3.mjs} +2 -2
- package/dist/cli/{chunk-DRK6FYJU.js → chunk-CJD5QKYK.js} +26 -26
- package/dist/cli/{chunk-EWWWOKX2.js → chunk-DD6MM6WX.js} +6 -6
- package/dist/cli/{chunk-OMWO2JLC.js → chunk-F3MMA7JY.js} +52 -52
- package/dist/cli/{chunk-H662SHPT.mjs → chunk-FJ5U2IZY.mjs} +8 -8
- package/dist/cli/{chunk-S6KG7JCR.mjs → chunk-HBW6PEVG.mjs} +2 -2
- package/dist/cli/{chunk-RAL75ND3.js → chunk-LSZZVHQP.js} +2 -2
- package/dist/cli/{chunk-AVOBDFQ5.js → chunk-M2VXDQI2.js} +10 -10
- package/dist/cli/{chunk-YNT7PJND.mjs → chunk-M67UCQKW.mjs} +3 -3
- package/dist/cli/{chunk-MHG3NND4.mjs → chunk-MFXQVT7P.mjs} +3 -3
- package/dist/cli/{chunk-PQ4G6MKI.js → chunk-OSNDC3VF.js} +16 -16
- package/dist/cli/{chunk-XSERB7H2.mjs → chunk-OWWFCA7A.mjs} +1 -1
- package/dist/cli/{chunk-WJO7KIFT.js → chunk-PNGJIAJ3.js} +50 -50
- package/dist/cli/{chunk-W42SSVM7.js → chunk-QP5ATTMC.js} +4 -4
- package/dist/cli/{chunk-5DGR3TB6.js → chunk-RISEING7.js} +2 -2
- package/dist/cli/{chunk-NFIZ5YED.mjs → chunk-UOZCQPD4.mjs} +2 -2
- package/dist/cli/{chunk-OPI7UCQG.mjs → chunk-UPH6UNUI.mjs} +1 -1
- package/dist/cli/{chunk-OZLMMMZH.js → chunk-UTF57UBW.js} +6 -6
- package/dist/cli/{chunk-IW5QK3K6.mjs → chunk-VC5NKF4B.mjs} +3 -3
- package/dist/cli/{chunk-2F5ULM2F.js → chunk-YA3LMTLU.js} +1 -1
- package/dist/cli/{chunk-NA6SGG7X.js → chunk-YMASNIC5.js} +79 -79
- package/dist/cli/{chunk-44US3EL2.mjs → chunk-ZMU2DDID.mjs} +5 -5
- package/dist/cli/{csv-5KW7M6ZS.mjs → csv-NM5IHLVM.mjs} +3 -3
- package/dist/cli/{csv-GF7VRES5.js → csv-RL53NPRV.js} +12 -12
- package/dist/cli/{db-NN4JQAC4.mjs → db-FZTIS4QG.mjs} +4 -4
- package/dist/cli/{db-AEDXKB4F.js → db-RJCFUM2J.js} +25 -25
- package/dist/cli/{describe-5RLXW332.js → describe-A2MGAI3Y.js} +16 -16
- package/dist/cli/{describe-RX6VROHQ.mjs → describe-T77IEILZ.mjs} +12 -12
- package/dist/cli/describe-core.d.mts +1 -1
- package/dist/cli/describe-core.d.ts +1 -1
- package/dist/cli/{executions-EJZ34VUB.mjs → executions-AMQK53QX.mjs} +4 -4
- package/dist/cli/{executions-PGIGFDDS.js → executions-R6UPRZ5N.js} +6 -6
- package/dist/cli/{feedback-6MWOKE7H.mjs → feedback-BA5ZHVCZ.mjs} +3 -3
- package/dist/cli/{feedback-L2ODMANV.js → feedback-JFT536KI.js} +7 -7
- package/dist/cli/{git-456RF3AT.mjs → git-5ONARXFO.mjs} +4 -4
- package/dist/cli/git-NHQR3NKF.js +24 -0
- package/dist/cli/index.js +131 -131
- package/dist/cli/index.mjs +36 -36
- package/dist/cli/{legacy-noops-ZPRBXQDE.mjs → legacy-noops-7J4K6QUX.mjs} +4 -4
- package/dist/cli/{legacy-noops-MDPB3MIS.js → legacy-noops-WT7M7WYD.js} +7 -7
- package/dist/cli/{monitors-ZLP6A7FT.mjs → monitors-N3WDXW7H.mjs} +17 -11
- package/dist/cli/{monitors-TXKR5XYW.js → monitors-YH6PKEIW.js} +97 -91
- package/dist/cli/{org-YZ62BIGM.mjs → org-2V5ELSYS.mjs} +4 -4
- package/dist/cli/{org-73SQ3AT2.js → org-KGYHMT5P.js} +64 -64
- package/dist/cli/{play-M75EBXEV.js → play-2JOQQRZI.js} +283 -283
- package/dist/cli/{play-VCYQKCKF.mjs → play-CL2LCBAF.mjs} +10 -10
- package/dist/cli/{providers-JLA6LST3.mjs → providers-I7EEPWNW.mjs} +4 -4
- package/dist/cli/{providers-GIINJPWQ.js → providers-VIP6MCWC.js} +7 -7
- package/dist/cli/{quickstart-HHHLYCHT.js → quickstart-33WC2KWE.js} +5 -5
- package/dist/cli/{quickstart-AHCU75GG.mjs → quickstart-VRBKQODE.mjs} +3 -3
- package/dist/cli/{search-5GACUIAX.mjs → search-7TDSKXOO.mjs} +5 -5
- package/dist/cli/search-A6RZZ4LK.js +30 -0
- package/dist/cli/{secrets-S2NBKAEN.mjs → secrets-DGLCIN7Y.mjs} +4 -4
- package/dist/cli/{secrets-PI7IPCOE.js → secrets-TQH5FXAC.js} +13 -13
- package/dist/cli/{sessions-BK4CSRFS.js → sessions-4D4UDPIS.js} +5 -5
- package/dist/cli/{sessions-IBKYGTBD.mjs → sessions-D6QGKQ2G.mjs} +4 -4
- package/dist/cli/{settings-JY6UN4KO.mjs → settings-6HVXBCVR.mjs} +8 -8
- package/dist/cli/{settings-2G7TUDM7.js → settings-V3QRG4AO.js} +75 -75
- package/dist/cli/{setup-R424FIBF.js → setup-6WP7D5I3.js} +42 -42
- package/dist/cli/{setup-HS5X3OSN.mjs → setup-CSJ3HSL7.mjs} +7 -7
- package/dist/cli/{skills-UIBUDTGN.mjs → skills-2MTWP4PS.mjs} +5 -5
- package/dist/cli/skills-QOYOARZT.js +29 -0
- package/dist/cli/{tools-SB4FREB6.mjs → tools-GAR3BWB6.mjs} +12 -12
- package/dist/cli/tools-MGEKAIOU.js +44 -0
- package/dist/cli/update-HMZCLFLZ.js +31 -0
- package/dist/cli/{update-NJSUE2YU.mjs → update-XV3WV3MU.mjs} +7 -7
- package/dist/cli/{workflow-HBG76XYX.mjs → workflow-DTZAWSB2.mjs} +5 -5
- package/dist/cli/{workflow-3AZWZ4J3.js → workflow-WNE7ORMT.js} +15 -15
- package/dist/{client-BTUOYGID.d.mts → client-BcfFWD4Z.d.mts} +9 -6
- package/dist/{client-C668iUhZ.d.ts → client-DH-fmT69.d.ts} +9 -6
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +80 -80
- package/dist/plays/play-description.d.mts +1 -1
- package/dist/plays/play-description.d.ts +1 -1
- package/dist/plays/run-request.d.mts +1 -1
- package/dist/plays/run-request.d.ts +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-SUNY477Y.js +0 -40
- package/dist/cli/git-2ZDCRTBD.js +0 -24
- package/dist/cli/search-W2PGBXQO.js +0 -30
- package/dist/cli/skills-M3RZAN4A.js +0 -29
- package/dist/cli/tools-K2GII2PA.js +0 -44
- package/dist/cli/update-C2ORJRXN.js +0 -31
|
@@ -1194,12 +1194,18 @@ export type MonitorsAvailableOptions = {
|
|
|
1194
1194
|
/**
|
|
1195
1195
|
* Stable customer-facing Monitor/Fleet state.
|
|
1196
1196
|
*
|
|
1197
|
-
*
|
|
1198
|
-
*
|
|
1199
|
-
*
|
|
1200
|
-
*
|
|
1197
|
+
* `provisioning` is a monitor whose create was recorded but that the provider
|
|
1198
|
+
* has not confirmed yet; it delivers no events and does not bill until it
|
|
1199
|
+
* becomes `active`. A Fleet is never `provisioning`. Provider cleanup,
|
|
1200
|
+
* retries, and failures are Monitor Job progress and must never be added to
|
|
1201
|
+
* this union. The `status` and `active` fields below are retained only as
|
|
1202
|
+
* deprecated compatibility aliases for older API responses.
|
|
1201
1203
|
*/
|
|
1202
|
-
export type MonitorState =
|
|
1204
|
+
export type MonitorState =
|
|
1205
|
+
| 'active'
|
|
1206
|
+
| 'provisioning'
|
|
1207
|
+
| 'billing_suspended'
|
|
1208
|
+
| 'disabled';
|
|
1203
1209
|
|
|
1204
1210
|
/** List filters accepted by the canonical state surface. */
|
|
1205
1211
|
export type MonitorStateFilter = MonitorState | 'all';
|
|
@@ -1873,7 +1879,8 @@ export type MonitorsNamespace = {
|
|
|
1873
1879
|
options?: MonitorLifecycleOptions,
|
|
1874
1880
|
) => Promise<MonitorJobResult | MonitorDeployResult>;
|
|
1875
1881
|
/** List deployed monitors (active by default). Use `state` to filter the
|
|
1876
|
-
*
|
|
1882
|
+
* four customer states (`active`, `provisioning`, `billing_suspended`,
|
|
1883
|
+
* `disabled`); `status` is retained for older servers.
|
|
1877
1884
|
* `includeConsumers` requires a limit of 20 or fewer. */
|
|
1878
1885
|
list: (options?: MonitorsListOptions) => Promise<MonitorsListResult>;
|
|
1879
1886
|
/** Fetch one deployed monitor by public key with bounded current listener health. */
|
|
@@ -205,7 +205,7 @@ export const SDK_RELEASE = {
|
|
|
205
205
|
// getters keep their established compatibility behavior.
|
|
206
206
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
207
207
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
208
|
-
version: '0.3.
|
|
208
|
+
version: '0.3.424',
|
|
209
209
|
updateSummary: {
|
|
210
210
|
introducedIn: '0.3.90',
|
|
211
211
|
summary:
|
|
@@ -46,6 +46,16 @@ export type FleetStatusVerdict =
|
|
|
46
46
|
| 'billing_suspended'
|
|
47
47
|
| 'billing_reactivating';
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* A Fleet's customer state. A Fleet has no `provisioning` state: its first
|
|
51
|
+
* convergence is reported by the durable Fleet operation, while each member
|
|
52
|
+
* monitor still pending its create reports `provisioning` itself.
|
|
53
|
+
*/
|
|
54
|
+
export type FleetCustomerState = Exclude<
|
|
55
|
+
ProviderMonitorCustomerState,
|
|
56
|
+
'provisioning'
|
|
57
|
+
>;
|
|
58
|
+
|
|
49
59
|
/**
|
|
50
60
|
* The Fleet's stable customer state. Convergence and lifecycle transitions are
|
|
51
61
|
* reported by the durable Fleet operation, not by growing this union.
|
|
@@ -54,7 +64,7 @@ export function fleetCustomerState(input: {
|
|
|
54
64
|
lifecycle: FleetLifecycleStatus;
|
|
55
65
|
verdict: FleetStatusVerdict;
|
|
56
66
|
convergedGeneration: number | null;
|
|
57
|
-
}):
|
|
67
|
+
}): FleetCustomerState {
|
|
58
68
|
switch (input.lifecycle) {
|
|
59
69
|
case 'billing_suspending':
|
|
60
70
|
case 'billing_suspended':
|
|
@@ -9,6 +9,17 @@ export type InventoryDecision = {
|
|
|
9
9
|
radarId?: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Desynced definition findings that audit-scoped repair acts on. Every other
|
|
14
|
+
* desynced reason is resolved elsewhere (operator bind, orphan cleanup), so
|
|
15
|
+
* submitting repair for it would be a no-op that recurs every audit.
|
|
16
|
+
*/
|
|
17
|
+
export const GLOBAL_AUDIT_REPAIRABLE_REASONS: ReadonlySet<string> = new Set([
|
|
18
|
+
'missing_tamradar_radar',
|
|
19
|
+
'tamradar_state_differs',
|
|
20
|
+
'tamradar_configuration_differs',
|
|
21
|
+
]);
|
|
22
|
+
|
|
12
23
|
/** Call only after BOTH inventories completed. Absence is otherwise unknown. */
|
|
13
24
|
export function compareMonitorInventory(input: {
|
|
14
25
|
desired: 'active' | 'inactive';
|
|
@@ -24,20 +35,43 @@ export function compareMonitorInventory(input: {
|
|
|
24
35
|
if (!resourceId) {
|
|
25
36
|
if (marker.length > 1)
|
|
26
37
|
return { verdict: 'unknown', reason: 'ambiguous_tamradar_binding' };
|
|
27
|
-
|
|
38
|
+
const stamped = marker[0];
|
|
39
|
+
if (stamped && desired === 'active')
|
|
28
40
|
return {
|
|
29
41
|
verdict: 'desynced',
|
|
30
42
|
reason: 'adoptable_tamradar_radar',
|
|
31
|
-
radarId:
|
|
43
|
+
radarId: stamped.id,
|
|
32
44
|
};
|
|
45
|
+
// An inactive definition never adopts: binding refuses a row that may not
|
|
46
|
+
// occupy an upstream identity. Its stamped radar is either already closed
|
|
47
|
+
// or a live leftover that provider-side orphan cleanup owns.
|
|
48
|
+
if (stamped) {
|
|
49
|
+
if (stamped.status === 'unknown')
|
|
50
|
+
return {
|
|
51
|
+
verdict: 'unknown',
|
|
52
|
+
reason: 'unknown_tamradar_state',
|
|
53
|
+
radarId: stamped.id,
|
|
54
|
+
};
|
|
55
|
+
return stamped.status === 'inactive'
|
|
56
|
+
? { verdict: 'converged', reason: 'in_sync', radarId: stamped.id }
|
|
57
|
+
: {
|
|
58
|
+
verdict: 'desynced',
|
|
59
|
+
reason: 'orphaned_tamradar_radar',
|
|
60
|
+
radarId: stamped.id,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
33
63
|
}
|
|
34
64
|
const radar = exact[0];
|
|
35
65
|
if (!radar) {
|
|
36
66
|
if (!resourceId) {
|
|
37
67
|
// A complete account list proves that no stamped counterpart exists; it
|
|
38
68
|
// cannot prove which resource an unbound historical row used to own.
|
|
39
|
-
// Creation or adoption is a separate, explicit operator operation.
|
|
40
|
-
|
|
69
|
+
// Creation or adoption is a separate, explicit operator operation. An
|
|
70
|
+
// inactive row wants nothing upstream, and a markerless legacy radar is
|
|
71
|
+
// reported on the provider side as unattributed, so it has converged.
|
|
72
|
+
return desired === 'inactive'
|
|
73
|
+
? { verdict: 'converged', reason: 'in_sync' }
|
|
74
|
+
: { verdict: 'unknown', reason: 'missing_tamradar_binding' };
|
|
41
75
|
}
|
|
42
76
|
return desired === 'inactive'
|
|
43
77
|
? { verdict: 'converged', reason: 'in_sync' }
|
|
@@ -235,6 +235,18 @@ export function providerMonitorBatchOperationId(input: {
|
|
|
235
235
|
return `monitor-batch:${orgId}:${idempotencyKey}`;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/**
|
|
239
|
+
* The lifecycle operation one batch run creates one monitor under. A row the
|
|
240
|
+
* run writes ahead names it, and its settle publishes under it, so both must
|
|
241
|
+
* derive it here.
|
|
242
|
+
*/
|
|
243
|
+
export function providerMonitorBatchCreateOperationId(
|
|
244
|
+
runId: string,
|
|
245
|
+
monitorKey: string,
|
|
246
|
+
): string {
|
|
247
|
+
return `${runId}:provider-create:${monitorKey}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
238
250
|
export function isProviderMonitorBatchOperationKind(
|
|
239
251
|
value: string,
|
|
240
252
|
): value is ProviderMonitorBatchOperationKind {
|
package/dist/bundling-sources/shared_libs/monitors/provider-monitor-control-plane-capability.ts
CHANGED
|
@@ -37,6 +37,31 @@ export function providerMonitorBatchOperationContinuationSecret(
|
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* TEMPORARY(#8221), disabled. Uncomment this, its re-export in
|
|
42
|
+
* apps/deepline-api/src/lib/monitors/provider-monitor-control-plane-capability.ts,
|
|
43
|
+
* the `expected` line in the five webhook-reconciliation continuation routes,
|
|
44
|
+
* and `reconciliationSecret` in scripts/lib/monitor-load-test-dispatch-config.ts
|
|
45
|
+
* together to let the update-feed reconciliation self-drive on a Preview.
|
|
46
|
+
*
|
|
47
|
+
* The webhook-reconciliation continuation routes accept only the dedicated
|
|
48
|
+
* secret, which Preview does not carry, so the update-feed reconciliation can
|
|
49
|
+
* never self-drive on a Preview and the monitor load test's Stage 2 cannot
|
|
50
|
+
* exercise it. On a Vercel Preview with no dedicated secret, this also accepts
|
|
51
|
+
* the capability derived from the Preview internal token, which the load-test
|
|
52
|
+
* driver sets on the branch Convex. Production carries the dedicated secret
|
|
53
|
+
* and is unaffected.
|
|
54
|
+
*/
|
|
55
|
+
// export function providerMonitorReconciliationContinuationSecret(
|
|
56
|
+
// env: Record<string, string | undefined> = process.env,
|
|
57
|
+
// ): string | undefined {
|
|
58
|
+
// const dedicated = env[LEGACY_SECRET_ENV]?.trim();
|
|
59
|
+
// if (dedicated) return dedicated;
|
|
60
|
+
// return env.VERCEL_ENV === 'preview'
|
|
61
|
+
// ? derivedControlPlaneCapability(env)
|
|
62
|
+
// : undefined;
|
|
63
|
+
// }
|
|
64
|
+
|
|
40
65
|
export function providerMonitorGlobalAuditContinuationSecret(
|
|
41
66
|
env: Record<string, string | undefined> = process.env,
|
|
42
67
|
): string | undefined {
|
|
@@ -121,6 +121,16 @@ export class ProviderMonitorDeleteOperationInProgressError extends Error {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/** A deploy found the monitor stopped or deleted after it was submitted. */
|
|
125
|
+
export class ProviderMonitorStoppedAfterSubmitError extends Error {
|
|
126
|
+
constructor(readonly monitorKey: string) {
|
|
127
|
+
super(
|
|
128
|
+
`Monitor "${monitorKey}" was stopped or deleted after this deploy was submitted, so the deploy left it as it is. Deploy it again to turn it back on.`,
|
|
129
|
+
);
|
|
130
|
+
this.name = 'ProviderMonitorStoppedAfterSubmitError';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
124
134
|
export class PriorityMonitorExecutionLimitError extends Error {
|
|
125
135
|
constructor(readonly max: number) {
|
|
126
136
|
super(
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ProviderMonitorIdentityBackfillInProgressError,
|
|
7
7
|
ProviderMonitorEntityLimitExceededError,
|
|
8
8
|
ProviderMonitorOrgLimitExceededError,
|
|
9
|
+
type ProviderMonitorCapacitySnapshot,
|
|
9
10
|
} from '@deepline/monitors/provider-monitor-errors';
|
|
10
11
|
import { MAX_PRIORITY_MONITORS_PER_ORG } from '@deepline/monitors/provider-monitor-priority-execution';
|
|
11
12
|
import { internal } from '@deepline/convex-client/function-references';
|
|
@@ -374,6 +375,206 @@ export async function beginProviderMonitorLifecycleReservation(input: {
|
|
|
374
375
|
});
|
|
375
376
|
}
|
|
376
377
|
|
|
378
|
+
/** Keys one batch provisioning call fences: Convex's own 100-key bound. */
|
|
379
|
+
const PROVISIONING_BATCH_CHUNK = 100;
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* One item's lifecycle admission, decided for its whole chunk ahead of time.
|
|
383
|
+
*
|
|
384
|
+
* Calling it yields exactly what `beginProviderMonitorLifecycleReservation`
|
|
385
|
+
* would have yielded for the item - the same reservation, or the same typed
|
|
386
|
+
* refusal thrown - so a caller can swap one for the other per item.
|
|
387
|
+
*/
|
|
388
|
+
export type ProviderMonitorLifecycleAdmission =
|
|
389
|
+
() => Promise<ProviderMonitorLifecycleReservation>;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Begin the provisioning fence for many new monitors, taking organization
|
|
393
|
+
* capacity once per chunk of 100 instead of once per item.
|
|
394
|
+
*
|
|
395
|
+
* Per chunk: one query counts which accounts already carry a monitor, one
|
|
396
|
+
* short mutation (`reserveProvisioningCapacityAdmission`) takes allowance for
|
|
397
|
+
* the accounts the chunk will open, and one transaction
|
|
398
|
+
* (`beginLifecycleProvisioningBatch`) fences every item against that grant
|
|
399
|
+
* without touching the organization fence. Items the grant cannot decide
|
|
400
|
+
* exactly are admitted by the scalar path when their admission is called.
|
|
401
|
+
*
|
|
402
|
+
* Asking for exactly the accounts with no monitor yet keeps the grant from
|
|
403
|
+
* holding allowance a concurrent job could use. Planning can race another
|
|
404
|
+
* writer either way: an account opened meanwhile simply hands its unit back
|
|
405
|
+
* when the chunk settles, and an item that needs a unit nobody asked for is
|
|
406
|
+
* handed to the scalar path - never refused by a limit the fence did not hit.
|
|
407
|
+
*/
|
|
408
|
+
export async function beginProviderMonitorProvisioningBatch(input: {
|
|
409
|
+
auth: OrgAuthContext;
|
|
410
|
+
items: ReadonlyArray<{
|
|
411
|
+
monitorKey: string;
|
|
412
|
+
operationId: string;
|
|
413
|
+
entityKey?: string | null;
|
|
414
|
+
}>;
|
|
415
|
+
}): Promise<Map<string, ProviderMonitorLifecycleAdmission>> {
|
|
416
|
+
const client = getRequiredInternalConvexClient();
|
|
417
|
+
const orgId = input.auth.orgId;
|
|
418
|
+
const admissions = new Map<string, ProviderMonitorLifecycleAdmission>();
|
|
419
|
+
const scalar =
|
|
420
|
+
(item: (typeof input.items)[number]): ProviderMonitorLifecycleAdmission =>
|
|
421
|
+
() =>
|
|
422
|
+
beginProviderMonitorLifecycleReservation({
|
|
423
|
+
auth: input.auth,
|
|
424
|
+
monitorKey: item.monitorKey,
|
|
425
|
+
operationId: item.operationId,
|
|
426
|
+
entityKey: item.entityKey ?? null,
|
|
427
|
+
state: 'provisioning',
|
|
428
|
+
});
|
|
429
|
+
for (
|
|
430
|
+
let offset = 0;
|
|
431
|
+
offset < input.items.length;
|
|
432
|
+
offset += PROVISIONING_BATCH_CHUNK
|
|
433
|
+
) {
|
|
434
|
+
const chunk = input.items.slice(offset, offset + PROVISIONING_BATCH_CHUNK);
|
|
435
|
+
const entityKeyOf = (item: (typeof chunk)[number]) =>
|
|
436
|
+
item.entityKey || `monitor:${item.monitorKey}`;
|
|
437
|
+
const entityKeys = [...new Set(chunk.map(entityKeyOf))];
|
|
438
|
+
const counts = (await client.query(
|
|
439
|
+
internal.providerMonitorCapacity.countMonitorsByEntities,
|
|
440
|
+
{ orgId, entityKeys },
|
|
441
|
+
)) as Array<{ entityKey: string; monitors: number }>;
|
|
442
|
+
const requested = counts.filter((count) => count.monitors === 0).length;
|
|
443
|
+
const reservationId = `direct-batch-provisioning:${randomUUID()}`;
|
|
444
|
+
const admission =
|
|
445
|
+
requested > 0
|
|
446
|
+
? ((await retryProviderMonitorLifecycleAdmission(() =>
|
|
447
|
+
client.mutation(
|
|
448
|
+
internal.providerMonitorCapacity
|
|
449
|
+
.reserveProvisioningCapacityAdmission,
|
|
450
|
+
{ orgId, reservationId, requested },
|
|
451
|
+
),
|
|
452
|
+
)) as {
|
|
453
|
+
granted: number;
|
|
454
|
+
capacity: ProviderMonitorCapacitySnapshot & {
|
|
455
|
+
monitors_per_entity: number;
|
|
456
|
+
};
|
|
457
|
+
})
|
|
458
|
+
: null;
|
|
459
|
+
let batch: {
|
|
460
|
+
items: Array<
|
|
461
|
+
| { monitorKey: string; kind: 'acquired' }
|
|
462
|
+
| {
|
|
463
|
+
monitorKey: string;
|
|
464
|
+
kind: 'in_progress' | 'deleting';
|
|
465
|
+
state: 'provisioning' | 'deleting';
|
|
466
|
+
retryAt: number;
|
|
467
|
+
}
|
|
468
|
+
| { monitorKey: string; kind: 'limit_exceeded' }
|
|
469
|
+
| {
|
|
470
|
+
monitorKey: string;
|
|
471
|
+
kind: 'entity_limit_exceeded';
|
|
472
|
+
entityKey: string;
|
|
473
|
+
monitorsPerEntity: number;
|
|
474
|
+
}
|
|
475
|
+
| { monitorKey: string; kind: 'cleanup_blocked' }
|
|
476
|
+
| { monitorKey: string; kind: 'fallback' }
|
|
477
|
+
>;
|
|
478
|
+
};
|
|
479
|
+
try {
|
|
480
|
+
batch = await retryProviderMonitorLifecycleAdmission(() =>
|
|
481
|
+
client.mutation(
|
|
482
|
+
internal.providerMonitorIdentityClaims
|
|
483
|
+
.beginLifecycleProvisioningBatch,
|
|
484
|
+
{
|
|
485
|
+
orgId,
|
|
486
|
+
...(admission ? { reservationId } : {}),
|
|
487
|
+
items: chunk.map((item) => ({
|
|
488
|
+
monitorKey: item.monitorKey,
|
|
489
|
+
operationId: item.operationId,
|
|
490
|
+
entityKey: entityKeyOf(item),
|
|
491
|
+
})),
|
|
492
|
+
},
|
|
493
|
+
),
|
|
494
|
+
);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
// Hand the grant back now rather than when it expires. Safe whether or
|
|
497
|
+
// not the batch committed: a committed batch consumed the grant, and
|
|
498
|
+
// releasing a consumed grant is a no-op.
|
|
499
|
+
if (admission && admission.granted > 0) {
|
|
500
|
+
await client
|
|
501
|
+
.mutation(
|
|
502
|
+
internal.providerMonitorCapacity.releaseExpiredOrgCapacityAdmission,
|
|
503
|
+
{ orgId, reservationId },
|
|
504
|
+
)
|
|
505
|
+
.catch(() => undefined);
|
|
506
|
+
}
|
|
507
|
+
// Every item of the chunk fails the way its own admission would have
|
|
508
|
+
// failed, on its own retry path; the error is not swallowed.
|
|
509
|
+
for (const item of chunk) {
|
|
510
|
+
admissions.set(item.monitorKey, () => Promise.reject(error));
|
|
511
|
+
}
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
const byKey = new Map(chunk.map((item) => [item.monitorKey, item]));
|
|
515
|
+
for (const result of batch.items) {
|
|
516
|
+
const item = byKey.get(result.monitorKey);
|
|
517
|
+
if (!item) {
|
|
518
|
+
throw new Error(
|
|
519
|
+
`Provider monitor batch provisioning answered for unknown monitor ${result.monitorKey}.`,
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
byKey.delete(result.monitorKey);
|
|
523
|
+
switch (result.kind) {
|
|
524
|
+
case 'acquired':
|
|
525
|
+
case 'in_progress':
|
|
526
|
+
case 'deleting': {
|
|
527
|
+
const reservation = normalizeProviderMonitorLifecycleReservation({
|
|
528
|
+
result,
|
|
529
|
+
state: 'provisioning',
|
|
530
|
+
operationId: item.operationId,
|
|
531
|
+
});
|
|
532
|
+
admissions.set(item.monitorKey, async () => reservation);
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
case 'limit_exceeded': {
|
|
536
|
+
if (!admission) {
|
|
537
|
+
throw new Error(
|
|
538
|
+
'Provider monitor batch provisioning refused an account it was never asked to grant.',
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
const capacity = admission.capacity;
|
|
542
|
+
admissions.set(item.monitorKey, () =>
|
|
543
|
+
Promise.reject(new ProviderMonitorOrgLimitExceededError(capacity)),
|
|
544
|
+
);
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case 'entity_limit_exceeded':
|
|
548
|
+
admissions.set(item.monitorKey, () =>
|
|
549
|
+
Promise.reject(
|
|
550
|
+
new ProviderMonitorEntityLimitExceededError(
|
|
551
|
+
result.entityKey,
|
|
552
|
+
result.monitorsPerEntity,
|
|
553
|
+
),
|
|
554
|
+
),
|
|
555
|
+
);
|
|
556
|
+
break;
|
|
557
|
+
case 'cleanup_blocked':
|
|
558
|
+
admissions.set(item.monitorKey, () =>
|
|
559
|
+
Promise.reject(
|
|
560
|
+
new ProviderMonitorCapacityCleanupRequiredError(item.monitorKey),
|
|
561
|
+
),
|
|
562
|
+
);
|
|
563
|
+
break;
|
|
564
|
+
case 'fallback':
|
|
565
|
+
admissions.set(item.monitorKey, scalar(item));
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (byKey.size > 0) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
'Provider monitor batch provisioning did not answer for every monitor key.',
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return admissions;
|
|
576
|
+
}
|
|
577
|
+
|
|
377
578
|
async function ensureProviderMonitorCapacityBackfill(input: {
|
|
378
579
|
auth: OrgAuthContext;
|
|
379
580
|
}) {
|
|
@@ -7,11 +7,16 @@ export type ProviderMonitorDeletionObservation = {
|
|
|
7
7
|
/**
|
|
8
8
|
* The complete customer-visible lifecycle of a monitor.
|
|
9
9
|
*
|
|
10
|
+
* `provisioning` means the monitor was accepted and recorded, but the provider
|
|
11
|
+
* has not yet confirmed that it exists: it does not deliver events or bill
|
|
12
|
+
* until the create commits and the monitor becomes `active`.
|
|
13
|
+
*
|
|
10
14
|
* Provider work, retries, and audit evidence intentionally live on separate
|
|
11
15
|
* axes. They must never become additional values in this union.
|
|
12
16
|
*/
|
|
13
17
|
export type ProviderMonitorCustomerState =
|
|
14
18
|
| 'active'
|
|
19
|
+
| 'provisioning'
|
|
15
20
|
| 'billing_suspended'
|
|
16
21
|
| 'disabled';
|
|
17
22
|
|
|
@@ -21,6 +26,32 @@ export type ProviderMonitorCustomerState =
|
|
|
21
26
|
*/
|
|
22
27
|
export type ProviderMonitorState = 'active' | 'inactive';
|
|
23
28
|
|
|
29
|
+
/**
|
|
30
|
+
* True when a deploy submitted at `submittedAt` must leave this monitor
|
|
31
|
+
* alone: its desired state was turned inactive, or it was deleted, after the
|
|
32
|
+
* deploy was submitted. That stop is newer customer (or policy) intent. A row
|
|
33
|
+
* without `desiredChangedAt`, or a deploy without `submittedAt`, keeps the
|
|
34
|
+
* earlier behavior.
|
|
35
|
+
*/
|
|
36
|
+
export function providerMonitorStoppedAfter(
|
|
37
|
+
row: {
|
|
38
|
+
status?: string;
|
|
39
|
+
desired?: ProviderMonitorState;
|
|
40
|
+
desiredChangedAt?: number;
|
|
41
|
+
},
|
|
42
|
+
submittedAt: number | undefined,
|
|
43
|
+
): boolean {
|
|
44
|
+
if (submittedAt === undefined || row.desiredChangedAt === undefined) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (row.desiredChangedAt <= submittedAt) return false;
|
|
48
|
+
return (
|
|
49
|
+
row.status === 'deleted' ||
|
|
50
|
+
row.status === 'deleting' ||
|
|
51
|
+
row.desired === 'inactive'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
export type ProviderMonitorStatusAlias = ProviderMonitorState;
|
|
25
56
|
|
|
26
57
|
declare const providerMonitorResourceIdBrand: unique symbol;
|
|
@@ -127,10 +158,11 @@ export function providerMonitorCustomerStateForBillingState(
|
|
|
127
158
|
|
|
128
159
|
/**
|
|
129
160
|
* The single public monitor-state projection. A billing suspension owns the
|
|
130
|
-
* off state.
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
161
|
+
* off state. A `pending_create` lifecycle is `provisioning`: the create was
|
|
162
|
+
* recorded but the provider has not confirmed the resource. Otherwise `active`
|
|
163
|
+
* is operational proof: a committed active lifecycle and a non-empty provider
|
|
164
|
+
* resource binding. Internal billing bookkeeping such as an unresolved usage
|
|
165
|
+
* charge must not make a usable provider resource look disabled.
|
|
134
166
|
*/
|
|
135
167
|
export function providerMonitorCustomerState(input: {
|
|
136
168
|
lifecycleStatus?: string | null;
|
|
@@ -141,6 +173,7 @@ export function providerMonitorCustomerState(input: {
|
|
|
141
173
|
input.billingState,
|
|
142
174
|
);
|
|
143
175
|
if (billingState === 'billing_suspended') return billingState;
|
|
176
|
+
if (input.lifecycleStatus === 'pending_create') return 'provisioning';
|
|
144
177
|
|
|
145
178
|
const providerResourceId = providerMonitorResourceId(
|
|
146
179
|
input.providerResourceId,
|
|
@@ -151,7 +184,11 @@ export function providerMonitorCustomerState(input: {
|
|
|
151
184
|
return 'disabled';
|
|
152
185
|
}
|
|
153
186
|
|
|
154
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* Deprecated compatibility projection for the old `status`/`active` keys. The
|
|
189
|
+
* alias stays two-valued: every non-active state, including `provisioning`,
|
|
190
|
+
* is `inactive`.
|
|
191
|
+
*/
|
|
155
192
|
export function providerMonitorStatusAlias(
|
|
156
193
|
state: ProviderMonitorCustomerState,
|
|
157
194
|
): ProviderMonitorStatusAlias {
|
|
@@ -94,16 +94,21 @@ function managedWebhookName(input: {
|
|
|
94
94
|
/**
|
|
95
95
|
* Resolve the externally reachable origin for provider callbacks and durable
|
|
96
96
|
* workers. Local Convex actions need the preview tunnel, not a loopback URL.
|
|
97
|
+
* A Vercel Preview shares its app URL settings with Production, so without
|
|
98
|
+
* an explicit origin it calls back to its own deployment, never Production.
|
|
97
99
|
*/
|
|
98
100
|
export function resolveProviderMonitorCallbackBaseUrl(
|
|
99
101
|
explicit?: string | null,
|
|
100
102
|
environment: NodeJS.ProcessEnv = process.env,
|
|
101
103
|
) {
|
|
104
|
+
const previewDeployment =
|
|
105
|
+
environment.VERCEL_ENV === 'preview' ? environment.VERCEL_URL : undefined;
|
|
102
106
|
const baseUrl =
|
|
103
107
|
explicit ||
|
|
104
108
|
environment.DEEPLINE_WORKER_CALLBACK_URL ||
|
|
105
109
|
readPreviewCallbackUrlFile(environment) ||
|
|
106
110
|
environment.WORKTREE_PUBLIC_APP_URL ||
|
|
111
|
+
previewDeployment ||
|
|
107
112
|
environment.DEEPLINE_API_BASE_URL ||
|
|
108
113
|
environment.NEXT_PUBLIC_APP_URL ||
|
|
109
114
|
environment.APP_URL ||
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunkPNGJIAJ3js = require('./chunk-PNGJIAJ3.js');
|
|
17
|
+
require('./chunk-DD6MM6WX.js');
|
|
18
|
+
require('./chunk-QP5ATTMC.js');
|
|
19
|
+
require('./chunk-NPBJI7RE.js');
|
|
20
|
+
require('./chunk-XNYIZMNQ.js');
|
|
21
|
+
require('./chunk-PPDBRJRW.js');
|
|
22
|
+
require('./chunk-YA3LMTLU.js');
|
|
23
|
+
require('./chunk-OG64RBAC.js');
|
|
24
|
+
require('./chunk-COGTRVWW.js');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
exports.EXIT_WORKSPACE_MISMATCH = _chunkPNGJIAJ3js.EXIT_WORKSPACE_MISMATCH; exports.authStatusLine = _chunkPNGJIAJ3js.authStatusLine; exports.clearPendingClaim = _chunkPNGJIAJ3js.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkPNGJIAJ3js.clearSatisfiedPendingClaim; exports.handleRegister = _chunkPNGJIAJ3js.handleRegister; exports.handleStatus = _chunkPNGJIAJ3js.handleStatus; exports.handleWait = _chunkPNGJIAJ3js.handleWait; exports.httpJson = _chunkPNGJIAJ3js.httpJson; exports.readPendingAuthClaim = _chunkPNGJIAJ3js.readPendingAuthClaim; exports.readStatusBanner = _chunkPNGJIAJ3js.readStatusBanner; exports.registerAuthCommands = _chunkPNGJIAJ3js.registerAuthCommands; exports.reportSetupCompleted = _chunkPNGJIAJ3js.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkPNGJIAJ3js.resolvePendingAuthClaimForResume; exports.statusBannerLine = _chunkPNGJIAJ3js.statusBannerLine;
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
reportSetupCompleted,
|
|
14
14
|
resolvePendingAuthClaimForResume,
|
|
15
15
|
statusBannerLine
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-UOZCQPD4.mjs";
|
|
17
|
+
import "./chunk-3O7KATMQ.mjs";
|
|
18
|
+
import "./chunk-OWWFCA7A.mjs";
|
|
19
19
|
import "./chunk-MAMVGOSC.mjs";
|
|
20
20
|
import "./chunk-DLIRSHV6.mjs";
|
|
21
21
|
import "./chunk-E4IXDAZI.mjs";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-5MD5I4MM.mjs";
|
|
23
23
|
import "./chunk-WZYKRD7T.mjs";
|
|
24
24
|
import "./chunk-KRD6H754.mjs";
|
|
25
25
|
export {
|