@valbuild/server 0.128.0 → 0.130.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.
@@ -1,9 +1,9 @@
1
1
  import { ValModules, PatchId, ModuleFilePath, ValConfig } from "@valbuild/core";
2
2
  import { Api, ServerOf } from "@valbuild/shared/internal";
3
3
  import { z } from "zod";
4
- import { ValOpsFS } from "./ValOpsFS.js";
5
- import { CommitSha } from "./ValOps.js";
4
+ import { AuthorId, CommitSha, ValOps, type GenericErrorMessage, type PreparedCommit } from "./ValOps.js";
6
5
  import { ValOpsHttp } from "./ValOpsHttp.js";
6
+ import { type ValPatchStore } from "./ValOpsMemory.js";
7
7
  export type ValServerOptions = {
8
8
  route: string;
9
9
  valEnableRedirectUrl?: string;
@@ -15,6 +15,72 @@ export type ValServerOptions = {
15
15
  apiKey?: string;
16
16
  project?: string;
17
17
  config: ValConfig;
18
+ /**
19
+ * Called after a save has applied its patches, with the files it produced.
20
+ *
21
+ * EXPERIMENTAL. The seam a host needs when "commit" does not mean "write to
22
+ * the working tree and let git take it from here". `patchedSourceFiles` is
23
+ * already path -> content (null = delete), which is what such a host
24
+ * publishes, so this hands over the thing that already exists rather than
25
+ * inventing a format.
26
+ *
27
+ * It runs AFTER the files are saved, not instead: the save is what makes the
28
+ * patches consumed, and a host that also wants them elsewhere is adding a
29
+ * destination, not replacing one. Throwing here fails the save.
30
+ */
31
+ commitPrepared?: (commit: {
32
+ patchedSourceFiles: Record<string, string | null>;
33
+ }) => Promise<void>;
34
+ /**
35
+ * What a publish DOES, in `http` mode.
36
+ *
37
+ * EXPERIMENTAL. By default a publish there is a git commit through the
38
+ * content API — the content service holds the patches, and publishing means
39
+ * turning them into a commit on the project's repository. A host whose
40
+ * "publish" is something else entirely (this one builds the site and flips a
41
+ * pointer) has no way to say so.
42
+ *
43
+ * The default is handed over as {@link CommitContext.commitToGit} rather than
44
+ * simply skipped, and that is the whole point: it lets a host REPLACE the
45
+ * commit (never call it) or ADD to it (call it, then do its own work with the
46
+ * files). Those are two genuinely different products — one where the
47
+ * repository is the source of truth and one where the build is — and this
48
+ * seam should not decide which.
49
+ *
50
+ * Return what the route should report. Throwing fails the publish, with the
51
+ * patches left where they were.
52
+ */
53
+ publishOverride?: (context: CommitContext) => Promise<CommitResult>;
54
+ };
55
+ /** What {@link ValServerOptions.publishOverride} is given. */
56
+ export type CommitContext = {
57
+ /** The files this commit produced: `path -> content`, `null` = delete. */
58
+ patchedSourceFiles: Record<string, string | null>;
59
+ /** Everything else the commit knows, for a host that needs more. */
60
+ preparedCommit: PreparedCommit;
61
+ message: string;
62
+ authorId: AuthorId;
63
+ /** The patch group this commit empties, if it empties one. */
64
+ patchGroupId?: string;
65
+ /**
66
+ * The default: a git commit through the content API.
67
+ *
68
+ * Call it to publish to the repository as well, or leave it alone to replace
69
+ * that step. Not calling it means the patches are NOT marked published by the
70
+ * content API, so a host that replaces the commit owns that too.
71
+ */
72
+ commitToGit: () => Promise<CommitResult>;
73
+ };
74
+ /** What a publish reports back, in either shape. */
75
+ export type CommitResult = {
76
+ isNotFastForward?: boolean;
77
+ updatedFiles: string[];
78
+ commit: CommitSha;
79
+ branch: string;
80
+ error?: undefined;
81
+ } | {
82
+ isNotFastForward?: boolean;
83
+ error: GenericErrorMessage;
18
84
  };
19
85
  export type ValServerConfig = ValServerOptions & ({
20
86
  mode: "fs";
@@ -28,6 +94,25 @@ export type ValServerConfig = ValServerOptions & ({
28
94
  branch: string;
29
95
  root?: string;
30
96
  config: ValConfig;
97
+ }
98
+ /**
99
+ * EXPERIMENTAL -- a host that holds the project's source itself.
100
+ *
101
+ * Neither of the other two fits a host that builds and publishes its own
102
+ * output: `fs` assumes a working tree it can watch and write, and `http`
103
+ * assumes Val's content service owns the patch chain and that a commit is a
104
+ * git commit. See {@link ValOpsMemory}, and `commitPrepared` above for
105
+ * where the publish goes.
106
+ */
107
+ | {
108
+ mode: "memory";
109
+ /** The project's source, by path. */
110
+ sourceFiles: Record<string, string>;
111
+ /** Where pending patches live. Defaults to memory; see ValPatchStore. */
112
+ patchStore?: ValPatchStore;
113
+ /** See ValServerOverrides. Off by default; memory mode authenticates. */
114
+ unsafelyAllowUnauthenticated?: boolean;
115
+ config: ValConfig;
31
116
  });
32
117
  export type ValServer = ServerOf<Api>;
33
118
  export declare const ValServer: (valModules: ValModules, options: ValServerConfig, callbacks: ValServerCallbacks) => ServerOf<Api>;
@@ -124,7 +209,7 @@ chain: readonly {
124
209
  * `undefined` means "apply everything", which is what every caller that does
125
210
  * not ask for scoping gets and must keep getting.
126
211
  */
127
- export declare function resolveOwnPatchScope(serverOps: ValOpsFS | ValOpsHttp, opts: {
212
+ export declare function resolveOwnPatchScope(serverOps: ValOps, opts: {
128
213
  /** A caller that named a list already knows what it wants. */
129
214
  explicitPatchIds: PatchId[] | undefined;
130
215
  ownGroupsOnly: boolean;
@@ -10,7 +10,9 @@ export declare function getSettings(projectName: string, auth: {
10
10
  pat: string;
11
11
  } | {
12
12
  apiKey: string;
13
- }): Promise<{
13
+ },
14
+ /** Overrides {@link defaultHost}. See the note there for why this exists. */
15
+ contentUrl?: string): Promise<{
14
16
  success: true;
15
17
  data: Settings;
16
18
  } | {
@@ -41,6 +41,7 @@ export type { JsonValuesEntryExtraction } from "./extractJsonValuesEntry.js";
41
41
  export type { ModulePathMap } from "./modulePathMap.js";
42
42
  export { ValOpsFS } from "./ValOpsFS.js";
43
43
  export { ValOpsHttp } from "./ValOpsHttp.js";
44
+ export { ValOpsMemory, InMemoryPatchStore, type ValPatchStore, type StoredPatch, type ValOpsMemoryOptions, } from "./ValOpsMemory.js";
44
45
  export { loadValModules, createValModuleFileInspector } from "./loadValModules.js";
45
46
  export type { ValModuleFileInspection } from "./loadValModules.js";
46
47
  export { formatPatchSourceError } from "./ValOps.js";
@@ -50,6 +51,7 @@ export type { OrderedPatches, PatchAnalysis, PatchSourceError, PreparedCommit, }
50
51
  export type { ValOps } from "./ValOps.js";
51
52
  export type { AuthorId, BinaryFileType, MetadataOfType, Schemas, Sources, } from "./ValOps.js";
52
53
  export type { ValServerConfig } from "./ValServer.js";
54
+ export type { CommitContext, CommitResult } from "./ValServer.js";
53
55
  /**
54
56
  * The local-dev patch store, exported so the CLI's debug tooling can read a
55
57
  * snapshot back with the same code the server uses rather than a second
@@ -3,6 +3,7 @@ import type { ValServerConfig } from "./ValServer.js";
3
3
  import type { ValApiOptions } from "./ValRouter.js";
4
4
  import { ValOpsFS } from "./ValOpsFS.js";
5
5
  import { ValOpsHttp } from "./ValOpsHttp.js";
6
+ import { ValOpsMemory } from "./ValOpsMemory.js";
6
7
  /**
7
8
  * Resolving how Val is configured, and building the data layer from it.
8
9
  *
@@ -54,7 +55,7 @@ export declare function initHandlerOptions(route: string, opts: ValApiOptions, c
54
55
  * can reach, including the ones the caller cannot. Callers are refused for a
55
56
  * missing credential well before this point.
56
57
  */
57
- export declare function createValOps(valModules: ValModules, options: ValServerConfig): ValOpsFS | ValOpsHttp;
58
+ export declare function createValOps(valModules: ValModules, options: ValServerConfig): ValOpsFS | ValOpsHttp | ValOpsMemory;
58
59
  /**
59
60
  * Hosts we send credentials to, and what each one puts at risk. They differ:
60
61
  * only `valBuildUrl` hands back the app token that becomes the session cookie,
@@ -114,7 +115,7 @@ export type ResolveRemoteFileAuthResult = {
114
115
  auth: RemoteFileAuth;
115
116
  } | {
116
117
  status: "error";
117
- errorCode: "project-not-configured" | "pat-error";
118
+ errorCode: "project-not-configured" | "pat-error" | "api-key-missing";
118
119
  message: string;
119
120
  };
120
121
  export declare function resolveRemoteFileAuth(options: ValServerConfig): Promise<ResolveRemoteFileAuthResult>;