@neocompose/cli 0.36.11 → 0.36.13
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
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.36.13] - 2026-08-22
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Refresh short-lived Convex JWTs during long-running commands. History plan
|
|
8
|
+
polling and other multi-request operations now keep using the existing CLI
|
|
9
|
+
device session instead of failing when the initial 15-minute JWT expires.
|
|
10
|
+
|
|
11
|
+
## [0.36.12] - 2026-08-22
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Let project owners and admins plan, apply, inspect, and resume history
|
|
16
|
+
rewrites through the CLI device login. The editor profile now requests the
|
|
17
|
+
changelog write grant, the registered OAuth client allows it, and every
|
|
18
|
+
history rewrite endpoint declares its read or write scope. Existing CLI
|
|
19
|
+
sessions must run `neo logout` followed by `neo login` once after upgrading.
|
|
20
|
+
|
|
3
21
|
## [0.36.11] - 2026-08-21
|
|
4
22
|
|
|
5
23
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -572,6 +572,7 @@ var init_login = __esm({
|
|
|
572
572
|
"project:version:create",
|
|
573
573
|
"project:version:status:read",
|
|
574
574
|
"project:version:changelog:read",
|
|
575
|
+
"project:version:changelog:write",
|
|
575
576
|
"project:record:schema:read",
|
|
576
577
|
"project:record:schema:write",
|
|
577
578
|
"project:record:values:read",
|
|
@@ -64547,6 +64548,11 @@ var init_constructor_argument_ownership = __esm({
|
|
|
64547
64548
|
init_compile_ns_property();
|
|
64548
64549
|
init_value_row_owner_members();
|
|
64549
64550
|
MaterializedValueGraphContext = class {
|
|
64551
|
+
/**
|
|
64552
|
+
* P79 §7a. Generic in the caller's document view so a pass typed against a
|
|
64553
|
+
* narrowed view does not get the whole document handed back on the first
|
|
64554
|
+
* line it reads `graph.document`.
|
|
64555
|
+
*/
|
|
64550
64556
|
document;
|
|
64551
64557
|
valuesById;
|
|
64552
64558
|
childrenByContainerId;
|
|
@@ -72157,9 +72163,9 @@ function constructionInitEvaluator(ctx, createdValues, argumentScopes, construct
|
|
|
72157
72163
|
let currentId = memberId;
|
|
72158
72164
|
while (currentId !== void 0 && !visited.has(currentId)) {
|
|
72159
72165
|
visited.add(currentId);
|
|
72160
|
-
const
|
|
72166
|
+
const declaringClassIds2 = indexes.declaringClassIdsByMemberId.get(currentId);
|
|
72161
72167
|
const owner = inheritanceChain.find(
|
|
72162
|
-
(schemaClass2) =>
|
|
72168
|
+
(schemaClass2) => declaringClassIds2?.has(schemaClass2.id)
|
|
72163
72169
|
);
|
|
72164
72170
|
if (owner !== void 0) return owner.id;
|
|
72165
72171
|
currentId = indexes.containerMemberIdByEntryId.get(currentId) ?? indexes.memberById.get(currentId)?.extendsMemberId;
|
|
@@ -82139,8 +82145,17 @@ function transactionImpactsAnyOwnerMember(scope, impactedIds) {
|
|
|
82139
82145
|
function collectNeoScriptRecompileTargets(args) {
|
|
82140
82146
|
if (args.forceRecompile === true) return completeTargets(args.postDocument);
|
|
82141
82147
|
const explicit = explicitTargetIds(args.changes);
|
|
82142
|
-
const {
|
|
82148
|
+
const {
|
|
82149
|
+
impactedIds,
|
|
82150
|
+
changedValueIds,
|
|
82151
|
+
impactedTypeNames,
|
|
82152
|
+
constructedClassIds
|
|
82153
|
+
} = collectChangedContractIds(args);
|
|
82143
82154
|
for (const id2 of args.additionalImpactedIds ?? []) impactedIds.add(id2);
|
|
82155
|
+
for (const id2 of args.additionalChangedValueIds ?? []) {
|
|
82156
|
+
changedValueIds.add(id2);
|
|
82157
|
+
explicit.valueIds.add(id2);
|
|
82158
|
+
}
|
|
82144
82159
|
includeDerivedConstructionContracts(
|
|
82145
82160
|
constructedClassIds,
|
|
82146
82161
|
args.postDocument.classes
|
|
@@ -82157,7 +82172,7 @@ function collectNeoScriptRecompileTargets(args) {
|
|
|
82157
82172
|
dependentsById.set(dependencyId, dependents);
|
|
82158
82173
|
}
|
|
82159
82174
|
}
|
|
82160
|
-
const queue = [...impactedIds];
|
|
82175
|
+
const queue = [...impactedIds, ...changedValueIds];
|
|
82161
82176
|
for (let index = 0; index < queue.length; index += 1) {
|
|
82162
82177
|
const dependencyId = queue[index];
|
|
82163
82178
|
if (dependencyId === void 0) continue;
|
|
@@ -82166,22 +82181,24 @@ function collectNeoScriptRecompileTargets(args) {
|
|
|
82166
82181
|
}
|
|
82167
82182
|
}
|
|
82168
82183
|
const constructorOwnerById = constructorOwners(args.postDocument);
|
|
82169
|
-
const
|
|
82170
|
-
|
|
82171
|
-
postDocument: args.postDocument,
|
|
82184
|
+
const gradesSourceOnlyBodies = impactedIds.size > 0 || impactedTypeNames.size > 0;
|
|
82185
|
+
const impactScope = {
|
|
82172
82186
|
impactedIds,
|
|
82187
|
+
changedValueIds,
|
|
82173
82188
|
impactedTypeNames,
|
|
82174
|
-
constructedClassIds
|
|
82175
|
-
|
|
82176
|
-
|
|
82177
|
-
|
|
82178
|
-
if (recordDependsOnChangedContract(
|
|
82179
|
-
member,
|
|
82189
|
+
constructedClassIds,
|
|
82190
|
+
impactedSourceNames: gradesSourceOnlyBodies ? collectImpactedSourceNames({
|
|
82191
|
+
currentDocument: args.currentDocument,
|
|
82192
|
+
postDocument: args.postDocument,
|
|
82180
82193
|
impactedIds,
|
|
82194
|
+
changedValueIds,
|
|
82181
82195
|
impactedTypeNames,
|
|
82182
|
-
constructedClassIds
|
|
82183
|
-
|
|
82184
|
-
|
|
82196
|
+
constructedClassIds
|
|
82197
|
+
}) : /* @__PURE__ */ new Set()
|
|
82198
|
+
};
|
|
82199
|
+
const memberIds = new Set(explicit.memberIds);
|
|
82200
|
+
for (const member of args.postDocument.members) {
|
|
82201
|
+
if (recordDependsOnChangedContract(member, impactScope)) {
|
|
82185
82202
|
memberIds.add(member.id);
|
|
82186
82203
|
}
|
|
82187
82204
|
}
|
|
@@ -82189,10 +82206,7 @@ function collectNeoScriptRecompileTargets(args) {
|
|
|
82189
82206
|
const valueIds = selectedRecordIds(
|
|
82190
82207
|
postValues,
|
|
82191
82208
|
explicit.valueIds,
|
|
82192
|
-
|
|
82193
|
-
impactedTypeNames,
|
|
82194
|
-
constructedClassIds,
|
|
82195
|
-
impactedSourceNames
|
|
82209
|
+
impactScope
|
|
82196
82210
|
);
|
|
82197
82211
|
if (impactedIds.size > 0 && postValues.length > 0) {
|
|
82198
82212
|
const scope = withVariantOwnershipRoots(
|
|
@@ -82219,35 +82233,23 @@ function collectNeoScriptRecompileTargets(args) {
|
|
|
82219
82233
|
constructorIds: selectedRecordIds(
|
|
82220
82234
|
args.postDocument.constructors ?? [],
|
|
82221
82235
|
explicit.constructorIds,
|
|
82222
|
-
|
|
82223
|
-
impactedTypeNames,
|
|
82224
|
-
constructedClassIds,
|
|
82225
|
-
impactedSourceNames,
|
|
82236
|
+
impactScope,
|
|
82226
82237
|
(record3) => constructorOwnerById.get(record3.id) ?? null
|
|
82227
82238
|
),
|
|
82228
82239
|
migrationIds: selectedRecordIds(
|
|
82229
82240
|
args.postDocument.migrations ?? [],
|
|
82230
82241
|
explicit.migrationIds,
|
|
82231
|
-
|
|
82232
|
-
impactedTypeNames,
|
|
82233
|
-
constructedClassIds,
|
|
82234
|
-
impactedSourceNames
|
|
82242
|
+
impactScope
|
|
82235
82243
|
),
|
|
82236
82244
|
dialogueNodeIds: selectedRecordIds(
|
|
82237
82245
|
args.postDocument.dialogueNodes ?? [],
|
|
82238
82246
|
explicit.dialogueNodeIds,
|
|
82239
|
-
|
|
82240
|
-
impactedTypeNames,
|
|
82241
|
-
constructedClassIds,
|
|
82242
|
-
impactedSourceNames
|
|
82247
|
+
impactScope
|
|
82243
82248
|
),
|
|
82244
82249
|
dialogueGroupIds: selectedRecordIds(
|
|
82245
82250
|
args.postDocument.dialogueGroups ?? [],
|
|
82246
82251
|
explicit.dialogueGroupIds,
|
|
82247
|
-
|
|
82248
|
-
impactedTypeNames,
|
|
82249
|
-
constructedClassIds,
|
|
82250
|
-
impactedSourceNames
|
|
82252
|
+
impactScope
|
|
82251
82253
|
),
|
|
82252
82254
|
valueIds
|
|
82253
82255
|
};
|
|
@@ -82323,6 +82325,7 @@ function isCompilerReferenceField(field) {
|
|
|
82323
82325
|
}
|
|
82324
82326
|
function collectChangedContractIds(args) {
|
|
82325
82327
|
const impactedIds = /* @__PURE__ */ new Set();
|
|
82328
|
+
const changedValueIds = /* @__PURE__ */ new Set();
|
|
82326
82329
|
const impactedTypeNames = /* @__PURE__ */ new Set();
|
|
82327
82330
|
const constructedClassIds = /* @__PURE__ */ new Set();
|
|
82328
82331
|
const currentMembers = new Map(
|
|
@@ -82383,7 +82386,7 @@ function collectChangedContractIds(args) {
|
|
|
82383
82386
|
const current2 = currentValues.get(change.recordId);
|
|
82384
82387
|
const next2 = postValues.get(change.recordId);
|
|
82385
82388
|
if (current2 === void 0 || next2 === void 0 || Reflect.get(current2, "classId") !== Reflect.get(next2, "classId")) {
|
|
82386
|
-
|
|
82389
|
+
changedValueIds.add(change.recordId);
|
|
82387
82390
|
}
|
|
82388
82391
|
continue;
|
|
82389
82392
|
}
|
|
@@ -82429,7 +82432,12 @@ function collectChangedContractIds(args) {
|
|
|
82429
82432
|
}
|
|
82430
82433
|
}
|
|
82431
82434
|
}
|
|
82432
|
-
return {
|
|
82435
|
+
return {
|
|
82436
|
+
impactedIds,
|
|
82437
|
+
changedValueIds,
|
|
82438
|
+
impactedTypeNames,
|
|
82439
|
+
constructedClassIds
|
|
82440
|
+
};
|
|
82433
82441
|
}
|
|
82434
82442
|
function generatedConstructorMemberContractChanged(current, next) {
|
|
82435
82443
|
if (current === void 0 || next === void 0) return true;
|
|
@@ -82616,50 +82624,51 @@ function explicitTargetIds(changes) {
|
|
|
82616
82624
|
}
|
|
82617
82625
|
return result;
|
|
82618
82626
|
}
|
|
82619
|
-
function selectedRecordIds(records2, explicitIds,
|
|
82627
|
+
function selectedRecordIds(records2, explicitIds, scope, ownerId = () => null) {
|
|
82620
82628
|
const selected = new Set(explicitIds);
|
|
82621
82629
|
for (const record3 of records2) {
|
|
82622
82630
|
const owner = ownerId(record3);
|
|
82623
|
-
if (owner !== null && impactedIds.has(owner) || recordDependsOnChangedContract(
|
|
82624
|
-
record3,
|
|
82625
|
-
impactedIds,
|
|
82626
|
-
impactedTypeNames,
|
|
82627
|
-
constructedClassIds,
|
|
82628
|
-
impactedSourceNames
|
|
82629
|
-
)) {
|
|
82631
|
+
if (owner !== null && scope.impactedIds.has(owner) || recordDependsOnChangedContract(record3, scope)) {
|
|
82630
82632
|
selected.add(record3.id);
|
|
82631
82633
|
}
|
|
82632
82634
|
}
|
|
82633
82635
|
return selected;
|
|
82634
82636
|
}
|
|
82635
|
-
function recordDependsOnChangedContract(record3,
|
|
82637
|
+
function recordDependsOnChangedContract(record3, scope) {
|
|
82636
82638
|
const recordId = isObjectRecord4(record3) ? record3.id : void 0;
|
|
82637
|
-
if (typeof recordId === "string" && impactedIds.has(recordId))
|
|
82638
|
-
if (intersects(collectCompilerReferenceIds(record3), impactedIds)) return true;
|
|
82639
|
-
if (intersects(collectCompilerReferenceNames(record3), impactedTypeNames)) {
|
|
82639
|
+
if (typeof recordId === "string" && scope.impactedIds.has(recordId)) {
|
|
82640
82640
|
return true;
|
|
82641
82641
|
}
|
|
82642
|
-
|
|
82642
|
+
const referenceIds = collectCompilerReferenceIds(record3);
|
|
82643
|
+
if (intersects(referenceIds, scope.impactedIds)) return true;
|
|
82644
|
+
if (intersects(referenceIds, scope.changedValueIds)) return true;
|
|
82645
|
+
if (intersects(collectCompilerReferenceNames(record3), scope.impactedTypeNames)) {
|
|
82643
82646
|
return true;
|
|
82644
82647
|
}
|
|
82645
|
-
if (
|
|
82648
|
+
if (intersects(collectConstructedClassIds(record3), scope.constructedClassIds)) {
|
|
82649
|
+
return true;
|
|
82650
|
+
}
|
|
82651
|
+
if (scope.impactedIds.size === 0 && scope.impactedTypeNames.size === 0) {
|
|
82652
|
+
return false;
|
|
82653
|
+
}
|
|
82646
82654
|
if (!containsAuthoredNeoScriptSource(record3)) return false;
|
|
82647
82655
|
if (containsCompiledNeoScriptBody(record3)) return false;
|
|
82648
|
-
if (impactedSourceNames === null) return true;
|
|
82656
|
+
if (scope.impactedSourceNames === null) return true;
|
|
82649
82657
|
const sourceIdentifiers = collectAuthoredNeoScriptSourceIdentifiers(record3);
|
|
82650
82658
|
if (sourceIdentifiers === null) return true;
|
|
82651
|
-
return intersects(sourceIdentifiers, impactedSourceNames);
|
|
82659
|
+
return intersects(sourceIdentifiers, scope.impactedSourceNames);
|
|
82652
82660
|
}
|
|
82653
82661
|
function collectImpactedSourceNames(args) {
|
|
82654
82662
|
const names = new Set(args.impactedTypeNames);
|
|
82655
82663
|
let recoveredContract = args.impactedTypeNames.size > 0;
|
|
82664
|
+
const isImpactedRecordId = (id2) => args.impactedIds.has(id2) || args.changedValueIds.has(id2);
|
|
82656
82665
|
const collectDocument = (document) => {
|
|
82657
82666
|
const classById = new Map(
|
|
82658
82667
|
document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
|
|
82659
82668
|
);
|
|
82660
82669
|
const ownerByConstructorId = constructorOwners(document);
|
|
82661
82670
|
const impactedValueIds = new Set(
|
|
82662
|
-
(document.values ?? []).filter((value) =>
|
|
82671
|
+
(document.values ?? []).filter((value) => isImpactedRecordId(value.id)).map((value) => value.id)
|
|
82663
82672
|
);
|
|
82664
82673
|
const scope = withVariantOwnershipRoots(document, document.variants ?? []);
|
|
82665
82674
|
const ownerByValueId = resolveOwnerMembersForValues(
|
|
@@ -82688,7 +82697,7 @@ function collectImpactedSourceNames(args) {
|
|
|
82688
82697
|
...document.values ?? []
|
|
82689
82698
|
];
|
|
82690
82699
|
for (const record3 of records2) {
|
|
82691
|
-
if (!
|
|
82700
|
+
if (!isImpactedRecordId(record3.id)) continue;
|
|
82692
82701
|
recoveredContract = true;
|
|
82693
82702
|
collectDeclaredSourceNames(record3, names);
|
|
82694
82703
|
const ownerClassId = ownerByConstructorId.get(record3.id);
|
|
@@ -89997,7 +90006,7 @@ function prepareServerOwnedSchemaCommit(args) {
|
|
|
89997
90006
|
const hasValueChange = authoredChanges.some(
|
|
89998
90007
|
(change) => change.recordKind === "value"
|
|
89999
90008
|
);
|
|
90000
|
-
const hasAdditionalContractImpact = (args.additionalImpactedIds?.size ?? 0) > 0;
|
|
90009
|
+
const hasAdditionalContractImpact = (args.additionalImpactedIds?.size ?? 0) > 0 || (args.additionalChangedValueIds?.size ?? 0) > 0;
|
|
90001
90010
|
if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange && !hasAdditionalContractImpact) {
|
|
90002
90011
|
return authoredChanges;
|
|
90003
90012
|
}
|
|
@@ -90010,6 +90019,7 @@ function prepareServerOwnedSchemaCommit(args) {
|
|
|
90010
90019
|
postDocument: authoredPostDocument,
|
|
90011
90020
|
changes: authoredChanges,
|
|
90012
90021
|
additionalImpactedIds: args.additionalImpactedIds,
|
|
90022
|
+
additionalChangedValueIds: args.additionalChangedValueIds,
|
|
90013
90023
|
forceRecompile: args.forceRecompile
|
|
90014
90024
|
});
|
|
90015
90025
|
const currentById = new Map(
|
|
@@ -90319,7 +90329,8 @@ function materializePreparedInstanceInitializers(args) {
|
|
|
90319
90329
|
const existingValueById = new Map(
|
|
90320
90330
|
args.document.values.map((value) => [value.id, value])
|
|
90321
90331
|
);
|
|
90322
|
-
|
|
90332
|
+
let currentGraph = null;
|
|
90333
|
+
const requireCurrentGraph = () => currentGraph ??= new MaterializedValueGraphContext(args.document);
|
|
90323
90334
|
const rootKinds = /* @__PURE__ */ new Map();
|
|
90324
90335
|
const materializationScope = withVariantOwnershipRoots(
|
|
90325
90336
|
compiledDocument,
|
|
@@ -90359,7 +90370,7 @@ function materializePreparedInstanceInitializers(args) {
|
|
|
90359
90370
|
if (existingConstructedRoot) {
|
|
90360
90371
|
if (!isLiteralValueContent(materialized.root) || existingRoot.classId !== materialized.root.classId || !replayedCreationDataMatches({
|
|
90361
90372
|
currentDocument: args.document,
|
|
90362
|
-
currentGraph,
|
|
90373
|
+
currentGraph: requireCurrentGraph(),
|
|
90363
90374
|
currentRoot: existingRoot,
|
|
90364
90375
|
replayRoot: materialized.root,
|
|
90365
90376
|
replayCreated: materialized.createdValues
|
|
@@ -91349,9 +91360,46 @@ function drainConstructedGraphValidations(args) {
|
|
|
91349
91360
|
});
|
|
91350
91361
|
}
|
|
91351
91362
|
}
|
|
91363
|
+
function indexAuthoredSeedDocument(document) {
|
|
91364
|
+
const declaringClassIdsByMemberId = /* @__PURE__ */ new Map();
|
|
91365
|
+
for (const schemaClass2 of document.classes) {
|
|
91366
|
+
const declared = /* @__PURE__ */ new Set();
|
|
91367
|
+
for (const memberId of Object.values(schemaClass2.schema)) {
|
|
91368
|
+
if (typeof memberId !== "string") continue;
|
|
91369
|
+
if (declared.has(memberId)) continue;
|
|
91370
|
+
declared.add(memberId);
|
|
91371
|
+
const owners = declaringClassIdsByMemberId.get(memberId);
|
|
91372
|
+
if (owners === void 0) {
|
|
91373
|
+
declaringClassIdsByMemberId.set(memberId, [schemaClass2.id]);
|
|
91374
|
+
continue;
|
|
91375
|
+
}
|
|
91376
|
+
owners.push(schemaClass2.id);
|
|
91377
|
+
}
|
|
91378
|
+
}
|
|
91379
|
+
return {
|
|
91380
|
+
valuesById: indexRecordsById(document.values),
|
|
91381
|
+
membersById: indexRecordsById(document.members),
|
|
91382
|
+
localizedTextIds: new Set(
|
|
91383
|
+
(document.localizedTexts ?? []).map((text) => text.id)
|
|
91384
|
+
),
|
|
91385
|
+
declaringClassIdsByMemberId
|
|
91386
|
+
};
|
|
91387
|
+
}
|
|
91388
|
+
function declaringClassIds(index, memberId) {
|
|
91389
|
+
return index.declaringClassIdsByMemberId.get(memberId) ?? [];
|
|
91390
|
+
}
|
|
91391
|
+
function hasLiveMemberChange(prepared) {
|
|
91392
|
+
return prepared.some(
|
|
91393
|
+
(change) => change.recordKind === "member" && change.operation !== "delete" && change.nextData !== void 0
|
|
91394
|
+
);
|
|
91395
|
+
}
|
|
91352
91396
|
function materializeAuthoredValueSeeds(args) {
|
|
91397
|
+
if (args.authoredValueSeeds.length === 0 && !hasLiveMemberChange(args.prepared)) {
|
|
91398
|
+
return;
|
|
91399
|
+
}
|
|
91353
91400
|
const pendingGraphValidations = [];
|
|
91354
91401
|
materializeStaticSeedBindingMembers(args);
|
|
91402
|
+
const documentIndex = indexAuthoredSeedDocument(args.document);
|
|
91355
91403
|
const seedByMemberId = new Map(
|
|
91356
91404
|
args.authoredValueSeeds.map((seed) => [seed.memberId, seed])
|
|
91357
91405
|
);
|
|
@@ -91371,6 +91419,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91371
91419
|
consumedSeedMemberIds.add(member.id);
|
|
91372
91420
|
materializeInstanceDefaultSeed({
|
|
91373
91421
|
document: args.document,
|
|
91422
|
+
documentIndex,
|
|
91374
91423
|
prepared: args.prepared,
|
|
91375
91424
|
pendingGraphValidations,
|
|
91376
91425
|
memberChange: { index, change },
|
|
@@ -91393,9 +91442,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91393
91442
|
`Static Generic member "${member.name}" (${member.id}) cannot materialize a value.`
|
|
91394
91443
|
);
|
|
91395
91444
|
}
|
|
91396
|
-
const owners =
|
|
91397
|
-
(schemaClass2) => Object.values(schemaClass2.schema).includes(member.id)
|
|
91398
|
-
);
|
|
91445
|
+
const owners = declaringClassIds(documentIndex, member.id);
|
|
91399
91446
|
if (owners.length !== 1) {
|
|
91400
91447
|
throw new Error(
|
|
91401
91448
|
`Stored static member "${member.name}" (${member.id}) must have exactly one direct declaring class; found ${owners.length}.`
|
|
@@ -91403,7 +91450,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91403
91450
|
}
|
|
91404
91451
|
if (change.operation === "update" && seed === void 0) continue;
|
|
91405
91452
|
if (change.operation === "create" && seed === void 0 && typeof member.valueId === "string") {
|
|
91406
|
-
if (!
|
|
91453
|
+
if (!documentIndex.valuesById.has(member.valueId)) {
|
|
91407
91454
|
throw new Error(
|
|
91408
91455
|
`Stored static member "${member.name}" (${member.id}) binds missing value "${member.valueId}".`
|
|
91409
91456
|
);
|
|
@@ -91427,6 +91474,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91427
91474
|
member: materializationMember
|
|
91428
91475
|
}) : materializeAuthoredStaticSeed({
|
|
91429
91476
|
document: args.document,
|
|
91477
|
+
documentIndex,
|
|
91430
91478
|
member: materializationMember,
|
|
91431
91479
|
// P61 must leave a computed static root as an init-backed prepared
|
|
91432
91480
|
// row until `materializePreparedInstanceInitializers` runs. The
|
|
@@ -91436,7 +91484,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91436
91484
|
seed: { ...seed, values: seed.values ?? [] }
|
|
91437
91485
|
});
|
|
91438
91486
|
const { createdValues, localizedTexts, storageKeyDeclarations, rootValue } = materialized;
|
|
91439
|
-
const ownedValueId =
|
|
91487
|
+
const ownedValueId = documentIndex.membersById.get(member.id)?.valueId ?? derivedMemberValueId(member.id);
|
|
91440
91488
|
if (seed?.valueId !== void 0 && seed.valueId !== ownedValueId) {
|
|
91441
91489
|
throw new Error(
|
|
91442
91490
|
`Static value seed for member "${member.name}" (${member.id}) binds value "${seed.valueId}", but the member owns value "${ownedValueId}".`
|
|
@@ -91449,7 +91497,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91449
91497
|
}
|
|
91450
91498
|
if (seed?.values === void 0 && rootValue.id !== ownedValueId) {
|
|
91451
91499
|
assertMintedRootValueIdIsFree({
|
|
91452
|
-
|
|
91500
|
+
documentIndex,
|
|
91453
91501
|
prepared: args.prepared,
|
|
91454
91502
|
member,
|
|
91455
91503
|
valueId: ownedValueId
|
|
@@ -91471,7 +91519,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91471
91519
|
rootValue.id,
|
|
91472
91520
|
{
|
|
91473
91521
|
mapKey: null,
|
|
91474
|
-
classId: owners[0]
|
|
91522
|
+
classId: owners[0]
|
|
91475
91523
|
}
|
|
91476
91524
|
]
|
|
91477
91525
|
])
|
|
@@ -91519,12 +91567,11 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91519
91567
|
}
|
|
91520
91568
|
for (const seed of args.authoredValueSeeds) {
|
|
91521
91569
|
if (consumedSeedMemberIds.has(seed.memberId)) continue;
|
|
91522
|
-
const member =
|
|
91523
|
-
(candidate) => candidate.id === seed.memberId
|
|
91524
|
-
);
|
|
91570
|
+
const member = documentIndex.membersById.get(seed.memberId);
|
|
91525
91571
|
if (member !== void 0 && member.isStatic !== true && !isProjectRootMember(args.document.project, member.id)) {
|
|
91526
91572
|
materializeInstanceDefaultSeed({
|
|
91527
91573
|
document: args.document,
|
|
91574
|
+
documentIndex,
|
|
91528
91575
|
prepared: args.prepared,
|
|
91529
91576
|
pendingGraphValidations,
|
|
91530
91577
|
memberChange: null,
|
|
@@ -91536,6 +91583,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91536
91583
|
}
|
|
91537
91584
|
materializeExistingAuthoredValueSeed({
|
|
91538
91585
|
document: args.document,
|
|
91586
|
+
documentIndex,
|
|
91539
91587
|
prepared: args.prepared,
|
|
91540
91588
|
pendingGraphValidations,
|
|
91541
91589
|
seed,
|
|
@@ -91550,9 +91598,7 @@ function materializeAuthoredValueSeeds(args) {
|
|
|
91550
91598
|
});
|
|
91551
91599
|
}
|
|
91552
91600
|
function materializeExistingAuthoredValueSeed(args) {
|
|
91553
|
-
const member = args.
|
|
91554
|
-
(candidate) => candidate.id === args.seed.memberId
|
|
91555
|
-
);
|
|
91601
|
+
const member = args.documentIndex.membersById.get(args.seed.memberId);
|
|
91556
91602
|
if (member === void 0) {
|
|
91557
91603
|
throw new Error(
|
|
91558
91604
|
`Member value seed "${args.seed.memberId}" does not target a stored member in this schema commit.`
|
|
@@ -91574,9 +91620,7 @@ function materializeExistingAuthoredValueSeed(args) {
|
|
|
91574
91620
|
`Existing value graph seed for member "${member.name}" (${member.id}) targets value "${args.seed.valueId}", but the member binds "${String(member.valueId)}".`
|
|
91575
91621
|
);
|
|
91576
91622
|
}
|
|
91577
|
-
const owners = args.
|
|
91578
|
-
(schemaClass2) => Object.values(schemaClass2.schema).includes(member.id)
|
|
91579
|
-
);
|
|
91623
|
+
const owners = declaringClassIds(args.documentIndex, member.id);
|
|
91580
91624
|
if (!isRootMember && owners.length !== 1) {
|
|
91581
91625
|
throw new Error(
|
|
91582
91626
|
`Stored static member "${member.name}" (${member.id}) must have exactly one direct declaring class; found ${owners.length}.`
|
|
@@ -91584,6 +91628,7 @@ function materializeExistingAuthoredValueSeed(args) {
|
|
|
91584
91628
|
}
|
|
91585
91629
|
const materialized = materializeAuthoredStaticSeed({
|
|
91586
91630
|
document: args.document,
|
|
91631
|
+
documentIndex: args.documentIndex,
|
|
91587
91632
|
member,
|
|
91588
91633
|
seed: { ...args.seed, values: args.seed.values },
|
|
91589
91634
|
allowExistingRows: true
|
|
@@ -91604,7 +91649,7 @@ function materializeExistingAuthoredValueSeed(args) {
|
|
|
91604
91649
|
mapKey: null,
|
|
91605
91650
|
// A root member's row has no enclosing class, so declared storage
|
|
91606
91651
|
// keys below it resolve against no parent class.
|
|
91607
|
-
classId: owners[0]
|
|
91652
|
+
classId: owners[0]
|
|
91608
91653
|
}
|
|
91609
91654
|
]
|
|
91610
91655
|
])
|
|
@@ -91623,9 +91668,7 @@ function materializeExistingAuthoredValueSeed(args) {
|
|
|
91623
91668
|
});
|
|
91624
91669
|
for (const value of materialized.createdValues) {
|
|
91625
91670
|
if (materialized.existingValueIds.has(value.id)) {
|
|
91626
|
-
if (isInitValueContent(value) && !isInitValueContent(
|
|
91627
|
-
args.document.values.find((candidate) => candidate.id === value.id)
|
|
91628
|
-
)) {
|
|
91671
|
+
if (isInitValueContent(value) && !isInitValueContent(args.documentIndex.valuesById.get(value.id))) {
|
|
91629
91672
|
args.prepared.push({
|
|
91630
91673
|
recordKind: "value",
|
|
91631
91674
|
recordId: value.id,
|
|
@@ -91829,9 +91872,7 @@ function materializeInstanceDefaultSeed(args) {
|
|
|
91829
91872
|
`Constructed default seed for member "${args.member.name}" (${args.member.id}) requires a root value id and explicit value rows.`
|
|
91830
91873
|
);
|
|
91831
91874
|
}
|
|
91832
|
-
const owners = args.
|
|
91833
|
-
(schemaClass2) => Object.values(schemaClass2.schema).includes(args.member.id)
|
|
91834
|
-
);
|
|
91875
|
+
const owners = declaringClassIds(args.documentIndex, args.member.id);
|
|
91835
91876
|
if (owners.length !== 1) {
|
|
91836
91877
|
throw new Error(
|
|
91837
91878
|
`Constructed default member "${args.member.name}" (${args.member.id}) must have exactly one direct declaring class; found ${owners.length}.`
|
|
@@ -91849,6 +91890,7 @@ function materializeInstanceDefaultSeed(args) {
|
|
|
91849
91890
|
existingValueIds
|
|
91850
91891
|
} = materializeAuthoredStaticSeed({
|
|
91851
91892
|
document: args.document,
|
|
91893
|
+
documentIndex: args.documentIndex,
|
|
91852
91894
|
member: materializationMember,
|
|
91853
91895
|
seed: { ...args.seed, values: args.seed.values },
|
|
91854
91896
|
allowExistingRows: args.memberChange === null || args.memberChange.change.operation === "update"
|
|
@@ -91862,7 +91904,7 @@ function materializeInstanceDefaultSeed(args) {
|
|
|
91862
91904
|
rootValue.id,
|
|
91863
91905
|
{
|
|
91864
91906
|
mapKey: null,
|
|
91865
|
-
classId: owners[0]
|
|
91907
|
+
classId: owners[0]
|
|
91866
91908
|
}
|
|
91867
91909
|
]
|
|
91868
91910
|
])
|
|
@@ -91953,7 +91995,7 @@ function materializeDefaultStaticSeed(args) {
|
|
|
91953
91995
|
};
|
|
91954
91996
|
}
|
|
91955
91997
|
function assertMintedRootValueIdIsFree(args) {
|
|
91956
|
-
if (args.
|
|
91998
|
+
if (args.documentIndex.valuesById.has(args.valueId)) {
|
|
91957
91999
|
throw new Error(
|
|
91958
92000
|
`Member "${args.member.name}" (${args.member.id}) owns value "${args.valueId}", which already exists in this version.`
|
|
91959
92001
|
);
|
|
@@ -91990,7 +92032,7 @@ function materializeAuthoredStaticSeed(args) {
|
|
|
91990
92032
|
const requestedIds = /* @__PURE__ */ new Set([requestedRootId, ...authoredRows.keys()]);
|
|
91991
92033
|
const existingValueIds = /* @__PURE__ */ new Set();
|
|
91992
92034
|
for (const id2 of requestedIds) {
|
|
91993
|
-
const existing = args.
|
|
92035
|
+
const existing = args.documentIndex.valuesById.get(id2);
|
|
91994
92036
|
if (existing === void 0) continue;
|
|
91995
92037
|
if (args.allowExistingRows !== true) {
|
|
91996
92038
|
throw new Error(`Value "${id2}" already exists.`);
|
|
@@ -92008,6 +92050,7 @@ function materializeAuthoredStaticSeed(args) {
|
|
|
92008
92050
|
const usedRows = /* @__PURE__ */ new Set();
|
|
92009
92051
|
const rootValue = materializeAuthoredSeedRow({
|
|
92010
92052
|
document: args.document,
|
|
92053
|
+
documentIndex: args.documentIndex,
|
|
92011
92054
|
member: args.member,
|
|
92012
92055
|
row: seedRootRow(args.member, args.seed, requestedRootId),
|
|
92013
92056
|
authoredRows,
|
|
@@ -92035,6 +92078,7 @@ function materializeAuthoredStaticSeed(args) {
|
|
|
92035
92078
|
}
|
|
92036
92079
|
const seededLocalizedTexts = materializeStaticLocalizedTexts({
|
|
92037
92080
|
document: args.document,
|
|
92081
|
+
documentIndex: args.documentIndex,
|
|
92038
92082
|
seeds: args.seed.localizedTexts ?? [],
|
|
92039
92083
|
createdValues
|
|
92040
92084
|
});
|
|
@@ -92170,9 +92214,7 @@ function materializeStaticLocalizedTexts(args) {
|
|
|
92170
92214
|
throw new Error(`Localized text seed repeats id "${seed.id}".`);
|
|
92171
92215
|
}
|
|
92172
92216
|
seen.add(seed.id);
|
|
92173
|
-
if (
|
|
92174
|
-
(text) => text.id === seed.id
|
|
92175
|
-
) || args.document.values.some((value) => value.id === seed.id)) {
|
|
92217
|
+
if (args.documentIndex.localizedTextIds.has(seed.id) || args.documentIndex.valuesById.has(seed.id)) {
|
|
92176
92218
|
throw new Error(`Localized text "${seed.id}" already exists.`);
|
|
92177
92219
|
}
|
|
92178
92220
|
const owner = args.createdValues.find((value) => value.id === seed.valueId);
|
|
@@ -92248,7 +92290,7 @@ function materializeAuthoredSeedRow(args) {
|
|
|
92248
92290
|
...isMemberClassBase(resolvedStoredMember) && args.row.classId !== null ? { topLevelClassId: args.row.classId } : {}
|
|
92249
92291
|
});
|
|
92250
92292
|
renameCreatedValueId({
|
|
92251
|
-
|
|
92293
|
+
documentIndex: args.documentIndex,
|
|
92252
92294
|
createdValues: args.createdValues,
|
|
92253
92295
|
storageKeyDeclarations: args.storageKeyDeclarations,
|
|
92254
92296
|
generatedId: generatedRoot.id,
|
|
@@ -92336,7 +92378,7 @@ function materializeAuthoredClassFields(args) {
|
|
|
92336
92378
|
`Class "${effectiveClassId}" has no stored member "${schemaKey}".`
|
|
92337
92379
|
);
|
|
92338
92380
|
}
|
|
92339
|
-
const childMember =
|
|
92381
|
+
const childMember = requireSeedMember(args.documentIndex, childMemberId);
|
|
92340
92382
|
const currentBody = isStringValueRecord(args.rootValue.value) ? args.rootValue.value : {};
|
|
92341
92383
|
const previousId = currentBody[schemaKey];
|
|
92342
92384
|
if (previousId !== void 0 && previousId !== childId) {
|
|
@@ -92365,8 +92407,8 @@ function materializeAuthoredListItems(args) {
|
|
|
92365
92407
|
if (!Array.isArray(args.row.value)) {
|
|
92366
92408
|
throw new Error(`List value "${args.row.id}" requires an array body.`);
|
|
92367
92409
|
}
|
|
92368
|
-
const entryMember =
|
|
92369
|
-
args.
|
|
92410
|
+
const entryMember = requireSeedMember(
|
|
92411
|
+
args.documentIndex,
|
|
92370
92412
|
args.member.entryMemberId
|
|
92371
92413
|
);
|
|
92372
92414
|
const unordered = listKindOf(args.member) === "unordered";
|
|
@@ -92397,8 +92439,8 @@ function materializeAuthoredDictionaryEntries(args) {
|
|
|
92397
92439
|
`Dictionary value "${args.row.id}" requires an object body.`
|
|
92398
92440
|
);
|
|
92399
92441
|
}
|
|
92400
|
-
const entryMember =
|
|
92401
|
-
args.
|
|
92442
|
+
const entryMember = requireSeedMember(
|
|
92443
|
+
args.documentIndex,
|
|
92402
92444
|
args.member.entryMemberId
|
|
92403
92445
|
);
|
|
92404
92446
|
const body = {};
|
|
@@ -92416,9 +92458,7 @@ function materializeAuthoredChild(args) {
|
|
|
92416
92458
|
if (authored !== void 0) {
|
|
92417
92459
|
return materializeAuthoredSeedRow({ ...args, row: authored });
|
|
92418
92460
|
}
|
|
92419
|
-
const existing = args.
|
|
92420
|
-
(value) => value.id === args.childId
|
|
92421
|
-
);
|
|
92461
|
+
const existing = args.documentIndex.valuesById.get(args.childId);
|
|
92422
92462
|
if (existing === void 0) {
|
|
92423
92463
|
throw new Error(
|
|
92424
92464
|
`Authored value graph references missing row "${args.childId}".`
|
|
@@ -92428,7 +92468,7 @@ function materializeAuthoredChild(args) {
|
|
|
92428
92468
|
}
|
|
92429
92469
|
function renameCreatedValueId(args) {
|
|
92430
92470
|
if (args.generatedId === args.requestedId) return;
|
|
92431
|
-
if (args.
|
|
92471
|
+
if (args.documentIndex.valuesById.has(args.requestedId) && !args.replaceExistingIds.has(args.requestedId) || args.createdValues.some(
|
|
92432
92472
|
(value2) => value2.id === args.requestedId && value2.id !== args.generatedId
|
|
92433
92473
|
)) {
|
|
92434
92474
|
throw new Error(`Value "${args.requestedId}" already exists.`);
|
|
@@ -92500,10 +92540,8 @@ function collectStringReferences2(value, output) {
|
|
|
92500
92540
|
collectStringReferences2(entry, output);
|
|
92501
92541
|
}
|
|
92502
92542
|
}
|
|
92503
|
-
function
|
|
92504
|
-
const member =
|
|
92505
|
-
(candidate) => candidate.id === memberId
|
|
92506
|
-
);
|
|
92543
|
+
function requireSeedMember(documentIndex, memberId) {
|
|
92544
|
+
const member = documentIndex.membersById.get(memberId);
|
|
92507
92545
|
if (member === void 0) throw new Error(`Member "${memberId}" is missing.`);
|
|
92508
92546
|
return member;
|
|
92509
92547
|
}
|
|
@@ -92761,6 +92799,18 @@ function prepareServerOwnedValueInitializerBodies(args) {
|
|
|
92761
92799
|
});
|
|
92762
92800
|
}
|
|
92763
92801
|
}
|
|
92802
|
+
function collectDelegateSweepRows(args) {
|
|
92803
|
+
if (args.targetIds.size === 0) return [];
|
|
92804
|
+
const preparedValueIds = indexChangesByRecordId(args.prepared, "value");
|
|
92805
|
+
const sweepRows = [];
|
|
92806
|
+
for (const value of args.postDocument.values) {
|
|
92807
|
+
if (!args.targetIds.has(value.id)) continue;
|
|
92808
|
+
if (preparedValueIds.has(value.id)) continue;
|
|
92809
|
+
const row = delegateValueRow(value);
|
|
92810
|
+
if (row !== null) sweepRows.push(row);
|
|
92811
|
+
}
|
|
92812
|
+
return sweepRows;
|
|
92813
|
+
}
|
|
92764
92814
|
function delegateValueRow(value) {
|
|
92765
92815
|
if (!isMemberValue(value) || !isLiteralValueContent(value)) return null;
|
|
92766
92816
|
if (!isNSDelegateClosureValueDraft(value.value) && !isNSDelegateClosureValue(value.value)) {
|
|
@@ -92778,11 +92828,7 @@ function prepareServerOwnedDelegateValueBodies(args) {
|
|
|
92778
92828
|
const row = delegateValueRow(change.nextData);
|
|
92779
92829
|
if (row !== null) explicitRows.set(index, row);
|
|
92780
92830
|
}
|
|
92781
|
-
const sweepRows = args
|
|
92782
|
-
(value) => args.targetIds.has(value.id) && delegateValueRow(value) !== null && !args.prepared.some(
|
|
92783
|
-
(change) => change.recordKind === "value" && change.recordId === value.id
|
|
92784
|
-
)
|
|
92785
|
-
);
|
|
92831
|
+
const sweepRows = collectDelegateSweepRows(args);
|
|
92786
92832
|
if (explicitRows.size === 0 && sweepRows.length === 0) return;
|
|
92787
92833
|
const committedDocument = applyProjectVersionWriteChanges(
|
|
92788
92834
|
args.postDocument,
|
|
@@ -93305,8 +93351,7 @@ function applyProjectVersionWriteChanges(document, changes) {
|
|
|
93305
93351
|
const hasGranularDialogueNodes = document.dialogueNodes !== void 0 || changes.some((change) => change.recordKind === "dialogue-node");
|
|
93306
93352
|
const dialogueRecords = hasGranularDialogueRecords ? applyArrayChanges(document.dialogueRecords ?? [], changes, "dialogue") : void 0;
|
|
93307
93353
|
const dialogueNodes = hasGranularDialogueNodes ? applyArrayChanges(document.dialogueNodes ?? [], changes, "dialogue-node") : void 0;
|
|
93308
|
-
|
|
93309
|
-
...document,
|
|
93354
|
+
const projected = {
|
|
93310
93355
|
project: applySingletonChange(document.project, changes, "project"),
|
|
93311
93356
|
members: applyArrayChanges(document.members, changes, "member"),
|
|
93312
93357
|
classes: applyArrayChanges(document.classes, changes, "class"),
|
|
@@ -93360,8 +93405,6 @@ function applyProjectVersionWriteChanges(document, changes) {
|
|
|
93360
93405
|
),
|
|
93361
93406
|
enums: applyArrayChanges(document.enums, changes, "enum"),
|
|
93362
93407
|
interfaces: applyArrayChanges(document.interfaces, changes, "interface"),
|
|
93363
|
-
...dialogueRecords === void 0 ? {} : { dialogueRecords },
|
|
93364
|
-
...dialogueNodes === void 0 ? {} : { dialogueNodes },
|
|
93365
93408
|
dialogues: dialogueRecords === void 0 || dialogueNodes === void 0 ? document.dialogues : materializeDialogues(
|
|
93366
93409
|
dialogueRecords,
|
|
93367
93410
|
dialogueNodes
|
|
@@ -93377,6 +93420,15 @@ function applyProjectVersionWriteChanges(document, changes) {
|
|
|
93377
93420
|
"migration"
|
|
93378
93421
|
)
|
|
93379
93422
|
};
|
|
93423
|
+
return {
|
|
93424
|
+
...document,
|
|
93425
|
+
...projected,
|
|
93426
|
+
...dialogueRecords === void 0 ? {} : { dialogueRecords },
|
|
93427
|
+
...dialogueNodes === void 0 ? {} : { dialogueNodes }
|
|
93428
|
+
// The document spread above carries every bucket the caller's view declares
|
|
93429
|
+
// beyond the projected ones, so the result is the same view; TypeScript
|
|
93430
|
+
// cannot prove that of an object literal built over a type parameter.
|
|
93431
|
+
};
|
|
93380
93432
|
}
|
|
93381
93433
|
function applySingletonChange(current, changes, recordKind) {
|
|
93382
93434
|
const change = changes.find(
|
|
@@ -93417,6 +93469,16 @@ function canonicallyEqual2(left, right) {
|
|
|
93417
93469
|
return canonicalJsonStringify(left) === canonicalJsonStringify(right);
|
|
93418
93470
|
}
|
|
93419
93471
|
function reconcileVariantConstructorArgs(args) {
|
|
93472
|
+
const changeIndexByValueId = indexChangesByRecordId(args.prepared, "value");
|
|
93473
|
+
const commitTouchesProjectionSchema = variantConstructorArgsSchemaIsTouched(
|
|
93474
|
+
args.prepared
|
|
93475
|
+
);
|
|
93476
|
+
if (changeIndexByValueId.size === 0 && !commitTouchesProjectionSchema) {
|
|
93477
|
+
return;
|
|
93478
|
+
}
|
|
93479
|
+
if ((args.document.variants ?? []).length === 0 && !args.prepared.some((change) => change.recordKind === "variant")) {
|
|
93480
|
+
return;
|
|
93481
|
+
}
|
|
93420
93482
|
const postDocument = applyProjectVersionWriteChanges(
|
|
93421
93483
|
args.document,
|
|
93422
93484
|
args.prepared
|
|
@@ -93427,7 +93489,6 @@ function reconcileVariantConstructorArgs(args) {
|
|
|
93427
93489
|
const classById = indexRecordsById(postDocument.classes);
|
|
93428
93490
|
const memberById2 = indexRecordsById(postDocument.members);
|
|
93429
93491
|
const constructorById = indexRecordsById(postDocument.constructors ?? []);
|
|
93430
|
-
const changeIndexByValueId = indexChangesByRecordId(args.prepared, "value");
|
|
93431
93492
|
let baseHashByValueId = null;
|
|
93432
93493
|
for (const variant of variants) {
|
|
93433
93494
|
const root = valueById.get(variant.valueId);
|
|
@@ -93444,6 +93505,9 @@ function reconcileVariantConstructorArgs(args) {
|
|
|
93444
93505
|
if (constructorRecord === void 0) continue;
|
|
93445
93506
|
if (typeof root.value !== "object" || root.value === null) continue;
|
|
93446
93507
|
if (Array.isArray(root.value)) continue;
|
|
93508
|
+
if (!commitTouchesProjectionSchema && !variantConstructorArgsAreTouched(root, changeIndexByValueId)) {
|
|
93509
|
+
continue;
|
|
93510
|
+
}
|
|
93447
93511
|
const nextArgs = {};
|
|
93448
93512
|
for (let index = 0; index < constructorRecord.argumentTypes.length; index += 1) {
|
|
93449
93513
|
const argument2 = constructorRecord.argumentTypes[index];
|
|
@@ -93513,6 +93577,21 @@ function reconcileVariantConstructorArgs(args) {
|
|
|
93513
93577
|
});
|
|
93514
93578
|
}
|
|
93515
93579
|
}
|
|
93580
|
+
function variantConstructorArgsSchemaIsTouched(prepared) {
|
|
93581
|
+
return prepared.some(
|
|
93582
|
+
(change) => VARIANT_CONSTRUCTOR_ARGS_SCHEMA_RECORD_KINDS.has(change.recordKind)
|
|
93583
|
+
);
|
|
93584
|
+
}
|
|
93585
|
+
function variantConstructorArgsAreTouched(root, changeIndexByValueId) {
|
|
93586
|
+
if (changeIndexByValueId.has(root.id)) return true;
|
|
93587
|
+
const body = root.value;
|
|
93588
|
+
for (const schemaKey of NEO_VARIANT_SCHEMA_KEY_BY_ARGUMENT_NAME.values()) {
|
|
93589
|
+
const childId = body[schemaKey];
|
|
93590
|
+
if (typeof childId !== "string") continue;
|
|
93591
|
+
if (changeIndexByValueId.has(childId)) return true;
|
|
93592
|
+
}
|
|
93593
|
+
return false;
|
|
93594
|
+
}
|
|
93516
93595
|
function variantConstructorArgumentIsRestValue(schemaKey, value) {
|
|
93517
93596
|
if (value === null) return true;
|
|
93518
93597
|
if (schemaKey === NEO_VARIANT_OVERRIDES_SCHEMA_KEY) {
|
|
@@ -93561,7 +93640,7 @@ function appendVariantGraphCascadeDeletes(args) {
|
|
|
93561
93640
|
});
|
|
93562
93641
|
}
|
|
93563
93642
|
}
|
|
93564
|
-
var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, READ_ONLY_SOURCE_CONVERSION_INTENT_SOURCE, SCHEMA_RECORD_KINDS, DIALOGUE_SOURCE_RECORD_KINDS, NEO_VARIANT_SCHEMA_KEY_BY_ARGUMENT_NAME;
|
|
93643
|
+
var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, READ_ONLY_SOURCE_CONVERSION_INTENT_SOURCE, SCHEMA_RECORD_KINDS, DIALOGUE_SOURCE_RECORD_KINDS, NEO_VARIANT_SCHEMA_KEY_BY_ARGUMENT_NAME, VARIANT_CONSTRUCTOR_ARGS_SCHEMA_RECORD_KINDS;
|
|
93565
93644
|
var init_project_version_schema_commit = __esm({
|
|
93566
93645
|
"../src/database/project-version-schema-commit.ts"() {
|
|
93567
93646
|
"use strict";
|
|
@@ -93623,6 +93702,9 @@ var init_project_version_schema_commit = __esm({
|
|
|
93623
93702
|
["overrides", NEO_VARIANT_OVERRIDES_SCHEMA_KEY],
|
|
93624
93703
|
["childoverrides", NEO_VARIANT_CHILD_OVERRIDES_SCHEMA_KEY]
|
|
93625
93704
|
]);
|
|
93705
|
+
VARIANT_CONSTRUCTOR_ARGS_SCHEMA_RECORD_KINDS = /* @__PURE__ */ new Set(
|
|
93706
|
+
["constructor", "class", "member", "variant"]
|
|
93707
|
+
);
|
|
93626
93708
|
}
|
|
93627
93709
|
});
|
|
93628
93710
|
|
|
@@ -105739,6 +105821,7 @@ var init_api = __esm({
|
|
|
105739
105821
|
|
|
105740
105822
|
// src/convex.ts
|
|
105741
105823
|
import { ConvexHttpClient } from "convex/browser";
|
|
105824
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
105742
105825
|
async function mintConvexJwt(apiBaseUrl) {
|
|
105743
105826
|
const sessionToken = loadToken(apiBaseUrl);
|
|
105744
105827
|
if (sessionToken === null) {
|
|
@@ -105796,9 +105879,10 @@ async function resolveConvexUrl(workspace) {
|
|
|
105796
105879
|
}
|
|
105797
105880
|
async function createConvexClient(workspace) {
|
|
105798
105881
|
const convexUrl = await resolveConvexUrl(workspace);
|
|
105799
|
-
|
|
105800
|
-
|
|
105801
|
-
|
|
105882
|
+
return await createAuthenticatedConvexClient(
|
|
105883
|
+
convexUrl,
|
|
105884
|
+
workspace.config.apiBaseUrl
|
|
105885
|
+
);
|
|
105802
105886
|
}
|
|
105803
105887
|
async function createConvexClientForApi(apiBaseUrl) {
|
|
105804
105888
|
const fromEnv = process.env.NEXT_PUBLIC_CONVEX_URL;
|
|
@@ -105816,9 +105900,52 @@ async function createConvexClientForApi(apiBaseUrl) {
|
|
|
105816
105900
|
});
|
|
105817
105901
|
convexUrl = await discoverConvexUrlFromProjectsResponse(response);
|
|
105818
105902
|
}
|
|
105819
|
-
|
|
105820
|
-
|
|
105821
|
-
|
|
105903
|
+
return await createAuthenticatedConvexClient(convexUrl, apiBaseUrl);
|
|
105904
|
+
}
|
|
105905
|
+
async function createAuthenticatedConvexClient(convexUrl, apiBaseUrl) {
|
|
105906
|
+
const tokenCache = new ConvexJwtCache(apiBaseUrl);
|
|
105907
|
+
const initialToken = await tokenCache.getToken();
|
|
105908
|
+
const authenticatedFetch = async (input, init) => {
|
|
105909
|
+
const headers = new Headers(
|
|
105910
|
+
init?.headers ?? (input instanceof Request ? input.headers : void 0)
|
|
105911
|
+
);
|
|
105912
|
+
headers.set("Authorization", `Bearer ${await tokenCache.getToken()}`);
|
|
105913
|
+
return await fetch(input, { ...init, headers });
|
|
105914
|
+
};
|
|
105915
|
+
return new ConvexHttpClient(convexUrl, {
|
|
105916
|
+
auth: initialToken,
|
|
105917
|
+
fetch: authenticatedFetch
|
|
105918
|
+
});
|
|
105919
|
+
}
|
|
105920
|
+
function convexJwtExpiration(token) {
|
|
105921
|
+
const segments = token.split(".");
|
|
105922
|
+
if (segments.length !== 3) {
|
|
105923
|
+
throw new Error("Convex token response is not a three-segment JWT.");
|
|
105924
|
+
}
|
|
105925
|
+
let payloadJson;
|
|
105926
|
+
try {
|
|
105927
|
+
payloadJson = Buffer2.from(segments[1], "base64url").toString("utf8");
|
|
105928
|
+
} catch {
|
|
105929
|
+
throw new Error(
|
|
105930
|
+
"Convex token response has an invalid JWT payload encoding."
|
|
105931
|
+
);
|
|
105932
|
+
}
|
|
105933
|
+
let payload;
|
|
105934
|
+
try {
|
|
105935
|
+
payload = JSON.parse(payloadJson);
|
|
105936
|
+
} catch {
|
|
105937
|
+
throw new Error("Convex token response has an invalid JWT payload.");
|
|
105938
|
+
}
|
|
105939
|
+
if (typeof payload !== "object" || payload === null) {
|
|
105940
|
+
throw new Error("Convex token response has a non-object JWT payload.");
|
|
105941
|
+
}
|
|
105942
|
+
if (!("exp" in payload)) {
|
|
105943
|
+
throw new Error('Convex token response JWT is missing an "exp" claim.');
|
|
105944
|
+
}
|
|
105945
|
+
if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
|
|
105946
|
+
throw new Error('Convex token response JWT has an invalid "exp" claim.');
|
|
105947
|
+
}
|
|
105948
|
+
return payload.exp * 1e3;
|
|
105822
105949
|
}
|
|
105823
105950
|
async function discoverConvexUrlFromProjectsResponse(response) {
|
|
105824
105951
|
const headerUrl = response.headers.get("x-neo-convex-url");
|
|
@@ -105843,7 +105970,7 @@ function missingProjectsConvexUrlError() {
|
|
|
105843
105970
|
"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)."
|
|
105844
105971
|
);
|
|
105845
105972
|
}
|
|
105846
|
-
var generatedApiModule, generatedApiValue, api2;
|
|
105973
|
+
var generatedApiModule, generatedApiValue, api2, CONVEX_JWT_REFRESH_LEEWAY_MS, ConvexJwtCache;
|
|
105847
105974
|
var init_convex = __esm({
|
|
105848
105975
|
"src/convex.ts"() {
|
|
105849
105976
|
"use strict";
|
|
@@ -105856,6 +105983,38 @@ var init_convex = __esm({
|
|
|
105856
105983
|
throw new Error("The generated Convex API module did not export api.");
|
|
105857
105984
|
}
|
|
105858
105985
|
api2 = generatedApiValue;
|
|
105986
|
+
CONVEX_JWT_REFRESH_LEEWAY_MS = 6e4;
|
|
105987
|
+
ConvexJwtCache = class {
|
|
105988
|
+
constructor(apiBaseUrl) {
|
|
105989
|
+
this.apiBaseUrl = apiBaseUrl;
|
|
105990
|
+
}
|
|
105991
|
+
apiBaseUrl;
|
|
105992
|
+
token = null;
|
|
105993
|
+
expiresAt = 0;
|
|
105994
|
+
refreshPromise = null;
|
|
105995
|
+
async getToken() {
|
|
105996
|
+
if (this.token !== null && Date.now() + CONVEX_JWT_REFRESH_LEEWAY_MS < this.expiresAt) {
|
|
105997
|
+
return this.token;
|
|
105998
|
+
}
|
|
105999
|
+
const pending = this.refreshPromise ?? this.refresh();
|
|
106000
|
+
this.refreshPromise = pending;
|
|
106001
|
+
try {
|
|
106002
|
+
return await pending;
|
|
106003
|
+
} finally {
|
|
106004
|
+
if (this.refreshPromise === pending) this.refreshPromise = null;
|
|
106005
|
+
}
|
|
106006
|
+
}
|
|
106007
|
+
async refresh() {
|
|
106008
|
+
const token = await mintConvexJwt(this.apiBaseUrl);
|
|
106009
|
+
const expiresAt = convexJwtExpiration(token);
|
|
106010
|
+
if (expiresAt <= Date.now()) {
|
|
106011
|
+
throw new Error("Convex token response contains an expired JWT.");
|
|
106012
|
+
}
|
|
106013
|
+
this.token = token;
|
|
106014
|
+
this.expiresAt = expiresAt;
|
|
106015
|
+
return token;
|
|
106016
|
+
}
|
|
106017
|
+
};
|
|
105859
106018
|
}
|
|
105860
106019
|
});
|
|
105861
106020
|
|
|
@@ -114586,7 +114745,7 @@ var init_registry2 = __esm({
|
|
|
114586
114745
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
114587
114746
|
formatVersion: 3,
|
|
114588
114747
|
contractVersion: "3.14",
|
|
114589
|
-
cliVersion: "0.36.
|
|
114748
|
+
cliVersion: "0.36.13",
|
|
114590
114749
|
projectFileUploadBatchSize: 32,
|
|
114591
114750
|
documentRecords: {
|
|
114592
114751
|
member: {
|
|
@@ -121205,7 +121364,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
121205
121364
|
async function main() {
|
|
121206
121365
|
const args = parseArgs(process.argv.slice(2));
|
|
121207
121366
|
if (args.command === "--version") {
|
|
121208
|
-
console.log("0.36.
|
|
121367
|
+
console.log("0.36.13");
|
|
121209
121368
|
return;
|
|
121210
121369
|
}
|
|
121211
121370
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neocompose/cli",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.13",
|
|
4
4
|
"description": "Neo Compose native project-source CLI with bidirectional sync.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@inquirer/prompts": "^8.5.2",
|
|
38
|
-
"convex": "^1.
|
|
38
|
+
"convex": "^1.45.0",
|
|
39
39
|
"ignore": "^7.0.6"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
@@ -83,7 +83,7 @@ wrappers.
|
|
|
83
83
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
|
-
<!-- reviewed-through-cli: 0.36.
|
|
86
|
+
<!-- reviewed-through-cli: 0.36.13 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -132,12 +132,24 @@ neo merge <branch> [--dry-run] [--migrate]
|
|
|
132
132
|
neo release cut [--bump major|minor|patch] [--dry-run]
|
|
133
133
|
neo history inspect
|
|
134
134
|
neo history log
|
|
135
|
+
neo history prune [--project <id|@latest|@current>]
|
|
136
|
+
neo history flatten [--project <id|@latest|@current>] --version <id|@latest|@current>
|
|
137
|
+
neo history apply --plan <plan-id> [--confirm-scope <project-id>[/<version-id>]]
|
|
138
|
+
neo history status --run <run-id>
|
|
139
|
+
neo history resume --run <run-id>
|
|
135
140
|
```
|
|
136
141
|
|
|
137
142
|
Treat branches as copy-on-write forks and releases as immutable snapshots. The
|
|
138
143
|
server derives the minimum compatibility bump; a caller may only raise it.
|
|
139
144
|
Require the release login profile for release operations.
|
|
140
145
|
|
|
146
|
+
History rewrites require project owner or admin authority. `prune` and
|
|
147
|
+
`flatten` create immutable plans without deleting anything. `apply` starts the
|
|
148
|
+
destructive run after the plan has sealed. Production also requires the exact
|
|
149
|
+
scope confirmation shown by the plan. CLI
|
|
150
|
+
tokens issued before 0.36.12 do not hold the history write grant, so run
|
|
151
|
+
`neo logout` followed by `neo login` once after upgrading.
|
|
152
|
+
|
|
141
153
|
## Authentication and automation
|
|
142
154
|
|
|
143
155
|
```sh
|
|
@@ -155,7 +167,9 @@ targeted repair is handed instead of scanning a project to rediscover them.
|
|
|
155
167
|
The Node CLI talks directly to authenticated Convex APIs through the
|
|
156
168
|
session-gated CAS boundary. Tokens use the OS credential store when available
|
|
157
169
|
and a protected file only as fallback. Use `NEO_COMPOSE_TOKEN` or
|
|
158
|
-
`--token-stdin` in CI. The
|
|
170
|
+
`--token-stdin` in CI. The CLI automatically re-mints its short-lived Convex
|
|
171
|
+
JWT before expiry during long-running commands; the stored device session
|
|
172
|
+
remains the credential. The editor profile cannot publish releases; server
|
|
159
173
|
scopes remain the security boundary.
|
|
160
174
|
|
|
161
175
|
`neo logout [--api <url>]` deletes the stored credential for exactly one API
|