@neocompose/cli 0.50.6 → 0.50.8
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 +17 -0
- package/dist/neo.mjs +965 -344
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +3 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/commands-and-sync.md +25 -2
- package/skills/neocompose-cli/references/values-identities-and-references.md +5 -1
package/dist/neo.mjs
CHANGED
|
@@ -41,6 +41,31 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
mod
|
|
42
42
|
));
|
|
43
43
|
|
|
44
|
+
// src/performance.ts
|
|
45
|
+
function startPerformanceSpan(phase, fields = {}) {
|
|
46
|
+
if (process.env.NEO_COMPOSE_TRACE_PERFORMANCE !== "1") return () => {
|
|
47
|
+
};
|
|
48
|
+
const started = performance.now();
|
|
49
|
+
return () => recordPerformance(phase, performance.now() - started, fields);
|
|
50
|
+
}
|
|
51
|
+
function recordPerformance(phase, durationMs, fields = {}) {
|
|
52
|
+
if (process.env.NEO_COMPOSE_TRACE_PERFORMANCE !== "1") return;
|
|
53
|
+
console.error(
|
|
54
|
+
JSON.stringify({
|
|
55
|
+
type: "neo-performance",
|
|
56
|
+
phase,
|
|
57
|
+
...fields,
|
|
58
|
+
startedMs: Math.round(performance.now() - durationMs),
|
|
59
|
+
durationMs: Math.round(durationMs)
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
var init_performance = __esm({
|
|
64
|
+
"src/performance.ts"() {
|
|
65
|
+
"use strict";
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
44
69
|
// src/project-source/workspace-source-path.ts
|
|
45
70
|
import { existsSync, lstatSync, realpathSync } from "node:fs";
|
|
46
71
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
@@ -34757,7 +34782,9 @@ __export(token_store_exports, {
|
|
|
34757
34782
|
keychainAccount: () => keychainAccount,
|
|
34758
34783
|
loadCredential: () => loadCredential,
|
|
34759
34784
|
loadToken: () => loadToken,
|
|
34760
|
-
|
|
34785
|
+
loadTrustedConvexSite: () => loadTrustedConvexSite,
|
|
34786
|
+
saveCredential: () => saveCredential,
|
|
34787
|
+
saveTrustedConvexSite: () => saveTrustedConvexSite
|
|
34761
34788
|
});
|
|
34762
34789
|
import {
|
|
34763
34790
|
chmodSync,
|
|
@@ -34884,6 +34911,22 @@ function loadCredential(apiBaseUrl) {
|
|
|
34884
34911
|
const file = readCredentialsFile();
|
|
34885
34912
|
return file.credentials[apiBaseUrl] ?? null;
|
|
34886
34913
|
}
|
|
34914
|
+
function loadTrustedConvexSite(apiBaseUrl) {
|
|
34915
|
+
return readCredentialsFile().convexSites?.[apiBaseUrl] ?? null;
|
|
34916
|
+
}
|
|
34917
|
+
function saveTrustedConvexSite(apiBaseUrl, siteUrl) {
|
|
34918
|
+
const file = readCredentialsFile();
|
|
34919
|
+
file.convexSites ??= {};
|
|
34920
|
+
file.convexSites[apiBaseUrl] = siteUrl;
|
|
34921
|
+
mkdirSync2(credentialsDir(), { recursive: true, mode: 448 });
|
|
34922
|
+
const path = credentialsPath();
|
|
34923
|
+
writeFileSync2(path, `${JSON.stringify(file, null, 2)}
|
|
34924
|
+
`, {
|
|
34925
|
+
encoding: "utf8",
|
|
34926
|
+
mode: 384
|
|
34927
|
+
});
|
|
34928
|
+
chmodSync(path, 384);
|
|
34929
|
+
}
|
|
34887
34930
|
function deleteCredential(apiBaseUrl) {
|
|
34888
34931
|
const account = keychainAccount(apiBaseUrl);
|
|
34889
34932
|
const fromKeychain = keychainGet(account);
|
|
@@ -34892,11 +34935,12 @@ function deleteCredential(apiBaseUrl) {
|
|
|
34892
34935
|
const token = fromKeychain ?? (fileEntry !== void 0 && fileEntry.token !== "" ? fileEntry.token : null);
|
|
34893
34936
|
const deletedKeychainEntry = keychainDelete(account);
|
|
34894
34937
|
let deletedFileEntry = false;
|
|
34895
|
-
if (fileEntry !== void 0) {
|
|
34938
|
+
if (fileEntry !== void 0 || file.convexSites?.[apiBaseUrl] !== void 0) {
|
|
34896
34939
|
delete file.credentials[apiBaseUrl];
|
|
34897
|
-
|
|
34940
|
+
if (file.convexSites !== void 0) delete file.convexSites[apiBaseUrl];
|
|
34941
|
+
deletedFileEntry = fileEntry !== void 0;
|
|
34898
34942
|
const path = credentialsPath();
|
|
34899
|
-
if (Object.keys(file.credentials).length === 0) {
|
|
34943
|
+
if (Object.keys(file.credentials).length === 0 && Object.keys(file.convexSites ?? {}).length === 0) {
|
|
34900
34944
|
rmSync(path, { force: true });
|
|
34901
34945
|
} else {
|
|
34902
34946
|
writeFileSync2(path, `${JSON.stringify(file, null, 2)}
|
|
@@ -76470,7 +76514,13 @@ function virtualExpandedRecordForReceiver(receiver, ctx) {
|
|
|
76470
76514
|
if (rowId === null) return null;
|
|
76471
76515
|
const rows = ctx.vm.databaseVM?.virtualInstanceRowsForValue(rowId);
|
|
76472
76516
|
if (rows === void 0 || rows.length === 0) return null;
|
|
76473
|
-
|
|
76517
|
+
ctx.__virtualRowsById ??= /* @__PURE__ */ new WeakMap();
|
|
76518
|
+
let rowsById = ctx.__virtualRowsById.get(rows);
|
|
76519
|
+
if (rowsById === void 0) {
|
|
76520
|
+
rowsById = new Map(rows.map((row) => [row.id, row]));
|
|
76521
|
+
ctx.__virtualRowsById.set(rows, rowsById);
|
|
76522
|
+
}
|
|
76523
|
+
const expanded = rowsById.get(rowId);
|
|
76474
76524
|
if (expanded === void 0) return null;
|
|
76475
76525
|
const record4 = expanded.value;
|
|
76476
76526
|
if (typeof record4 !== "object" || record4 === null || Array.isArray(record4)) {
|
|
@@ -79022,7 +79072,7 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
|
|
|
79022
79072
|
if (isMemberLookupBase(member)) {
|
|
79023
79073
|
return encodeLookupInitializerResult(member, result.value, created, ctx);
|
|
79024
79074
|
}
|
|
79025
|
-
|
|
79075
|
+
let rootRow = initializerRootRow(result.value, created);
|
|
79026
79076
|
for (const row of created) {
|
|
79027
79077
|
if (row === rootRow) continue;
|
|
79028
79078
|
createdValues.push(row);
|
|
@@ -79038,11 +79088,36 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
|
|
|
79038
79088
|
existingValueRow
|
|
79039
79089
|
};
|
|
79040
79090
|
}
|
|
79041
|
-
|
|
79091
|
+
if (existingValueRow !== null && existingRuntimeClassId !== null && isMemberClassBase(member)) {
|
|
79092
|
+
const storage = constructorArgumentStorage(existingValueRow.id, ctx);
|
|
79093
|
+
if (storage !== 3 /* Session */) {
|
|
79094
|
+
const checkpoint = sessionCreationCheckpoint(ctx);
|
|
79095
|
+
const value = cloneClassValueGraph(
|
|
79096
|
+
result.value,
|
|
79097
|
+
existingRuntimeClassId,
|
|
79098
|
+
ctx
|
|
79099
|
+
);
|
|
79100
|
+
const importedRows = createdSessionValuesSince(ctx, checkpoint);
|
|
79101
|
+
const imported = initializerRootRow(value, importedRows);
|
|
79102
|
+
if (imported === null) {
|
|
79103
|
+
throw new NSGetterRuntimeError(
|
|
79104
|
+
`Initializer '${member.name}' imported a Class without a backing row.`
|
|
79105
|
+
);
|
|
79106
|
+
}
|
|
79107
|
+
rootRow = imported;
|
|
79108
|
+
result = { ...result, value };
|
|
79109
|
+
for (const row of importedRows) {
|
|
79110
|
+
if (row !== rootRow) createdValues.push(row);
|
|
79111
|
+
}
|
|
79112
|
+
}
|
|
79113
|
+
}
|
|
79114
|
+
if (rootRow === null) {
|
|
79115
|
+
return { value: result.value, classId: existingRuntimeClassId };
|
|
79116
|
+
}
|
|
79042
79117
|
}
|
|
79043
79118
|
deleteRuntimeSessionValue(ctx, rootRow.id);
|
|
79044
79119
|
ctx.__executionState?.constructorGroups.delete(rootRow.id);
|
|
79045
|
-
const constructorArgs = typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue.get(result.value) : void 0;
|
|
79120
|
+
const constructorArgs = typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue.get(result.value) ?? rootRow.constructorArgs ?? void 0 : void 0;
|
|
79046
79121
|
const provenance = pickInstanceProvenance({
|
|
79047
79122
|
constructorArgs,
|
|
79048
79123
|
instanceConstructorId: rootRow.instanceConstructorId,
|
|
@@ -80420,7 +80495,11 @@ function cloneConstructorArgumentGraph(args) {
|
|
|
80420
80495
|
);
|
|
80421
80496
|
const record4 = {};
|
|
80422
80497
|
clone.value = record4;
|
|
80423
|
-
|
|
80498
|
+
const sourceRecord = {
|
|
80499
|
+
...virtualExpandedRecordForReceiver(source.value, args.ctx),
|
|
80500
|
+
...source.value
|
|
80501
|
+
};
|
|
80502
|
+
for (const [schemaKey, childId] of Object.entries(sourceRecord)) {
|
|
80424
80503
|
if (typeof childId !== "string") {
|
|
80425
80504
|
throw new NSGetterRuntimeError(
|
|
80426
80505
|
`Constructor import found a non-id Class field '${schemaKey}' on value '${source.id}'.`
|
|
@@ -80979,10 +81058,12 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
|
|
|
80979
81058
|
registerRuntimeSessionValue(ctx, clone);
|
|
80980
81059
|
clonedBySourceId.set(sourceRow.id, clone);
|
|
80981
81060
|
if (typeof sourceRow.value === "object" && sourceRow.value !== null && !Array.isArray(sourceRow.value)) {
|
|
80982
|
-
const
|
|
80983
|
-
|
|
81061
|
+
const clonedRecord = {
|
|
81062
|
+
...virtualExpandedRecordForReceiver(sourceRow.value, ctx),
|
|
81063
|
+
...sourceRow.value
|
|
81064
|
+
};
|
|
80984
81065
|
clone.value = clonedRecord;
|
|
80985
|
-
for (const [key, childId] of Object.entries(
|
|
81066
|
+
for (const [key, childId] of Object.entries(clonedRecord)) {
|
|
80986
81067
|
if (typeof childId !== "string") continue;
|
|
80987
81068
|
const childMember = sourceTypeInfo?.type === 5 /* Dictionary */ ? null : ownedObjectChildMember(sourceRow, sourceMember, key, ctx);
|
|
80988
81069
|
const childTypeInfo = sourceTypeInfo?.type === 5 /* Dictionary */ ? sourceTypeInfo.entryTypeInfo : void 0;
|
|
@@ -82328,25 +82409,66 @@ function resolvedStoredInstanceRows(args) {
|
|
|
82328
82409
|
const rows = new Map(document.values.map((row) => [row.id, row]));
|
|
82329
82410
|
const materializedIndex = buildVirtualInstanceMaterializedIndex({ document });
|
|
82330
82411
|
const queue = [{ root: args.instanceRoot, member: args.rootMember }];
|
|
82412
|
+
const visitedArguments = /* @__PURE__ */ new Set();
|
|
82413
|
+
const argumentRoots = (row) => {
|
|
82414
|
+
const roots = [];
|
|
82415
|
+
const collectArgument = (valueId, type) => {
|
|
82416
|
+
if (visitedArguments.has(valueId)) return;
|
|
82417
|
+
const row2 = materializedIndex.rowsById.get(valueId);
|
|
82418
|
+
if (row2 === void 0) return;
|
|
82419
|
+
visitedArguments.add(valueId);
|
|
82420
|
+
if (type.type === 7 /* Class */ || type.type === 22 /* Interface */) {
|
|
82421
|
+
const classId = row2.classId ?? (type.type === 7 /* Class */ ? type.classId : void 0);
|
|
82422
|
+
if (classId === void 0) return;
|
|
82423
|
+
roots.push({
|
|
82424
|
+
root: row2,
|
|
82425
|
+
member: {
|
|
82426
|
+
name: "Constructor argument",
|
|
82427
|
+
kind: 7 /* Class */,
|
|
82428
|
+
classId,
|
|
82429
|
+
requirement: 1 /* Required */
|
|
82430
|
+
}
|
|
82431
|
+
});
|
|
82432
|
+
} else if (type.type === 6 /* List */) {
|
|
82433
|
+
const children = materializedIndex.unorderedEntryIdsByContainerId.get(valueId);
|
|
82434
|
+
for (const childId of children ?? (Array.isArray(row2.value) ? row2.value : [])) {
|
|
82435
|
+
if (typeof childId === "string")
|
|
82436
|
+
collectArgument(childId, type.entryTypeInfo);
|
|
82437
|
+
}
|
|
82438
|
+
} else if (type.type === 5 /* Dictionary */) {
|
|
82439
|
+
for (const childId of Object.values(stringRecord2(row2.value)))
|
|
82440
|
+
collectArgument(childId, type.entryTypeInfo);
|
|
82441
|
+
}
|
|
82442
|
+
};
|
|
82443
|
+
for (const edge of materializedIndex.graph.constructorEdges(row)) {
|
|
82444
|
+
collectArgument(edge.targetValueId, edge.typeInfo);
|
|
82445
|
+
}
|
|
82446
|
+
return roots;
|
|
82447
|
+
};
|
|
82331
82448
|
const stored = indexExpansion({
|
|
82332
82449
|
document,
|
|
82333
82450
|
instanceRoot: args.instanceRoot,
|
|
82334
82451
|
rootMember: args.rootMember,
|
|
82335
82452
|
expandedRoot: rows.get(args.instanceRoot.id) ?? args.instanceRoot,
|
|
82336
|
-
expandedRows: document.values
|
|
82453
|
+
expandedRows: document.values,
|
|
82454
|
+
additionalRoots: argumentRoots
|
|
82337
82455
|
});
|
|
82338
|
-
|
|
82339
|
-
|
|
82340
|
-
|
|
82341
|
-
|
|
82342
|
-
|
|
82343
|
-
|
|
82456
|
+
const enqueueStoredRoots = (nodes) => {
|
|
82457
|
+
for (const node of nodes) {
|
|
82458
|
+
if (node.expandedRow.id === args.instanceRoot.id) continue;
|
|
82459
|
+
if (!isMemberClassBase(node.member)) continue;
|
|
82460
|
+
if (!isStoredClassResolutionRoot(node.expandedRow)) continue;
|
|
82461
|
+
queue.push({ root: node.expandedRow, member: node.member });
|
|
82462
|
+
}
|
|
82463
|
+
};
|
|
82464
|
+
enqueueStoredRoots(stored.nodesByPath.values());
|
|
82344
82465
|
const resolvedRootIds = /* @__PURE__ */ new Set();
|
|
82345
82466
|
const resolvedFrameByValueId = /* @__PURE__ */ new Map();
|
|
82346
|
-
|
|
82347
|
-
const next = queue
|
|
82467
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
82468
|
+
const next = queue[index];
|
|
82348
82469
|
if (next === void 0 || resolvedRootIds.has(next.root.id)) continue;
|
|
82349
82470
|
resolvedRootIds.add(next.root.id);
|
|
82471
|
+
enqueueStoredRoots(stored.includeRoot(next.root, next.member));
|
|
82350
82472
|
const expanded = expandStoredClassValue({
|
|
82351
82473
|
evaluateInitializer: args.evaluateInitializer,
|
|
82352
82474
|
document,
|
|
@@ -83226,6 +83348,7 @@ function indexExpansion(args) {
|
|
|
83226
83348
|
if (paths === void 0) childPathsByParentPath.set(parentPath, [pathKey]);
|
|
83227
83349
|
else paths.push(pathKey);
|
|
83228
83350
|
};
|
|
83351
|
+
let discoveredNodes = null;
|
|
83229
83352
|
const visit = (rowId, rawMember, pathKey, parentPath, parentSegment, genericEnv) => {
|
|
83230
83353
|
const row = rowsByExpandedId.get(rowId);
|
|
83231
83354
|
if (row === void 0 || nodesByExpandedId.has(rowId)) return;
|
|
@@ -83260,6 +83383,7 @@ function indexExpansion(args) {
|
|
|
83260
83383
|
virtualId
|
|
83261
83384
|
};
|
|
83262
83385
|
nodesByExpandedId.set(rowId, node);
|
|
83386
|
+
discoveredNodes?.push(node);
|
|
83263
83387
|
nodesByPath.set(pathKey, node);
|
|
83264
83388
|
appendChildPath(parentPath, pathKey);
|
|
83265
83389
|
const childEnv = row.genericBindings ? envFromStamp(row.genericBindings) : genericEnv;
|
|
@@ -83362,15 +83486,49 @@ function indexExpansion(args) {
|
|
|
83362
83486
|
);
|
|
83363
83487
|
}
|
|
83364
83488
|
};
|
|
83365
|
-
|
|
83366
|
-
|
|
83367
|
-
|
|
83368
|
-
|
|
83369
|
-
|
|
83370
|
-
|
|
83371
|
-
/* @__PURE__ */ new Map()
|
|
83372
|
-
|
|
83489
|
+
const includeRoot = (root, member, path = appendPath(ROOT_PATH, {
|
|
83490
|
+
kind: "class",
|
|
83491
|
+
schemaKey: `@stored:${root.id}`
|
|
83492
|
+
})) => {
|
|
83493
|
+
const added = [];
|
|
83494
|
+
discoveredNodes = added;
|
|
83495
|
+
visit(root.id, member, path, null, null, /* @__PURE__ */ new Map());
|
|
83496
|
+
if (args.additionalRoots !== void 0) {
|
|
83497
|
+
for (let index = 0; index < added.length; index += 1) {
|
|
83498
|
+
for (const { root: root2, member: member2 } of args.additionalRoots(
|
|
83499
|
+
added[index].expandedRow
|
|
83500
|
+
)) {
|
|
83501
|
+
visit(
|
|
83502
|
+
root2.id,
|
|
83503
|
+
member2,
|
|
83504
|
+
appendPath(ROOT_PATH, {
|
|
83505
|
+
kind: "class",
|
|
83506
|
+
schemaKey: `@constructor:${root2.id}`
|
|
83507
|
+
}),
|
|
83508
|
+
null,
|
|
83509
|
+
null,
|
|
83510
|
+
/* @__PURE__ */ new Map()
|
|
83511
|
+
);
|
|
83512
|
+
}
|
|
83513
|
+
}
|
|
83514
|
+
}
|
|
83515
|
+
discoveredNodes = null;
|
|
83516
|
+
return added;
|
|
83517
|
+
};
|
|
83518
|
+
if (args.additionalRoots === void 0) {
|
|
83519
|
+
visit(
|
|
83520
|
+
args.expandedRoot.id,
|
|
83521
|
+
args.rootMember,
|
|
83522
|
+
ROOT_PATH,
|
|
83523
|
+
null,
|
|
83524
|
+
null,
|
|
83525
|
+
/* @__PURE__ */ new Map()
|
|
83526
|
+
);
|
|
83527
|
+
} else {
|
|
83528
|
+
includeRoot(args.expandedRoot, args.rootMember, ROOT_PATH);
|
|
83529
|
+
}
|
|
83373
83530
|
return {
|
|
83531
|
+
includeRoot,
|
|
83374
83532
|
nodesByExpandedId,
|
|
83375
83533
|
nodesByPath,
|
|
83376
83534
|
rowsByExpandedId,
|
|
@@ -109701,17 +109859,17 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
109701
109859
|
useBuildCaches: options.useBuildCaches !== false
|
|
109702
109860
|
})
|
|
109703
109861
|
});
|
|
109862
|
+
const compilationSources = projectSources.map((source) => ({
|
|
109863
|
+
uri: source.uri,
|
|
109864
|
+
kind: source.kind,
|
|
109865
|
+
text: source.source
|
|
109866
|
+
}));
|
|
109704
109867
|
try {
|
|
109705
109868
|
if (!baseManifest) {
|
|
109706
109869
|
throw new Error(
|
|
109707
109870
|
"Format-4 status requires a pulled schema base; run `neo pull --reset`."
|
|
109708
109871
|
);
|
|
109709
109872
|
}
|
|
109710
|
-
const compilationSources = projectSources.map((source) => ({
|
|
109711
|
-
uri: source.uri,
|
|
109712
|
-
kind: source.kind,
|
|
109713
|
-
text: source.source
|
|
109714
|
-
}));
|
|
109715
109873
|
const analysis = options.readProjectAnalysisCache?.(workspace.root, compilationSources) ?? options.compileProjectAnalysis?.(workspace.root, compilationSources) ?? compileNeoProjectSources(compilationSources);
|
|
109716
109874
|
projectAnalysisV4 = analysis;
|
|
109717
109875
|
for (const diagnostic of analysis.diagnostics) {
|
|
@@ -110414,6 +110572,12 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
110414
110572
|
}
|
|
110415
110573
|
reportPhase("initializer-materialization");
|
|
110416
110574
|
return {
|
|
110575
|
+
...projectAnalysisV4 === null ? {} : {
|
|
110576
|
+
sourceSnapshot: {
|
|
110577
|
+
inputs: compilationSources,
|
|
110578
|
+
analysis: projectAnalysisV4
|
|
110579
|
+
}
|
|
110580
|
+
},
|
|
110417
110581
|
localValues: valueLowerRegistry.localValues?.placements(),
|
|
110418
110582
|
changes,
|
|
110419
110583
|
conflictedFiles,
|
|
@@ -123276,6 +123440,7 @@ function computeWorkspaceStatus2(workspace, options = {}) {
|
|
|
123276
123440
|
}));
|
|
123277
123441
|
return computeWorkspaceStatus(workspace, {
|
|
123278
123442
|
...options,
|
|
123443
|
+
reportPhase: options.reportPhase ?? ((phase, milliseconds) => recordPerformance(`workspace-${phase}`, milliseconds)),
|
|
123279
123444
|
virtualSourceFiles,
|
|
123280
123445
|
writeProjectAnalysisCache: options.writeProjectAnalysisCache ?? writeProjectSourceAnalysisCacheV4,
|
|
123281
123446
|
readProjectAnalysisCache: options.readProjectAnalysisCache ?? readProjectSourceAnalysisBuildCacheV4,
|
|
@@ -123292,6 +123457,7 @@ var init_workspace_status = __esm({
|
|
|
123292
123457
|
"use strict";
|
|
123293
123458
|
import_ignore = __toESM(require_ignore(), 1);
|
|
123294
123459
|
init_src();
|
|
123460
|
+
init_performance();
|
|
123295
123461
|
init_project_document_cache();
|
|
123296
123462
|
init_project_files();
|
|
123297
123463
|
init_supplemental_records_file_system();
|
|
@@ -123428,6 +123594,164 @@ var init_status_output = __esm({
|
|
|
123428
123594
|
}
|
|
123429
123595
|
});
|
|
123430
123596
|
|
|
123597
|
+
// src/http.ts
|
|
123598
|
+
var NeoApiError, NeoApiClient;
|
|
123599
|
+
var init_http = __esm({
|
|
123600
|
+
"src/http.ts"() {
|
|
123601
|
+
"use strict";
|
|
123602
|
+
init_performance();
|
|
123603
|
+
init_token_store();
|
|
123604
|
+
NeoApiError = class extends Error {
|
|
123605
|
+
constructor(message, status, body) {
|
|
123606
|
+
super(message);
|
|
123607
|
+
this.status = status;
|
|
123608
|
+
this.body = body;
|
|
123609
|
+
this.name = "NeoApiError";
|
|
123610
|
+
}
|
|
123611
|
+
status;
|
|
123612
|
+
body;
|
|
123613
|
+
};
|
|
123614
|
+
NeoApiClient = class _NeoApiClient {
|
|
123615
|
+
constructor(apiBaseUrl, token) {
|
|
123616
|
+
this.apiBaseUrl = apiBaseUrl;
|
|
123617
|
+
this.token = token;
|
|
123618
|
+
}
|
|
123619
|
+
apiBaseUrl;
|
|
123620
|
+
token;
|
|
123621
|
+
static forBaseUrl(apiBaseUrl) {
|
|
123622
|
+
const token = loadToken(apiBaseUrl);
|
|
123623
|
+
if (token === null) {
|
|
123624
|
+
throw new Error(
|
|
123625
|
+
`No credentials stored for "${apiBaseUrl}". Run "neo login" (or set NEO_COMPOSE_TOKEN).`
|
|
123626
|
+
);
|
|
123627
|
+
}
|
|
123628
|
+
return new _NeoApiClient(apiBaseUrl, token);
|
|
123629
|
+
}
|
|
123630
|
+
async post(path, body, headers, options = {}) {
|
|
123631
|
+
return await this.postBytes(
|
|
123632
|
+
path,
|
|
123633
|
+
body === void 0 ? void 0 : JSON.stringify(body),
|
|
123634
|
+
headers,
|
|
123635
|
+
options
|
|
123636
|
+
);
|
|
123637
|
+
}
|
|
123638
|
+
async postBytes(path, body, headers, options = {}) {
|
|
123639
|
+
const url = new URL(path, this.apiBaseUrl).toString();
|
|
123640
|
+
const finish = startPerformanceSpan("http", {
|
|
123641
|
+
method: "POST",
|
|
123642
|
+
path: new URL(url).pathname
|
|
123643
|
+
});
|
|
123644
|
+
try {
|
|
123645
|
+
const response = await fetch(url, {
|
|
123646
|
+
method: "POST",
|
|
123647
|
+
headers: {
|
|
123648
|
+
Authorization: `Bearer ${this.token}`,
|
|
123649
|
+
"Content-Type": "application/json",
|
|
123650
|
+
...headers
|
|
123651
|
+
},
|
|
123652
|
+
body,
|
|
123653
|
+
signal: options.signal
|
|
123654
|
+
});
|
|
123655
|
+
const text = await response.text();
|
|
123656
|
+
let parsed = null;
|
|
123657
|
+
if (text.length > 0) {
|
|
123658
|
+
try {
|
|
123659
|
+
parsed = JSON.parse(text);
|
|
123660
|
+
} catch {
|
|
123661
|
+
parsed = text;
|
|
123662
|
+
}
|
|
123663
|
+
}
|
|
123664
|
+
if (!response.ok) {
|
|
123665
|
+
const detail = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string" ? parsed.error : text.slice(0, 300);
|
|
123666
|
+
throw new NeoApiError(
|
|
123667
|
+
`POST ${path} failed with status ${response.status}: ${detail}`,
|
|
123668
|
+
response.status,
|
|
123669
|
+
parsed
|
|
123670
|
+
);
|
|
123671
|
+
}
|
|
123672
|
+
return parsed;
|
|
123673
|
+
} finally {
|
|
123674
|
+
finish();
|
|
123675
|
+
}
|
|
123676
|
+
}
|
|
123677
|
+
async get(path, options = {}) {
|
|
123678
|
+
const url = new URL(path, this.apiBaseUrl).toString();
|
|
123679
|
+
const finish = startPerformanceSpan("http", {
|
|
123680
|
+
method: "GET",
|
|
123681
|
+
path: new URL(url).pathname
|
|
123682
|
+
});
|
|
123683
|
+
try {
|
|
123684
|
+
const response = await fetch(url, {
|
|
123685
|
+
method: "GET",
|
|
123686
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
123687
|
+
signal: options.signal
|
|
123688
|
+
});
|
|
123689
|
+
const text = await response.text();
|
|
123690
|
+
let parsed = null;
|
|
123691
|
+
if (text.length > 0) {
|
|
123692
|
+
try {
|
|
123693
|
+
parsed = JSON.parse(text);
|
|
123694
|
+
} catch {
|
|
123695
|
+
parsed = text;
|
|
123696
|
+
}
|
|
123697
|
+
}
|
|
123698
|
+
if (!response.ok) {
|
|
123699
|
+
const detail = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string" ? parsed.error : text.slice(0, 300);
|
|
123700
|
+
throw new NeoApiError(
|
|
123701
|
+
`GET ${path} failed with status ${response.status}: ${detail}`,
|
|
123702
|
+
response.status,
|
|
123703
|
+
parsed
|
|
123704
|
+
);
|
|
123705
|
+
}
|
|
123706
|
+
return parsed;
|
|
123707
|
+
} finally {
|
|
123708
|
+
finish();
|
|
123709
|
+
}
|
|
123710
|
+
}
|
|
123711
|
+
async getBytes(path) {
|
|
123712
|
+
const url = new URL(path, this.apiBaseUrl).toString();
|
|
123713
|
+
const finish = startPerformanceSpan("http", {
|
|
123714
|
+
method: "GET",
|
|
123715
|
+
path: new URL(url).pathname
|
|
123716
|
+
});
|
|
123717
|
+
try {
|
|
123718
|
+
const response = await fetch(url, {
|
|
123719
|
+
method: "GET",
|
|
123720
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
123721
|
+
});
|
|
123722
|
+
if (!response.ok) {
|
|
123723
|
+
const detail = (await response.text()).slice(0, 300);
|
|
123724
|
+
throw new NeoApiError(
|
|
123725
|
+
`GET ${path} failed with status ${response.status}: ${detail}`,
|
|
123726
|
+
response.status,
|
|
123727
|
+
detail
|
|
123728
|
+
);
|
|
123729
|
+
}
|
|
123730
|
+
return {
|
|
123731
|
+
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
123732
|
+
contentSha256: response.headers.get("x-neo-content-sha256"),
|
|
123733
|
+
contentType: response.headers.get("content-type")
|
|
123734
|
+
};
|
|
123735
|
+
} finally {
|
|
123736
|
+
finish();
|
|
123737
|
+
}
|
|
123738
|
+
}
|
|
123739
|
+
};
|
|
123740
|
+
}
|
|
123741
|
+
});
|
|
123742
|
+
|
|
123743
|
+
// ../src/common/schema-commit-transport.ts
|
|
123744
|
+
var SCHEMA_COMMIT_HTTP_MAX_BYTES, SCHEMA_COMMIT_HTTP_MAX_DECODED_BYTES, SCHEMA_COMMIT_HTTP_PATH, SCHEMA_COMMIT_V8_MAX_DECODED_BYTES;
|
|
123745
|
+
var init_schema_commit_transport = __esm({
|
|
123746
|
+
"../src/common/schema-commit-transport.ts"() {
|
|
123747
|
+
"use strict";
|
|
123748
|
+
SCHEMA_COMMIT_HTTP_MAX_BYTES = 18 * 1024 * 1024;
|
|
123749
|
+
SCHEMA_COMMIT_HTTP_MAX_DECODED_BYTES = 32 * 1024 * 1024;
|
|
123750
|
+
SCHEMA_COMMIT_HTTP_PATH = "/schema-commit";
|
|
123751
|
+
SCHEMA_COMMIT_V8_MAX_DECODED_BYTES = 1024 * 1024;
|
|
123752
|
+
}
|
|
123753
|
+
});
|
|
123754
|
+
|
|
123431
123755
|
// ../convex/_generated/api.js
|
|
123432
123756
|
var api_exports = {};
|
|
123433
123757
|
__export(api_exports, {
|
|
@@ -123450,35 +123774,62 @@ var init_api = __esm({
|
|
|
123450
123774
|
var convex_exports = {};
|
|
123451
123775
|
__export(convex_exports, {
|
|
123452
123776
|
api: () => api2,
|
|
123777
|
+
convexHttpActionUrl: () => convexHttpActionUrl,
|
|
123453
123778
|
createConvexClient: () => createConvexClient,
|
|
123454
123779
|
createConvexClientForApi: () => createConvexClientForApi,
|
|
123780
|
+
createConvexPushConnection: () => createConvexPushConnection,
|
|
123455
123781
|
mintConvexJwt: () => mintConvexJwt,
|
|
123456
123782
|
resolveConvexUrl: () => resolveConvexUrl
|
|
123457
123783
|
});
|
|
123458
|
-
import {
|
|
123784
|
+
import { gzipSync } from "node:zlib";
|
|
123785
|
+
import { ConvexClient, ConvexHttpClient } from "convex/browser";
|
|
123459
123786
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
123460
|
-
async function mintConvexJwt(apiBaseUrl) {
|
|
123461
|
-
const
|
|
123462
|
-
|
|
123463
|
-
|
|
123464
|
-
|
|
123465
|
-
|
|
123466
|
-
|
|
123467
|
-
|
|
123468
|
-
|
|
123469
|
-
|
|
123470
|
-
|
|
123471
|
-
|
|
123472
|
-
|
|
123473
|
-
|
|
123787
|
+
async function mintConvexJwt(apiBaseUrl, signal, convexSiteUrl) {
|
|
123788
|
+
const finish = startPerformanceSpan("authentication");
|
|
123789
|
+
try {
|
|
123790
|
+
const sessionToken = loadToken(apiBaseUrl);
|
|
123791
|
+
if (sessionToken === null) {
|
|
123792
|
+
throw new Error(
|
|
123793
|
+
`No credentials stored for "${apiBaseUrl}". Run "neo login".`
|
|
123794
|
+
);
|
|
123795
|
+
}
|
|
123796
|
+
const pinnedSite = loadTrustedConvexSite(apiBaseUrl);
|
|
123797
|
+
const direct = convexSiteUrl !== void 0 && pinnedSite === convexSiteUrl;
|
|
123798
|
+
const response = await fetch(
|
|
123799
|
+
new URL("/api/auth/convex/token", direct ? convexSiteUrl : apiBaseUrl),
|
|
123800
|
+
{
|
|
123801
|
+
headers: { Authorization: `Bearer ${sessionToken}` },
|
|
123802
|
+
redirect: "error",
|
|
123803
|
+
signal
|
|
123804
|
+
}
|
|
123474
123805
|
);
|
|
123806
|
+
const body = await response.json();
|
|
123807
|
+
if (!response.ok) {
|
|
123808
|
+
throw new Error(
|
|
123809
|
+
`Convex JWT mint failed with status ${response.status}: ${JSON.stringify(body).slice(0, 200)}`
|
|
123810
|
+
);
|
|
123811
|
+
}
|
|
123812
|
+
if (typeof body !== "object" || body === null || !("token" in body) || typeof body.token !== "string")
|
|
123813
|
+
throw new Error('Convex token response is missing a string "token".');
|
|
123814
|
+
const payload = convexJwtPayload(body.token);
|
|
123815
|
+
if (convexSiteUrl !== void 0) {
|
|
123816
|
+
if (payload.iss !== convexSiteUrl)
|
|
123817
|
+
throw new Error(
|
|
123818
|
+
"The workspace Convex deployment does not match the authenticated API origin."
|
|
123819
|
+
);
|
|
123820
|
+
if (!direct) {
|
|
123821
|
+
try {
|
|
123822
|
+
saveTrustedConvexSite(apiBaseUrl, convexSiteUrl);
|
|
123823
|
+
} catch {
|
|
123824
|
+
}
|
|
123825
|
+
}
|
|
123826
|
+
}
|
|
123827
|
+
return body.token;
|
|
123828
|
+
} finally {
|
|
123829
|
+
finish();
|
|
123475
123830
|
}
|
|
123476
|
-
if (typeof body !== "object" || body === null || typeof body.token !== "string") {
|
|
123477
|
-
throw new Error('Convex token response is missing a string "token".');
|
|
123478
|
-
}
|
|
123479
|
-
return body.token;
|
|
123480
123831
|
}
|
|
123481
|
-
async function resolveConvexUrl(workspace) {
|
|
123832
|
+
async function resolveConvexUrl(workspace, signal) {
|
|
123482
123833
|
const fromEnv = process.env.NEXT_PUBLIC_CONVEX_URL;
|
|
123483
123834
|
if (fromEnv !== void 0 && fromEnv.length > 0) return fromEnv;
|
|
123484
123835
|
const persisted = workspace.config.convexUrl;
|
|
@@ -123496,7 +123847,8 @@ async function resolveConvexUrl(workspace) {
|
|
|
123496
123847
|
),
|
|
123497
123848
|
{
|
|
123498
123849
|
method: "POST",
|
|
123499
|
-
headers: { Authorization: `Bearer ${sessionToken}` }
|
|
123850
|
+
headers: { Authorization: `Bearer ${sessionToken}` },
|
|
123851
|
+
signal
|
|
123500
123852
|
}
|
|
123501
123853
|
);
|
|
123502
123854
|
const convexUrl = response.headers.get("x-neo-convex-url");
|
|
@@ -123512,11 +123864,12 @@ async function resolveConvexUrl(workspace) {
|
|
|
123512
123864
|
writeWorkspaceConfig(workspace.root, workspace.config);
|
|
123513
123865
|
return convexUrl;
|
|
123514
123866
|
}
|
|
123515
|
-
async function createConvexClient(workspace) {
|
|
123516
|
-
const convexUrl = await resolveConvexUrl(workspace);
|
|
123867
|
+
async function createConvexClient(workspace, options = {}) {
|
|
123868
|
+
const convexUrl = await resolveConvexUrl(workspace, options.signal);
|
|
123517
123869
|
return await createAuthenticatedConvexClient(
|
|
123518
123870
|
convexUrl,
|
|
123519
|
-
workspace.config.apiBaseUrl
|
|
123871
|
+
workspace.config.apiBaseUrl,
|
|
123872
|
+
options.signal
|
|
123520
123873
|
);
|
|
123521
123874
|
}
|
|
123522
123875
|
async function createConvexClientForApi(apiBaseUrl) {
|
|
@@ -123537,22 +123890,35 @@ async function createConvexClientForApi(apiBaseUrl) {
|
|
|
123537
123890
|
}
|
|
123538
123891
|
return await createAuthenticatedConvexClient(convexUrl, apiBaseUrl);
|
|
123539
123892
|
}
|
|
123540
|
-
async function createAuthenticatedConvexClient(convexUrl, apiBaseUrl) {
|
|
123541
|
-
const tokenCache = new ConvexJwtCache(
|
|
123893
|
+
async function createAuthenticatedConvexClient(convexUrl, apiBaseUrl, signal) {
|
|
123894
|
+
const tokenCache = new ConvexJwtCache(
|
|
123895
|
+
apiBaseUrl,
|
|
123896
|
+
signal,
|
|
123897
|
+
convexHttpActionUrl(convexUrl)
|
|
123898
|
+
);
|
|
123542
123899
|
const initialToken = await tokenCache.getToken();
|
|
123543
123900
|
const authenticatedFetch = async (input, init) => {
|
|
123544
123901
|
const headers = new Headers(
|
|
123545
123902
|
init?.headers ?? (input instanceof Request ? input.headers : void 0)
|
|
123546
123903
|
);
|
|
123547
123904
|
headers.set("Authorization", `Bearer ${await tokenCache.getToken()}`);
|
|
123548
|
-
|
|
123905
|
+
const finish = startPerformanceSpan("convex-response-headers");
|
|
123906
|
+
try {
|
|
123907
|
+
return await fetch(input, {
|
|
123908
|
+
...init,
|
|
123909
|
+
headers,
|
|
123910
|
+
...signal === void 0 ? {} : { signal }
|
|
123911
|
+
});
|
|
123912
|
+
} finally {
|
|
123913
|
+
finish();
|
|
123914
|
+
}
|
|
123549
123915
|
};
|
|
123550
123916
|
return new ConvexHttpClient(convexUrl, {
|
|
123551
123917
|
auth: initialToken,
|
|
123552
123918
|
fetch: authenticatedFetch
|
|
123553
123919
|
});
|
|
123554
123920
|
}
|
|
123555
|
-
function
|
|
123921
|
+
function convexJwtPayload(token) {
|
|
123556
123922
|
const segments = token.split(".");
|
|
123557
123923
|
if (segments.length !== 3) {
|
|
123558
123924
|
throw new Error("Convex token response is not a three-segment JWT.");
|
|
@@ -123571,9 +123937,16 @@ function convexJwtExpiration(token) {
|
|
|
123571
123937
|
} catch {
|
|
123572
123938
|
throw new Error("Convex token response has an invalid JWT payload.");
|
|
123573
123939
|
}
|
|
123574
|
-
if (typeof payload !== "object" || payload === null) {
|
|
123940
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
123575
123941
|
throw new Error("Convex token response has a non-object JWT payload.");
|
|
123576
123942
|
}
|
|
123943
|
+
return {
|
|
123944
|
+
exp: "exp" in payload ? payload.exp : void 0,
|
|
123945
|
+
iss: "iss" in payload ? payload.iss : void 0
|
|
123946
|
+
};
|
|
123947
|
+
}
|
|
123948
|
+
function convexJwtExpiration(token) {
|
|
123949
|
+
const payload = convexJwtPayload(token);
|
|
123577
123950
|
if (!("exp" in payload)) {
|
|
123578
123951
|
throw new Error('Convex token response JWT is missing an "exp" claim.');
|
|
123579
123952
|
}
|
|
@@ -123605,10 +123978,93 @@ function missingProjectsConvexUrlError() {
|
|
|
123605
123978
|
"Could not discover the Convex deployment URL (/api/projects supplied neither a non-empty x-neo-convex-url header nor a non-empty convexUrl JSON field)."
|
|
123606
123979
|
);
|
|
123607
123980
|
}
|
|
123981
|
+
function convexHttpActionUrl(convexUrl) {
|
|
123982
|
+
const url = new URL(convexUrl);
|
|
123983
|
+
if (url.protocol !== "https:" || url.port !== "" || url.username !== "" || url.password !== "" || !url.hostname.endsWith(".convex.cloud"))
|
|
123984
|
+
throw new Error(
|
|
123985
|
+
"Direct schema commits require a Convex cloud deployment URL."
|
|
123986
|
+
);
|
|
123987
|
+
url.hostname = url.hostname.slice(0, -".convex.cloud".length) + ".convex.site";
|
|
123988
|
+
return url.origin;
|
|
123989
|
+
}
|
|
123990
|
+
async function createConvexPushConnection(workspace) {
|
|
123991
|
+
const convexUrl = await resolveConvexUrl(workspace);
|
|
123992
|
+
const siteUrl = convexHttpActionUrl(convexUrl);
|
|
123993
|
+
const tokenCache = new ConvexJwtCache(
|
|
123994
|
+
workspace.config.apiBaseUrl,
|
|
123995
|
+
void 0,
|
|
123996
|
+
siteUrl
|
|
123997
|
+
);
|
|
123998
|
+
return {
|
|
123999
|
+
async submit(body, force) {
|
|
124000
|
+
const json = JSON.stringify(body);
|
|
124001
|
+
const bytes = Buffer2.from(json);
|
|
124002
|
+
if (bytes.byteLength > SCHEMA_COMMIT_HTTP_MAX_DECODED_BYTES)
|
|
124003
|
+
throw new NeoApiError(
|
|
124004
|
+
"Schema commit requires the large-payload route.",
|
|
124005
|
+
413,
|
|
124006
|
+
{ error: "schema-commit-route-required" }
|
|
124007
|
+
);
|
|
124008
|
+
const compressed = bytes.byteLength >= 1024 ? gzipSync(bytes) : bytes;
|
|
124009
|
+
const gzip = compressed.byteLength < bytes.byteLength;
|
|
124010
|
+
const payload = gzip ? compressed : bytes;
|
|
124011
|
+
if (payload.byteLength > SCHEMA_COMMIT_HTTP_MAX_BYTES)
|
|
124012
|
+
throw new NeoApiError(
|
|
124013
|
+
"Schema commit exceeds the HTTP body limit.",
|
|
124014
|
+
413,
|
|
124015
|
+
{ error: "schema-commit-route-required" }
|
|
124016
|
+
);
|
|
124017
|
+
const client = new NeoApiClient(siteUrl, await tokenCache.getToken());
|
|
124018
|
+
const path = `${SCHEMA_COMMIT_HTTP_PATH}?${new URLSearchParams({ projectId: workspace.config.projectId, versionId: workspace.config.versionId })}`;
|
|
124019
|
+
const finish = startPerformanceSpan("commit-transport", {
|
|
124020
|
+
decodedBytes: bytes.byteLength,
|
|
124021
|
+
encodedBytes: payload.byteLength,
|
|
124022
|
+
compression: gzip ? "gzip" : "identity"
|
|
124023
|
+
});
|
|
124024
|
+
try {
|
|
124025
|
+
return await client.postBytes(path, payload, {
|
|
124026
|
+
"x-neo-decoded-content-length": String(bytes.byteLength),
|
|
124027
|
+
...process.env.NEO_COMPOSE_TRACE_PERFORMANCE === "1" ? { "x-neo-trace-performance": "1" } : {},
|
|
124028
|
+
...typeof body === "object" && body !== null && "stagedFiles" in body && Array.isArray(body.stagedFiles) && body.stagedFiles.length > 0 ? { "x-neo-commit-runtime": "node" } : {},
|
|
124029
|
+
"Content-Type": gzip ? "application/gzip" : "application/json",
|
|
124030
|
+
...force ? { "x-neo-force-project-version-write": "true" } : {}
|
|
124031
|
+
});
|
|
124032
|
+
} finally {
|
|
124033
|
+
finish();
|
|
124034
|
+
}
|
|
124035
|
+
},
|
|
124036
|
+
async subscribe(signal, onError) {
|
|
124037
|
+
await tokenCache.getToken(false, signal);
|
|
124038
|
+
signal.throwIfAborted();
|
|
124039
|
+
const client = new ConvexClient(convexUrl, {
|
|
124040
|
+
initialAuthTokenReuse: true,
|
|
124041
|
+
logger: false
|
|
124042
|
+
});
|
|
124043
|
+
client.setAuth(
|
|
124044
|
+
async ({ forceRefreshToken }) => {
|
|
124045
|
+
try {
|
|
124046
|
+
return await tokenCache.getToken(forceRefreshToken, signal);
|
|
124047
|
+
} catch (error) {
|
|
124048
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
124049
|
+
return null;
|
|
124050
|
+
}
|
|
124051
|
+
},
|
|
124052
|
+
(authenticated) => {
|
|
124053
|
+
if (!authenticated && !signal.aborted)
|
|
124054
|
+
onError(new Error("Convex rejected the session authentication."));
|
|
124055
|
+
}
|
|
124056
|
+
);
|
|
124057
|
+
return client;
|
|
124058
|
+
}
|
|
124059
|
+
};
|
|
124060
|
+
}
|
|
123608
124061
|
var generatedApiModule, generatedApiValue, api2, CONVEX_JWT_REFRESH_LEEWAY_MS, ConvexJwtCache;
|
|
123609
124062
|
var init_convex = __esm({
|
|
123610
124063
|
"src/convex.ts"() {
|
|
123611
124064
|
"use strict";
|
|
124065
|
+
init_http();
|
|
124066
|
+
init_schema_commit_transport();
|
|
124067
|
+
init_performance();
|
|
123612
124068
|
init_api();
|
|
123613
124069
|
init_token_store();
|
|
123614
124070
|
init_workspace();
|
|
@@ -123620,18 +124076,22 @@ var init_convex = __esm({
|
|
|
123620
124076
|
api2 = generatedApiValue;
|
|
123621
124077
|
CONVEX_JWT_REFRESH_LEEWAY_MS = 6e4;
|
|
123622
124078
|
ConvexJwtCache = class {
|
|
123623
|
-
constructor(apiBaseUrl) {
|
|
124079
|
+
constructor(apiBaseUrl, signal, convexSiteUrl) {
|
|
123624
124080
|
this.apiBaseUrl = apiBaseUrl;
|
|
124081
|
+
this.signal = signal;
|
|
124082
|
+
this.convexSiteUrl = convexSiteUrl;
|
|
123625
124083
|
}
|
|
123626
124084
|
apiBaseUrl;
|
|
124085
|
+
signal;
|
|
124086
|
+
convexSiteUrl;
|
|
123627
124087
|
token = null;
|
|
123628
124088
|
expiresAt = 0;
|
|
123629
124089
|
refreshPromise = null;
|
|
123630
|
-
async getToken() {
|
|
123631
|
-
if (this.token !== null && Date.now() + CONVEX_JWT_REFRESH_LEEWAY_MS < this.expiresAt) {
|
|
124090
|
+
async getToken(forceRefresh = false, signal = this.signal) {
|
|
124091
|
+
if (!forceRefresh && this.token !== null && Date.now() + CONVEX_JWT_REFRESH_LEEWAY_MS < this.expiresAt) {
|
|
123632
124092
|
return this.token;
|
|
123633
124093
|
}
|
|
123634
|
-
const pending = this.refreshPromise ?? this.refresh();
|
|
124094
|
+
const pending = this.refreshPromise ?? this.refresh(signal);
|
|
123635
124095
|
this.refreshPromise = pending;
|
|
123636
124096
|
try {
|
|
123637
124097
|
return await pending;
|
|
@@ -123639,8 +124099,12 @@ var init_convex = __esm({
|
|
|
123639
124099
|
if (this.refreshPromise === pending) this.refreshPromise = null;
|
|
123640
124100
|
}
|
|
123641
124101
|
}
|
|
123642
|
-
async refresh() {
|
|
123643
|
-
const token = await mintConvexJwt(
|
|
124102
|
+
async refresh(signal) {
|
|
124103
|
+
const token = await mintConvexJwt(
|
|
124104
|
+
this.apiBaseUrl,
|
|
124105
|
+
signal,
|
|
124106
|
+
this.convexSiteUrl
|
|
124107
|
+
);
|
|
123644
124108
|
const expiresAt = convexJwtExpiration(token);
|
|
123645
124109
|
if (expiresAt <= Date.now()) {
|
|
123646
124110
|
throw new Error("Convex token response contains an expired JWT.");
|
|
@@ -124577,119 +125041,6 @@ var init_reset = __esm({
|
|
|
124577
125041
|
}
|
|
124578
125042
|
});
|
|
124579
125043
|
|
|
124580
|
-
// src/http.ts
|
|
124581
|
-
var NeoApiError, NeoApiClient;
|
|
124582
|
-
var init_http = __esm({
|
|
124583
|
-
"src/http.ts"() {
|
|
124584
|
-
"use strict";
|
|
124585
|
-
init_token_store();
|
|
124586
|
-
NeoApiError = class extends Error {
|
|
124587
|
-
constructor(message, status, body) {
|
|
124588
|
-
super(message);
|
|
124589
|
-
this.status = status;
|
|
124590
|
-
this.body = body;
|
|
124591
|
-
this.name = "NeoApiError";
|
|
124592
|
-
}
|
|
124593
|
-
status;
|
|
124594
|
-
body;
|
|
124595
|
-
};
|
|
124596
|
-
NeoApiClient = class _NeoApiClient {
|
|
124597
|
-
constructor(apiBaseUrl, token) {
|
|
124598
|
-
this.apiBaseUrl = apiBaseUrl;
|
|
124599
|
-
this.token = token;
|
|
124600
|
-
}
|
|
124601
|
-
apiBaseUrl;
|
|
124602
|
-
token;
|
|
124603
|
-
static forBaseUrl(apiBaseUrl) {
|
|
124604
|
-
const token = loadToken(apiBaseUrl);
|
|
124605
|
-
if (token === null) {
|
|
124606
|
-
throw new Error(
|
|
124607
|
-
`No credentials stored for "${apiBaseUrl}". Run "neo login" (or set NEO_COMPOSE_TOKEN).`
|
|
124608
|
-
);
|
|
124609
|
-
}
|
|
124610
|
-
return new _NeoApiClient(apiBaseUrl, token);
|
|
124611
|
-
}
|
|
124612
|
-
async post(path, body, headers, options = {}) {
|
|
124613
|
-
const url = new URL(path, this.apiBaseUrl).toString();
|
|
124614
|
-
const response = await fetch(url, {
|
|
124615
|
-
method: "POST",
|
|
124616
|
-
headers: {
|
|
124617
|
-
Authorization: `Bearer ${this.token}`,
|
|
124618
|
-
"Content-Type": "application/json",
|
|
124619
|
-
...headers
|
|
124620
|
-
},
|
|
124621
|
-
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
124622
|
-
signal: options.signal
|
|
124623
|
-
});
|
|
124624
|
-
const text = await response.text();
|
|
124625
|
-
let parsed = null;
|
|
124626
|
-
if (text.length > 0) {
|
|
124627
|
-
try {
|
|
124628
|
-
parsed = JSON.parse(text);
|
|
124629
|
-
} catch {
|
|
124630
|
-
parsed = text;
|
|
124631
|
-
}
|
|
124632
|
-
}
|
|
124633
|
-
if (!response.ok) {
|
|
124634
|
-
const detail = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string" ? parsed.error : text.slice(0, 300);
|
|
124635
|
-
throw new NeoApiError(
|
|
124636
|
-
`POST ${path} failed with status ${response.status}: ${detail}`,
|
|
124637
|
-
response.status,
|
|
124638
|
-
parsed
|
|
124639
|
-
);
|
|
124640
|
-
}
|
|
124641
|
-
return parsed;
|
|
124642
|
-
}
|
|
124643
|
-
async get(path, options = {}) {
|
|
124644
|
-
const url = new URL(path, this.apiBaseUrl).toString();
|
|
124645
|
-
const response = await fetch(url, {
|
|
124646
|
-
method: "GET",
|
|
124647
|
-
headers: { Authorization: `Bearer ${this.token}` },
|
|
124648
|
-
signal: options.signal
|
|
124649
|
-
});
|
|
124650
|
-
const text = await response.text();
|
|
124651
|
-
let parsed = null;
|
|
124652
|
-
if (text.length > 0) {
|
|
124653
|
-
try {
|
|
124654
|
-
parsed = JSON.parse(text);
|
|
124655
|
-
} catch {
|
|
124656
|
-
parsed = text;
|
|
124657
|
-
}
|
|
124658
|
-
}
|
|
124659
|
-
if (!response.ok) {
|
|
124660
|
-
const detail = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string" ? parsed.error : text.slice(0, 300);
|
|
124661
|
-
throw new NeoApiError(
|
|
124662
|
-
`GET ${path} failed with status ${response.status}: ${detail}`,
|
|
124663
|
-
response.status,
|
|
124664
|
-
parsed
|
|
124665
|
-
);
|
|
124666
|
-
}
|
|
124667
|
-
return parsed;
|
|
124668
|
-
}
|
|
124669
|
-
async getBytes(path) {
|
|
124670
|
-
const url = new URL(path, this.apiBaseUrl).toString();
|
|
124671
|
-
const response = await fetch(url, {
|
|
124672
|
-
method: "GET",
|
|
124673
|
-
headers: { Authorization: `Bearer ${this.token}` }
|
|
124674
|
-
});
|
|
124675
|
-
if (!response.ok) {
|
|
124676
|
-
const detail = (await response.text()).slice(0, 300);
|
|
124677
|
-
throw new NeoApiError(
|
|
124678
|
-
`GET ${path} failed with status ${response.status}: ${detail}`,
|
|
124679
|
-
response.status,
|
|
124680
|
-
detail
|
|
124681
|
-
);
|
|
124682
|
-
}
|
|
124683
|
-
return {
|
|
124684
|
-
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
124685
|
-
contentSha256: response.headers.get("x-neo-content-sha256"),
|
|
124686
|
-
contentType: response.headers.get("content-type")
|
|
124687
|
-
};
|
|
124688
|
-
}
|
|
124689
|
-
};
|
|
124690
|
-
}
|
|
124691
|
-
});
|
|
124692
|
-
|
|
124693
125044
|
// src/project-source/project-file-pull.ts
|
|
124694
125045
|
import { existsSync as existsSync7, rmSync as rmSync4 } from "node:fs";
|
|
124695
125046
|
import { join as join9 } from "node:path";
|
|
@@ -129126,6 +129477,78 @@ var init_script = __esm({
|
|
|
129126
129477
|
}
|
|
129127
129478
|
});
|
|
129128
129479
|
|
|
129480
|
+
// ../convex/convexValues.ts
|
|
129481
|
+
function decodeConvexOpaqueJson(value, context) {
|
|
129482
|
+
if (typeof value !== "string") {
|
|
129483
|
+
throw new Error(`${context} must be an encoded JSON string.`);
|
|
129484
|
+
}
|
|
129485
|
+
try {
|
|
129486
|
+
return JSON.parse(value);
|
|
129487
|
+
} catch (error) {
|
|
129488
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
129489
|
+
throw new Error(`${context} could not be parsed as JSON: ${message}`);
|
|
129490
|
+
}
|
|
129491
|
+
}
|
|
129492
|
+
var CONVEX_DOCUMENT_WARNING_BYTES, CONVEX_DOCUMENT_MAX_BYTES;
|
|
129493
|
+
var init_convexValues = __esm({
|
|
129494
|
+
"../convex/convexValues.ts"() {
|
|
129495
|
+
"use strict";
|
|
129496
|
+
CONVEX_DOCUMENT_WARNING_BYTES = 750 * 1024;
|
|
129497
|
+
CONVEX_DOCUMENT_MAX_BYTES = 1024 * 1024;
|
|
129498
|
+
}
|
|
129499
|
+
});
|
|
129500
|
+
|
|
129501
|
+
// ../src/database/project-version-transaction-result.ts
|
|
129502
|
+
function decodeProjectVersionTransactionResultPage(page) {
|
|
129503
|
+
const assignments = {};
|
|
129504
|
+
const changedRecords = [];
|
|
129505
|
+
for (const chunk of page.chunks) {
|
|
129506
|
+
const chunkAssignments = decodeConvexOpaqueJson(
|
|
129507
|
+
chunk.assignmentsJson,
|
|
129508
|
+
`Project transaction "${page.transactionId}" result chunk ${chunk.chunkIndex} assignments`
|
|
129509
|
+
);
|
|
129510
|
+
if (!isRecord9(chunkAssignments)) {
|
|
129511
|
+
throw new Error(
|
|
129512
|
+
`Project transaction "${page.transactionId}" result chunk ${chunk.chunkIndex} assignments are not an object.`
|
|
129513
|
+
);
|
|
129514
|
+
}
|
|
129515
|
+
for (const [pendingId2, assignedId] of Object.entries(chunkAssignments)) {
|
|
129516
|
+
if (typeof assignedId !== "string") {
|
|
129517
|
+
throw new Error(
|
|
129518
|
+
`Project transaction "${page.transactionId}" result chunk ${chunk.chunkIndex} assignment ${JSON.stringify(pendingId2)} is not a string.`
|
|
129519
|
+
);
|
|
129520
|
+
}
|
|
129521
|
+
assignments[pendingId2] = assignedId;
|
|
129522
|
+
}
|
|
129523
|
+
const chunkRecords = decodeConvexOpaqueJson(
|
|
129524
|
+
chunk.changedRecordsJson,
|
|
129525
|
+
`Project transaction "${page.transactionId}" result chunk ${chunk.chunkIndex} changed records`
|
|
129526
|
+
);
|
|
129527
|
+
if (!Array.isArray(chunkRecords)) {
|
|
129528
|
+
throw new Error(
|
|
129529
|
+
`Project transaction "${page.transactionId}" result chunk ${chunk.chunkIndex} changed records are not an array.`
|
|
129530
|
+
);
|
|
129531
|
+
}
|
|
129532
|
+
for (const record4 of chunkRecords) changedRecords.push(record4);
|
|
129533
|
+
}
|
|
129534
|
+
return {
|
|
129535
|
+
transactionId: page.transactionId,
|
|
129536
|
+
assignments,
|
|
129537
|
+
changedRecords,
|
|
129538
|
+
continueCursor: page.continueCursor,
|
|
129539
|
+
isDone: page.isDone
|
|
129540
|
+
};
|
|
129541
|
+
}
|
|
129542
|
+
function isRecord9(value) {
|
|
129543
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
129544
|
+
}
|
|
129545
|
+
var init_project_version_transaction_result = __esm({
|
|
129546
|
+
"../src/database/project-version-transaction-result.ts"() {
|
|
129547
|
+
"use strict";
|
|
129548
|
+
init_convexValues();
|
|
129549
|
+
}
|
|
129550
|
+
});
|
|
129551
|
+
|
|
129129
129552
|
// src/project-source/identity-rewriter.ts
|
|
129130
129553
|
function createIdentityRewriter(assignments) {
|
|
129131
129554
|
if (assignments.size === 0) return (value) => value;
|
|
@@ -130241,6 +130664,7 @@ function assignPendingIds(changes, authoredValueSeeds, reconstructed3, localInit
|
|
|
130241
130664
|
}
|
|
130242
130665
|
const rewriteString = createIdentityRewriter(assigned);
|
|
130243
130666
|
const rewrite = (value) => {
|
|
130667
|
+
if (assigned.size === 0) return value;
|
|
130244
130668
|
if (typeof value === "string") {
|
|
130245
130669
|
return rewriteString(value);
|
|
130246
130670
|
}
|
|
@@ -130311,7 +130735,7 @@ function assignPendingIds(changes, authoredValueSeeds, reconstructed3, localInit
|
|
|
130311
130735
|
});
|
|
130312
130736
|
}
|
|
130313
130737
|
}
|
|
130314
|
-
if (reconstructed3 !== void 0) {
|
|
130738
|
+
if (reconstructed3 !== void 0 && assigned.size > 0) {
|
|
130315
130739
|
const rewrittenRecords = /* @__PURE__ */ new Map();
|
|
130316
130740
|
for (const record4 of reconstructed3.values()) {
|
|
130317
130741
|
const rewrittenRecordId = rewrite(record4.recordId);
|
|
@@ -130434,6 +130858,10 @@ function readProjectVersionTransactionStatus(value, transactionId) {
|
|
|
130434
130858
|
return {
|
|
130435
130859
|
transactionId,
|
|
130436
130860
|
commitStatus: value.commitStatus,
|
|
130861
|
+
transactionHash: readNullableString(
|
|
130862
|
+
value.transactionHash,
|
|
130863
|
+
`Project transaction "${transactionId}" transactionHash`
|
|
130864
|
+
),
|
|
130437
130865
|
totalChangeCount: readNullableCount(
|
|
130438
130866
|
value.totalChangeCount,
|
|
130439
130867
|
`Project transaction "${transactionId}" totalChangeCount`
|
|
@@ -130643,66 +131071,164 @@ function progressEventFromStatus(status) {
|
|
|
130643
131071
|
};
|
|
130644
131072
|
}
|
|
130645
131073
|
async function waitForAcceptedProjectVersionTransaction(args) {
|
|
130646
|
-
const {
|
|
130647
|
-
const
|
|
131074
|
+
const { workspace, accepted, reporter } = args;
|
|
131075
|
+
const { projectId, versionId } = workspace.config;
|
|
130648
131076
|
const controller = new AbortController();
|
|
130649
|
-
|
|
130650
|
-
|
|
130651
|
-
|
|
130652
|
-
controller.abort();
|
|
130653
|
-
};
|
|
131077
|
+
const interrupt = () => controller.abort(
|
|
131078
|
+
new ProjectTransactionInterruptedError(accepted.transactionId)
|
|
131079
|
+
);
|
|
130654
131080
|
process.once("SIGINT", interrupt);
|
|
130655
131081
|
reporter.report(progressEventFromAccepted(accepted));
|
|
130656
|
-
|
|
131082
|
+
const finishWait = startPerformanceSpan("transaction-wait");
|
|
131083
|
+
let client;
|
|
131084
|
+
let unsubscribe;
|
|
131085
|
+
let progressTimer;
|
|
131086
|
+
let settled = false;
|
|
130657
131087
|
try {
|
|
130658
|
-
|
|
130659
|
-
|
|
130660
|
-
|
|
130661
|
-
|
|
130662
|
-
|
|
130663
|
-
|
|
130664
|
-
|
|
130665
|
-
|
|
130666
|
-
|
|
130667
|
-
|
|
131088
|
+
const connection = args.connection ?? await withTransactionAbort(
|
|
131089
|
+
createConvexPushConnection(workspace),
|
|
131090
|
+
controller.signal
|
|
131091
|
+
);
|
|
131092
|
+
let failed = () => void 0;
|
|
131093
|
+
let updated = () => void 0;
|
|
131094
|
+
let firstResultPage;
|
|
131095
|
+
const terminal2 = new Promise(
|
|
131096
|
+
(resolve5, reject) => {
|
|
131097
|
+
failed = (error) => {
|
|
131098
|
+
if (!settled) {
|
|
131099
|
+
settled = true;
|
|
131100
|
+
reject(error);
|
|
131101
|
+
}
|
|
131102
|
+
};
|
|
131103
|
+
updated = (response) => {
|
|
131104
|
+
if (settled) return;
|
|
131105
|
+
if (response === null) return;
|
|
131106
|
+
try {
|
|
131107
|
+
const status = readProjectVersionTransactionStatus(
|
|
131108
|
+
response,
|
|
131109
|
+
accepted.transactionId
|
|
131110
|
+
);
|
|
131111
|
+
reporter.report(progressEventFromStatus(status));
|
|
131112
|
+
if (status.commitStatus === "failed") {
|
|
131113
|
+
failed(new ProjectTransactionFailedError(status));
|
|
131114
|
+
return;
|
|
131115
|
+
}
|
|
131116
|
+
if (status.commitStatus === "committed") {
|
|
131117
|
+
settled = true;
|
|
131118
|
+
resolve5(status);
|
|
131119
|
+
}
|
|
131120
|
+
} catch (error) {
|
|
131121
|
+
failed(error instanceof Error ? error : new Error(String(error)));
|
|
131122
|
+
}
|
|
131123
|
+
};
|
|
131124
|
+
}
|
|
131125
|
+
);
|
|
131126
|
+
void terminal2.catch(() => void 0);
|
|
131127
|
+
client = await connection.subscribe(controller.signal, (error) => {
|
|
131128
|
+
controller.abort(error);
|
|
131129
|
+
failed(error);
|
|
131130
|
+
});
|
|
131131
|
+
const progressClient = client;
|
|
131132
|
+
const refreshProgress = async () => {
|
|
131133
|
+
if (settled || controller.signal.aborted) return;
|
|
131134
|
+
try {
|
|
131135
|
+
const response = await withTransactionAbort(
|
|
131136
|
+
progressClient.query(
|
|
131137
|
+
api2.projectVersionTransactionJobs.getTransactionStatus,
|
|
131138
|
+
{
|
|
131139
|
+
projectId,
|
|
131140
|
+
versionId,
|
|
131141
|
+
transactionId: accepted.transactionId
|
|
131142
|
+
}
|
|
131143
|
+
),
|
|
131144
|
+
controller.signal
|
|
131145
|
+
);
|
|
131146
|
+
if (settled || controller.signal.aborted) return;
|
|
131147
|
+
const status = readProjectVersionTransactionStatus(
|
|
131148
|
+
response,
|
|
131149
|
+
accepted.transactionId
|
|
131150
|
+
);
|
|
131151
|
+
if (status.commitStatus === "committed") return;
|
|
131152
|
+
updated(status);
|
|
131153
|
+
if (!settled)
|
|
131154
|
+
progressTimer = setTimeout(() => void refreshProgress(), 5e3);
|
|
131155
|
+
} catch (error) {
|
|
131156
|
+
failed(error instanceof Error ? error : new Error(String(error)));
|
|
131157
|
+
}
|
|
131158
|
+
};
|
|
131159
|
+
const finishFirstStatus = startPerformanceSpan("transaction-first-status");
|
|
131160
|
+
let firstStatus = true;
|
|
131161
|
+
try {
|
|
131162
|
+
unsubscribe = client.onUpdate(
|
|
131163
|
+
api2.projectVersionTransactionJobs.getTransactionCompletion,
|
|
131164
|
+
{
|
|
131165
|
+
projectId,
|
|
131166
|
+
versionId,
|
|
131167
|
+
transactionId: accepted.transactionId,
|
|
131168
|
+
includeResultPage: true
|
|
131169
|
+
},
|
|
131170
|
+
(response) => {
|
|
131171
|
+
if (firstStatus) {
|
|
131172
|
+
firstStatus = false;
|
|
131173
|
+
finishFirstStatus();
|
|
131174
|
+
}
|
|
131175
|
+
if (settled) return;
|
|
131176
|
+
firstResultPage = response?.resultPage;
|
|
131177
|
+
updated(response);
|
|
131178
|
+
},
|
|
131179
|
+
failed
|
|
131180
|
+
);
|
|
131181
|
+
if (!settled)
|
|
131182
|
+
progressTimer = setTimeout(() => void refreshProgress(), 5e3);
|
|
131183
|
+
const status = await withTransactionAbort(terminal2, controller.signal);
|
|
131184
|
+
unsubscribe();
|
|
131185
|
+
unsubscribe = void 0;
|
|
131186
|
+
const finishDownload = startPerformanceSpan("result-download");
|
|
131187
|
+
try {
|
|
130668
131188
|
return await downloadProjectVersionTransactionResult({
|
|
130669
131189
|
client,
|
|
130670
|
-
|
|
131190
|
+
projectId,
|
|
131191
|
+
versionId,
|
|
130671
131192
|
transactionId: accepted.transactionId,
|
|
130672
131193
|
status,
|
|
131194
|
+
firstResultPage,
|
|
130673
131195
|
signal: controller.signal
|
|
130674
131196
|
});
|
|
131197
|
+
} finally {
|
|
131198
|
+
finishDownload();
|
|
130675
131199
|
}
|
|
130676
|
-
|
|
130677
|
-
|
|
130678
|
-
}
|
|
130679
|
-
const delay = PROJECT_TRANSACTION_POLL_DELAYS_MS[Math.min(pollIndex, PROJECT_TRANSACTION_POLL_DELAYS_MS.length - 1)];
|
|
130680
|
-
pollIndex += 1;
|
|
130681
|
-
await waitForPollDelay(delay, controller.signal);
|
|
130682
|
-
}
|
|
130683
|
-
} catch (error) {
|
|
130684
|
-
if (interrupted) {
|
|
130685
|
-
throw new ProjectTransactionInterruptedError(accepted.transactionId);
|
|
131200
|
+
} finally {
|
|
131201
|
+
if (firstStatus) finishFirstStatus();
|
|
130686
131202
|
}
|
|
130687
|
-
throw error;
|
|
130688
131203
|
} finally {
|
|
131204
|
+
settled = true;
|
|
131205
|
+
clearTimeout(progressTimer);
|
|
131206
|
+
unsubscribe?.();
|
|
131207
|
+
controller.abort();
|
|
131208
|
+
if (client !== void 0) await client.close();
|
|
131209
|
+
finishWait();
|
|
130689
131210
|
process.removeListener("SIGINT", interrupt);
|
|
130690
131211
|
}
|
|
130691
131212
|
}
|
|
130692
|
-
async function
|
|
130693
|
-
|
|
130694
|
-
|
|
130695
|
-
|
|
130696
|
-
|
|
130697
|
-
|
|
130698
|
-
clearTimeout(timer);
|
|
130699
|
-
reject(new Error("Project transaction polling was interrupted."));
|
|
131213
|
+
async function withTransactionAbort(pending, signal) {
|
|
131214
|
+
signal.throwIfAborted();
|
|
131215
|
+
return await new Promise((resolve5, reject) => {
|
|
131216
|
+
const abort = () => {
|
|
131217
|
+
cleanup();
|
|
131218
|
+
reject(signal.reason);
|
|
130700
131219
|
};
|
|
130701
|
-
const
|
|
130702
|
-
|
|
130703
|
-
|
|
130704
|
-
|
|
130705
|
-
|
|
131220
|
+
const cleanup = () => signal.removeEventListener("abort", abort);
|
|
131221
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
131222
|
+
pending.then(
|
|
131223
|
+
(value) => {
|
|
131224
|
+
cleanup();
|
|
131225
|
+
resolve5(value);
|
|
131226
|
+
},
|
|
131227
|
+
(error) => {
|
|
131228
|
+
cleanup();
|
|
131229
|
+
reject(error);
|
|
131230
|
+
}
|
|
131231
|
+
);
|
|
130706
131232
|
});
|
|
130707
131233
|
}
|
|
130708
131234
|
async function downloadProjectVersionTransactionResult(args) {
|
|
@@ -130717,11 +131243,20 @@ async function downloadProjectVersionTransactionResult(args) {
|
|
|
130717
131243
|
);
|
|
130718
131244
|
}
|
|
130719
131245
|
seenCursors.add(cursor);
|
|
130720
|
-
|
|
130721
|
-
const
|
|
130722
|
-
|
|
130723
|
-
|
|
131246
|
+
args.signal.throwIfAborted();
|
|
131247
|
+
const storedPage = cursor === "" && args.firstResultPage !== void 0 ? args.firstResultPage : await withTransactionAbort(
|
|
131248
|
+
args.client.query(
|
|
131249
|
+
api2.projectVersionTransactionJobs.getTransactionResultPage,
|
|
131250
|
+
{
|
|
131251
|
+
projectId: args.projectId,
|
|
131252
|
+
versionId: args.versionId,
|
|
131253
|
+
transactionId: args.transactionId,
|
|
131254
|
+
paginationOpts: { cursor, numItems: 16 }
|
|
131255
|
+
}
|
|
131256
|
+
),
|
|
131257
|
+
args.signal
|
|
130724
131258
|
);
|
|
131259
|
+
const rawPage = storedPage === null ? null : decodeProjectVersionTransactionResultPage(storedPage);
|
|
130725
131260
|
const page = readProjectVersionTransactionResultPage(
|
|
130726
131261
|
rawPage,
|
|
130727
131262
|
args.transactionId
|
|
@@ -130747,8 +131282,13 @@ async function downloadProjectVersionTransactionResult(args) {
|
|
|
130747
131282
|
`Project transaction "${args.transactionId}" committed ${args.status.totalChangeCount} changes but its result download returned ${changedRecords.length}.`
|
|
130748
131283
|
);
|
|
130749
131284
|
}
|
|
131285
|
+
if (args.status.transactionHash === null)
|
|
131286
|
+
throw new Error(
|
|
131287
|
+
`Committed project transaction "${args.transactionId}" has no transaction hash.`
|
|
131288
|
+
);
|
|
130750
131289
|
return {
|
|
130751
131290
|
kind: "committed",
|
|
131291
|
+
headTransactionHash: args.status.transactionHash,
|
|
130752
131292
|
transactionId: args.transactionId,
|
|
130753
131293
|
totalChangeCount: args.status.totalChangeCount,
|
|
130754
131294
|
totalChunkCount: args.status.totalChunkCount ?? 0,
|
|
@@ -130863,6 +131403,7 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
130863
131403
|
const verifiesConfiguredHook = options.noVerify !== true && configuredHook !== void 0;
|
|
130864
131404
|
const preparedInputFingerprint = verifiesConfiguredHook ? fingerprintPushInputs(workspace) : void 0;
|
|
130865
131405
|
const preparation = preparationOverride === void 0 ? process.stdout.isTTY === true && options.json !== true ? spinner("Preparing push\u2026") : null : preparationOverride;
|
|
131406
|
+
const finishCandidate = startPerformanceSpan("local-candidate");
|
|
130866
131407
|
let candidate;
|
|
130867
131408
|
try {
|
|
130868
131409
|
candidate = await prepareLocalCandidateV4(workspace, {
|
|
@@ -130885,6 +131426,8 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
130885
131426
|
}
|
|
130886
131427
|
preparation?.fail("Push preparation failed.");
|
|
130887
131428
|
throw error;
|
|
131429
|
+
} finally {
|
|
131430
|
+
finishCandidate();
|
|
130888
131431
|
}
|
|
130889
131432
|
const status = candidate.status;
|
|
130890
131433
|
const local = candidate.preparedLocal;
|
|
@@ -131065,7 +131608,12 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131065
131608
|
};
|
|
131066
131609
|
let preparedPush;
|
|
131067
131610
|
try {
|
|
131068
|
-
|
|
131611
|
+
const finishUploads = startPerformanceSpan("file-uploads");
|
|
131612
|
+
try {
|
|
131613
|
+
preparedPush = await stagePreparedPush();
|
|
131614
|
+
} finally {
|
|
131615
|
+
finishUploads();
|
|
131616
|
+
}
|
|
131069
131617
|
} catch (error) {
|
|
131070
131618
|
progress.stop();
|
|
131071
131619
|
if (error instanceof ProjectFilePushCancelledError) {
|
|
@@ -131085,9 +131633,9 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131085
131633
|
stagedUploadSessionId
|
|
131086
131634
|
} = preparedPush;
|
|
131087
131635
|
const { stagedFiles } = preparedPush;
|
|
131088
|
-
|
|
131089
|
-
|
|
131090
|
-
{
|
|
131636
|
+
let pushConnection;
|
|
131637
|
+
const commit = async (force) => {
|
|
131638
|
+
const body = {
|
|
131091
131639
|
operation: transactionOperation,
|
|
131092
131640
|
changes: transportChanges,
|
|
131093
131641
|
authoredValueSeeds: transportSeeds,
|
|
@@ -131102,9 +131650,20 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131102
131650
|
headTransactionHash: workspace.state.headTransactionHash ?? null,
|
|
131103
131651
|
derivedEdgeExtractorVersion: PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION,
|
|
131104
131652
|
forceRecompile: options.forceRecompile === true
|
|
131105
|
-
}
|
|
131106
|
-
|
|
131107
|
-
|
|
131653
|
+
};
|
|
131654
|
+
pushConnection ??= await createConvexPushConnection(workspace);
|
|
131655
|
+
try {
|
|
131656
|
+
return await pushConnection.submit(body, force);
|
|
131657
|
+
} catch (error) {
|
|
131658
|
+
if (!(error instanceof NeoApiError) || error.status !== 413 || !isObjectRecord2(error.body) || error.body.error !== "schema-commit-route-required")
|
|
131659
|
+
throw error;
|
|
131660
|
+
}
|
|
131661
|
+
return await client.post(
|
|
131662
|
+
`/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/schema/commit`,
|
|
131663
|
+
body,
|
|
131664
|
+
force ? { "x-neo-force-project-version-write": "true" } : void 0
|
|
131665
|
+
);
|
|
131666
|
+
};
|
|
131108
131667
|
const finishCommitResponse = async (response, reporter) => {
|
|
131109
131668
|
let accepted;
|
|
131110
131669
|
try {
|
|
@@ -131119,7 +131678,12 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131119
131678
|
if (!applyCommittedHeadTransactionHash(workspace, response)) {
|
|
131120
131679
|
await recoverHeadTransactionHashFromSchemaSignal(workspace);
|
|
131121
131680
|
}
|
|
131122
|
-
applyPushResult(
|
|
131681
|
+
applyPushResult(
|
|
131682
|
+
workspace,
|
|
131683
|
+
response,
|
|
131684
|
+
pendingAssignment.assigned,
|
|
131685
|
+
preparedLocal.submittedStatus
|
|
131686
|
+
);
|
|
131123
131687
|
} catch (error) {
|
|
131124
131688
|
reporter.stop();
|
|
131125
131689
|
throw error;
|
|
@@ -131147,11 +131711,10 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131147
131711
|
let completed;
|
|
131148
131712
|
try {
|
|
131149
131713
|
completed = await waitForAcceptedProjectVersionTransaction({
|
|
131150
|
-
|
|
131151
|
-
projectId: workspace.config.projectId,
|
|
131152
|
-
versionId: workspace.config.versionId,
|
|
131714
|
+
workspace,
|
|
131153
131715
|
accepted,
|
|
131154
|
-
reporter
|
|
131716
|
+
reporter,
|
|
131717
|
+
connection: pushConnection
|
|
131155
131718
|
});
|
|
131156
131719
|
} catch (error) {
|
|
131157
131720
|
if (error instanceof ProjectTransactionInterruptedError) {
|
|
@@ -131197,15 +131760,19 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131197
131760
|
throw error;
|
|
131198
131761
|
}
|
|
131199
131762
|
try {
|
|
131200
|
-
|
|
131201
|
-
|
|
131763
|
+
applyCommittedHeadTransactionHash(workspace, completed);
|
|
131764
|
+
const finishApply = startPerformanceSpan("apply-result");
|
|
131765
|
+
try {
|
|
131766
|
+
applyCommittedProjectTransactionResult({
|
|
131767
|
+
workspace,
|
|
131768
|
+
result: completed,
|
|
131769
|
+
submittedChanges: status.changes,
|
|
131770
|
+
candidateAssignments: pendingAssignment.assigned,
|
|
131771
|
+
submittedStatus: preparedLocal.submittedStatus
|
|
131772
|
+
});
|
|
131773
|
+
} finally {
|
|
131774
|
+
finishApply();
|
|
131202
131775
|
}
|
|
131203
|
-
applyCommittedProjectTransactionResult({
|
|
131204
|
-
workspace,
|
|
131205
|
-
result: completed,
|
|
131206
|
-
submittedChanges: status.changes,
|
|
131207
|
-
candidateAssignments: pendingAssignment.assigned
|
|
131208
|
-
});
|
|
131209
131776
|
} catch (error) {
|
|
131210
131777
|
reporter.stop();
|
|
131211
131778
|
throw error;
|
|
@@ -131245,7 +131812,12 @@ async function runPush(workspace, options, preparationOverride) {
|
|
|
131245
131812
|
}
|
|
131246
131813
|
let result;
|
|
131247
131814
|
try {
|
|
131248
|
-
|
|
131815
|
+
const finishSubmit = startPerformanceSpan("submit");
|
|
131816
|
+
try {
|
|
131817
|
+
result = await commit(options.acceptBump);
|
|
131818
|
+
} finally {
|
|
131819
|
+
finishSubmit();
|
|
131820
|
+
}
|
|
131249
131821
|
} catch (error) {
|
|
131250
131822
|
progress.stop();
|
|
131251
131823
|
if (!(error instanceof NeoApiError)) throw error;
|
|
@@ -131325,12 +131897,19 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
131325
131897
|
fullValidation: true,
|
|
131326
131898
|
forceRecompile: false
|
|
131327
131899
|
}) {
|
|
131328
|
-
|
|
131329
|
-
|
|
131900
|
+
const submittedStatus = {
|
|
131901
|
+
status: cloneWorkspaceStatus(status),
|
|
131902
|
+
records: workspace.state.records,
|
|
131903
|
+
config: structuredClone(workspace.config),
|
|
131904
|
+
root: workspace.root
|
|
131905
|
+
};
|
|
131906
|
+
onPhase("Hashing project source\u2026");
|
|
131907
|
+
const source = projectSourceIdentityForStatus(status);
|
|
131908
|
+
const verificationSource = options.fullValidation ? createPendingProjectSourceIdentityV4(
|
|
131330
131909
|
workspace,
|
|
131331
131910
|
status,
|
|
131332
131911
|
status.authoredValueSeeds
|
|
131333
|
-
);
|
|
131912
|
+
) : null;
|
|
131334
131913
|
const pendingTransportChanges = transportChangesForStatus(status);
|
|
131335
131914
|
const pendingTransportSeeds = [...status.authoredValueSeeds].map(
|
|
131336
131915
|
([memberId, seed]) => ({ memberId, ...seed })
|
|
@@ -131364,20 +131943,20 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
131364
131943
|
localizedTextCreateEnvelopeConfig2(workspace, status.changes)
|
|
131365
131944
|
);
|
|
131366
131945
|
let preparedChanges = null;
|
|
131367
|
-
if (
|
|
131946
|
+
if (verificationSource !== null) {
|
|
131368
131947
|
onPhase("Verifying the assigned-id source rewrite\u2026");
|
|
131369
131948
|
materializeAssignedSchemaIdsInAuthoredSource(
|
|
131370
131949
|
workspace,
|
|
131371
131950
|
pendingAssignment.assigned,
|
|
131372
131951
|
status.pendingValueIdentitySites,
|
|
131373
|
-
true
|
|
131952
|
+
{ sourceSnapshot: status.sourceSnapshot, validateResult: true }
|
|
131374
131953
|
);
|
|
131375
131954
|
onPhase("Verifying the complete source round trip\u2026");
|
|
131376
131955
|
verifyProjectSourceCommitAgainstStateV4({
|
|
131377
131956
|
projectId: workspace.config.projectId,
|
|
131378
131957
|
versionId: workspace.config.versionId,
|
|
131379
131958
|
stateRecords: workspace.state.records,
|
|
131380
|
-
files:
|
|
131959
|
+
files: verificationSource.files,
|
|
131381
131960
|
changes: transportChanges,
|
|
131382
131961
|
authoredValueSeeds: transportSeeds,
|
|
131383
131962
|
initializerMaterialization: pendingAssignment.localInitializerMaterialization ?? { roots: [] },
|
|
@@ -131402,6 +131981,7 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
131402
131981
|
}
|
|
131403
131982
|
return {
|
|
131404
131983
|
source,
|
|
131984
|
+
submittedStatus,
|
|
131405
131985
|
pendingAssignment,
|
|
131406
131986
|
transactionOperation,
|
|
131407
131987
|
transportChanges,
|
|
@@ -131431,7 +132011,7 @@ async function prepareLocalCandidateV4(workspace, options = {}) {
|
|
|
131431
132011
|
let documentStatus = status;
|
|
131432
132012
|
if (status.changes.length > 0 || status.authoredValueSeeds.size > 0) {
|
|
131433
132013
|
try {
|
|
131434
|
-
documentStatus = pushOptions.dryRun ?
|
|
132014
|
+
documentStatus = pushOptions.dryRun ? cloneWorkspaceStatus(status) : status;
|
|
131435
132015
|
if (options.refreshDerivedEdgeVersion === true) {
|
|
131436
132016
|
const convex = await createConvexClient(workspace);
|
|
131437
132017
|
const signal = await convex.query(api2.projectExportData.schemaSignal, {
|
|
@@ -131457,20 +132037,7 @@ async function prepareLocalCandidateV4(workspace, options = {}) {
|
|
|
131457
132037
|
}
|
|
131458
132038
|
sourceHash = preparedLocal.source.sourceHash;
|
|
131459
132039
|
} else {
|
|
131460
|
-
|
|
131461
|
-
(absolutePath) => {
|
|
131462
|
-
const path = relative7(workspace.root, absolutePath).split(sep7).join("/");
|
|
131463
|
-
const content = readFileSync16(absolutePath, "utf8");
|
|
131464
|
-
const kind = neoProjectSourceKind(path, content);
|
|
131465
|
-
if (kind === null || !isNeoProjectProductionSourceKind(kind)) {
|
|
131466
|
-
throw new Error(
|
|
131467
|
-
`Listed workspace source ${JSON.stringify(path)} is not production Neo source.`
|
|
131468
|
-
);
|
|
131469
|
-
}
|
|
131470
|
-
return { path, kind, content };
|
|
131471
|
-
}
|
|
131472
|
-
);
|
|
131473
|
-
sourceHash = hashProjectSourceFiles(files);
|
|
132040
|
+
sourceHash = projectSourceIdentityForStatus(status).sourceHash;
|
|
131474
132041
|
}
|
|
131475
132042
|
if (options.includeDocument === false) {
|
|
131476
132043
|
return { status, document: null, sourceHash, preparedLocal };
|
|
@@ -131611,7 +132178,7 @@ function describeChangeOrigin(change) {
|
|
|
131611
132178
|
if (parts.length === 0) return "";
|
|
131612
132179
|
return ` (${parts.join(" in ")})`;
|
|
131613
132180
|
}
|
|
131614
|
-
function
|
|
132181
|
+
function cloneWorkspaceStatus(status) {
|
|
131615
132182
|
return {
|
|
131616
132183
|
...status,
|
|
131617
132184
|
changes: structuredClone(status.changes),
|
|
@@ -131663,6 +132230,19 @@ function reportDryRunFailure(error, json) {
|
|
|
131663
132230
|
}
|
|
131664
132231
|
console.error(`Dry run failed: ${message}`);
|
|
131665
132232
|
}
|
|
132233
|
+
function projectSourceIdentityForStatus(status) {
|
|
132234
|
+
if (status.sourceSnapshot === void 0) {
|
|
132235
|
+
throw new Error(
|
|
132236
|
+
"Push source identity requires the analyzed source snapshot."
|
|
132237
|
+
);
|
|
132238
|
+
}
|
|
132239
|
+
const files = status.sourceSnapshot.inputs.map((input) => ({
|
|
132240
|
+
path: input.uri,
|
|
132241
|
+
kind: input.kind,
|
|
132242
|
+
content: input.text
|
|
132243
|
+
}));
|
|
132244
|
+
return { files, sourceHash: hashProjectSourceFiles(files) };
|
|
132245
|
+
}
|
|
131666
132246
|
function createPendingProjectSourceIdentityV4(workspace, status, authoredValueSeeds) {
|
|
131667
132247
|
const records2 = /* @__PURE__ */ new Map();
|
|
131668
132248
|
for (const [key, state] of Object.entries(workspace.state.records)) {
|
|
@@ -131944,7 +132524,7 @@ function reportAdditionalServerChanges(totalChangeCount, authoredChangeCount, js
|
|
|
131944
132524
|
}
|
|
131945
132525
|
function applyCommittedProjectTransactionResult(args) {
|
|
131946
132526
|
const { workspace, result, submittedChanges, candidateAssignments } = args;
|
|
131947
|
-
const localStatus =
|
|
132527
|
+
const localStatus = statusForPushResult(workspace, args.submittedStatus);
|
|
131948
132528
|
const blockingErrors = localStatus.parseErrors.filter(
|
|
131949
132529
|
isBlockingSchemaSourceError
|
|
131950
132530
|
);
|
|
@@ -131966,7 +132546,8 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
131966
132546
|
const preservedSourceFiles = materializeAssignedSchemaIdsInAuthoredSource(
|
|
131967
132547
|
workspace,
|
|
131968
132548
|
replacements.exact,
|
|
131969
|
-
localStatus.pendingValueIdentitySites
|
|
132549
|
+
localStatus.pendingValueIdentitySites,
|
|
132550
|
+
{ sourceSnapshot: localStatus.sourceSnapshot }
|
|
131970
132551
|
);
|
|
131971
132552
|
const localRecords = rewriteReconstructedRecords(
|
|
131972
132553
|
localStatus.reconstructed,
|
|
@@ -132046,6 +132627,38 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
132046
132627
|
throw error;
|
|
132047
132628
|
}
|
|
132048
132629
|
}
|
|
132630
|
+
function statusForPushResult(workspace, submitted) {
|
|
132631
|
+
if (submitted === void 0) return computeWorkspaceStatus2(workspace);
|
|
132632
|
+
if (submitted.records !== workspace.state.records)
|
|
132633
|
+
return computeWorkspaceStatus2(workspace);
|
|
132634
|
+
if (submitted.root !== workspace.root)
|
|
132635
|
+
return computeWorkspaceStatus2(workspace);
|
|
132636
|
+
if (!canonicallyEqual(submitted.config, workspace.config))
|
|
132637
|
+
return computeWorkspaceStatus2(workspace);
|
|
132638
|
+
const submittedStatus = submitted.status;
|
|
132639
|
+
const snapshot = submittedStatus?.sourceSnapshot;
|
|
132640
|
+
if (snapshot === void 0 || submittedStatus?.binaryFiles === void 0)
|
|
132641
|
+
return computeWorkspaceStatus2(workspace);
|
|
132642
|
+
const paths = listProjectSourceFilesV4(workspace.root);
|
|
132643
|
+
if (paths.length !== snapshot.inputs.length)
|
|
132644
|
+
return computeWorkspaceStatus2(workspace);
|
|
132645
|
+
for (let index = 0; index < paths.length; index += 1) {
|
|
132646
|
+
const path = paths[index];
|
|
132647
|
+
const input = snapshot.inputs[index];
|
|
132648
|
+
if (input?.uri !== relative7(workspace.root, path).split(sep7).join("/"))
|
|
132649
|
+
return computeWorkspaceStatus2(workspace);
|
|
132650
|
+
if (input.text !== readFileSync16(path, "utf8"))
|
|
132651
|
+
return computeWorkspaceStatus2(workspace);
|
|
132652
|
+
}
|
|
132653
|
+
const binaries = inspectProjectBinaryStatusV4(
|
|
132654
|
+
workspace.root,
|
|
132655
|
+
workspace.state.records,
|
|
132656
|
+
snapshot.analysis
|
|
132657
|
+
);
|
|
132658
|
+
if (!canonicallyEqual(binaries, submittedStatus.binaryFiles))
|
|
132659
|
+
return computeWorkspaceStatus2(workspace);
|
|
132660
|
+
return submittedStatus;
|
|
132661
|
+
}
|
|
132049
132662
|
function projectTransactionResultReplacements(candidateAssignments, resultAssignments) {
|
|
132050
132663
|
const replacements = /* @__PURE__ */ new Map();
|
|
132051
132664
|
for (const [pendingId2, assignedId] of Object.entries(resultAssignments)) {
|
|
@@ -132059,6 +132672,7 @@ function projectTransactionResultReplacements(candidateAssignments, resultAssign
|
|
|
132059
132672
|
};
|
|
132060
132673
|
}
|
|
132061
132674
|
function rewriteReconstructedRecords(records2, replacements) {
|
|
132675
|
+
if (replacements.exact.size === 0) return records2;
|
|
132062
132676
|
const rewritten = /* @__PURE__ */ new Map();
|
|
132063
132677
|
for (const record4 of records2.values()) {
|
|
132064
132678
|
const recordId = rewriteAssignedString(record4.recordId, replacements);
|
|
@@ -132213,15 +132827,16 @@ function foldChangedRecords(previous, changedRecords) {
|
|
|
132213
132827
|
}
|
|
132214
132828
|
return records2;
|
|
132215
132829
|
}
|
|
132216
|
-
function applyPushResult(workspace, result, pendingIdAssignments = /* @__PURE__ */ new Map()) {
|
|
132830
|
+
function applyPushResult(workspace, result, pendingIdAssignments = /* @__PURE__ */ new Map(), submittedStatus) {
|
|
132217
132831
|
if (!isObjectRecord2(result) || !Array.isArray(result.changedRecords)) {
|
|
132218
132832
|
throw new Error("Transaction response is missing changedRecords.");
|
|
132219
132833
|
}
|
|
132220
|
-
const localStatus =
|
|
132834
|
+
const localStatus = statusForPushResult(workspace, submittedStatus);
|
|
132221
132835
|
const preservedSourceFiles = materializeAssignedSchemaIdsInAuthoredSource(
|
|
132222
132836
|
workspace,
|
|
132223
132837
|
pendingIdAssignments,
|
|
132224
|
-
localStatus.pendingValueIdentitySites
|
|
132838
|
+
localStatus.pendingValueIdentitySites,
|
|
132839
|
+
{ sourceSnapshot: localStatus.sourceSnapshot }
|
|
132225
132840
|
);
|
|
132226
132841
|
const replacements = {
|
|
132227
132842
|
exact: pendingIdAssignments,
|
|
@@ -132341,19 +132956,20 @@ function rewriteFilesFromState(workspace, records2 = new Map(
|
|
|
132341
132956
|
)
|
|
132342
132957
|
};
|
|
132343
132958
|
});
|
|
132344
|
-
const
|
|
132345
|
-
|
|
132346
|
-
|
|
132347
|
-
|
|
132348
|
-
|
|
132349
|
-
|
|
132350
|
-
|
|
132351
|
-
|
|
132352
|
-
|
|
132353
|
-
|
|
132354
|
-
|
|
132959
|
+
const finalInputs = files.map((file) => {
|
|
132960
|
+
const kind = neoProjectSourceKind(file.path, file.content);
|
|
132961
|
+
if (kind === null || !isNeoProjectProductionSourceKind(kind)) {
|
|
132962
|
+
throw new Error(
|
|
132963
|
+
`Emitted project source ${JSON.stringify(file.path)} has an unsupported path.`
|
|
132964
|
+
);
|
|
132965
|
+
}
|
|
132966
|
+
return { uri: file.path, kind, text: file.content };
|
|
132967
|
+
});
|
|
132968
|
+
const finalAnalysis = files.every(
|
|
132969
|
+
(file, index) => file.content === result.files[index]?.content
|
|
132970
|
+
) ? result.analysis : compileNeoProjectSources(finalInputs);
|
|
132355
132971
|
assertAssignedIdSourceRewriteValid(finalAnalysis);
|
|
132356
|
-
writeProjectSourceAnalysisCacheV4(workspace.root, finalAnalysis);
|
|
132972
|
+
writeProjectSourceAnalysisCacheV4(workspace.root, finalAnalysis, finalInputs);
|
|
132357
132973
|
const resolveSourcePath = createWorkspaceSourcePathResolver(workspace.root);
|
|
132358
132974
|
const emittedPaths = new Set(files.map((file) => file.path));
|
|
132359
132975
|
for (const recordState of Object.values(workspace.state.records)) {
|
|
@@ -132401,7 +133017,7 @@ ${finalErrors.map(
|
|
|
132401
133017
|
);
|
|
132402
133018
|
}
|
|
132403
133019
|
}
|
|
132404
|
-
function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, pendingValueIdentitySites = /* @__PURE__ */ new Map(),
|
|
133020
|
+
function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, pendingValueIdentitySites = /* @__PURE__ */ new Map(), options = {}) {
|
|
132405
133021
|
const pendingIdsByUri = /* @__PURE__ */ new Map();
|
|
132406
133022
|
for (const pendingId2 of replacements.keys()) {
|
|
132407
133023
|
if (!isPendingId(pendingId2)) continue;
|
|
@@ -132412,25 +133028,23 @@ function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, p
|
|
|
132412
133028
|
pendingIdsByUri.set(uri, pendingIds);
|
|
132413
133029
|
}
|
|
132414
133030
|
if (pendingIdsByUri.size === 0) return /* @__PURE__ */ new Map();
|
|
132415
|
-
const inputs = listProjectSourceFilesV4(workspace.root).map(
|
|
132416
|
-
(absolutePath)
|
|
132417
|
-
|
|
132418
|
-
|
|
132419
|
-
|
|
132420
|
-
|
|
132421
|
-
|
|
132422
|
-
|
|
132423
|
-
);
|
|
132424
|
-
}
|
|
132425
|
-
return {
|
|
132426
|
-
uri,
|
|
132427
|
-
kind,
|
|
132428
|
-
text
|
|
132429
|
-
};
|
|
133031
|
+
const inputs = options.sourceSnapshot?.inputs ?? listProjectSourceFilesV4(workspace.root).map((absolutePath) => {
|
|
133032
|
+
const uri = relative7(workspace.root, absolutePath).split(sep7).join("/");
|
|
133033
|
+
const text = readFileSync16(absolutePath, "utf8");
|
|
133034
|
+
const kind = neoProjectSourceKind(uri, text);
|
|
133035
|
+
if (kind === null || !isNeoProjectProductionSourceKind(kind)) {
|
|
133036
|
+
throw new Error(
|
|
133037
|
+
`Listed workspace source ${JSON.stringify(uri)} has an unsupported path.`
|
|
133038
|
+
);
|
|
132430
133039
|
}
|
|
132431
|
-
|
|
133040
|
+
return {
|
|
133041
|
+
uri,
|
|
133042
|
+
kind,
|
|
133043
|
+
text
|
|
133044
|
+
};
|
|
133045
|
+
});
|
|
132432
133046
|
const inputByUri = new Map(inputs.map((input) => [input.uri, input.text]));
|
|
132433
|
-
const analysis = compileNeoProjectSources(inputs);
|
|
133047
|
+
const analysis = options.sourceSnapshot?.analysis ?? compileNeoProjectSources(inputs);
|
|
132434
133048
|
if (analysis.diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
132435
133049
|
return /* @__PURE__ */ new Map();
|
|
132436
133050
|
}
|
|
@@ -132578,7 +133192,7 @@ function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, p
|
|
|
132578
133192
|
}
|
|
132579
133193
|
preserved.set(uri, source);
|
|
132580
133194
|
}
|
|
132581
|
-
if (validateResult && preserved.size > 0) {
|
|
133195
|
+
if (options.validateResult === true && preserved.size > 0) {
|
|
132582
133196
|
assertAssignedIdSourceRewriteValid(
|
|
132583
133197
|
compileNeoProjectSources(
|
|
132584
133198
|
inputs.map((input) => ({
|
|
@@ -133144,10 +133758,12 @@ function compileMigrationAction(context, migrationData, locator) {
|
|
|
133144
133758
|
locator
|
|
133145
133759
|
);
|
|
133146
133760
|
}
|
|
133147
|
-
var compileNSVoidBody2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createNeoScriptCompilationProject2, ProjectTransactionInterruptedError, ProjectTransactionFailedError,
|
|
133761
|
+
var compileNSVoidBody2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createNeoScriptCompilationProject2, ProjectTransactionInterruptedError, ProjectTransactionFailedError, LocalCandidateArtifactError, SERVER_MINTED_PUSH_RECORD_KINDS;
|
|
133148
133762
|
var init_push = __esm({
|
|
133149
133763
|
"src/commands/push.ts"() {
|
|
133150
133764
|
"use strict";
|
|
133765
|
+
init_project_version_transaction_result();
|
|
133766
|
+
init_performance();
|
|
133151
133767
|
init_identity_rewriter();
|
|
133152
133768
|
init_source_layout();
|
|
133153
133769
|
init_src();
|
|
@@ -133163,6 +133779,7 @@ var init_push = __esm({
|
|
|
133163
133779
|
init_push_hook();
|
|
133164
133780
|
init_project_documents();
|
|
133165
133781
|
init_project_document_cache();
|
|
133782
|
+
init_project_files();
|
|
133166
133783
|
init_workspace_status();
|
|
133167
133784
|
init_lower_support();
|
|
133168
133785
|
init_init_conversion();
|
|
@@ -133214,14 +133831,6 @@ var init_push = __esm({
|
|
|
133214
133831
|
}
|
|
133215
133832
|
status;
|
|
133216
133833
|
};
|
|
133217
|
-
PROJECT_TRANSACTION_POLL_DELAYS_MS = [
|
|
133218
|
-
250,
|
|
133219
|
-
500,
|
|
133220
|
-
1e3,
|
|
133221
|
-
2e3,
|
|
133222
|
-
4e3,
|
|
133223
|
-
5e3
|
|
133224
|
-
];
|
|
133225
133834
|
LocalCandidateArtifactError = class extends Error {
|
|
133226
133835
|
constructor(cause) {
|
|
133227
133836
|
super(cause instanceof Error ? cause.message : String(cause));
|
|
@@ -133242,7 +133851,7 @@ var init_registry2 = __esm({
|
|
|
133242
133851
|
"schema-contract/registry.mjs"() {
|
|
133243
133852
|
"use strict";
|
|
133244
133853
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
133245
|
-
cliVersion: "0.50.
|
|
133854
|
+
cliVersion: "0.50.8",
|
|
133246
133855
|
projectFileUploadBatchSize: 32,
|
|
133247
133856
|
documentRecords: {
|
|
133248
133857
|
member: {
|
|
@@ -134687,7 +135296,7 @@ import {
|
|
|
134687
135296
|
sep as sep8
|
|
134688
135297
|
} from "node:path";
|
|
134689
135298
|
import { isDeepStrictEqual } from "node:util";
|
|
134690
|
-
function
|
|
135299
|
+
function isRecord10(value) {
|
|
134691
135300
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
134692
135301
|
}
|
|
134693
135302
|
function expectation(actual, negated = false) {
|
|
@@ -134698,13 +135307,13 @@ function expectation(actual, negated = false) {
|
|
|
134698
135307
|
return value;
|
|
134699
135308
|
}
|
|
134700
135309
|
function readExpectation(value) {
|
|
134701
|
-
if (!
|
|
135310
|
+
if (!isRecord10(value) || value.__neoExpectation !== true) {
|
|
134702
135311
|
throw new NeoTestAssertionError("Matcher receiver is not an expectation.");
|
|
134703
135312
|
}
|
|
134704
135313
|
return value;
|
|
134705
135314
|
}
|
|
134706
135315
|
function readMockHandle(value) {
|
|
134707
|
-
if (!
|
|
135316
|
+
if (!isRecord10(value) || value.__neoMockHandle !== true || typeof value.mockId !== "number") {
|
|
134708
135317
|
throw new NeoTestAssertionError(
|
|
134709
135318
|
"Mock configuration receiver is not a mock handle."
|
|
134710
135319
|
);
|
|
@@ -134815,13 +135424,13 @@ function errorMessage2(error) {
|
|
|
134815
135424
|
return error instanceof Error ? error.message : String(error);
|
|
134816
135425
|
}
|
|
134817
135426
|
function findDelegateTargetMemberId(value) {
|
|
134818
|
-
return
|
|
135427
|
+
return isRecord10(value) && typeof value.memberId === "string" ? value.memberId : null;
|
|
134819
135428
|
}
|
|
134820
135429
|
function sharedEvaluatorBase(rawDocument) {
|
|
134821
135430
|
const cached = SHARED_EVALUATOR_BASES.get(rawDocument);
|
|
134822
135431
|
if (cached !== void 0) return cached;
|
|
134823
135432
|
const document = readDocumentArrays(rawDocument);
|
|
134824
|
-
const constructors = Array.isArray(rawDocument.constructors) ? rawDocument.constructors.filter(
|
|
135433
|
+
const constructors = Array.isArray(rawDocument.constructors) ? rawDocument.constructors.filter(isRecord10) : [];
|
|
134825
135434
|
const runtime = cliEvaluatorRuntime(
|
|
134826
135435
|
{ ...document, constructors },
|
|
134827
135436
|
{ includeValueGraphIndexes: true }
|
|
@@ -134890,7 +135499,7 @@ function preparedHookCandidate(workspace) {
|
|
|
134890
135499
|
const parsed = JSON.parse(
|
|
134891
135500
|
readFileSync17(join15(directory, "candidate.json"), "utf8")
|
|
134892
135501
|
);
|
|
134893
|
-
if (!
|
|
135502
|
+
if (!isRecord10(parsed)) {
|
|
134894
135503
|
throw new NeoTestPreparedCandidateError(
|
|
134895
135504
|
"Configured push hook candidate manifest must be a JSON object."
|
|
134896
135505
|
);
|
|
@@ -134910,7 +135519,7 @@ function preparedHookCandidate(workspace) {
|
|
|
134910
135519
|
"Configured push hook candidate inputs no longer match the workspace."
|
|
134911
135520
|
);
|
|
134912
135521
|
}
|
|
134913
|
-
if (!
|
|
135522
|
+
if (!isRecord10(parsed.document)) {
|
|
134914
135523
|
throw new NeoTestPreparedCandidateError(
|
|
134915
135524
|
"Configured push hook candidate is missing its project document."
|
|
134916
135525
|
);
|
|
@@ -134959,7 +135568,7 @@ function cachedTestCandidate(workspace, inputFingerprint) {
|
|
|
134959
135568
|
try {
|
|
134960
135569
|
const candidatePath = testCandidateCachePath(workspace, inputFingerprint);
|
|
134961
135570
|
const parsed = JSON.parse(readFileSync17(candidatePath, "utf8"));
|
|
134962
|
-
if (!
|
|
135571
|
+
if (!isRecord10(parsed)) return null;
|
|
134963
135572
|
if (parsed.version !== 1) return null;
|
|
134964
135573
|
if (parsed.candidateRevision !== TEST_CANDIDATE_CACHE_REVISION) return null;
|
|
134965
135574
|
if (parsed.cliVersion !== PROJECT_SCHEMA_CONTRACT.cliVersion) return null;
|
|
@@ -134977,7 +135586,7 @@ function cachedTestCandidate(workspace, inputFingerprint) {
|
|
|
134977
135586
|
return null;
|
|
134978
135587
|
}
|
|
134979
135588
|
const document = JSON.parse(documentJson);
|
|
134980
|
-
if (!
|
|
135589
|
+
if (!isRecord10(document)) return null;
|
|
134981
135590
|
return {
|
|
134982
135591
|
document,
|
|
134983
135592
|
sourceHash: parsed.sourceHash,
|
|
@@ -135021,7 +135630,7 @@ function compileSpec(workspace, document, absolutePath, projectCompilationHash2)
|
|
|
135021
135630
|
);
|
|
135022
135631
|
try {
|
|
135023
135632
|
const cached = JSON.parse(readFileSync17(artifactPath, "utf8"));
|
|
135024
|
-
if (
|
|
135633
|
+
if (isRecord10(cached) && cached.version === 1 && cached.compilerRevision === NEOSCRIPT_COMPILER_REVISION && cached.projectCompilationHash === projectCompilationHash2 && cached.sourceHash === sourceHash && isRecord10(cached.action) && typeof cached.artifactSha256 === "string" && createHash11("sha256").update(JSON.stringify(cached.action)).digest("hex") === cached.artifactSha256 && cached.action.compilerRevision === NEOSCRIPT_COMPILER_REVISION && Array.isArray(cached.action.parameters) && Array.isArray(cached.action.instructions) && isRecord10(cached.action.typeInfo)) {
|
|
135025
135634
|
return {
|
|
135026
135635
|
path,
|
|
135027
135636
|
source,
|
|
@@ -135185,7 +135794,7 @@ function portableDelegate(value) {
|
|
|
135185
135794
|
}
|
|
135186
135795
|
}
|
|
135187
135796
|
function callMemberId(value) {
|
|
135188
|
-
if (!
|
|
135797
|
+
if (!isRecord10(value) || value.type !== "callFunction") return null;
|
|
135189
135798
|
return typeof value.memberId === "string" ? value.memberId : null;
|
|
135190
135799
|
}
|
|
135191
135800
|
function assertNoNestedRegistration(value) {
|
|
@@ -135193,7 +135802,7 @@ function assertNoNestedRegistration(value) {
|
|
|
135193
135802
|
for (const entry of value) assertNoNestedRegistration(entry);
|
|
135194
135803
|
return;
|
|
135195
135804
|
}
|
|
135196
|
-
if (!
|
|
135805
|
+
if (!isRecord10(value)) return;
|
|
135197
135806
|
const memberId = callMemberId(value);
|
|
135198
135807
|
if (memberId !== null && REGISTRATION_IDS.has(memberId)) {
|
|
135199
135808
|
throw new NeoTestRegistrationError(
|
|
@@ -135209,8 +135818,8 @@ function compiledDelegateActions(value) {
|
|
|
135209
135818
|
for (const child of entry) visit(child);
|
|
135210
135819
|
return;
|
|
135211
135820
|
}
|
|
135212
|
-
if (!
|
|
135213
|
-
if (
|
|
135821
|
+
if (!isRecord10(entry)) return;
|
|
135822
|
+
if (isRecord10(entry.action) && Array.isArray(entry.action.instructions) && Array.isArray(entry.action.parameters) && isRecord10(entry.action.typeInfo)) {
|
|
135214
135823
|
actions.push(entry.action);
|
|
135215
135824
|
return;
|
|
135216
135825
|
}
|
|
@@ -135221,7 +135830,7 @@ function compiledDelegateActions(value) {
|
|
|
135221
135830
|
}
|
|
135222
135831
|
function validateRegistrationAction(action, allowRegistration) {
|
|
135223
135832
|
for (const instruction of action.instructions) {
|
|
135224
|
-
const record4 =
|
|
135833
|
+
const record4 = isRecord10(instruction) ? instruction : null;
|
|
135225
135834
|
const call = record4?.type === "functionCall" ? record4.call : null;
|
|
135226
135835
|
const memberId = callMemberId(call);
|
|
135227
135836
|
if (memberId !== null && REGISTRATION_IDS.has(memberId)) {
|
|
@@ -135354,8 +135963,8 @@ function mockResponse(environment, mock, selected, call) {
|
|
|
135354
135963
|
};
|
|
135355
135964
|
}
|
|
135356
135965
|
function partialObjectMatch(actual, expected) {
|
|
135357
|
-
if (!
|
|
135358
|
-
if (!
|
|
135966
|
+
if (!isRecord10(expected)) return isDeepStrictEqual(actual, expected);
|
|
135967
|
+
if (!isRecord10(actual)) return false;
|
|
135359
135968
|
return Object.entries(expected).every(
|
|
135360
135969
|
([key, value]) => partialObjectMatch(actual[key], value)
|
|
135361
135970
|
);
|
|
@@ -135547,7 +136156,7 @@ function interceptTestCallCore(environment, call) {
|
|
|
135547
136156
|
const contains2 = typeof actual === "string" ? actual.includes(String(call.args[0])) : Array.isArray(actual) && actual.some((entry) => isDeepStrictEqual(entry, call.args[0]));
|
|
135548
136157
|
assertMatcher(contains2, expectationValue, "toContain", call.args[0]);
|
|
135549
136158
|
} else if (call.memberId === NEO_TEST_IDS.toHaveLength) {
|
|
135550
|
-
const length = typeof actual === "string" || Array.isArray(actual) ? actual.length :
|
|
136159
|
+
const length = typeof actual === "string" || Array.isArray(actual) ? actual.length : isRecord10(actual) ? Object.keys(actual).length : -1;
|
|
135551
136160
|
assertMatcher(
|
|
135552
136161
|
length === call.args[0],
|
|
135553
136162
|
expectationValue,
|
|
@@ -135638,11 +136247,11 @@ function snapshotEnvironmentDocument(environment) {
|
|
|
135638
136247
|
const values = [...baseValues];
|
|
135639
136248
|
const byId = /* @__PURE__ */ new Map();
|
|
135640
136249
|
values.forEach((value, index) => {
|
|
135641
|
-
if (
|
|
136250
|
+
if (isRecord10(value) && typeof value.id === "string")
|
|
135642
136251
|
byId.set(value.id, index);
|
|
135643
136252
|
});
|
|
135644
136253
|
const mergeRow = (row) => {
|
|
135645
|
-
if (!
|
|
136254
|
+
if (!isRecord10(row) || typeof row.id !== "string") return;
|
|
135646
136255
|
const cloned = structuredClone(row);
|
|
135647
136256
|
const index = byId.get(row.id);
|
|
135648
136257
|
if (index === void 0) {
|
|
@@ -135658,7 +136267,7 @@ function snapshotEnvironmentDocument(environment) {
|
|
|
135658
136267
|
if (bindings.size > 0) {
|
|
135659
136268
|
const baseMembers = Array.isArray(snapshot.members) ? snapshot.members : [];
|
|
135660
136269
|
snapshot.members = baseMembers.map((member) => {
|
|
135661
|
-
if (!
|
|
136270
|
+
if (!isRecord10(member) || typeof member.id !== "string" || !bindings.has(member.id)) {
|
|
135662
136271
|
return member;
|
|
135663
136272
|
}
|
|
135664
136273
|
return { ...member, valueId: bindings.get(member.id) ?? null };
|
|
@@ -139943,7 +140552,7 @@ __export(dev_exports, {
|
|
|
139943
140552
|
import { watch } from "node:fs";
|
|
139944
140553
|
import { join as join20 } from "node:path";
|
|
139945
140554
|
import { emitKeypressEvents } from "node:readline";
|
|
139946
|
-
import { ConvexClient } from "convex/browser";
|
|
140555
|
+
import { ConvexClient as ConvexClient2 } from "convex/browser";
|
|
139947
140556
|
function isSchemaSignal(value) {
|
|
139948
140557
|
if (typeof value !== "object" || value === null) return false;
|
|
139949
140558
|
return typeof value.transactionHash === "string";
|
|
@@ -140018,8 +140627,14 @@ async function runDev(workspace, options) {
|
|
|
140018
140627
|
busy = false;
|
|
140019
140628
|
}
|
|
140020
140629
|
};
|
|
140021
|
-
const convex = new
|
|
140022
|
-
convex.setAuth(
|
|
140630
|
+
const convex = new ConvexClient2(convexUrl, { initialAuthTokenReuse: true });
|
|
140631
|
+
convex.setAuth(
|
|
140632
|
+
async () => await mintConvexJwt(
|
|
140633
|
+
workspace.config.apiBaseUrl,
|
|
140634
|
+
void 0,
|
|
140635
|
+
convexHttpActionUrl(convexUrl)
|
|
140636
|
+
)
|
|
140637
|
+
);
|
|
140023
140638
|
convex.onUpdate(
|
|
140024
140639
|
api2.projectExportData.schemaSignal,
|
|
140025
140640
|
{
|
|
@@ -140458,7 +141073,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
140458
141073
|
async function main() {
|
|
140459
141074
|
const args = parseArgs(process.argv.slice(2));
|
|
140460
141075
|
if (args.command === "--version") {
|
|
140461
|
-
console.log("0.50.
|
|
141076
|
+
console.log("0.50.8");
|
|
140462
141077
|
return;
|
|
140463
141078
|
}
|
|
140464
141079
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
|
@@ -140862,12 +141477,15 @@ async function main() {
|
|
|
140862
141477
|
return;
|
|
140863
141478
|
}
|
|
140864
141479
|
case "push": {
|
|
141480
|
+
const finishPush = startPerformanceSpan("push");
|
|
141481
|
+
const finishWorkspace = startPerformanceSpan("workspace");
|
|
140865
141482
|
const json = boolFlag(args, "json");
|
|
140866
141483
|
const preparation = process.stdout.isTTY === true && json !== true ? spinner("Preparing push\u2026") : null;
|
|
140867
141484
|
let handedOffPreparation = false;
|
|
140868
141485
|
try {
|
|
140869
141486
|
const workspace = loadWorkspaceForCommand(args);
|
|
140870
141487
|
const { runPush: runPush2 } = await Promise.resolve().then(() => (init_push(), push_exports));
|
|
141488
|
+
finishWorkspace();
|
|
140871
141489
|
handedOffPreparation = true;
|
|
140872
141490
|
await runPush2(
|
|
140873
141491
|
workspace,
|
|
@@ -140886,6 +141504,8 @@ async function main() {
|
|
|
140886
141504
|
preparation?.fail("Push preparation failed.");
|
|
140887
141505
|
}
|
|
140888
141506
|
throw error;
|
|
141507
|
+
} finally {
|
|
141508
|
+
finishPush();
|
|
140889
141509
|
}
|
|
140890
141510
|
return;
|
|
140891
141511
|
}
|
|
@@ -140985,6 +141605,7 @@ var DEFAULT_API_BASE_URL;
|
|
|
140985
141605
|
var init_main = __esm({
|
|
140986
141606
|
"src/main.ts"() {
|
|
140987
141607
|
"use strict";
|
|
141608
|
+
init_performance();
|
|
140988
141609
|
init_auth_api_base_url();
|
|
140989
141610
|
init_login();
|
|
140990
141611
|
init_args();
|