@valbuild/server 0.94.0 → 0.95.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.
@@ -2374,8 +2374,8 @@ class ValOps {
2374
2374
  }
2375
2375
 
2376
2376
  // #region createPatch
2377
- async createPatch(path, patch, patchId, parentRef, authorId) {
2378
- const saveRes = await this.saveSourceFilePatch(path, patch, patchId, parentRef, authorId);
2377
+ async createPatch(path, patch, patchId, parentRef, sessionId, authorId) {
2378
+ const saveRes = await this.saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId);
2379
2379
  if (result.isErr(saveRes)) {
2380
2380
  console.error(`Could not save source patch at path: '${path}'. Error: ${saveRes.error.errorType === "other" ? saveRes.error.message : saveRes.error.errorType}`);
2381
2381
  if (saveRes.error.errorType === "patch-head-conflict") {
@@ -2767,11 +2767,17 @@ class ValOpsFS extends ValOps {
2767
2767
  parentPatchId: dir
2768
2768
  });
2769
2769
  } else {
2770
- if (includes && includes.length > 0 && !includes.includes(parsedPatch.data.patchId)) {
2770
+ const patchId = parsedPatch.data.patchId;
2771
+ if (includes && includes.length > 0 && !includes.includes(patchId)) {
2771
2772
  return;
2772
2773
  }
2773
- patches[parsedPatch.data.patchId] = {
2774
- ...parsedPatch.data,
2774
+ patches[patchId] = {
2775
+ path: parsedPatch.data.path,
2776
+ patch: parsedPatch.data.patch,
2777
+ parentRef: parsedPatch.data.parentRef,
2778
+ baseSha: parsedPatch.data.baseSha,
2779
+ createdAt: parsedPatch.data.createdAt,
2780
+ authorId: parsedPatch.data.authorId,
2775
2781
  appliedAt: null
2776
2782
  };
2777
2783
  }
@@ -2942,7 +2948,7 @@ class ValOpsFS extends ValOps {
2942
2948
  };
2943
2949
  }
2944
2950
  }
2945
- async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
2951
+ async saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId) {
2946
2952
  const patchDir = this.getParentPatchIdFromParentRef(parentRef);
2947
2953
  try {
2948
2954
  const baseSha = await this.getBaseSha();
@@ -2952,6 +2958,7 @@ class ValOpsFS extends ValOps {
2952
2958
  parentRef,
2953
2959
  path,
2954
2960
  authorId,
2961
+ sessionId,
2955
2962
  baseSha,
2956
2963
  coreVersion: Internal.VERSION.core,
2957
2964
  createdAt: new Date().toISOString()
@@ -3390,12 +3397,6 @@ class ValOpsFS extends ValOps {
3390
3397
  return result.ok(Object.fromEntries(Object.entries(patches.patches).map(([patchId, value]) => [patchId, this.getParentPatchIdFromParentRef(value.parentRef)])));
3391
3398
  }
3392
3399
 
3393
- // #region profiles
3394
- async getProfiles() {
3395
- // We do not have profiles in FS mode
3396
- return [];
3397
- }
3398
-
3399
3400
  // #region fs file path helpers
3400
3401
  getPatchesDir() {
3401
3402
  return path__default.join(this.rootDir, ValOpsFS.VAL_DIR, "patches");
@@ -3504,7 +3505,9 @@ const FSPatch = z.object({
3504
3505
  parentRef: ParentRef,
3505
3506
  authorId: z.string().refine(p => true).nullable(),
3506
3507
  createdAt: z.string().datetime(),
3507
- coreVersion: z.string().nullable() // TODO: use this to check if patch is compatible with current core version?
3508
+ coreVersion: z.string().nullable(),
3509
+ // TODO: use this to check if patch is compatible with current core version?
3510
+ sessionId: z.string().nullable()
3508
3511
  });
3509
3512
  const FSPatchBase = z.object({
3510
3513
  baseSha: z.string().refine(p => true),
@@ -3606,17 +3609,6 @@ const CommitResponse = z.object({
3606
3609
  commit: CommitSha,
3607
3610
  branch: z.string()
3608
3611
  });
3609
- const ProfilesResponse = z.object({
3610
- profiles: z.array(z.object({
3611
- profileId: z.string(),
3612
- fullName: z.string(),
3613
- email: z.string().optional(),
3614
- // TODO: make this required once this can be guaranteed
3615
- avatar: z.object({
3616
- url: z.string()
3617
- }).nullable()
3618
- }))
3619
- });
3620
3612
  const NonceResponse = z.object({
3621
3613
  nonce: z.string(),
3622
3614
  url: z.string()
@@ -4067,7 +4059,7 @@ class ValOpsHttp extends ValOps {
4067
4059
  };
4068
4060
  }
4069
4061
  }
4070
- async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
4062
+ async saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId) {
4071
4063
  const baseSha = await this.getBaseSha();
4072
4064
  return fetch(`${this.contentUrl}/v1/${this.project}/patches`, {
4073
4065
  method: "POST",
@@ -4079,6 +4071,7 @@ class ValOpsHttp extends ValOps {
4079
4071
  path,
4080
4072
  patch,
4081
4073
  authorId,
4074
+ sessionId,
4082
4075
  patchId,
4083
4076
  parentPatchId: parentRef.type === "patch" ? parentRef.patchId : null,
4084
4077
  baseSha,
@@ -4502,31 +4495,6 @@ class ValOpsHttp extends ValOps {
4502
4495
  };
4503
4496
  }
4504
4497
  }
4505
-
4506
- // #region profiles
4507
- async getProfiles() {
4508
- var _res$headers$get6;
4509
- const res = await fetch(`${this.contentUrl}/v1/${this.project}/profiles`, {
4510
- headers: {
4511
- ...this.authHeaders,
4512
- "Content-Type": "application/json"
4513
- }
4514
- });
4515
- if (res.ok) {
4516
- const parsed = ProfilesResponse.safeParse(await res.json());
4517
- if (parsed.error) {
4518
- console.error("Could not parse profiles response", parsed.error);
4519
- throw Error(`Could not get profiles from remote server: wrong format. You might need to upgrade Val.`);
4520
- }
4521
- return parsed.data.profiles;
4522
- }
4523
- if ((_res$headers$get6 = res.headers.get("Content-Type")) !== null && _res$headers$get6 !== void 0 && _res$headers$get6.includes("application/json")) {
4524
- const json = await res.json();
4525
- const message = getErrorMessageFromUnknownJson(json, "Unknown error");
4526
- throw Error(`Could not get profiles (status: ${res.status}): ${message}`);
4527
- }
4528
- throw Error(`Could not get profiles. Got status: ${res.status}`);
4529
- }
4530
4498
  }
4531
4499
 
4532
4500
  const host = process.env.VAL_CONTENT_URL || DEFAULT_CONTENT_HOST;
@@ -4679,6 +4647,16 @@ function hasRemoteFileSchema(schema) {
4679
4647
 
4680
4648
  /* eslint-disable @typescript-eslint/no-unused-vars */
4681
4649
  const ValServer = (valModules, options, callbacks) => {
4650
+ const ProfilesResponse = z.object({
4651
+ profiles: z.array(z.object({
4652
+ profileId: z.string(),
4653
+ fullName: z.string(),
4654
+ email: z.string().optional(),
4655
+ avatar: z.object({
4656
+ url: z.string()
4657
+ }).nullable()
4658
+ }))
4659
+ });
4682
4660
  let serverOps;
4683
4661
  if (options.mode === "fs") {
4684
4662
  serverOps = new ValOpsFS(options.valContentUrl, options.cwd, valModules, {
@@ -5528,10 +5506,11 @@ const ValServer = (valModules, options, callbacks) => {
5528
5506
  }
5529
5507
  const patches = req.body.patches;
5530
5508
  let parentRef = req.body.parentRef;
5509
+ const sessionId = req.body.sessionId ?? null;
5531
5510
  const authorId = "id" in auth ? auth.id : null;
5532
5511
  const newPatchIds = [];
5533
5512
  for (const patch of patches) {
5534
- const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, patch.patchId, parentRef, authorId);
5513
+ const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, patch.patchId, parentRef, sessionId, authorId);
5535
5514
  if (result.isErr(createPatchRes)) {
5536
5515
  if (createPatchRes.error.errorType === "patch-head-conflict") {
5537
5516
  return {
@@ -5892,13 +5871,87 @@ const ValServer = (valModules, options, callbacks) => {
5892
5871
  }
5893
5872
  };
5894
5873
  }
5895
- const profiles = await serverOps.getProfiles();
5896
- return {
5897
- status: 200,
5898
- json: {
5899
- profiles
5874
+ if (!options.project) {
5875
+ return {
5876
+ status: 500,
5877
+ json: {
5878
+ message: "Project is not configured"
5879
+ }
5880
+ };
5881
+ }
5882
+ const authDataRes = await getRemoteFileAuth();
5883
+ if (authDataRes.status !== 200) {
5884
+ if (serverOps instanceof ValOpsFS && authDataRes.json.errorCode === "pat-error") {
5885
+ return {
5886
+ status: 200,
5887
+ json: {
5888
+ profiles: []
5889
+ }
5890
+ };
5891
+ }
5892
+ return {
5893
+ status: 500,
5894
+ json: {
5895
+ message: authDataRes.json.message
5896
+ }
5897
+ };
5898
+ }
5899
+ const authData = authDataRes.json.remoteFileAuth;
5900
+ const execFetch = async headers => {
5901
+ try {
5902
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/profiles`;
5903
+ const upstreamRes = await fetch(upstreamUrl, {
5904
+ method: "GET",
5905
+ headers
5906
+ });
5907
+ if (!upstreamRes.ok) {
5908
+ const text = await upstreamRes.text();
5909
+ const isAuthError = upstreamRes.status === 401 || upstreamRes.status === 403;
5910
+ return {
5911
+ status: isAuthError ? 401 : 500,
5912
+ json: {
5913
+ message: isAuthError ? `Profile authentication failed: ${upstreamRes.status} ${text}` : `Profiles failed: ${upstreamRes.status} ${text}`
5914
+ }
5915
+ };
5916
+ }
5917
+ const parseRes = ProfilesResponse.safeParse(await upstreamRes.json());
5918
+ if (!parseRes.success) {
5919
+ return {
5920
+ status: 500,
5921
+ json: {
5922
+ message: "Could not parse profiles response: " + fromError(parseRes.error).toString()
5923
+ }
5924
+ };
5925
+ }
5926
+ return {
5927
+ status: 200,
5928
+ json: {
5929
+ profiles: parseRes.data.profiles
5930
+ }
5931
+ };
5932
+ } catch (err) {
5933
+ return {
5934
+ status: 500,
5935
+ json: {
5936
+ message: err instanceof Error ? err.message : "Profiles request failed"
5937
+ }
5938
+ };
5900
5939
  }
5901
5940
  };
5941
+ if (serverOps instanceof ValOpsFS) {
5942
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
5943
+ }
5944
+ if (!options.valSecret) {
5945
+ return {
5946
+ status: 500,
5947
+ json: {
5948
+ message: "Secret is not configured"
5949
+ }
5950
+ };
5951
+ }
5952
+ return withAuth(options.valSecret, cookies, "profiles", data => {
5953
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
5954
+ });
5902
5955
  }
5903
5956
  },
5904
5957
  "/commit-summary": {
@@ -6080,6 +6133,381 @@ const ValServer = (valModules, options, callbacks) => {
6080
6133
  }
6081
6134
  }
6082
6135
  },
6136
+ //#region ai proxy
6137
+ "/ai/initialize": {
6138
+ POST: async req => {
6139
+ const cookies = req.cookies;
6140
+ const auth = getAuth(cookies);
6141
+ if (auth.error) {
6142
+ return {
6143
+ status: 401,
6144
+ json: {
6145
+ message: auth.error
6146
+ }
6147
+ };
6148
+ }
6149
+ if (!options.project) {
6150
+ return {
6151
+ status: 500,
6152
+ json: {
6153
+ message: "Project is not configured"
6154
+ }
6155
+ };
6156
+ }
6157
+ const authDataRes = await getRemoteFileAuth();
6158
+ if (authDataRes.status !== 200) {
6159
+ return {
6160
+ status: 500,
6161
+ json: {
6162
+ message: authDataRes.json.message
6163
+ }
6164
+ };
6165
+ }
6166
+ const authData = authDataRes.json.remoteFileAuth;
6167
+ const execFetch = async headers => {
6168
+ try {
6169
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/initialize`;
6170
+ const upstreamRes = await fetch(upstreamUrl, {
6171
+ method: "POST",
6172
+ headers,
6173
+ body: JSON.stringify({})
6174
+ });
6175
+ if (!upstreamRes.ok) {
6176
+ const text = await upstreamRes.text();
6177
+ return {
6178
+ status: 500,
6179
+ json: {
6180
+ message: `AI initialize failed: ${upstreamRes.status} ${text}`
6181
+ }
6182
+ };
6183
+ }
6184
+ const json = await upstreamRes.json();
6185
+ const wsUrl = options.valContentUrl.replace(/^https:/, "wss:").replace(/^http:/, "ws:") + `/v1/${options.project}/ai/connect`;
6186
+ return {
6187
+ status: 200,
6188
+ json: {
6189
+ nonce: json.nonce,
6190
+ wsUrl
6191
+ }
6192
+ };
6193
+ } catch (err) {
6194
+ return {
6195
+ status: 500,
6196
+ json: {
6197
+ message: err instanceof Error ? err.message : "AI initialize error"
6198
+ }
6199
+ };
6200
+ }
6201
+ };
6202
+ if (serverOps instanceof ValOpsFS) {
6203
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6204
+ }
6205
+ if (!options.valSecret) {
6206
+ return {
6207
+ status: 500,
6208
+ json: {
6209
+ message: "Secret is not configured"
6210
+ }
6211
+ };
6212
+ }
6213
+ return withAuth(options.valSecret, cookies, "ai/initialize", data => {
6214
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6215
+ });
6216
+ }
6217
+ },
6218
+ "/ai/sessions": {
6219
+ GET: async req => {
6220
+ const cookies = req.cookies;
6221
+ const auth = getAuth(cookies);
6222
+ if (auth.error) {
6223
+ return {
6224
+ status: 401,
6225
+ json: {
6226
+ message: auth.error
6227
+ }
6228
+ };
6229
+ }
6230
+ if (!options.project) {
6231
+ return {
6232
+ status: 500,
6233
+ json: {
6234
+ message: "Project is not configured"
6235
+ }
6236
+ };
6237
+ }
6238
+ const authDataRes = await getRemoteFileAuth();
6239
+ if (authDataRes.status !== 200) {
6240
+ return {
6241
+ status: 500,
6242
+ json: {
6243
+ message: authDataRes.json.message
6244
+ }
6245
+ };
6246
+ }
6247
+ const authData = authDataRes.json.remoteFileAuth;
6248
+ const execFetch = async headers => {
6249
+ try {
6250
+ const SessionsResponse = z.object({
6251
+ sessions: z.array(z.object({
6252
+ id: z.string(),
6253
+ name: z.string().nullable(),
6254
+ createdAt: z.string(),
6255
+ updatedAt: z.string()
6256
+ })),
6257
+ nextCursor: z.object({
6258
+ updatedAt: z.string(),
6259
+ id: z.string()
6260
+ }).nullable().optional()
6261
+ });
6262
+ const params = new URLSearchParams();
6263
+ if (req.query.limit) params.set("limit", req.query.limit);
6264
+ if (req.query.cursor_updatedAt) {
6265
+ params.set("cursor_updatedAt", req.query.cursor_updatedAt);
6266
+ }
6267
+ if (req.query.cursor_id) {
6268
+ params.set("cursor_id", req.query.cursor_id);
6269
+ }
6270
+ const qs = params.toString();
6271
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions${qs ? `?${qs}` : ""}`;
6272
+ const upstreamRes = await fetch(upstreamUrl, {
6273
+ headers
6274
+ });
6275
+ if (!upstreamRes.ok) {
6276
+ const text = await upstreamRes.text();
6277
+ return {
6278
+ status: 500,
6279
+ json: {
6280
+ message: `AI sessions failed: ${upstreamRes.status} ${text}`
6281
+ }
6282
+ };
6283
+ }
6284
+ const json = SessionsResponse.safeParse(await upstreamRes.json());
6285
+ if (!json.success) {
6286
+ return {
6287
+ status: 500,
6288
+ json: {
6289
+ message: "Could not parse AI sessions response: " + fromError(json.error).toString()
6290
+ }
6291
+ };
6292
+ }
6293
+ return {
6294
+ status: 200,
6295
+ json: json.data
6296
+ };
6297
+ } catch (err) {
6298
+ return {
6299
+ status: 500,
6300
+ json: {
6301
+ message: err instanceof Error ? err.message : "AI sessions error"
6302
+ }
6303
+ };
6304
+ }
6305
+ };
6306
+ if (serverOps instanceof ValOpsFS) {
6307
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6308
+ }
6309
+ if (!options.valSecret) {
6310
+ return {
6311
+ status: 500,
6312
+ json: {
6313
+ message: "Secret is not configured"
6314
+ }
6315
+ };
6316
+ }
6317
+ return withAuth(options.valSecret, cookies, "ai/sessions", data => {
6318
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6319
+ });
6320
+ },
6321
+ PATCH: async req => {
6322
+ const cookies = req.cookies;
6323
+ const auth = getAuth(cookies);
6324
+ if (auth.error) {
6325
+ return {
6326
+ status: 401,
6327
+ json: {
6328
+ message: auth.error
6329
+ }
6330
+ };
6331
+ }
6332
+ if (!options.project) {
6333
+ return {
6334
+ status: 500,
6335
+ json: {
6336
+ message: "Project is not configured"
6337
+ }
6338
+ };
6339
+ }
6340
+ const pathParts = (req.path || "").split("/").filter(Boolean);
6341
+ const sessionId = pathParts[0];
6342
+ if (!sessionId) {
6343
+ return {
6344
+ status: 500,
6345
+ json: {
6346
+ message: "Missing sessionId in path"
6347
+ }
6348
+ };
6349
+ }
6350
+ const authDataRes = await getRemoteFileAuth();
6351
+ if (authDataRes.status !== 200) {
6352
+ return {
6353
+ status: 500,
6354
+ json: {
6355
+ message: authDataRes.json.message
6356
+ }
6357
+ };
6358
+ }
6359
+ const authData = authDataRes.json.remoteFileAuth;
6360
+ const execFetch = async headers => {
6361
+ try {
6362
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions/${encodeURIComponent(sessionId)}`;
6363
+ const upstreamRes = await fetch(upstreamUrl, {
6364
+ method: "PATCH",
6365
+ headers,
6366
+ body: JSON.stringify({
6367
+ name: req.body.name
6368
+ })
6369
+ });
6370
+ if (!upstreamRes.ok) {
6371
+ const text = await upstreamRes.text();
6372
+ return {
6373
+ status: 500,
6374
+ json: {
6375
+ message: `AI session rename failed: ${upstreamRes.status} ${text}`
6376
+ }
6377
+ };
6378
+ }
6379
+ return {
6380
+ status: 200,
6381
+ json: {}
6382
+ };
6383
+ } catch (err) {
6384
+ return {
6385
+ status: 500,
6386
+ json: {
6387
+ message: err instanceof Error ? err.message : "AI session rename error"
6388
+ }
6389
+ };
6390
+ }
6391
+ };
6392
+ if (serverOps instanceof ValOpsFS) {
6393
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6394
+ }
6395
+ if (!options.valSecret) {
6396
+ return {
6397
+ status: 500,
6398
+ json: {
6399
+ message: "Secret is not configured"
6400
+ }
6401
+ };
6402
+ }
6403
+ return withAuth(options.valSecret, cookies, "ai/sessions/rename", data => {
6404
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6405
+ });
6406
+ }
6407
+ },
6408
+ "/ai/messages": {
6409
+ GET: async req => {
6410
+ const cookies = req.cookies;
6411
+ const auth = getAuth(cookies);
6412
+ if (auth.error) {
6413
+ return {
6414
+ status: 401,
6415
+ json: {
6416
+ message: auth.error
6417
+ }
6418
+ };
6419
+ }
6420
+ if (!options.project) {
6421
+ return {
6422
+ status: 500,
6423
+ json: {
6424
+ message: "Project is not configured"
6425
+ }
6426
+ };
6427
+ }
6428
+ const pathParts = (req.path || "").split("/").filter(Boolean);
6429
+ const sessionId = pathParts[0];
6430
+ if (!sessionId) {
6431
+ return {
6432
+ status: 500,
6433
+ json: {
6434
+ message: "Missing sessionId in path"
6435
+ }
6436
+ };
6437
+ }
6438
+ const authDataRes = await getRemoteFileAuth();
6439
+ if (authDataRes.status !== 200) {
6440
+ return {
6441
+ status: 500,
6442
+ json: {
6443
+ message: authDataRes.json.message
6444
+ }
6445
+ };
6446
+ }
6447
+ const authData = authDataRes.json.remoteFileAuth;
6448
+ const execFetch = async headers => {
6449
+ try {
6450
+ const SessionMessagesResponse = z.object({
6451
+ messages: z.array(z.object({
6452
+ role: z.string(),
6453
+ content: z.string()
6454
+ })),
6455
+ nextCursor: z.object({
6456
+ updatedAt: z.string(),
6457
+ id: z.string()
6458
+ }).nullable().optional()
6459
+ });
6460
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions/${encodeURIComponent(sessionId)}/messages`;
6461
+ const upstreamRes = await fetch(upstreamUrl, {
6462
+ headers
6463
+ });
6464
+ if (!upstreamRes.ok) {
6465
+ const text = await upstreamRes.text();
6466
+ return {
6467
+ status: 500,
6468
+ json: {
6469
+ message: `AI session messages failed: ${upstreamRes.status} ${text}`
6470
+ }
6471
+ };
6472
+ }
6473
+ const json = SessionMessagesResponse.safeParse(await upstreamRes.json());
6474
+ if (!json.success) {
6475
+ return {
6476
+ status: 500,
6477
+ json: {
6478
+ message: "Could not parse AI session messages response: " + fromError(json.error).toString()
6479
+ }
6480
+ };
6481
+ }
6482
+ return {
6483
+ status: 200,
6484
+ json: json.data
6485
+ };
6486
+ } catch (err) {
6487
+ return {
6488
+ status: 500,
6489
+ json: {
6490
+ message: err instanceof Error ? err.message : "AI session messages error"
6491
+ }
6492
+ };
6493
+ }
6494
+ };
6495
+ if (serverOps instanceof ValOpsFS) {
6496
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6497
+ }
6498
+ if (!options.valSecret) {
6499
+ return {
6500
+ status: 500,
6501
+ json: {
6502
+ message: "Secret is not configured"
6503
+ }
6504
+ };
6505
+ }
6506
+ return withAuth(options.valSecret, cookies, "ai/sessions/messages", data => {
6507
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6508
+ });
6509
+ }
6510
+ },
6083
6511
  //#region files
6084
6512
  "/files": {
6085
6513
  GET: async req => {
@@ -6301,6 +6729,21 @@ async function withAuth(secret, cookies, errorMessageType, handler) {
6301
6729
  };
6302
6730
  }
6303
6731
  }
6732
+ function getProfileAuthHeaders(auth, data, type) {
6733
+ if ("pat" in auth) {
6734
+ return {
6735
+ "x-val-pat": auth.pat,
6736
+ "Content-Type": type
6737
+ };
6738
+ }
6739
+ if ("apiKey" in auth && data) {
6740
+ return {
6741
+ ...getAuthHeaders(auth.apiKey, type),
6742
+ "x-val-profile-id": data.sub
6743
+ };
6744
+ }
6745
+ throw new Error("Invalid auth");
6746
+ }
6304
6747
  function getAuthHeaders(token, type) {
6305
6748
  if (!type) {
6306
6749
  return {
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "./package.json": "./package.json"
17
17
  },
18
18
  "types": "dist/valbuild-server.cjs.d.ts",
19
- "version": "0.94.0",
19
+ "version": "0.95.0",
20
20
  "devDependencies": {
21
21
  "@prettier/sync": "^0.6.1",
22
22
  "@types/jest": "^30.0.0"
@@ -30,9 +30,9 @@
30
30
  "typescript": "^5.9.3",
31
31
  "zod": "^4.3.5",
32
32
  "zod-validation-error": "^5.0.0",
33
- "@valbuild/core": "0.94.0",
34
- "@valbuild/shared": "0.94.0",
35
- "@valbuild/ui": "0.94.0"
33
+ "@valbuild/core": "0.95.0",
34
+ "@valbuild/shared": "0.95.0",
35
+ "@valbuild/ui": "0.95.0"
36
36
  },
37
37
  "engines": {
38
38
  "node": ">=18.17.0"