@valbuild/server 0.74.0 → 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.
@@ -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 + schema + config */
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
- let baseSha = this.hash(JSON.stringify(this.valModules.config));
1569
- let schemaSha = baseSha;
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 || currentSchemaSha !== params.schemaSha || patches.length !== params.patches.length || patches.some((p, i) => p !== params.patches[i]);
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, auth, testMode) {
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
- for (const [ref, {
3223
- patchId
3224
- }] of remoteFileDescriptors) {
3225
- var _this$options4;
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
- continue;
3232
- }
3233
- const fileBuffer = await this.getBase64EncodedBinaryFileFromPatch(splitRemoteRefRes.filePath, patchId);
3234
- if (!fileBuffer) {
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
- console.log("Uploading remote file", ref);
3251
- const res = await uploadRemoteFile(this.contentUrl, this.options.config.project, splitRemoteRefRes.bucket, splitRemoteRefRes.fileHash, getFileExt(splitRemoteRefRes.filePath), fileBuffer, auth);
3252
- if (!res.success) {
3253
- console.error("Failed to upload remote file", ref, res.error);
3254
- throw new Error(`Failed to upload remote file: ${ref}. ${res.error}`);
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 || "https://content.val.build";
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: null
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: null
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: "id" in auth ? auth.id : undefined
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
- mode: serverOps instanceof ValOpsFS ? "fs" : serverOps instanceof ValOpsHttp ? "http" : "unknown",
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
- if (moduleFilePath.startsWith(moduleFilePath)) {
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
- const remoteFileAuthRes = await getRemoteFileAuth();
5657
- if (remoteFileAuthRes.status !== 200) {
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.saveOrUploadFiles(preparedCommit, remoteFileAuth);
5662
- await serverOps.deletePatches(patchIds);
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$ai, _options$config$files;
5670
- let message = body.message || "Update content: " + Object.keys(analysis.patchesByModule) + " modules changed";
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 || "https://content.val.build";
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) {