@neocompose/cli 0.6.0 → 0.6.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/CHANGELOG.md +9 -0
- package/dist/neo.mjs +1054 -85
- package/package.json +1 -1
package/dist/neo.mjs
CHANGED
|
@@ -26173,6 +26173,9 @@ var init_merge = __esm({
|
|
|
26173
26173
|
});
|
|
26174
26174
|
|
|
26175
26175
|
// src/project-manifest/merge.ts
|
|
26176
|
+
function isSchemaDocumentRecordKind(recordKind) {
|
|
26177
|
+
return Object.hasOwn(SCHEMA_DOCUMENT_FIELD_CONTRACTS, recordKind);
|
|
26178
|
+
}
|
|
26176
26179
|
function schemaDocumentSemanticallyEqual(recordKind, left, right) {
|
|
26177
26180
|
return canonicallyEqual(
|
|
26178
26181
|
normalizeDocumentForComparison(recordKind, left, "left"),
|
|
@@ -28256,29 +28259,38 @@ function genericConstraint(context, type) {
|
|
|
28256
28259
|
};
|
|
28257
28260
|
}
|
|
28258
28261
|
function inheritedMemberId(context, ownerClass, name) {
|
|
28259
|
-
const
|
|
28262
|
+
const directBase = ownerClass.baseTypes.find(
|
|
28260
28263
|
(entry) => context.classIdsByName.has(entry.name)
|
|
28261
28264
|
);
|
|
28262
|
-
|
|
28263
|
-
const
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
|
|
28270
|
-
|
|
28271
|
-
|
|
28272
|
-
|
|
28273
|
-
|
|
28274
|
-
|
|
28275
|
-
|
|
28276
|
-
|
|
28277
|
-
|
|
28278
|
-
|
|
28279
|
-
|
|
28280
|
-
|
|
28281
|
-
|
|
28265
|
+
let classId = directBase ? requiredName(context.classIdsByName, directBase.name, "class") : null;
|
|
28266
|
+
const visited = /* @__PURE__ */ new Set();
|
|
28267
|
+
while (classId !== null && !visited.has(classId)) {
|
|
28268
|
+
visited.add(classId);
|
|
28269
|
+
const sourceClass = context.sourceClasses.get(classId);
|
|
28270
|
+
if (sourceClass !== void 0) {
|
|
28271
|
+
const sourceMember = sourceClass.members.find(
|
|
28272
|
+
(member) => member.name === name
|
|
28273
|
+
);
|
|
28274
|
+
if (sourceMember !== void 0) {
|
|
28275
|
+
return materializedId(
|
|
28276
|
+
sourceMember,
|
|
28277
|
+
"member",
|
|
28278
|
+
`${sourceClass.name}.${sourceMember.name}`
|
|
28279
|
+
);
|
|
28280
|
+
}
|
|
28281
|
+
const sourceBase = sourceClass.baseTypes.find(
|
|
28282
|
+
(entry) => context.classIdsByName.has(entry.name)
|
|
28283
|
+
);
|
|
28284
|
+
classId = sourceBase ? requiredName(context.classIdsByName, sourceBase.name, "class") : null;
|
|
28285
|
+
continue;
|
|
28286
|
+
}
|
|
28287
|
+
const pulledClass = context.baseClasses.get(classId);
|
|
28288
|
+
if (pulledClass === void 0) return null;
|
|
28289
|
+
const memberId = pulledClass.schema[name];
|
|
28290
|
+
if (memberId !== void 0) return memberId;
|
|
28291
|
+
classId = pulledClass.extendsClassId;
|
|
28292
|
+
}
|
|
28293
|
+
return null;
|
|
28282
28294
|
}
|
|
28283
28295
|
function resolveQualifiedMemberId(context, expression) {
|
|
28284
28296
|
const match = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(
|
|
@@ -39728,6 +39740,7 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
|
|
|
39728
39740
|
if (record3.recordKind === "value") pulledValueIds.add(record3.recordId);
|
|
39729
39741
|
}
|
|
39730
39742
|
const memberDefaultValues = /* @__PURE__ */ new Map();
|
|
39743
|
+
const seeds = /* @__PURE__ */ new Map();
|
|
39731
39744
|
for (const sourceClass of analysis.schema.classes) {
|
|
39732
39745
|
for (const declaration of sourceClass.members) {
|
|
39733
39746
|
if (declaration.kind !== "field" || declaration.initializer === null) {
|
|
@@ -39736,13 +39749,6 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
|
|
|
39736
39749
|
if (declaration.modifiers.includes("static")) continue;
|
|
39737
39750
|
const label = `${sourceClass.name}.${declaration.name}`;
|
|
39738
39751
|
const memberId = sourceIdentityId(declaration, "member", label);
|
|
39739
|
-
const baseData3 = stateData(context, "member", memberId);
|
|
39740
|
-
if (baseData3 === null) continue;
|
|
39741
|
-
const backed = rowBackedDefaultBody(
|
|
39742
|
-
baseData3,
|
|
39743
|
-
(id2) => pulledValueIds.has(id2)
|
|
39744
|
-
);
|
|
39745
|
-
if (backed === null) continue;
|
|
39746
39752
|
const member = context.members.get(memberId);
|
|
39747
39753
|
if (member === void 0) continue;
|
|
39748
39754
|
const binding = {
|
|
@@ -39751,17 +39757,52 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
|
|
|
39751
39757
|
source: declaration.source,
|
|
39752
39758
|
label
|
|
39753
39759
|
};
|
|
39754
|
-
|
|
39755
|
-
|
|
39756
|
-
|
|
39760
|
+
const baseData3 = stateData(context, "member", memberId);
|
|
39761
|
+
const backed = baseData3 === null ? null : rowBackedDefaultBody(baseData3, (id2) => pulledValueIds.has(id2));
|
|
39762
|
+
if (backed !== null && baseData3 !== null) {
|
|
39763
|
+
memberDefaultValues.set(
|
|
39764
|
+
memberId,
|
|
39765
|
+
lowerRowBackedDefault(context, member, backed, baseData3, binding)
|
|
39766
|
+
);
|
|
39767
|
+
continue;
|
|
39768
|
+
}
|
|
39769
|
+
const expression = parseCachedInitializer(
|
|
39770
|
+
context.parsedInitializers,
|
|
39771
|
+
declaration.initializer
|
|
39772
|
+
);
|
|
39773
|
+
if (!defaultRequiresOwnedRows(member, expression)) continue;
|
|
39774
|
+
const rootValueId = pendingValueId(binding, `${label}.default`);
|
|
39775
|
+
const seed = lowerStaticSeed(
|
|
39776
|
+
context,
|
|
39777
|
+
member,
|
|
39778
|
+
expression,
|
|
39779
|
+
binding,
|
|
39780
|
+
rootValueId
|
|
39757
39781
|
);
|
|
39782
|
+
seeds.set(memberId, { ...seed, valueId: rootValueId });
|
|
39783
|
+
memberDefaultValues.set(memberId, {
|
|
39784
|
+
value: seed.value,
|
|
39785
|
+
classId: seed.classId
|
|
39786
|
+
});
|
|
39758
39787
|
}
|
|
39759
39788
|
}
|
|
39760
39789
|
return {
|
|
39761
39790
|
records: [...context.reconstructed.values()],
|
|
39762
|
-
memberDefaultValues
|
|
39791
|
+
memberDefaultValues,
|
|
39792
|
+
seeds
|
|
39763
39793
|
};
|
|
39764
39794
|
}
|
|
39795
|
+
function defaultRequiresOwnedRows(member, sourceExpression) {
|
|
39796
|
+
const expression = annotatedValue(sourceExpression).expression;
|
|
39797
|
+
if (member.kind === "class") return expression.kind === "new";
|
|
39798
|
+
if (member.kind === "list") {
|
|
39799
|
+
return expression.kind === "litList" && expression.elements.length > 0;
|
|
39800
|
+
}
|
|
39801
|
+
if (member.kind === "dictionary") {
|
|
39802
|
+
return expression.kind === "litDict" && expression.entries.length > 0;
|
|
39803
|
+
}
|
|
39804
|
+
return false;
|
|
39805
|
+
}
|
|
39765
39806
|
function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
|
|
39766
39807
|
const baseDefault = isObjectRecord2(baseData3.defaultValue) ? baseData3.defaultValue : {};
|
|
39767
39808
|
const storedClassId = stringOrNull(baseDefault.classId);
|
|
@@ -43737,7 +43778,8 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
43737
43778
|
let staticMemberValueIds = /* @__PURE__ */ new Map();
|
|
43738
43779
|
let memberDefaults = {
|
|
43739
43780
|
records: [],
|
|
43740
|
-
memberDefaultValues: /* @__PURE__ */ new Map()
|
|
43781
|
+
memberDefaultValues: /* @__PURE__ */ new Map(),
|
|
43782
|
+
seeds: /* @__PURE__ */ new Map()
|
|
43741
43783
|
};
|
|
43742
43784
|
let projectAnalysisV4 = null;
|
|
43743
43785
|
try {
|
|
@@ -43887,7 +43929,7 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
43887
43929
|
projectAnalysisV4,
|
|
43888
43930
|
manifest
|
|
43889
43931
|
);
|
|
43890
|
-
staticValueSeeds = staticValues.seeds;
|
|
43932
|
+
staticValueSeeds = new Map([...staticValues.seeds, ...memberDefaults.seeds]);
|
|
43891
43933
|
staticMemberValueIds = staticValues.memberValueIds;
|
|
43892
43934
|
const rootRecords = lowerProjectRootSourceV4(
|
|
43893
43935
|
workspace.state.records,
|
|
@@ -45434,6 +45476,7 @@ __export(project_document_read_exports, {
|
|
|
45434
45476
|
readOptionalArrayField: () => readOptionalArrayField,
|
|
45435
45477
|
readProjectDocument: () => readProjectDocument,
|
|
45436
45478
|
readProjectDocumentContentHashHeads: () => readProjectDocumentContentHashHeads,
|
|
45479
|
+
readProjectDocumentManifestPageRecords: () => readProjectDocumentManifestPageRecords,
|
|
45437
45480
|
readProjectDocumentManifestRecords: () => readProjectDocumentManifestRecords,
|
|
45438
45481
|
readProjectDocumentRevisionMarker: () => readProjectDocumentRevisionMarker
|
|
45439
45482
|
});
|
|
@@ -45639,6 +45682,12 @@ function readProjectDocumentManifestRecords(value) {
|
|
|
45639
45682
|
};
|
|
45640
45683
|
});
|
|
45641
45684
|
}
|
|
45685
|
+
function readProjectDocumentManifestPageRecords(value) {
|
|
45686
|
+
if (!isObject3(value)) {
|
|
45687
|
+
throw new Error("Convex project document manifest page must be an object.");
|
|
45688
|
+
}
|
|
45689
|
+
return readProjectDocumentManifestRecords(value.records);
|
|
45690
|
+
}
|
|
45642
45691
|
async function fetchProjectDocumentSnapshots(fetchBatch, snapshotIds) {
|
|
45643
45692
|
const chunks = [];
|
|
45644
45693
|
for (let offset = 0; offset < snapshotIds.length; offset += DOCUMENT_SNAPSHOT_FETCH_CHUNK_SIZE) {
|
|
@@ -46600,6 +46649,32 @@ var init_http = __esm({
|
|
|
46600
46649
|
}
|
|
46601
46650
|
return parsed;
|
|
46602
46651
|
}
|
|
46652
|
+
async get(path, options = {}) {
|
|
46653
|
+
const url = new URL(path, this.apiBaseUrl).toString();
|
|
46654
|
+
const response = await fetch(url, {
|
|
46655
|
+
method: "GET",
|
|
46656
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
46657
|
+
signal: options.signal
|
|
46658
|
+
});
|
|
46659
|
+
const text = await response.text();
|
|
46660
|
+
let parsed = null;
|
|
46661
|
+
if (text.length > 0) {
|
|
46662
|
+
try {
|
|
46663
|
+
parsed = JSON.parse(text);
|
|
46664
|
+
} catch {
|
|
46665
|
+
parsed = text;
|
|
46666
|
+
}
|
|
46667
|
+
}
|
|
46668
|
+
if (!response.ok) {
|
|
46669
|
+
const detail = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string" ? parsed.error : text.slice(0, 300);
|
|
46670
|
+
throw new NeoApiError(
|
|
46671
|
+
`GET ${path} failed with status ${response.status}: ${detail}`,
|
|
46672
|
+
response.status,
|
|
46673
|
+
parsed
|
|
46674
|
+
);
|
|
46675
|
+
}
|
|
46676
|
+
return parsed;
|
|
46677
|
+
}
|
|
46603
46678
|
async getBytes(path) {
|
|
46604
46679
|
const url = new URL(path, this.apiBaseUrl).toString();
|
|
46605
46680
|
const response = await fetch(url, {
|
|
@@ -59024,11 +59099,32 @@ async function runMerge(workspace, sourceRef, dryRun, runMigrations = false) {
|
|
|
59024
59099
|
}
|
|
59025
59100
|
}
|
|
59026
59101
|
try {
|
|
59027
|
-
|
|
59102
|
+
let result = await client.post(mergePath, {
|
|
59028
59103
|
sourceVersionId: source.id,
|
|
59029
59104
|
dryRun,
|
|
59030
59105
|
resolutions: resolutions.length > 0 ? resolutions : void 0
|
|
59031
59106
|
});
|
|
59107
|
+
const accepted = readAcceptedMergeTransaction(result);
|
|
59108
|
+
if (accepted !== null) {
|
|
59109
|
+
const progress = spinner("Preparing merge\u2026");
|
|
59110
|
+
try {
|
|
59111
|
+
await waitForMergeTransaction({
|
|
59112
|
+
client,
|
|
59113
|
+
projectId: workspace.config.projectId,
|
|
59114
|
+
versionId: workspace.config.versionId,
|
|
59115
|
+
accepted,
|
|
59116
|
+
update: (label) => progress.update(label)
|
|
59117
|
+
});
|
|
59118
|
+
progress.succeed("Merge transaction committed.");
|
|
59119
|
+
} catch (error) {
|
|
59120
|
+
progress.fail("Merge transaction failed.");
|
|
59121
|
+
throw error;
|
|
59122
|
+
}
|
|
59123
|
+
result = { ...result, commitStatus: "committed" };
|
|
59124
|
+
if (result.sourceArchivePending === true) {
|
|
59125
|
+
console.log("Source branch archival is finishing in the background.");
|
|
59126
|
+
}
|
|
59127
|
+
}
|
|
59032
59128
|
const merged = typeof result.merged === "number" ? result.merged : 0;
|
|
59033
59129
|
if (dryRun) {
|
|
59034
59130
|
console.log(`Merge dry-run: ${merged} record(s) would merge cleanly.`);
|
|
@@ -59096,6 +59192,104 @@ async function runMerge(workspace, sourceRef, dryRun, runMigrations = false) {
|
|
|
59096
59192
|
throw error;
|
|
59097
59193
|
}
|
|
59098
59194
|
}
|
|
59195
|
+
function readAcceptedMergeTransaction(value) {
|
|
59196
|
+
if (!isObjectRecord2(value)) {
|
|
59197
|
+
throw new Error("Merge response must be an object.");
|
|
59198
|
+
}
|
|
59199
|
+
if (value.kind !== "accepted") return null;
|
|
59200
|
+
if (typeof value.transactionId !== "string") {
|
|
59201
|
+
throw new Error("Accepted merge is missing transactionId.");
|
|
59202
|
+
}
|
|
59203
|
+
if (!isMergeTransactionStatus(value.commitStatus)) {
|
|
59204
|
+
throw new Error("Accepted merge has an invalid commitStatus.");
|
|
59205
|
+
}
|
|
59206
|
+
const totalChangeCount = value.totalChangeCount === null ? null : readMergeProgressCount(value.totalChangeCount, "totalChangeCount");
|
|
59207
|
+
const appliedChangeCount = readMergeProgressCount(
|
|
59208
|
+
value.appliedChangeCount,
|
|
59209
|
+
"appliedChangeCount"
|
|
59210
|
+
);
|
|
59211
|
+
return {
|
|
59212
|
+
transactionId: value.transactionId,
|
|
59213
|
+
commitStatus: value.commitStatus,
|
|
59214
|
+
totalChangeCount,
|
|
59215
|
+
appliedChangeCount
|
|
59216
|
+
};
|
|
59217
|
+
}
|
|
59218
|
+
async function waitForMergeTransaction(args) {
|
|
59219
|
+
const transactionPath = `/api/projects/${encodeURIComponent(args.projectId)}/versions/${encodeURIComponent(args.versionId)}/schema/transactions/${encodeURIComponent(args.accepted.transactionId)}`;
|
|
59220
|
+
let status = args.accepted;
|
|
59221
|
+
let delayMs = 250;
|
|
59222
|
+
for (; ; ) {
|
|
59223
|
+
args.update(mergeTransactionProgressLabel(status));
|
|
59224
|
+
if (status.commitStatus === "committed") return;
|
|
59225
|
+
if (status.commitStatus === "failed") {
|
|
59226
|
+
throw new Error(
|
|
59227
|
+
`Merge transaction "${status.transactionId}" failed after rollback.`
|
|
59228
|
+
);
|
|
59229
|
+
}
|
|
59230
|
+
const response = await args.client.get(transactionPath);
|
|
59231
|
+
status = readMergeTransactionStatus(response, status.transactionId);
|
|
59232
|
+
if (status.commitStatus === "committed") continue;
|
|
59233
|
+
if (status.commitStatus === "failed") continue;
|
|
59234
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
59235
|
+
delayMs = Math.min(delayMs * 2, 5e3);
|
|
59236
|
+
}
|
|
59237
|
+
}
|
|
59238
|
+
function readMergeTransactionStatus(value, transactionId) {
|
|
59239
|
+
if (!isObjectRecord2(value)) {
|
|
59240
|
+
throw new Error(
|
|
59241
|
+
`Merge transaction "${transactionId}" status must be an object.`
|
|
59242
|
+
);
|
|
59243
|
+
}
|
|
59244
|
+
if (value.transactionId !== transactionId) {
|
|
59245
|
+
throw new Error(
|
|
59246
|
+
`Merge transaction status expected "${transactionId}", received ${JSON.stringify(value.transactionId)}.`
|
|
59247
|
+
);
|
|
59248
|
+
}
|
|
59249
|
+
if (!isMergeTransactionStatus(value.commitStatus)) {
|
|
59250
|
+
throw new Error(
|
|
59251
|
+
`Merge transaction "${transactionId}" has an invalid commitStatus.`
|
|
59252
|
+
);
|
|
59253
|
+
}
|
|
59254
|
+
const totalChangeCount = value.totalChangeCount === null ? null : readMergeProgressCount(value.totalChangeCount, "totalChangeCount");
|
|
59255
|
+
const appliedChangeCount = readMergeProgressCount(
|
|
59256
|
+
value.appliedChangeCount,
|
|
59257
|
+
"appliedChangeCount"
|
|
59258
|
+
);
|
|
59259
|
+
return {
|
|
59260
|
+
transactionId,
|
|
59261
|
+
commitStatus: value.commitStatus,
|
|
59262
|
+
totalChangeCount,
|
|
59263
|
+
appliedChangeCount
|
|
59264
|
+
};
|
|
59265
|
+
}
|
|
59266
|
+
function readMergeProgressCount(value, field) {
|
|
59267
|
+
if (typeof value !== "number") {
|
|
59268
|
+
throw new Error(`Merge transaction ${field} must be a number.`);
|
|
59269
|
+
}
|
|
59270
|
+
if (!Number.isSafeInteger(value)) {
|
|
59271
|
+
throw new Error(`Merge transaction ${field} must be a safe integer.`);
|
|
59272
|
+
}
|
|
59273
|
+
if (value < 0) {
|
|
59274
|
+
throw new Error(`Merge transaction ${field} must not be negative.`);
|
|
59275
|
+
}
|
|
59276
|
+
return value;
|
|
59277
|
+
}
|
|
59278
|
+
function isMergeTransactionStatus(value) {
|
|
59279
|
+
return value === "preparing" || value === "waiting" || value === "queued" || value === "applying" || value === "reverting" || value === "committed" || value === "failed";
|
|
59280
|
+
}
|
|
59281
|
+
function mergeTransactionProgressLabel(status) {
|
|
59282
|
+
if (status.commitStatus === "preparing") return "Preparing merge\u2026";
|
|
59283
|
+
if (status.commitStatus === "waiting") return "Waiting to apply merge\u2026";
|
|
59284
|
+
if (status.commitStatus === "queued") return "Queueing merge\u2026";
|
|
59285
|
+
if (status.commitStatus === "reverting") return "Reverting merge\u2026";
|
|
59286
|
+
if (status.commitStatus === "committed") return "Merge committed.";
|
|
59287
|
+
if (status.commitStatus === "failed") return "Merge failed.";
|
|
59288
|
+
if (status.totalChangeCount !== null) {
|
|
59289
|
+
return `Applying merge\u2026 ${status.appliedChangeCount.toLocaleString("en-US")}/${status.totalChangeCount.toLocaleString("en-US")} changes`;
|
|
59290
|
+
}
|
|
59291
|
+
return "Applying merge\u2026";
|
|
59292
|
+
}
|
|
59099
59293
|
async function runRefresh(workspace, dryRun) {
|
|
59100
59294
|
const { versions } = await loadVersionMetadata(workspace);
|
|
59101
59295
|
const current = versions.find(
|
|
@@ -61687,6 +61881,345 @@ function assignPendingIds(changes, staticValueSeeds, reconstructed3) {
|
|
|
61687
61881
|
}
|
|
61688
61882
|
return { assigned, staticValueSeeds: rewrittenSeeds };
|
|
61689
61883
|
}
|
|
61884
|
+
function readAcceptedProjectVersionCommitResponse(value) {
|
|
61885
|
+
if (!isObjectRecord2(value) || value.kind !== "accepted") return null;
|
|
61886
|
+
if (typeof value.transactionId !== "string") {
|
|
61887
|
+
throw new Error("Accepted project transaction is missing transactionId.");
|
|
61888
|
+
}
|
|
61889
|
+
const rawStatus = value.commitStatus ?? value.status;
|
|
61890
|
+
if (rawStatus !== "preparing" && rawStatus !== "waiting" && rawStatus !== "queued" && rawStatus !== "applying" && rawStatus !== "reverting" && rawStatus !== "committed" && rawStatus !== "failed") {
|
|
61891
|
+
throw new Error(
|
|
61892
|
+
`Accepted project transaction "${value.transactionId}" has invalid commitStatus ${JSON.stringify(rawStatus)}.`
|
|
61893
|
+
);
|
|
61894
|
+
}
|
|
61895
|
+
const totalChangeCount = readNullableCount(
|
|
61896
|
+
value.totalChangeCount,
|
|
61897
|
+
"accepted totalChangeCount"
|
|
61898
|
+
);
|
|
61899
|
+
const appliedChangeCount = readCount(
|
|
61900
|
+
value.appliedChangeCount,
|
|
61901
|
+
"accepted appliedChangeCount"
|
|
61902
|
+
);
|
|
61903
|
+
const totalChunkCount = readNullableCount(
|
|
61904
|
+
value.totalChunkCount,
|
|
61905
|
+
"accepted totalChunkCount"
|
|
61906
|
+
);
|
|
61907
|
+
const appliedChunkCount = readCount(
|
|
61908
|
+
value.appliedChunkCount,
|
|
61909
|
+
"accepted appliedChunkCount"
|
|
61910
|
+
);
|
|
61911
|
+
return {
|
|
61912
|
+
kind: "accepted",
|
|
61913
|
+
transactionId: value.transactionId,
|
|
61914
|
+
commitStatus: rawStatus,
|
|
61915
|
+
totalChangeCount,
|
|
61916
|
+
appliedChangeCount,
|
|
61917
|
+
totalChunkCount,
|
|
61918
|
+
appliedChunkCount
|
|
61919
|
+
};
|
|
61920
|
+
}
|
|
61921
|
+
function readProjectVersionTransactionStatus(value, transactionId) {
|
|
61922
|
+
if (!isObjectRecord2(value)) {
|
|
61923
|
+
throw new Error(
|
|
61924
|
+
`Project transaction "${transactionId}" status response must be an object.`
|
|
61925
|
+
);
|
|
61926
|
+
}
|
|
61927
|
+
if (value.transactionId !== transactionId) {
|
|
61928
|
+
throw new Error(
|
|
61929
|
+
`Project transaction status response expected transactionId "${transactionId}"; received ${JSON.stringify(value.transactionId)}.`
|
|
61930
|
+
);
|
|
61931
|
+
}
|
|
61932
|
+
if (!isProjectVersionTransactionCommitStatus(value.commitStatus)) {
|
|
61933
|
+
throw new Error(
|
|
61934
|
+
`Project transaction "${transactionId}" has invalid commitStatus ${JSON.stringify(value.commitStatus)}.`
|
|
61935
|
+
);
|
|
61936
|
+
}
|
|
61937
|
+
const errorCode = readNullableString(
|
|
61938
|
+
value.errorCode,
|
|
61939
|
+
`Project transaction "${transactionId}" errorCode`
|
|
61940
|
+
);
|
|
61941
|
+
const errorMessage3 = readNullableString(
|
|
61942
|
+
value.errorMessage,
|
|
61943
|
+
`Project transaction "${transactionId}" errorMessage`
|
|
61944
|
+
);
|
|
61945
|
+
const resultCursor = readNullableString(
|
|
61946
|
+
value.resultCursor,
|
|
61947
|
+
`Project transaction "${transactionId}" resultCursor`
|
|
61948
|
+
);
|
|
61949
|
+
return {
|
|
61950
|
+
transactionId,
|
|
61951
|
+
commitStatus: value.commitStatus,
|
|
61952
|
+
totalChangeCount: readNullableCount(
|
|
61953
|
+
value.totalChangeCount,
|
|
61954
|
+
`Project transaction "${transactionId}" totalChangeCount`
|
|
61955
|
+
),
|
|
61956
|
+
appliedChangeCount: readCount(
|
|
61957
|
+
value.appliedChangeCount,
|
|
61958
|
+
`Project transaction "${transactionId}" appliedChangeCount`
|
|
61959
|
+
),
|
|
61960
|
+
totalChunkCount: readNullableCount(
|
|
61961
|
+
value.totalChunkCount,
|
|
61962
|
+
`Project transaction "${transactionId}" totalChunkCount`
|
|
61963
|
+
),
|
|
61964
|
+
appliedChunkCount: readCount(
|
|
61965
|
+
value.appliedChunkCount,
|
|
61966
|
+
`Project transaction "${transactionId}" appliedChunkCount`
|
|
61967
|
+
),
|
|
61968
|
+
errorCode,
|
|
61969
|
+
errorMessage: errorMessage3,
|
|
61970
|
+
resultCursor
|
|
61971
|
+
};
|
|
61972
|
+
}
|
|
61973
|
+
function readProjectVersionTransactionResultPage(value, transactionId) {
|
|
61974
|
+
if (!isObjectRecord2(value)) {
|
|
61975
|
+
throw new Error(
|
|
61976
|
+
`Project transaction "${transactionId}" result page must be an object.`
|
|
61977
|
+
);
|
|
61978
|
+
}
|
|
61979
|
+
if (value.transactionId !== transactionId) {
|
|
61980
|
+
throw new Error(
|
|
61981
|
+
`Project transaction result page expected transactionId "${transactionId}"; received ${JSON.stringify(value.transactionId)}.`
|
|
61982
|
+
);
|
|
61983
|
+
}
|
|
61984
|
+
if (!isObjectRecord2(value.assignments)) {
|
|
61985
|
+
throw new Error(
|
|
61986
|
+
`Project transaction "${transactionId}" result page assignments must be an object.`
|
|
61987
|
+
);
|
|
61988
|
+
}
|
|
61989
|
+
const assignments = {};
|
|
61990
|
+
for (const [pendingId2, assignedId] of Object.entries(value.assignments)) {
|
|
61991
|
+
if (typeof assignedId !== "string") {
|
|
61992
|
+
throw new Error(
|
|
61993
|
+
`Project transaction "${transactionId}" result assignment ${JSON.stringify(pendingId2)} must be a string.`
|
|
61994
|
+
);
|
|
61995
|
+
}
|
|
61996
|
+
assignments[pendingId2] = assignedId;
|
|
61997
|
+
}
|
|
61998
|
+
if (!Array.isArray(value.changedRecords)) {
|
|
61999
|
+
throw new Error(
|
|
62000
|
+
`Project transaction "${transactionId}" result page changedRecords must be an array.`
|
|
62001
|
+
);
|
|
62002
|
+
}
|
|
62003
|
+
const continueCursor = readNullableString(
|
|
62004
|
+
value.continueCursor,
|
|
62005
|
+
`Project transaction "${transactionId}" result page continueCursor`
|
|
62006
|
+
);
|
|
62007
|
+
if (typeof value.isDone !== "boolean") {
|
|
62008
|
+
throw new Error(
|
|
62009
|
+
`Project transaction "${transactionId}" result page isDone must be a boolean.`
|
|
62010
|
+
);
|
|
62011
|
+
}
|
|
62012
|
+
return {
|
|
62013
|
+
transactionId,
|
|
62014
|
+
assignments,
|
|
62015
|
+
changedRecords: value.changedRecords,
|
|
62016
|
+
continueCursor,
|
|
62017
|
+
isDone: value.isDone
|
|
62018
|
+
};
|
|
62019
|
+
}
|
|
62020
|
+
function readCount(value, field) {
|
|
62021
|
+
if (typeof value !== "number") {
|
|
62022
|
+
throw new Error(`${field} must be a number.`);
|
|
62023
|
+
}
|
|
62024
|
+
if (!Number.isSafeInteger(value)) {
|
|
62025
|
+
throw new Error(`${field} must be a safe integer.`);
|
|
62026
|
+
}
|
|
62027
|
+
if (value < 0) {
|
|
62028
|
+
throw new Error(`${field} must not be negative.`);
|
|
62029
|
+
}
|
|
62030
|
+
return value;
|
|
62031
|
+
}
|
|
62032
|
+
function readNullableCount(value, field) {
|
|
62033
|
+
if (value === null) return null;
|
|
62034
|
+
return readCount(value, field);
|
|
62035
|
+
}
|
|
62036
|
+
function readNullableString(value, field) {
|
|
62037
|
+
if (value === null) return null;
|
|
62038
|
+
if (typeof value !== "string") {
|
|
62039
|
+
throw new Error(`${field} must be a string or null.`);
|
|
62040
|
+
}
|
|
62041
|
+
return value;
|
|
62042
|
+
}
|
|
62043
|
+
function isProjectVersionTransactionCommitStatus(value) {
|
|
62044
|
+
return value === "preparing" || value === "waiting" || value === "queued" || value === "applying" || value === "reverting" || value === "committed" || value === "failed";
|
|
62045
|
+
}
|
|
62046
|
+
function createPushProgressReporter(json) {
|
|
62047
|
+
const animated = process.stdout.isTTY === true && !json;
|
|
62048
|
+
const indicator = animated ? spinner("Pushing\u2026") : null;
|
|
62049
|
+
let lastStructuredEvent = "";
|
|
62050
|
+
return {
|
|
62051
|
+
report(event) {
|
|
62052
|
+
if (indicator !== null) {
|
|
62053
|
+
indicator.update(projectTransactionProgressLabel(event));
|
|
62054
|
+
return;
|
|
62055
|
+
}
|
|
62056
|
+
const encoded = JSON.stringify(event);
|
|
62057
|
+
if (encoded === lastStructuredEvent) return;
|
|
62058
|
+
lastStructuredEvent = encoded;
|
|
62059
|
+
console.log(encoded);
|
|
62060
|
+
},
|
|
62061
|
+
stop() {
|
|
62062
|
+
indicator?.stop();
|
|
62063
|
+
}
|
|
62064
|
+
};
|
|
62065
|
+
}
|
|
62066
|
+
function projectTransactionProgressLabel(event) {
|
|
62067
|
+
if (event.phase === "submitting") return "Pushing\u2026";
|
|
62068
|
+
if (event.phase === "preparing") return "Preparing push\u2026";
|
|
62069
|
+
if (event.phase === "waiting") return "Waiting to apply project transaction\u2026";
|
|
62070
|
+
if (event.phase === "reverting") return "Reverting project transaction\u2026";
|
|
62071
|
+
if (event.phase === "finalizing") return "Finalizing project transaction\u2026";
|
|
62072
|
+
if (event.phase === "committed") return "Push complete.";
|
|
62073
|
+
if (event.phase === "failed") return "Project transaction failed.";
|
|
62074
|
+
if (event.phase === "interrupted")
|
|
62075
|
+
return "Project transaction still running.";
|
|
62076
|
+
if (event.totalChangeCount !== null && event.appliedChangeCount < event.totalChangeCount) {
|
|
62077
|
+
return `Applying project transaction\u2026 ${event.appliedChangeCount.toLocaleString("en-US")}/${event.totalChangeCount.toLocaleString("en-US")} changes`;
|
|
62078
|
+
}
|
|
62079
|
+
if (event.totalChunkCount !== null && event.appliedChunkCount < event.totalChunkCount) {
|
|
62080
|
+
return `Applying project transaction\u2026 ${event.appliedChunkCount.toLocaleString("en-US")}/${event.totalChunkCount.toLocaleString("en-US")} chunks`;
|
|
62081
|
+
}
|
|
62082
|
+
return "Finalizing project transaction\u2026";
|
|
62083
|
+
}
|
|
62084
|
+
function progressEventFromAccepted(accepted) {
|
|
62085
|
+
return {
|
|
62086
|
+
type: "project-transaction-progress",
|
|
62087
|
+
transactionId: accepted.transactionId,
|
|
62088
|
+
phase: accepted.commitStatus,
|
|
62089
|
+
totalChangeCount: accepted.totalChangeCount,
|
|
62090
|
+
appliedChangeCount: accepted.appliedChangeCount,
|
|
62091
|
+
totalChunkCount: accepted.totalChunkCount,
|
|
62092
|
+
appliedChunkCount: accepted.appliedChunkCount,
|
|
62093
|
+
errorCode: null,
|
|
62094
|
+
errorMessage: null
|
|
62095
|
+
};
|
|
62096
|
+
}
|
|
62097
|
+
function progressEventFromStatus(status) {
|
|
62098
|
+
const phase = status.commitStatus === "committed" || status.commitStatus === "applying" && status.totalChunkCount !== null && status.appliedChunkCount === status.totalChunkCount ? "finalizing" : status.commitStatus;
|
|
62099
|
+
return {
|
|
62100
|
+
type: "project-transaction-progress",
|
|
62101
|
+
transactionId: status.transactionId,
|
|
62102
|
+
phase,
|
|
62103
|
+
totalChangeCount: status.totalChangeCount,
|
|
62104
|
+
appliedChangeCount: status.appliedChangeCount,
|
|
62105
|
+
totalChunkCount: status.totalChunkCount,
|
|
62106
|
+
appliedChunkCount: status.appliedChunkCount,
|
|
62107
|
+
errorCode: status.errorCode,
|
|
62108
|
+
errorMessage: status.errorMessage
|
|
62109
|
+
};
|
|
62110
|
+
}
|
|
62111
|
+
async function waitForAcceptedProjectVersionTransaction(args) {
|
|
62112
|
+
const { client, projectId, versionId, accepted, reporter } = args;
|
|
62113
|
+
const transactionPath = `/api/projects/${projectId}/versions/${versionId}/schema/transactions/${accepted.transactionId}`;
|
|
62114
|
+
const controller = new AbortController();
|
|
62115
|
+
let interrupted = false;
|
|
62116
|
+
const interrupt = () => {
|
|
62117
|
+
interrupted = true;
|
|
62118
|
+
controller.abort();
|
|
62119
|
+
};
|
|
62120
|
+
process.once("SIGINT", interrupt);
|
|
62121
|
+
reporter.report(progressEventFromAccepted(accepted));
|
|
62122
|
+
let pollIndex = 0;
|
|
62123
|
+
try {
|
|
62124
|
+
for (; ; ) {
|
|
62125
|
+
const rawStatus = await client.get(transactionPath, {
|
|
62126
|
+
signal: controller.signal
|
|
62127
|
+
});
|
|
62128
|
+
const status = readProjectVersionTransactionStatus(
|
|
62129
|
+
rawStatus,
|
|
62130
|
+
accepted.transactionId
|
|
62131
|
+
);
|
|
62132
|
+
reporter.report(progressEventFromStatus(status));
|
|
62133
|
+
if (status.commitStatus === "committed") {
|
|
62134
|
+
return await downloadProjectVersionTransactionResult({
|
|
62135
|
+
client,
|
|
62136
|
+
transactionPath,
|
|
62137
|
+
transactionId: accepted.transactionId,
|
|
62138
|
+
status,
|
|
62139
|
+
signal: controller.signal
|
|
62140
|
+
});
|
|
62141
|
+
}
|
|
62142
|
+
if (status.commitStatus === "failed") {
|
|
62143
|
+
throw new ProjectTransactionFailedError(status);
|
|
62144
|
+
}
|
|
62145
|
+
const delay = PROJECT_TRANSACTION_POLL_DELAYS_MS[Math.min(pollIndex, PROJECT_TRANSACTION_POLL_DELAYS_MS.length - 1)];
|
|
62146
|
+
pollIndex += 1;
|
|
62147
|
+
await waitForPollDelay(delay, controller.signal);
|
|
62148
|
+
}
|
|
62149
|
+
} catch (error) {
|
|
62150
|
+
if (interrupted) {
|
|
62151
|
+
throw new ProjectTransactionInterruptedError(accepted.transactionId);
|
|
62152
|
+
}
|
|
62153
|
+
throw error;
|
|
62154
|
+
} finally {
|
|
62155
|
+
process.removeListener("SIGINT", interrupt);
|
|
62156
|
+
}
|
|
62157
|
+
}
|
|
62158
|
+
async function waitForPollDelay(delayMs, signal) {
|
|
62159
|
+
if (signal.aborted) {
|
|
62160
|
+
throw new Error("Project transaction polling was interrupted.");
|
|
62161
|
+
}
|
|
62162
|
+
await new Promise((resolve4, reject) => {
|
|
62163
|
+
const aborted = () => {
|
|
62164
|
+
clearTimeout(timer);
|
|
62165
|
+
reject(new Error("Project transaction polling was interrupted."));
|
|
62166
|
+
};
|
|
62167
|
+
const timer = setTimeout(() => {
|
|
62168
|
+
signal.removeEventListener("abort", aborted);
|
|
62169
|
+
resolve4();
|
|
62170
|
+
}, delayMs);
|
|
62171
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
62172
|
+
});
|
|
62173
|
+
}
|
|
62174
|
+
async function downloadProjectVersionTransactionResult(args) {
|
|
62175
|
+
const assignments = {};
|
|
62176
|
+
const changedRecords = [];
|
|
62177
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
62178
|
+
let cursor = args.status.resultCursor ?? "";
|
|
62179
|
+
for (; ; ) {
|
|
62180
|
+
if (seenCursors.has(cursor)) {
|
|
62181
|
+
throw new Error(
|
|
62182
|
+
`Project transaction "${args.transactionId}" result pagination repeated cursor ${JSON.stringify(cursor)}.`
|
|
62183
|
+
);
|
|
62184
|
+
}
|
|
62185
|
+
seenCursors.add(cursor);
|
|
62186
|
+
const query = new URLSearchParams({ cursor });
|
|
62187
|
+
const rawPage = await args.client.get(
|
|
62188
|
+
`${args.transactionPath}/results?${query.toString()}`,
|
|
62189
|
+
{ signal: args.signal }
|
|
62190
|
+
);
|
|
62191
|
+
const page = readProjectVersionTransactionResultPage(
|
|
62192
|
+
rawPage,
|
|
62193
|
+
args.transactionId
|
|
62194
|
+
);
|
|
62195
|
+
for (const [pendingId2, assignedId] of Object.entries(page.assignments)) {
|
|
62196
|
+
const existing = assignments[pendingId2];
|
|
62197
|
+
if (existing !== void 0 && existing !== assignedId) {
|
|
62198
|
+
throw new Error(
|
|
62199
|
+
`Project transaction "${args.transactionId}" returned conflicting assignments for ${JSON.stringify(pendingId2)}.`
|
|
62200
|
+
);
|
|
62201
|
+
}
|
|
62202
|
+
assignments[pendingId2] = assignedId;
|
|
62203
|
+
}
|
|
62204
|
+
changedRecords.push(...page.changedRecords);
|
|
62205
|
+
if (page.isDone) {
|
|
62206
|
+
return {
|
|
62207
|
+
kind: "committed",
|
|
62208
|
+
transactionId: args.transactionId,
|
|
62209
|
+
totalChangeCount: args.status.totalChangeCount ?? changedRecords.length,
|
|
62210
|
+
totalChunkCount: args.status.totalChunkCount ?? 0,
|
|
62211
|
+
assignments,
|
|
62212
|
+
changedRecords
|
|
62213
|
+
};
|
|
62214
|
+
}
|
|
62215
|
+
if (page.continueCursor === null) {
|
|
62216
|
+
throw new Error(
|
|
62217
|
+
`Project transaction "${args.transactionId}" result page is not done but has no continueCursor.`
|
|
62218
|
+
);
|
|
62219
|
+
}
|
|
62220
|
+
cursor = page.continueCursor;
|
|
62221
|
+
}
|
|
62222
|
+
}
|
|
61690
62223
|
async function runPush(workspace, options) {
|
|
61691
62224
|
const status = computeWorkspaceStatus(workspace);
|
|
61692
62225
|
if (status.conflictedFiles.length > 0) {
|
|
@@ -61717,7 +62250,19 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61717
62250
|
binaryChanges: status.binaryChanges ?? []
|
|
61718
62251
|
});
|
|
61719
62252
|
if (status.changes.length === 0) {
|
|
61720
|
-
|
|
62253
|
+
if (options.json === true) {
|
|
62254
|
+
console.log(
|
|
62255
|
+
JSON.stringify({
|
|
62256
|
+
type: "push-plan",
|
|
62257
|
+
dryRun: options.dryRun,
|
|
62258
|
+
changeCount: 0,
|
|
62259
|
+
staticValueSeedCount: 0,
|
|
62260
|
+
changes: []
|
|
62261
|
+
})
|
|
62262
|
+
);
|
|
62263
|
+
} else {
|
|
62264
|
+
console.log("Nothing to push \u2014 working copy is clean.");
|
|
62265
|
+
}
|
|
61721
62266
|
return;
|
|
61722
62267
|
}
|
|
61723
62268
|
prepareNSPropertySetterChanges(workspace, status);
|
|
@@ -61763,23 +62308,42 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61763
62308
|
change.nextData = { ...change.nextData, updatedAt: now };
|
|
61764
62309
|
}
|
|
61765
62310
|
}
|
|
61766
|
-
|
|
61767
|
-
`${options.dryRun ? "Would push" : "Pushing"} ${color.bold(String(status.changes.length))} change(s):`
|
|
61768
|
-
);
|
|
61769
|
-
for (const change of status.changes) {
|
|
62311
|
+
if (options.json === true) {
|
|
61770
62312
|
console.log(
|
|
61771
|
-
|
|
62313
|
+
JSON.stringify({
|
|
62314
|
+
type: "push-plan",
|
|
62315
|
+
dryRun: options.dryRun,
|
|
62316
|
+
changeCount: status.changes.length,
|
|
62317
|
+
staticValueSeedCount: status.staticValueSeeds.size,
|
|
62318
|
+
changes: status.changes.map((change) => ({
|
|
62319
|
+
kind: change.kind,
|
|
62320
|
+
recordKind: change.recordKind,
|
|
62321
|
+
recordId: change.recordId
|
|
62322
|
+
}))
|
|
62323
|
+
})
|
|
61772
62324
|
);
|
|
61773
|
-
|
|
61774
|
-
for (const line of summarizeFieldDiff(change.baseData, change.nextData)) {
|
|
61775
|
-
console.log(color.dim(` ${line}`));
|
|
61776
|
-
}
|
|
61777
|
-
}
|
|
61778
|
-
}
|
|
61779
|
-
if (status.staticValueSeeds.size > 0) {
|
|
62325
|
+
} else {
|
|
61780
62326
|
console.log(
|
|
61781
|
-
|
|
62327
|
+
`${options.dryRun ? "Would push" : "Pushing"} ${color.bold(String(status.changes.length))} change(s):`
|
|
61782
62328
|
);
|
|
62329
|
+
for (const change of status.changes) {
|
|
62330
|
+
console.log(
|
|
62331
|
+
` ${paintChangeKind(change.kind)} ${describeChange(change).replace(`${change.kind} `, "")}`
|
|
62332
|
+
);
|
|
62333
|
+
if (change.kind === "update") {
|
|
62334
|
+
for (const line of summarizeFieldDiff(
|
|
62335
|
+
change.baseData,
|
|
62336
|
+
change.nextData
|
|
62337
|
+
)) {
|
|
62338
|
+
console.log(color.dim(` ${line}`));
|
|
62339
|
+
}
|
|
62340
|
+
}
|
|
62341
|
+
}
|
|
62342
|
+
if (status.staticValueSeeds.size > 0) {
|
|
62343
|
+
console.log(
|
|
62344
|
+
` ${color.dim(`create ${status.staticValueSeeds.size} member value seed(s)`)}`
|
|
62345
|
+
);
|
|
62346
|
+
}
|
|
61783
62347
|
}
|
|
61784
62348
|
if (options.dryRun) return;
|
|
61785
62349
|
if (isInteractive() && !await promptConfirm({
|
|
@@ -61843,12 +62407,131 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61843
62407
|
},
|
|
61844
62408
|
force ? { "x-neo-force-project-version-write": "true" } : void 0
|
|
61845
62409
|
);
|
|
61846
|
-
const
|
|
62410
|
+
const finishCommitResponse = async (response, reporter) => {
|
|
62411
|
+
let accepted;
|
|
62412
|
+
try {
|
|
62413
|
+
accepted = readAcceptedProjectVersionCommitResponse(response);
|
|
62414
|
+
} catch (error) {
|
|
62415
|
+
reporter.stop();
|
|
62416
|
+
throw error;
|
|
62417
|
+
}
|
|
62418
|
+
if (accepted === null) {
|
|
62419
|
+
try {
|
|
62420
|
+
applyPushResult(workspace, response);
|
|
62421
|
+
} catch (error) {
|
|
62422
|
+
reporter.stop();
|
|
62423
|
+
throw error;
|
|
62424
|
+
}
|
|
62425
|
+
reporter.report({
|
|
62426
|
+
type: "project-transaction-progress",
|
|
62427
|
+
transactionId: immediateTransactionId(response),
|
|
62428
|
+
phase: "committed",
|
|
62429
|
+
totalChangeCount: status.changes.length,
|
|
62430
|
+
appliedChangeCount: status.changes.length,
|
|
62431
|
+
totalChunkCount: null,
|
|
62432
|
+
appliedChunkCount: 0,
|
|
62433
|
+
errorCode: null,
|
|
62434
|
+
errorMessage: null
|
|
62435
|
+
});
|
|
62436
|
+
reporter.stop();
|
|
62437
|
+
if (options.json !== true) success("Push complete.");
|
|
62438
|
+
return true;
|
|
62439
|
+
}
|
|
62440
|
+
let completed;
|
|
62441
|
+
try {
|
|
62442
|
+
completed = await waitForAcceptedProjectVersionTransaction({
|
|
62443
|
+
client,
|
|
62444
|
+
projectId: workspace.config.projectId,
|
|
62445
|
+
versionId: workspace.config.versionId,
|
|
62446
|
+
accepted,
|
|
62447
|
+
reporter
|
|
62448
|
+
});
|
|
62449
|
+
} catch (error) {
|
|
62450
|
+
if (error instanceof ProjectTransactionInterruptedError) {
|
|
62451
|
+
reporter.report({
|
|
62452
|
+
type: "project-transaction-progress",
|
|
62453
|
+
transactionId: error.transactionId,
|
|
62454
|
+
phase: "interrupted",
|
|
62455
|
+
totalChangeCount: accepted.totalChangeCount,
|
|
62456
|
+
appliedChangeCount: accepted.appliedChangeCount,
|
|
62457
|
+
totalChunkCount: accepted.totalChunkCount,
|
|
62458
|
+
appliedChunkCount: accepted.appliedChunkCount,
|
|
62459
|
+
errorCode: null,
|
|
62460
|
+
errorMessage: error.message
|
|
62461
|
+
});
|
|
62462
|
+
reporter.stop();
|
|
62463
|
+
if (options.json !== true) console.error(error.message);
|
|
62464
|
+
process.exitCode = 130;
|
|
62465
|
+
return false;
|
|
62466
|
+
}
|
|
62467
|
+
if (error instanceof ProjectTransactionFailedError) {
|
|
62468
|
+
const failed = error.status;
|
|
62469
|
+
reporter.report({
|
|
62470
|
+
type: "project-transaction-progress",
|
|
62471
|
+
transactionId: failed.transactionId,
|
|
62472
|
+
phase: "failed",
|
|
62473
|
+
totalChangeCount: failed.totalChangeCount,
|
|
62474
|
+
appliedChangeCount: failed.appliedChangeCount,
|
|
62475
|
+
totalChunkCount: failed.totalChunkCount,
|
|
62476
|
+
appliedChunkCount: failed.appliedChunkCount,
|
|
62477
|
+
errorCode: failed.errorCode,
|
|
62478
|
+
errorMessage: error.message
|
|
62479
|
+
});
|
|
62480
|
+
reporter.stop();
|
|
62481
|
+
if (options.json !== true) {
|
|
62482
|
+
console.error(
|
|
62483
|
+
`Push failed (${failed.errorCode ?? "project-transaction-failed"}, transaction ${failed.transactionId}): ${error.message}`
|
|
62484
|
+
);
|
|
62485
|
+
}
|
|
62486
|
+
process.exitCode = 1;
|
|
62487
|
+
return false;
|
|
62488
|
+
}
|
|
62489
|
+
reporter.stop();
|
|
62490
|
+
throw error;
|
|
62491
|
+
}
|
|
62492
|
+
try {
|
|
62493
|
+
applyCommittedProjectTransactionResult({
|
|
62494
|
+
workspace,
|
|
62495
|
+
result: completed,
|
|
62496
|
+
submittedChanges: status.changes,
|
|
62497
|
+
candidateAssignments: pendingAssignment.assigned
|
|
62498
|
+
});
|
|
62499
|
+
} catch (error) {
|
|
62500
|
+
reporter.stop();
|
|
62501
|
+
throw error;
|
|
62502
|
+
}
|
|
62503
|
+
reporter.report({
|
|
62504
|
+
type: "project-transaction-progress",
|
|
62505
|
+
transactionId: completed.transactionId,
|
|
62506
|
+
phase: "committed",
|
|
62507
|
+
totalChangeCount: completed.totalChangeCount,
|
|
62508
|
+
appliedChangeCount: completed.totalChangeCount,
|
|
62509
|
+
totalChunkCount: completed.totalChunkCount,
|
|
62510
|
+
appliedChunkCount: completed.totalChunkCount,
|
|
62511
|
+
errorCode: null,
|
|
62512
|
+
errorMessage: null
|
|
62513
|
+
});
|
|
62514
|
+
reporter.stop();
|
|
62515
|
+
if (options.json !== true) success("Push complete.");
|
|
62516
|
+
return true;
|
|
62517
|
+
};
|
|
62518
|
+
let progress = createPushProgressReporter(options.json === true);
|
|
62519
|
+
progress.report({
|
|
62520
|
+
type: "project-transaction-progress",
|
|
62521
|
+
transactionId: null,
|
|
62522
|
+
phase: "submitting",
|
|
62523
|
+
totalChangeCount: status.changes.length,
|
|
62524
|
+
appliedChangeCount: 0,
|
|
62525
|
+
totalChunkCount: null,
|
|
62526
|
+
appliedChunkCount: 0,
|
|
62527
|
+
errorCode: null,
|
|
62528
|
+
errorMessage: null
|
|
62529
|
+
});
|
|
61847
62530
|
let result;
|
|
61848
62531
|
try {
|
|
61849
62532
|
result = await commit(options.acceptBump);
|
|
61850
62533
|
} catch (error) {
|
|
61851
|
-
|
|
62534
|
+
progress.stop();
|
|
61852
62535
|
if (!(error instanceof NeoApiError)) throw error;
|
|
61853
62536
|
const rejection = error.body;
|
|
61854
62537
|
if (isInteractive() && !options.acceptBump && isObjectRecord2(rejection) && rejection.error === "version-bump-required") {
|
|
@@ -61864,7 +62547,18 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61864
62547
|
message: "Accept the bump and push?",
|
|
61865
62548
|
fallback: false
|
|
61866
62549
|
})) {
|
|
61867
|
-
|
|
62550
|
+
progress = createPushProgressReporter(options.json === true);
|
|
62551
|
+
progress.report({
|
|
62552
|
+
type: "project-transaction-progress",
|
|
62553
|
+
transactionId: null,
|
|
62554
|
+
phase: "submitting",
|
|
62555
|
+
totalChangeCount: status.changes.length,
|
|
62556
|
+
appliedChangeCount: 0,
|
|
62557
|
+
totalChunkCount: null,
|
|
62558
|
+
appliedChunkCount: 0,
|
|
62559
|
+
errorCode: null,
|
|
62560
|
+
errorMessage: null
|
|
62561
|
+
});
|
|
61868
62562
|
try {
|
|
61869
62563
|
stagedFiles = await stageProjectFilePushesV4({
|
|
61870
62564
|
workspace,
|
|
@@ -61875,7 +62569,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61875
62569
|
});
|
|
61876
62570
|
result = await commit(true);
|
|
61877
62571
|
} catch (retryError) {
|
|
61878
|
-
|
|
62572
|
+
progress.stop();
|
|
61879
62573
|
if (retryError instanceof NeoApiError) {
|
|
61880
62574
|
reportPushRejection(retryError.body);
|
|
61881
62575
|
process.exitCode = 1;
|
|
@@ -61883,9 +62577,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61883
62577
|
}
|
|
61884
62578
|
throw retryError;
|
|
61885
62579
|
}
|
|
61886
|
-
|
|
61887
|
-
applyPushResult(workspace, result);
|
|
61888
|
-
success("Push complete.");
|
|
62580
|
+
await finishCommitResponse(result, progress);
|
|
61889
62581
|
return;
|
|
61890
62582
|
}
|
|
61891
62583
|
console.log("Push cancelled.");
|
|
@@ -61896,9 +62588,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
61896
62588
|
process.exitCode = 1;
|
|
61897
62589
|
return;
|
|
61898
62590
|
}
|
|
61899
|
-
|
|
61900
|
-
applyPushResult(workspace, result);
|
|
61901
|
-
success("Push complete.");
|
|
62591
|
+
await finishCommitResponse(result, progress);
|
|
61902
62592
|
}
|
|
61903
62593
|
async function createPendingProjectSourceBundleV4(workspace, status, staticValueSeeds) {
|
|
61904
62594
|
const records2 = /* @__PURE__ */ new Map();
|
|
@@ -62045,52 +62735,298 @@ function reportPushRejection(body) {
|
|
|
62045
62735
|
}
|
|
62046
62736
|
console.error(`Push rejected (409): ${JSON.stringify(body)}`);
|
|
62047
62737
|
}
|
|
62048
|
-
function
|
|
62049
|
-
if (!isObjectRecord2(result)
|
|
62050
|
-
|
|
62738
|
+
function immediateTransactionId(result) {
|
|
62739
|
+
if (!isObjectRecord2(result)) return null;
|
|
62740
|
+
if (typeof result.transactionId === "string") return result.transactionId;
|
|
62741
|
+
if (!isObjectRecord2(result.transaction)) return null;
|
|
62742
|
+
return typeof result.transaction.id === "string" ? result.transaction.id : null;
|
|
62743
|
+
}
|
|
62744
|
+
function applyCommittedProjectTransactionResult(args) {
|
|
62745
|
+
const { workspace, result, submittedChanges, candidateAssignments } = args;
|
|
62746
|
+
const localStatus = computeWorkspaceStatus(workspace);
|
|
62747
|
+
const blockingErrors = localStatus.parseErrors.filter(
|
|
62748
|
+
isBlockingSchemaSourceError
|
|
62749
|
+
);
|
|
62750
|
+
if (blockingErrors.length > 0) {
|
|
62751
|
+
throw new Error(
|
|
62752
|
+
`Project transaction "${result.transactionId}" committed, but its result cannot be applied while the working copy has parse errors. Fix the source and run the same neo push again:
|
|
62753
|
+
${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
62754
|
+
);
|
|
62755
|
+
}
|
|
62756
|
+
if (localStatus.conflictedFiles.length > 0) {
|
|
62757
|
+
throw new Error(
|
|
62758
|
+
`Project transaction "${result.transactionId}" committed, but its result cannot be applied while conflict markers remain in ${localStatus.conflictedFiles.join(", ")}. Resolve them and run the same neo push again.`
|
|
62759
|
+
);
|
|
62760
|
+
}
|
|
62761
|
+
const replacements = projectTransactionResultReplacements(
|
|
62762
|
+
candidateAssignments,
|
|
62763
|
+
result.assignments
|
|
62764
|
+
);
|
|
62765
|
+
const localRecords = rewriteReconstructedRecords(
|
|
62766
|
+
localStatus.reconstructed,
|
|
62767
|
+
replacements
|
|
62768
|
+
);
|
|
62769
|
+
const submittedByKey = /* @__PURE__ */ new Map();
|
|
62770
|
+
for (const change of submittedChanges) {
|
|
62771
|
+
if (change.nextData === void 0) continue;
|
|
62772
|
+
const recordId = rewriteAssignedString(change.recordId, replacements);
|
|
62773
|
+
const nextData = rewriteAssignedValue(change.nextData, replacements);
|
|
62774
|
+
if (!isObjectRecord2(nextData)) {
|
|
62775
|
+
throw new Error(
|
|
62776
|
+
`Submitted ${change.recordKind} "${recordId}" did not rewrite to an object.`
|
|
62777
|
+
);
|
|
62778
|
+
}
|
|
62779
|
+
submittedByKey.set(recordStateKey(change.recordKind, recordId), nextData);
|
|
62051
62780
|
}
|
|
62781
|
+
const previousRecords = workspace.state.records;
|
|
62782
|
+
const nextRecords = foldChangedRecords(
|
|
62783
|
+
previousRecords,
|
|
62784
|
+
result.changedRecords
|
|
62785
|
+
);
|
|
62786
|
+
const changedKeys = /* @__PURE__ */ new Set();
|
|
62052
62787
|
for (const changed of result.changedRecords) {
|
|
62053
|
-
|
|
62054
|
-
|
|
62788
|
+
const identity2 = readChangedRecordIdentity(changed);
|
|
62789
|
+
changedKeys.add(recordStateKey(identity2.recordKind, identity2.recordId));
|
|
62790
|
+
}
|
|
62791
|
+
const emitRecords = /* @__PURE__ */ new Map();
|
|
62792
|
+
for (const [key, state] of Object.entries(nextRecords)) {
|
|
62793
|
+
const prior = previousRecords[key];
|
|
62794
|
+
const local = localRecords.get(key);
|
|
62795
|
+
if (local === void 0 && prior?.file !== void 0) continue;
|
|
62796
|
+
const submitted = submittedByKey.get(key);
|
|
62797
|
+
const emitData = local === void 0 ? state.data : changedKeys.has(key) && submitted !== void 0 ? mergeCommittedRecordWithLaterLocalEdits(
|
|
62798
|
+
state.recordKind,
|
|
62799
|
+
submitted,
|
|
62800
|
+
state.data,
|
|
62801
|
+
local.fullData
|
|
62802
|
+
) : local.fullData;
|
|
62803
|
+
emitRecords.set(key, {
|
|
62804
|
+
recordKind: state.recordKind,
|
|
62805
|
+
recordId: state.recordId,
|
|
62806
|
+
contentHash: state.contentHash,
|
|
62807
|
+
deleted: false,
|
|
62808
|
+
data: emitData
|
|
62809
|
+
});
|
|
62810
|
+
}
|
|
62811
|
+
for (const [key, local] of localRecords) {
|
|
62812
|
+
if (emitRecords.has(key)) continue;
|
|
62813
|
+
if (changedKeys.has(key)) continue;
|
|
62814
|
+
emitRecords.set(key, {
|
|
62815
|
+
recordKind: local.recordKind,
|
|
62816
|
+
recordId: local.recordId,
|
|
62817
|
+
contentHash: "",
|
|
62818
|
+
deleted: false,
|
|
62819
|
+
data: local.fullData
|
|
62820
|
+
});
|
|
62821
|
+
}
|
|
62822
|
+
const previousState = workspace.state;
|
|
62823
|
+
workspace.state = { ...previousState, records: nextRecords };
|
|
62824
|
+
try {
|
|
62825
|
+
rewriteFilesFromState(workspace, emitRecords);
|
|
62826
|
+
writeWorkspaceState(workspace.root, workspace.state);
|
|
62827
|
+
} catch (error) {
|
|
62828
|
+
workspace.state = previousState;
|
|
62829
|
+
throw error;
|
|
62830
|
+
}
|
|
62831
|
+
}
|
|
62832
|
+
function projectTransactionResultReplacements(candidateAssignments, resultAssignments) {
|
|
62833
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
62834
|
+
for (const [pendingId2, assignedId] of Object.entries(resultAssignments)) {
|
|
62835
|
+
replacements.set(pendingId2, assignedId);
|
|
62836
|
+
const candidateId = candidateAssignments.get(pendingId2);
|
|
62837
|
+
if (candidateId !== void 0) replacements.set(candidateId, assignedId);
|
|
62838
|
+
}
|
|
62839
|
+
return {
|
|
62840
|
+
exact: replacements,
|
|
62841
|
+
embedded: [...replacements].sort(
|
|
62842
|
+
([left], [right]) => right.length - left.length
|
|
62843
|
+
)
|
|
62844
|
+
};
|
|
62845
|
+
}
|
|
62846
|
+
function rewriteReconstructedRecords(records2, replacements) {
|
|
62847
|
+
const rewritten = /* @__PURE__ */ new Map();
|
|
62848
|
+
for (const record3 of records2.values()) {
|
|
62849
|
+
const recordId = rewriteAssignedString(record3.recordId, replacements);
|
|
62850
|
+
const fileFields = rewriteAssignedValue(record3.fileFields, replacements);
|
|
62851
|
+
if (!isObjectRecord2(fileFields)) {
|
|
62852
|
+
throw new Error(
|
|
62853
|
+
`Local ${record3.recordKind} "${recordId}" file fields did not rewrite to an object.`
|
|
62854
|
+
);
|
|
62855
|
+
}
|
|
62856
|
+
const fullData = rewriteAssignedValue(record3.fullData, replacements);
|
|
62857
|
+
if (!isObjectRecord2(fullData)) {
|
|
62858
|
+
throw new Error(
|
|
62859
|
+
`Local ${record3.recordKind} "${recordId}" full data did not rewrite to an object.`
|
|
62860
|
+
);
|
|
62861
|
+
}
|
|
62862
|
+
const key = recordStateKey(record3.recordKind, recordId);
|
|
62863
|
+
if (rewritten.has(key)) {
|
|
62864
|
+
throw new Error(
|
|
62865
|
+
`Project transaction assignments collapse multiple local records onto "${key}".`
|
|
62866
|
+
);
|
|
62867
|
+
}
|
|
62868
|
+
rewritten.set(key, { ...record3, recordId, fileFields, fullData });
|
|
62869
|
+
}
|
|
62870
|
+
return rewritten;
|
|
62871
|
+
}
|
|
62872
|
+
function rewriteAssignedString(value, replacements) {
|
|
62873
|
+
const exact = replacements.exact.get(value);
|
|
62874
|
+
if (exact !== void 0) return exact;
|
|
62875
|
+
let result = value;
|
|
62876
|
+
for (const [source, target] of replacements.embedded) {
|
|
62877
|
+
if (result.includes(source)) result = result.replaceAll(source, target);
|
|
62878
|
+
}
|
|
62879
|
+
return result;
|
|
62880
|
+
}
|
|
62881
|
+
function rewriteAssignedValue(value, replacements) {
|
|
62882
|
+
if (typeof value === "string") {
|
|
62883
|
+
return rewriteAssignedString(value, replacements);
|
|
62884
|
+
}
|
|
62885
|
+
if (Array.isArray(value)) {
|
|
62886
|
+
return value.map((entry) => rewriteAssignedValue(entry, replacements));
|
|
62887
|
+
}
|
|
62888
|
+
if (!isObjectRecord2(value)) return value;
|
|
62889
|
+
const rewritten = {};
|
|
62890
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
62891
|
+
rewritten[rewriteAssignedString(key, replacements)] = rewriteAssignedValue(
|
|
62892
|
+
entry,
|
|
62893
|
+
replacements
|
|
62894
|
+
);
|
|
62895
|
+
}
|
|
62896
|
+
return rewritten;
|
|
62897
|
+
}
|
|
62898
|
+
function mergeCommittedRecordWithLaterLocalEdits(recordKind, submitted, committed, local) {
|
|
62899
|
+
if (!isObjectRecord2(committed)) return local;
|
|
62900
|
+
if (isSchemaDocumentRecordKind(recordKind)) {
|
|
62901
|
+
if (schemaDocumentAuthoredSemanticallyEqual(recordKind, submitted, local)) {
|
|
62902
|
+
return committed;
|
|
62055
62903
|
}
|
|
62056
|
-
const
|
|
62057
|
-
|
|
62058
|
-
|
|
62059
|
-
|
|
62904
|
+
const merged2 = mergeSchemaDocumentRecord(
|
|
62905
|
+
recordKind,
|
|
62906
|
+
submitted,
|
|
62907
|
+
committed,
|
|
62908
|
+
local
|
|
62909
|
+
);
|
|
62910
|
+
return merged2.conflictFields.length === 0 ? merged2.merged : local;
|
|
62911
|
+
}
|
|
62912
|
+
const comparison = {
|
|
62913
|
+
base: sourceComparableRecordForPush(recordKind, submitted),
|
|
62914
|
+
server: sourceComparableRecordForPush(recordKind, committed),
|
|
62915
|
+
local: sourceComparableRecordForPush(recordKind, local)
|
|
62916
|
+
};
|
|
62917
|
+
if (canonicallyEqual(comparison.base, comparison.local)) return committed;
|
|
62918
|
+
const merged = threeWayMergeRecord(submitted, committed, local, {
|
|
62919
|
+
comparison,
|
|
62920
|
+
serverWinsFields: /* @__PURE__ */ new Set([
|
|
62921
|
+
"projectId",
|
|
62922
|
+
"createdAt",
|
|
62923
|
+
"updatedAt",
|
|
62924
|
+
"getter",
|
|
62925
|
+
"setter",
|
|
62926
|
+
"action",
|
|
62927
|
+
"layout"
|
|
62928
|
+
]),
|
|
62929
|
+
recursive: true
|
|
62930
|
+
});
|
|
62931
|
+
return merged.conflictFields.length === 0 ? merged.merged : local;
|
|
62932
|
+
}
|
|
62933
|
+
function sourceComparableRecordForPush(recordKind, value) {
|
|
62934
|
+
const result = {};
|
|
62935
|
+
const hasAuthoredCode = typeof value.code === "string" || typeof value.setterCode === "string";
|
|
62936
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
62937
|
+
if (key === "projectId" || key === "createdAt" || key === "updatedAt") {
|
|
62938
|
+
continue;
|
|
62060
62939
|
}
|
|
62940
|
+
if (recordKind === "dialogue-node" && key === "layout") continue;
|
|
62941
|
+
if (hasAuthoredCode && (key === "getter" || key === "setter" || key === "action")) {
|
|
62942
|
+
continue;
|
|
62943
|
+
}
|
|
62944
|
+
result[key] = sourceComparableValueForPush(recordKind, entry);
|
|
62945
|
+
}
|
|
62946
|
+
return result;
|
|
62947
|
+
}
|
|
62948
|
+
function sourceComparableValueForPush(recordKind, value) {
|
|
62949
|
+
if (Array.isArray(value)) {
|
|
62950
|
+
return value.map(
|
|
62951
|
+
(entry) => sourceComparableValueForPush(recordKind, entry)
|
|
62952
|
+
);
|
|
62953
|
+
}
|
|
62954
|
+
if (!isObjectRecord2(value)) return value;
|
|
62955
|
+
return sourceComparableRecordForPush(recordKind, value);
|
|
62956
|
+
}
|
|
62957
|
+
function readChangedRecordIdentity(changed) {
|
|
62958
|
+
if (!isObjectRecord2(changed)) {
|
|
62959
|
+
throw new Error("Transaction changedRecords entries must be objects.");
|
|
62960
|
+
}
|
|
62961
|
+
if (typeof changed.recordKind !== "string") {
|
|
62962
|
+
throw new Error(
|
|
62963
|
+
"Changed record is missing recordKind/recordId: recordKind is not a string."
|
|
62964
|
+
);
|
|
62965
|
+
}
|
|
62966
|
+
if (typeof changed.recordId !== "string") {
|
|
62967
|
+
throw new Error(
|
|
62968
|
+
"Changed record is missing recordKind/recordId: recordId is not a string."
|
|
62969
|
+
);
|
|
62970
|
+
}
|
|
62971
|
+
return { recordKind: changed.recordKind, recordId: changed.recordId };
|
|
62972
|
+
}
|
|
62973
|
+
function foldChangedRecords(previous, changedRecords) {
|
|
62974
|
+
const records2 = { ...previous };
|
|
62975
|
+
for (const changed of changedRecords) {
|
|
62976
|
+
const { recordKind, recordId } = readChangedRecordIdentity(changed);
|
|
62061
62977
|
const key = recordStateKey(recordKind, recordId);
|
|
62978
|
+
if (!isObjectRecord2(changed)) {
|
|
62979
|
+
throw new Error(`Changed record "${key}" must be an object.`);
|
|
62980
|
+
}
|
|
62062
62981
|
if (changed.deleted === true) {
|
|
62063
|
-
delete
|
|
62982
|
+
delete records2[key];
|
|
62064
62983
|
continue;
|
|
62065
62984
|
}
|
|
62066
62985
|
const snapshot = changed.snapshot;
|
|
62067
|
-
if (!isObjectRecord2(snapshot)
|
|
62986
|
+
if (!isObjectRecord2(snapshot)) {
|
|
62987
|
+
throw new Error(
|
|
62988
|
+
`Changed record "${key}" response is missing its snapshot.`
|
|
62989
|
+
);
|
|
62990
|
+
}
|
|
62991
|
+
if (typeof snapshot.contentHash !== "string") {
|
|
62068
62992
|
throw new Error(
|
|
62069
62993
|
`Changed record "${key}" response is missing its snapshot content hash.`
|
|
62070
62994
|
);
|
|
62071
62995
|
}
|
|
62072
|
-
|
|
62996
|
+
records2[key] = {
|
|
62073
62997
|
recordKind,
|
|
62074
62998
|
recordId,
|
|
62075
62999
|
contentHash: snapshot.contentHash,
|
|
62076
63000
|
data: changed.data,
|
|
62077
|
-
file:
|
|
63001
|
+
file: records2[key]?.file,
|
|
63002
|
+
projectBinary: records2[key]?.projectBinary
|
|
62078
63003
|
};
|
|
62079
63004
|
}
|
|
63005
|
+
return records2;
|
|
63006
|
+
}
|
|
63007
|
+
function applyPushResult(workspace, result) {
|
|
63008
|
+
if (!isObjectRecord2(result) || !Array.isArray(result.changedRecords)) {
|
|
63009
|
+
throw new Error("Transaction response is missing changedRecords.");
|
|
63010
|
+
}
|
|
63011
|
+
workspace.state.records = foldChangedRecords(
|
|
63012
|
+
workspace.state.records,
|
|
63013
|
+
result.changedRecords
|
|
63014
|
+
);
|
|
62080
63015
|
rewriteFilesFromState(workspace);
|
|
62081
63016
|
writeWorkspaceState(workspace.root, workspace.state);
|
|
62082
63017
|
}
|
|
62083
|
-
function rewriteFilesFromState(workspace
|
|
62084
|
-
|
|
62085
|
-
|
|
62086
|
-
|
|
63018
|
+
function rewriteFilesFromState(workspace, records2 = new Map(
|
|
63019
|
+
Object.entries(workspace.state.records).map(([key, recordState]) => [
|
|
63020
|
+
key,
|
|
63021
|
+
{
|
|
62087
63022
|
recordKind: recordState.recordKind,
|
|
62088
63023
|
recordId: recordState.recordId,
|
|
62089
63024
|
contentHash: recordState.contentHash,
|
|
62090
63025
|
deleted: false,
|
|
62091
63026
|
data: recordState.data
|
|
62092
|
-
}
|
|
62093
|
-
|
|
63027
|
+
}
|
|
63028
|
+
])
|
|
63029
|
+
)) {
|
|
62094
63030
|
const result = emitProjectDocumentFilesV4(records2);
|
|
62095
63031
|
writeProjectSourceAnalysisCacheV4(workspace.root, result.analysis);
|
|
62096
63032
|
const emittedPaths = new Set(result.files.map((file) => file.path));
|
|
@@ -62571,7 +63507,7 @@ function compileMigrationAction(schema, migrationData) {
|
|
|
62571
63507
|
migrationContext: true
|
|
62572
63508
|
});
|
|
62573
63509
|
}
|
|
62574
|
-
var compileNSAction2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createProjectVersionIntent2, isKnownProjectVersionIntentType2;
|
|
63510
|
+
var compileNSAction2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createProjectVersionIntent2, isKnownProjectVersionIntentType2, ProjectTransactionInterruptedError, ProjectTransactionFailedError, PROJECT_TRANSACTION_POLL_DELAYS_MS;
|
|
62575
63511
|
var init_push = __esm({
|
|
62576
63512
|
"src/commands/push.ts"() {
|
|
62577
63513
|
"use strict";
|
|
@@ -62588,8 +63524,38 @@ var init_push = __esm({
|
|
|
62588
63524
|
init_source_diagnostics();
|
|
62589
63525
|
init_projection();
|
|
62590
63526
|
init_project_file_push();
|
|
63527
|
+
init_project_manifest();
|
|
63528
|
+
init_merge();
|
|
62591
63529
|
({ compileNSAction: compileNSAction2, compileNSFunction: compileNSFunction2, compileNSGetter: compileNSGetter2, compileNSSetter: compileNSSetter2 } = compiler_adapter_exports);
|
|
62592
63530
|
({ createProjectVersionIntent: createProjectVersionIntent2, isKnownProjectVersionIntentType: isKnownProjectVersionIntentType2 } = project_version_intents_exports);
|
|
63531
|
+
ProjectTransactionInterruptedError = class extends Error {
|
|
63532
|
+
constructor(transactionId) {
|
|
63533
|
+
super(
|
|
63534
|
+
`Project transaction "${transactionId}" is still running. Run the same neo push again to reconnect.`
|
|
63535
|
+
);
|
|
63536
|
+
this.transactionId = transactionId;
|
|
63537
|
+
this.name = "ProjectTransactionInterruptedError";
|
|
63538
|
+
}
|
|
63539
|
+
transactionId;
|
|
63540
|
+
};
|
|
63541
|
+
ProjectTransactionFailedError = class extends Error {
|
|
63542
|
+
constructor(status) {
|
|
63543
|
+
super(
|
|
63544
|
+
status.errorMessage ?? `Project transaction "${status.transactionId}" failed after rollback.`
|
|
63545
|
+
);
|
|
63546
|
+
this.status = status;
|
|
63547
|
+
this.name = "ProjectTransactionFailedError";
|
|
63548
|
+
}
|
|
63549
|
+
status;
|
|
63550
|
+
};
|
|
63551
|
+
PROJECT_TRANSACTION_POLL_DELAYS_MS = [
|
|
63552
|
+
250,
|
|
63553
|
+
500,
|
|
63554
|
+
1e3,
|
|
63555
|
+
2e3,
|
|
63556
|
+
4e3,
|
|
63557
|
+
5e3
|
|
63558
|
+
];
|
|
62593
63559
|
}
|
|
62594
63560
|
});
|
|
62595
63561
|
|
|
@@ -63329,7 +64295,7 @@ ${h("Start")}
|
|
|
63329
64295
|
whoami ${d("[--api <url>]")}
|
|
63330
64296
|
|
|
63331
64297
|
${h("Working copy")}
|
|
63332
|
-
pull ${d("[--force|--reset] [--regenerate-source-names]")} push ${d("[--dry-run] [--summary <text>] [--accept-bump]")}
|
|
64298
|
+
pull ${d("[--force|--reset] [--regenerate-source-names]")} push ${d("[--dry-run] [--summary <text>] [--accept-bump] [--json]")}
|
|
63333
64299
|
status ${d("[--json]")} diff ${d("[--json]")}
|
|
63334
64300
|
dev ${d("[--push]")} resolve ${d("[--mine|--theirs]")}
|
|
63335
64301
|
doctor ${d("[--json]")} ${d("validate format/compiler/editor/source/file contracts")}
|
|
@@ -63379,16 +64345,18 @@ and tracked project binary from the authoritative server records.
|
|
|
63379
64345
|
return `${h("neo push")} \u2014 commit the working copy to the server
|
|
63380
64346
|
|
|
63381
64347
|
${h("Usage")}
|
|
63382
|
-
neo push ${d("[--dry-run] [--summary <text>] [--accept-bump]")}
|
|
64348
|
+
neo push ${d("[--dry-run] [--summary <text>] [--accept-bump] [--json]")}
|
|
63383
64349
|
|
|
63384
64350
|
${h("Flags")}
|
|
63385
64351
|
--dry-run ${d("Preview the change set; commit nothing.")}
|
|
63386
64352
|
--summary <text> ${d("Attach a summary message to the transaction.")}
|
|
63387
64353
|
--accept-bump ${d("Accept a server-required version bump instead of aborting.")}
|
|
64354
|
+
--json ${d("Emit machine-readable plan and transaction progress events.")}
|
|
63388
64355
|
|
|
63389
|
-
Push sends the ${h("entire")} working copy as one
|
|
63390
|
-
transaction.
|
|
63391
|
-
|
|
64356
|
+
Push sends the ${h("entire")} working copy as one compare-and-swap logical
|
|
64357
|
+
transaction. Large pushes continue as a durable server job; rerun the identical
|
|
64358
|
+
push to reconnect if the terminal closes. Run ${h("neo status")} / ${h("neo diff")}
|
|
64359
|
+
first \u2014 local-ahead changes you did not make this session ride along too.
|
|
63392
64360
|
`;
|
|
63393
64361
|
}
|
|
63394
64362
|
if (command === "script") {
|
|
@@ -63880,7 +64848,8 @@ async function main() {
|
|
|
63880
64848
|
await runPush2(workspace, {
|
|
63881
64849
|
dryRun: boolFlag(args, "dry-run"),
|
|
63882
64850
|
summary: stringFlag(args, "summary"),
|
|
63883
|
-
acceptBump: boolFlag(args, "accept-bump")
|
|
64851
|
+
acceptBump: boolFlag(args, "accept-bump"),
|
|
64852
|
+
json: boolFlag(args, "json")
|
|
63884
64853
|
});
|
|
63885
64854
|
return;
|
|
63886
64855
|
}
|