@valbuild/server 0.73.2 → 0.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/valbuild-server.cjs.dev.js +287 -75
- package/dist/valbuild-server.cjs.prod.js +287 -75
- package/dist/valbuild-server.esm.js +288 -76
- package/package.json +4 -4
@@ -1485,7 +1485,11 @@ const tsOps = new TSOps(document => {
|
|
1485
1485
|
class ValOps {
|
1486
1486
|
/** Sources from val modules, immutable (without patches or anything) */
|
1487
1487
|
|
1488
|
-
/** The sha256 / hash of sources +
|
1488
|
+
/** The sha256 / hash of all sources + all schemas + config */
|
1489
|
+
|
1490
|
+
/** The sha256 / hash of all sources */
|
1491
|
+
|
1492
|
+
/** The sha256 / hash of config */
|
1489
1493
|
|
1490
1494
|
/** Schema from val modules, immutable */
|
1491
1495
|
|
@@ -1498,6 +1502,8 @@ class ValOps {
|
|
1498
1502
|
this.baseSha = null;
|
1499
1503
|
this.schemas = null;
|
1500
1504
|
this.schemaSha = null;
|
1505
|
+
this.sourcesSha = null;
|
1506
|
+
this.configSha = null;
|
1501
1507
|
this.modulesErrors = null;
|
1502
1508
|
}
|
1503
1509
|
hash(input) {
|
@@ -1555,7 +1561,7 @@ class ValOps {
|
|
1555
1561
|
|
1556
1562
|
// #region initTree
|
1557
1563
|
async initSources() {
|
1558
|
-
if (this.baseSha === null || this.schemaSha === null || this.sources === null || this.schemas === null || this.modulesErrors === null) {
|
1564
|
+
if (this.baseSha === null || this.sourcesSha === null || this.configSha === null || this.schemaSha === null || this.sources === null || this.schemas === null || this.modulesErrors === null) {
|
1559
1565
|
const currentModulesErrors = [];
|
1560
1566
|
const addModuleError = (message, index, path) => {
|
1561
1567
|
currentModulesErrors[index] = {
|
@@ -1565,8 +1571,10 @@ class ValOps {
|
|
1565
1571
|
};
|
1566
1572
|
const currentSources = {};
|
1567
1573
|
const currentSchemas = {};
|
1568
|
-
|
1569
|
-
let
|
1574
|
+
const configSha = this.hash(JSON.stringify(this.valModules.config));
|
1575
|
+
let sourcesSha = "";
|
1576
|
+
let baseSha = configSha;
|
1577
|
+
let schemaSha = configSha;
|
1570
1578
|
for (let moduleIdx = 0; moduleIdx < this.valModules.modules.length; moduleIdx++) {
|
1571
1579
|
const module = this.valModules.modules[moduleIdx];
|
1572
1580
|
if (!module.def) {
|
@@ -1621,6 +1629,10 @@ class ValOps {
|
|
1621
1629
|
currentSources[pathM] = source;
|
1622
1630
|
currentSchemas[pathM] = schema;
|
1623
1631
|
// make sure the checks above is enough that this does not fail - even if val modules are not set up correctly
|
1632
|
+
sourcesSha = this.hash(sourcesSha + JSON.stringify({
|
1633
|
+
path,
|
1634
|
+
source
|
1635
|
+
}));
|
1624
1636
|
baseSha = this.hash(baseSha + JSON.stringify({
|
1625
1637
|
path,
|
1626
1638
|
schema: serializedSchema,
|
@@ -1634,11 +1646,15 @@ class ValOps {
|
|
1634
1646
|
this.schemas = currentSchemas;
|
1635
1647
|
this.baseSha = baseSha;
|
1636
1648
|
this.schemaSha = schemaSha;
|
1649
|
+
this.sourcesSha = sourcesSha;
|
1650
|
+
this.configSha = configSha;
|
1637
1651
|
this.modulesErrors = currentModulesErrors;
|
1638
1652
|
}
|
1639
1653
|
return {
|
1640
1654
|
baseSha: this.baseSha,
|
1641
1655
|
schemaSha: this.schemaSha,
|
1656
|
+
sourcesSha: this.sourcesSha,
|
1657
|
+
configSha: this.configSha,
|
1642
1658
|
sources: this.sources,
|
1643
1659
|
schemas: this.schemas,
|
1644
1660
|
moduleErrors: this.modulesErrors
|
@@ -1663,6 +1679,12 @@ class ValOps {
|
|
1663
1679
|
async getBaseSha() {
|
1664
1680
|
return this.initSources().then(result => result.baseSha);
|
1665
1681
|
}
|
1682
|
+
async getConfigSha() {
|
1683
|
+
return this.initSources().then(result => result.configSha);
|
1684
|
+
}
|
1685
|
+
async getSourcesSha() {
|
1686
|
+
return this.initSources().then(result => result.sourcesSha);
|
1687
|
+
}
|
1666
1688
|
async getSchemaSha() {
|
1667
1689
|
return this.initSources().then(result => result.schemaSha);
|
1668
1690
|
}
|
@@ -2222,7 +2244,7 @@ class ValOps {
|
|
2222
2244
|
}
|
2223
2245
|
|
2224
2246
|
// #region createPatch
|
2225
|
-
async createPatch(path, patch$1, parentRef, authorId) {
|
2247
|
+
async createPatch(path, patch$1, patchId, parentRef, authorId) {
|
2226
2248
|
const initTree = await this.initSources();
|
2227
2249
|
const schemas = initTree.schemas;
|
2228
2250
|
const moduleErrors = initTree.moduleErrors;
|
@@ -2311,7 +2333,7 @@ class ValOps {
|
|
2311
2333
|
}
|
2312
2334
|
}
|
2313
2335
|
}
|
2314
|
-
const saveRes = await this.saveSourceFilePatch(path, patch$1, parentRef, authorId);
|
2336
|
+
const saveRes = await this.saveSourceFilePatch(path, patch$1, patchId, parentRef, authorId);
|
2315
2337
|
if (fp.result.isErr(saveRes)) {
|
2316
2338
|
console.error(`Could not save source patch at path: '${path}'. Error: ${saveRes.error.errorType === "other" ? saveRes.error.message : saveRes.error.errorType}`);
|
2317
2339
|
if (saveRes.error.errorType === "patch-head-conflict") {
|
@@ -2324,7 +2346,6 @@ class ValOps {
|
|
2324
2346
|
error: saveRes.error
|
2325
2347
|
});
|
2326
2348
|
}
|
2327
|
-
const patchId = saveRes.value.patchId;
|
2328
2349
|
const saveFileRes = await Promise.all(Object.entries(files).map(async ([filePath, data]) => {
|
2329
2350
|
if (data.error) {
|
2330
2351
|
return {
|
@@ -2634,6 +2655,7 @@ class ValOpsFS extends ValOps {
|
|
2634
2655
|
var _this$options, _this$options2;
|
2635
2656
|
const currentBaseSha = await this.getBaseSha();
|
2636
2657
|
const currentSchemaSha = await this.getSchemaSha();
|
2658
|
+
const currentSourcesSha = await this.getSourcesSha();
|
2637
2659
|
const moduleFilePaths = Object.keys(await this.getSchemas());
|
2638
2660
|
const patchData = await this.readPatches();
|
2639
2661
|
const patches = [];
|
@@ -2644,12 +2666,15 @@ class ValOpsFS extends ValOps {
|
|
2644
2666
|
patches.push(patchId);
|
2645
2667
|
}
|
2646
2668
|
// something changed: return immediately
|
2647
|
-
const didChange = !params || currentBaseSha !== params.baseSha ||
|
2669
|
+
const didChange = !params || currentBaseSha !== params.baseSha ||
|
2670
|
+
// base sha covers both sources sha and schema sha, so we could remove checks for schema sha and sources sha
|
2671
|
+
currentSourcesSha !== params.sourcesSha || currentSchemaSha !== params.schemaSha || patches.length !== params.patches.length || patches.some((p, i) => p !== params.patches[i]);
|
2648
2672
|
if (didChange) {
|
2649
2673
|
return {
|
2650
2674
|
type: "did-change",
|
2651
2675
|
baseSha: currentBaseSha,
|
2652
2676
|
schemaSha: currentSchemaSha,
|
2677
|
+
sourcesSha: currentSourcesSha,
|
2653
2678
|
patches
|
2654
2679
|
};
|
2655
2680
|
}
|
@@ -2763,6 +2788,7 @@ class ValOpsFS extends ValOps {
|
|
2763
2788
|
type,
|
2764
2789
|
baseSha: currentBaseSha,
|
2765
2790
|
schemaSha: currentSchemaSha,
|
2791
|
+
sourcesSha: currentSourcesSha,
|
2766
2792
|
patches
|
2767
2793
|
};
|
2768
2794
|
} catch (err) {
|
@@ -2837,6 +2863,11 @@ class ValOpsFS extends ValOps {
|
|
2837
2863
|
};
|
2838
2864
|
}
|
2839
2865
|
return patchData;
|
2866
|
+
}).filter(patchData => {
|
2867
|
+
if (filters.patchIds && filters.patchIds.length > 0) {
|
2868
|
+
return filters.patchIds.includes(patchData.patchId);
|
2869
|
+
}
|
2870
|
+
return true;
|
2840
2871
|
});
|
2841
2872
|
return {
|
2842
2873
|
patches: sortedPatches,
|
@@ -2973,11 +3004,10 @@ class ValOpsFS extends ValOps {
|
|
2973
3004
|
};
|
2974
3005
|
}
|
2975
3006
|
}
|
2976
|
-
async saveSourceFilePatch(path, patch, parentRef, authorId) {
|
3007
|
+
async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
|
2977
3008
|
const patchDir = this.getParentPatchIdFromParentRef(parentRef);
|
2978
3009
|
try {
|
2979
3010
|
const baseSha = await this.getBaseSha();
|
2980
|
-
const patchId = crypto.randomUUID();
|
2981
3011
|
const data = {
|
2982
3012
|
patch,
|
2983
3013
|
patchId,
|
@@ -2988,6 +3018,13 @@ class ValOpsFS extends ValOps {
|
|
2988
3018
|
coreVersion: core.Internal.VERSION.core,
|
2989
3019
|
createdAt: new Date().toISOString()
|
2990
3020
|
};
|
3021
|
+
const headParentPatchId = "head";
|
3022
|
+
if (patchDir !== headParentPatchId && !this.host.fileExists(this.getPatchFilePath(headParentPatchId))) {
|
3023
|
+
console.error("Val: out-of-band patch detected.", this.getPatchFilePath(headParentPatchId));
|
3024
|
+
return fp.result.err({
|
3025
|
+
errorType: "patch-head-conflict"
|
3026
|
+
});
|
3027
|
+
}
|
2991
3028
|
const writeRes = this.host.tryWriteUf8File(this.getPatchFilePath(patchDir), JSON.stringify(data));
|
2992
3029
|
if (writeRes.type === "error") {
|
2993
3030
|
return writeRes.errorType === "dir-already-exists" ? fp.result.err({
|
@@ -3159,6 +3196,28 @@ class ValOpsFS extends ValOps {
|
|
3159
3196
|
deleted
|
3160
3197
|
};
|
3161
3198
|
}
|
3199
|
+
async deleteAllPatches() {
|
3200
|
+
const patchesCacheDir = this.getPatchesDir();
|
3201
|
+
const tmpDir = fsPath__namespace["default"].join(this.rootDir, ValOpsFS.VAL_DIR, "patches-deleted-" + crypto.randomUUID());
|
3202
|
+
try {
|
3203
|
+
this.host.moveDir(patchesCacheDir, tmpDir);
|
3204
|
+
this.host.deleteDir(tmpDir);
|
3205
|
+
return {};
|
3206
|
+
} catch (err) {
|
3207
|
+
if (err instanceof Error) {
|
3208
|
+
return {
|
3209
|
+
error: {
|
3210
|
+
message: `Got an error while deleting patches: ${err.message}`
|
3211
|
+
}
|
3212
|
+
};
|
3213
|
+
}
|
3214
|
+
return {
|
3215
|
+
error: {
|
3216
|
+
message: "Got an unexpected error while deleting patches"
|
3217
|
+
}
|
3218
|
+
};
|
3219
|
+
}
|
3220
|
+
}
|
3162
3221
|
updateOrderedPatches(updates, patchDirMap, deletePatchIds) {
|
3163
3222
|
for (const patchId of deletePatchIds) {
|
3164
3223
|
const patchDir = patchDirMap[patchId];
|
@@ -3201,7 +3260,7 @@ class ValOpsFS extends ValOps {
|
|
3201
3260
|
}
|
3202
3261
|
}
|
3203
3262
|
}
|
3204
|
-
async saveOrUploadFiles(preparedCommit,
|
3263
|
+
async saveOrUploadFiles(preparedCommit, mode, auth) {
|
3205
3264
|
const updatedFiles = [];
|
3206
3265
|
const uploadedRemoteRefs = [];
|
3207
3266
|
const errors = {};
|
@@ -3219,42 +3278,50 @@ class ValOpsFS extends ValOps {
|
|
3219
3278
|
}]) => [ref, {
|
3220
3279
|
patchId
|
3221
3280
|
}]);
|
3222
|
-
|
3223
|
-
|
3224
|
-
|
3225
|
-
|
3226
|
-
const splitRemoteRefRes = core.Internal.remote.splitRemoteRef(ref);
|
3227
|
-
if (splitRemoteRefRes.status === "error") {
|
3228
|
-
errors[ref] = {
|
3229
|
-
message: "Failed to split remote ref: " + ref
|
3281
|
+
if (mode === "upload-remote") {
|
3282
|
+
if (!auth) {
|
3283
|
+
errors["auth"] = {
|
3284
|
+
message: "No auth provided"
|
3230
3285
|
};
|
3231
|
-
|
3232
|
-
|
3233
|
-
|
3234
|
-
|
3235
|
-
errors[ref] = {
|
3236
|
-
message: "Failed to get binary file from patch. Ref: " + ref + ". PatchId: " + patchId
|
3237
|
-
};
|
3238
|
-
continue;
|
3239
|
-
}
|
3240
|
-
if (testMode === "test-skip-remote") {
|
3241
|
-
console.log("Skip remote flag enabled. Skipping file upload", ref);
|
3242
|
-
continue;
|
3243
|
-
}
|
3244
|
-
if (!((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.config.project)) {
|
3245
|
-
errors[ref] = {
|
3246
|
-
message: "No project found in config"
|
3286
|
+
return {
|
3287
|
+
updatedFiles,
|
3288
|
+
uploadedRemoteRefs,
|
3289
|
+
errors
|
3247
3290
|
};
|
3248
|
-
continue;
|
3249
3291
|
}
|
3250
|
-
|
3251
|
-
|
3252
|
-
|
3253
|
-
|
3254
|
-
|
3292
|
+
for (const [ref, {
|
3293
|
+
patchId
|
3294
|
+
}] of remoteFileDescriptors) {
|
3295
|
+
var _this$options4;
|
3296
|
+
const splitRemoteRefRes = core.Internal.remote.splitRemoteRef(ref);
|
3297
|
+
if (splitRemoteRefRes.status === "error") {
|
3298
|
+
errors[ref] = {
|
3299
|
+
message: "Failed to split remote ref: " + ref
|
3300
|
+
};
|
3301
|
+
continue;
|
3302
|
+
}
|
3303
|
+
const fileBuffer = await this.getBase64EncodedBinaryFileFromPatch(splitRemoteRefRes.filePath, patchId);
|
3304
|
+
if (!fileBuffer) {
|
3305
|
+
errors[ref] = {
|
3306
|
+
message: "Failed to get binary file from patch. Ref: " + ref + ". PatchId: " + patchId
|
3307
|
+
};
|
3308
|
+
continue;
|
3309
|
+
}
|
3310
|
+
if (!((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.config.project)) {
|
3311
|
+
errors[ref] = {
|
3312
|
+
message: "No project found in config"
|
3313
|
+
};
|
3314
|
+
continue;
|
3315
|
+
}
|
3316
|
+
console.log("Uploading remote file", ref);
|
3317
|
+
const res = await uploadRemoteFile(this.contentUrl, this.options.config.project, splitRemoteRefRes.bucket, splitRemoteRefRes.fileHash, getFileExt(splitRemoteRefRes.filePath), fileBuffer, auth);
|
3318
|
+
if (!res.success) {
|
3319
|
+
console.error("Failed to upload remote file", ref, res.error);
|
3320
|
+
throw new Error(`Failed to upload remote file: ${ref}. ${res.error}`);
|
3321
|
+
}
|
3322
|
+
console.log("Completed remote file", ref);
|
3323
|
+
uploadedRemoteRefs.push(ref);
|
3255
3324
|
}
|
3256
|
-
console.log("Completed remote file", ref);
|
3257
|
-
uploadedRemoteRefs.push(ref);
|
3258
3325
|
}
|
3259
3326
|
const patchIdToPatchDirMapRes = await this.getParentPatchIdFromPatchIdMap();
|
3260
3327
|
if (fp.result.isErr(patchIdToPatchDirMapRes)) {
|
@@ -3553,9 +3620,17 @@ const GetApplicablePatches = zod.z.object({
|
|
3553
3620
|
commitSha: zod.z.string(),
|
3554
3621
|
clientCommitSha: zod.z.string(),
|
3555
3622
|
parentCommitSha: zod.z.string(),
|
3623
|
+
commitMessage: zod.z.string().nullable(),
|
3556
3624
|
branch: zod.z.string(),
|
3557
3625
|
creator: zod.z.string(),
|
3558
3626
|
createdAt: zod.z.string()
|
3627
|
+
})).optional(),
|
3628
|
+
deployments: zod.z.array(zod.z.object({
|
3629
|
+
deploymentId: zod.z.string(),
|
3630
|
+
commitSha: zod.z.string(),
|
3631
|
+
deploymentState: zod.z.string(),
|
3632
|
+
createdAt: zod.z.string(),
|
3633
|
+
updatedAt: zod.z.string()
|
3559
3634
|
})).optional()
|
3560
3635
|
});
|
3561
3636
|
const FilesResponse = zod.z.object({
|
@@ -3607,6 +3682,8 @@ const ProfilesResponse = zod.z.object({
|
|
3607
3682
|
profiles: zod.z.array(zod.z.object({
|
3608
3683
|
profileId: zod.z.string(),
|
3609
3684
|
fullName: zod.z.string(),
|
3685
|
+
email: zod.z.string().optional(),
|
3686
|
+
// TODO: make this required once this can be guaranteed
|
3610
3687
|
avatar: zod.z.object({
|
3611
3688
|
url: zod.z.string()
|
3612
3689
|
}).nullable()
|
@@ -3704,6 +3781,7 @@ class ValOpsHttp extends ValOps {
|
|
3704
3781
|
}
|
3705
3782
|
const currentBaseSha = await this.getBaseSha();
|
3706
3783
|
const currentSchemaSha = await this.getSchemaSha();
|
3784
|
+
const currentSourcesSha = await this.getSourcesSha();
|
3707
3785
|
const allPatchData = await this.fetchPatches({
|
3708
3786
|
excludePatchOps: true,
|
3709
3787
|
patchIds: undefined
|
@@ -3763,6 +3841,9 @@ class ValOpsHttp extends ValOps {
|
|
3763
3841
|
nonce,
|
3764
3842
|
baseSha: currentBaseSha,
|
3765
3843
|
schemaSha: currentSchemaSha,
|
3844
|
+
sourcesSha: currentSourcesSha,
|
3845
|
+
commits: allPatchData.commits || [],
|
3846
|
+
deployments: allPatchData.deployments || [],
|
3766
3847
|
patches,
|
3767
3848
|
commitSha: this.commitSha
|
3768
3849
|
};
|
@@ -3772,7 +3853,8 @@ class ValOpsHttp extends ValOps {
|
|
3772
3853
|
method: "POST",
|
3773
3854
|
body: JSON.stringify({
|
3774
3855
|
branch: this.branch,
|
3775
|
-
profileId
|
3856
|
+
profileId,
|
3857
|
+
commitSha: this.commitSha
|
3776
3858
|
}),
|
3777
3859
|
headers: {
|
3778
3860
|
...this.authHeaders,
|
@@ -3912,12 +3994,26 @@ class ValOpsHttp extends ValOps {
|
|
3912
3994
|
parentCommitSha: commit.parentCommitSha,
|
3913
3995
|
branch: commit.branch,
|
3914
3996
|
creator: commit.creator,
|
3915
|
-
createdAt: commit.createdAt
|
3997
|
+
createdAt: commit.createdAt,
|
3998
|
+
commitMessage: commit.commitMessage
|
3999
|
+
});
|
4000
|
+
}
|
4001
|
+
}
|
4002
|
+
const deployments = [];
|
4003
|
+
if (data.deployments) {
|
4004
|
+
for (const deployment of data.deployments) {
|
4005
|
+
deployments.push({
|
4006
|
+
commitSha: deployment.commitSha,
|
4007
|
+
deploymentId: deployment.deploymentId,
|
4008
|
+
deploymentState: deployment.deploymentState,
|
4009
|
+
createdAt: deployment.createdAt,
|
4010
|
+
updatedAt: deployment.updatedAt
|
3916
4011
|
});
|
3917
4012
|
}
|
3918
4013
|
}
|
3919
4014
|
return {
|
3920
4015
|
commits,
|
4016
|
+
deployments,
|
3921
4017
|
patches,
|
3922
4018
|
errors
|
3923
4019
|
};
|
@@ -3956,7 +4052,7 @@ class ValOpsHttp extends ValOps {
|
|
3956
4052
|
};
|
3957
4053
|
}
|
3958
4054
|
}
|
3959
|
-
async saveSourceFilePatch(path, patch, parentRef, authorId) {
|
4055
|
+
async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
|
3960
4056
|
const baseSha = await this.getBaseSha();
|
3961
4057
|
return fetch(`${this.contentUrl}/v1/${this.project}/patches`, {
|
3962
4058
|
method: "POST",
|
@@ -3968,6 +4064,7 @@ class ValOpsHttp extends ValOps {
|
|
3968
4064
|
path,
|
3969
4065
|
patch,
|
3970
4066
|
authorId,
|
4067
|
+
patchId,
|
3971
4068
|
parentPatchId: parentRef.type === "patch" ? parentRef.patchId : null,
|
3972
4069
|
baseSha,
|
3973
4070
|
commit: this.commitSha,
|
@@ -4413,7 +4510,7 @@ class ValOpsHttp extends ValOps {
|
|
4413
4510
|
}
|
4414
4511
|
}
|
4415
4512
|
|
4416
|
-
const host = process.env.VAL_CONTENT_URL ||
|
4513
|
+
const host = process.env.VAL_CONTENT_URL || core.DEFAULT_CONTENT_HOST;
|
4417
4514
|
const SettingsSchema = zod.z.object({
|
4418
4515
|
publicProjectId: zod.z.string(),
|
4419
4516
|
remoteFileBuckets: zod.z.array(zod.z.object({
|
@@ -4516,6 +4613,51 @@ function parsePersonalAccessTokenFile(content) {
|
|
4516
4613
|
}
|
4517
4614
|
}
|
4518
4615
|
|
4616
|
+
/**
|
4617
|
+
* Iterates through all schemas and find if there is 1 or more remote files in them
|
4618
|
+
*/
|
4619
|
+
function hasRemoteFileSchema(schema) {
|
4620
|
+
if (schema.type === "file" || schema.type === "image") {
|
4621
|
+
return !!schema.remote;
|
4622
|
+
} else if (schema.type === "richtext") {
|
4623
|
+
var _schema$options;
|
4624
|
+
if (typeof ((_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img) === "object") {
|
4625
|
+
return hasRemoteFileSchema(schema.options.inline.img);
|
4626
|
+
}
|
4627
|
+
return false;
|
4628
|
+
} else if (schema.type === "array" || schema.type === "record") {
|
4629
|
+
return hasRemoteFileSchema(schema.item);
|
4630
|
+
} else if (schema.type === "object") {
|
4631
|
+
for (const key in schema.items) {
|
4632
|
+
const hasRemoteFile = hasRemoteFileSchema(schema.items[key]);
|
4633
|
+
if (hasRemoteFile) {
|
4634
|
+
return true;
|
4635
|
+
}
|
4636
|
+
}
|
4637
|
+
return false;
|
4638
|
+
} else if (schema.type === "union") {
|
4639
|
+
const unionStringSchema = typeof schema.key === "object" && schema.key.type === "literal" ? schema : undefined;
|
4640
|
+
const unionObjectSchema = typeof schema.key === "string" ? schema : undefined;
|
4641
|
+
if (unionStringSchema) {
|
4642
|
+
return false;
|
4643
|
+
}
|
4644
|
+
if (unionObjectSchema) {
|
4645
|
+
for (const key in unionObjectSchema.items) {
|
4646
|
+
const hasRemoteFile = hasRemoteFileSchema(unionObjectSchema.items[key]);
|
4647
|
+
if (hasRemoteFile) {
|
4648
|
+
return true;
|
4649
|
+
}
|
4650
|
+
}
|
4651
|
+
}
|
4652
|
+
return false;
|
4653
|
+
} else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf") {
|
4654
|
+
return false;
|
4655
|
+
} else {
|
4656
|
+
const exhaustiveCheck = schema;
|
4657
|
+
throw new Error(`Unexpected schema: ${JSON.stringify(exhaustiveCheck)}`);
|
4658
|
+
}
|
4659
|
+
}
|
4660
|
+
|
4519
4661
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
4520
4662
|
const ValServer = (valModules, options, callbacks) => {
|
4521
4663
|
let serverOps;
|
@@ -4686,7 +4828,7 @@ const ValServer = (valModules, options, callbacks) => {
|
|
4686
4828
|
apiKey: options.apiKey
|
4687
4829
|
};
|
4688
4830
|
} else if (serverOps instanceof ValOpsFS) {
|
4689
|
-
const projectRootDir = options.config.root;
|
4831
|
+
const projectRootDir = options.config.root || ".";
|
4690
4832
|
if (!projectRootDir) {
|
4691
4833
|
return {
|
4692
4834
|
status: 400,
|
@@ -5040,15 +5182,59 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5040
5182
|
}
|
5041
5183
|
},
|
5042
5184
|
"/logout": {
|
5043
|
-
GET: async
|
5185
|
+
GET: async req => {
|
5186
|
+
const query = req.query;
|
5187
|
+
const redirectTo = query.redirect_to;
|
5188
|
+
if (redirectTo) {
|
5189
|
+
return {
|
5190
|
+
status: 302,
|
5191
|
+
redirectTo: redirectTo,
|
5192
|
+
cookies: {
|
5193
|
+
[internal.VAL_SESSION_COOKIE]: {
|
5194
|
+
value: "empty",
|
5195
|
+
options: {
|
5196
|
+
httpOnly: true,
|
5197
|
+
sameSite: "strict",
|
5198
|
+
path: "/",
|
5199
|
+
secure: true,
|
5200
|
+
expires: new Date(0)
|
5201
|
+
}
|
5202
|
+
},
|
5203
|
+
[internal.VAL_STATE_COOKIE]: {
|
5204
|
+
value: "empty",
|
5205
|
+
options: {
|
5206
|
+
httpOnly: true,
|
5207
|
+
sameSite: "strict",
|
5208
|
+
path: "/",
|
5209
|
+
secure: true,
|
5210
|
+
expires: new Date(0)
|
5211
|
+
}
|
5212
|
+
}
|
5213
|
+
}
|
5214
|
+
};
|
5215
|
+
}
|
5044
5216
|
return {
|
5045
5217
|
status: 200,
|
5046
5218
|
cookies: {
|
5047
5219
|
[internal.VAL_SESSION_COOKIE]: {
|
5048
|
-
value:
|
5220
|
+
value: "empty",
|
5221
|
+
options: {
|
5222
|
+
httpOnly: true,
|
5223
|
+
sameSite: "strict",
|
5224
|
+
path: "/",
|
5225
|
+
secure: true,
|
5226
|
+
expires: new Date(0)
|
5227
|
+
}
|
5049
5228
|
},
|
5050
5229
|
[internal.VAL_STATE_COOKIE]: {
|
5051
|
-
value:
|
5230
|
+
value: "empty",
|
5231
|
+
options: {
|
5232
|
+
httpOnly: true,
|
5233
|
+
sameSite: "strict",
|
5234
|
+
path: "/",
|
5235
|
+
secure: true,
|
5236
|
+
expires: new Date(0)
|
5237
|
+
}
|
5052
5238
|
}
|
5053
5239
|
}
|
5054
5240
|
};
|
@@ -5132,9 +5318,10 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5132
5318
|
}
|
5133
5319
|
};
|
5134
5320
|
}
|
5321
|
+
const profileId = "id" in auth ? auth.id : undefined;
|
5135
5322
|
const currentStat = await serverOps.getStat({
|
5136
5323
|
...req.body,
|
5137
|
-
profileId
|
5324
|
+
profileId
|
5138
5325
|
});
|
5139
5326
|
if (currentStat.type === "error" && currentStat.networkError) {
|
5140
5327
|
return {
|
@@ -5158,11 +5345,21 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5158
5345
|
json: currentStat.error
|
5159
5346
|
};
|
5160
5347
|
}
|
5348
|
+
const mode = serverOps instanceof ValOpsFS ? "fs" : serverOps instanceof ValOpsHttp ? "http" : "unknown";
|
5349
|
+
if (mode === "unknown") {
|
5350
|
+
return {
|
5351
|
+
status: 500,
|
5352
|
+
json: {
|
5353
|
+
message: "Server mode is neither fs nor http - this is an internal Val bug"
|
5354
|
+
}
|
5355
|
+
};
|
5356
|
+
}
|
5161
5357
|
return {
|
5162
5358
|
status: 200,
|
5163
5359
|
json: {
|
5164
5360
|
...currentStat,
|
5165
|
-
|
5361
|
+
profileId: profileId ?? null,
|
5362
|
+
mode,
|
5166
5363
|
config: options.config
|
5167
5364
|
}
|
5168
5365
|
};
|
@@ -5194,7 +5391,7 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5194
5391
|
const authorId = "id" in auth ? auth.id : null;
|
5195
5392
|
const newPatchIds = [];
|
5196
5393
|
for (const patch of patches) {
|
5197
|
-
const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, parentRef, authorId);
|
5394
|
+
const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, patch.patchId, parentRef, authorId);
|
5198
5395
|
if (fp.result.isErr(createPatchRes)) {
|
5199
5396
|
if (createPatchRes.error.errorType === "patch-head-conflict") {
|
5200
5397
|
return {
|
@@ -5428,6 +5625,7 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5428
5625
|
}
|
5429
5626
|
};
|
5430
5627
|
}
|
5628
|
+
const sourcesSha = await serverOps.getSourcesSha();
|
5431
5629
|
const moduleErrors = await serverOps.getModuleErrors();
|
5432
5630
|
if ((moduleErrors === null || moduleErrors === void 0 ? void 0 : moduleErrors.length) > 0) {
|
5433
5631
|
console.error("Val: Module errors", moduleErrors);
|
@@ -5488,7 +5686,9 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5488
5686
|
const modules = {};
|
5489
5687
|
for (const [moduleFilePathS, module] of Object.entries(sourcesRes.sources)) {
|
5490
5688
|
const moduleFilePath = moduleFilePathS;
|
5491
|
-
|
5689
|
+
// TODO: currently sourcesRes contains ALL MODULES.
|
5690
|
+
// We should only evaluate exactly what we need
|
5691
|
+
if (!req.path || moduleFilePath.startsWith(req.path)) {
|
5492
5692
|
var _patchAnalysis$patche, _sourcesValidation$er;
|
5493
5693
|
const skippedPatches = [];
|
5494
5694
|
const patchErrors = {};
|
@@ -5525,6 +5725,7 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5525
5725
|
status: 200,
|
5526
5726
|
json: {
|
5527
5727
|
schemaSha,
|
5728
|
+
sourcesSha,
|
5528
5729
|
modules
|
5529
5730
|
}
|
5530
5731
|
};
|
@@ -5653,33 +5854,33 @@ const ValServer = (valModules, options, callbacks) => {
|
|
5653
5854
|
};
|
5654
5855
|
}
|
5655
5856
|
if (serverOps instanceof ValOpsFS) {
|
5656
|
-
|
5657
|
-
|
5857
|
+
var _remoteFileAuthRes;
|
5858
|
+
const isRemoteRequired = getIsRemoteRequired(await serverOps.getSchemas());
|
5859
|
+
let mode;
|
5860
|
+
let remoteFileAuthRes;
|
5861
|
+
if (isRemoteRequired) {
|
5862
|
+
mode = "upload-remote";
|
5863
|
+
remoteFileAuthRes = await getRemoteFileAuth();
|
5864
|
+
} else {
|
5865
|
+
mode = "skip-remote";
|
5866
|
+
}
|
5867
|
+
if (remoteFileAuthRes && remoteFileAuthRes.status !== 200) {
|
5658
5868
|
return remoteFileAuthRes;
|
5659
5869
|
}
|
5660
|
-
const remoteFileAuth = remoteFileAuthRes.json.remoteFileAuth;
|
5661
|
-
await serverOps.
|
5662
|
-
await serverOps.
|
5870
|
+
const remoteFileAuth = (_remoteFileAuthRes = remoteFileAuthRes) === null || _remoteFileAuthRes === void 0 || (_remoteFileAuthRes = _remoteFileAuthRes.json) === null || _remoteFileAuthRes === void 0 ? void 0 : _remoteFileAuthRes.remoteFileAuth;
|
5871
|
+
const deleteRes = await serverOps.deleteAllPatches();
|
5872
|
+
await serverOps.saveOrUploadFiles(preparedCommit, mode, remoteFileAuth);
|
5873
|
+
if (deleteRes.error) {
|
5874
|
+
console.error(`Val got an error while cleaning up patches after publish: ${deleteRes.error.message}`);
|
5875
|
+
}
|
5663
5876
|
return {
|
5664
5877
|
status: 200,
|
5665
5878
|
json: {} // TODO:
|
5666
5879
|
};
|
5667
5880
|
} else if (serverOps instanceof ValOpsHttp) {
|
5668
5881
|
if (auth.error === undefined && auth.id) {
|
5669
|
-
var _options$config$
|
5670
|
-
|
5671
|
-
if (!((_options$config$ai = options.config.ai) !== null && _options$config$ai !== void 0 && (_options$config$ai = _options$config$ai.commitMessages) !== null && _options$config$ai !== void 0 && _options$config$ai.disabled)) {
|
5672
|
-
const res = await serverOps.getCommitMessage(preparedCommit);
|
5673
|
-
if (res.error) {
|
5674
|
-
// ignore
|
5675
|
-
console.error("Failed to get commit message", res.error.message);
|
5676
|
-
} else {
|
5677
|
-
message = res.commitSummary;
|
5678
|
-
}
|
5679
|
-
}
|
5680
|
-
console.log({
|
5681
|
-
message
|
5682
|
-
});
|
5882
|
+
var _options$config$files;
|
5883
|
+
const message = body.message || "Val CMS update (" + Object.keys(analysis.patchesByModule).length + " files changed)";
|
5683
5884
|
const commitRes = await serverOps.commit(preparedCommit, message, auth.id, ((_options$config$files = options.config.files) === null || _options$config$files === void 0 ? void 0 : _options$config$files.directory) || "/public/val");
|
5684
5885
|
if (commitRes.error) {
|
5685
5886
|
console.error("Failed to commit", commitRes.error);
|
@@ -6072,6 +6273,17 @@ function guessMimeTypeFromPath(filePath) {
|
|
6072
6273
|
}
|
6073
6274
|
return null;
|
6074
6275
|
}
|
6276
|
+
function getIsRemoteRequired(schemas) {
|
6277
|
+
for (const moduleFilePathS in schemas) {
|
6278
|
+
const moduleFilePath = moduleFilePathS;
|
6279
|
+
const schema = schemas[moduleFilePath].serialize();
|
6280
|
+
const isRemoteRequired = hasRemoteFileSchema(schema);
|
6281
|
+
if (isRemoteRequired) {
|
6282
|
+
return true;
|
6283
|
+
}
|
6284
|
+
}
|
6285
|
+
return false;
|
6286
|
+
}
|
6075
6287
|
|
6076
6288
|
async function createValServer(valModules, route, opts, config, callbacks, formatter) {
|
6077
6289
|
const valServerConfig = await initHandlerOptions(route, opts, config);
|
@@ -6088,7 +6300,7 @@ async function initHandlerOptions(route, opts, config) {
|
|
6088
6300
|
const valDisableRedirectUrl = opts.valDisableRedirectUrl || process.env.VAL_DISABLE_REDIRECT_URL;
|
6089
6301
|
const maybeValProject = opts.project || process.env.VAL_PROJECT;
|
6090
6302
|
const valBuildUrl = opts.valBuildUrl || process.env.VAL_BUILD_URL || "https://app.val.build";
|
6091
|
-
const valContentUrl = opts.valContentUrl || process.env.VAL_CONTENT_URL ||
|
6303
|
+
const valContentUrl = opts.valContentUrl || process.env.VAL_CONTENT_URL || core.DEFAULT_CONTENT_HOST;
|
6092
6304
|
if (isProxyMode) {
|
6093
6305
|
var _opts$versions, _opts$versions2;
|
6094
6306
|
if (!maybeApiKey || !maybeValSecret) {
|