@valbuild/server 0.97.2 → 0.97.4

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,29 +1,23 @@
1
- import { QuickJSRuntime } from "quickjs-emscripten";
2
1
  import { Patch } from "@valbuild/core/patch";
3
- import { ValModuleLoader } from "./ValModuleLoader.js";
4
2
  import { ValSourceFileHandler } from "./ValSourceFileHandler.js";
5
3
  import { IValFSHost } from "./ValFSHost.js";
6
4
  import { SerializedModuleContent } from "./SerializedModuleContent.js";
7
- import { ModuleFilePath, ModulePath } from "@valbuild/core";
8
- export type ServiceOptions = {
9
- /**
10
- * Disable cache for transpilation
11
- *
12
- * @default false
13
- */
14
- disableCache?: boolean;
15
- };
16
- export declare function createService(projectRoot: string, opts: ServiceOptions, host?: IValFSHost, loader?: ValModuleLoader): Promise<Service>;
5
+ import { ModuleFilePath, ModulePath, extractValModules } from "@valbuild/core";
6
+ export declare function createService(projectRoot: string, host?: IValFSHost): Promise<Service>;
7
+ type ExtractedModules = Awaited<ReturnType<typeof extractValModules>>;
17
8
  export declare class Service {
18
9
  readonly sourceFileHandler: ValSourceFileHandler;
19
- private readonly runtime;
10
+ private readonly extracted;
20
11
  readonly projectRoot: string;
21
- constructor(projectRoot: string, sourceFileHandler: ValSourceFileHandler, runtime: QuickJSRuntime);
12
+ constructor(projectRoot: string, sourceFileHandler: ValSourceFileHandler, extracted: ExtractedModules);
13
+ /**
14
+ * The module file paths that are registered in the project's val.modules.
15
+ */
16
+ getModuleFilePaths(): ModuleFilePath[];
22
17
  get(moduleFilePath: ModuleFilePath, modulePath: ModulePath, options?: {
23
18
  validate: boolean;
24
- source: boolean;
25
- schema: boolean;
26
19
  }): Promise<SerializedModuleContent>;
27
20
  patch(moduleFilePath: ModuleFilePath, patch: Patch): Promise<void>;
28
21
  dispose(): void;
29
22
  }
23
+ export {};
@@ -0,0 +1,349 @@
1
+ import { FileMetadata, FileSource, ImageMetadata, ModuleFilePath, PatchId, RemoteSource, Schema, SelectorSource, SerializedSchema, Source, SourcePath, ValConfig, ValModules, ValidationError } from "@valbuild/core";
2
+ import { result } from "@valbuild/core/fp";
3
+ import { ParentRef, Patch, PatchError } from "@valbuild/core/patch";
4
+ import { ValSyntaxError, ValSyntaxErrorTree } from "./patch/ts/syntax.js";
5
+ import { ParentPatchId } from "@valbuild/core";
6
+ import { ValCommit, ValDeployment } from "@valbuild/shared/internal";
7
+ import { ReifiedRender } from "@valbuild/core";
8
+ export type BaseSha = string & {
9
+ readonly _tag: unique symbol;
10
+ };
11
+ export type ConfigSha = string & {
12
+ readonly _tag: unique symbol;
13
+ };
14
+ export type SourcesSha = string & {
15
+ readonly _tag: unique symbol;
16
+ };
17
+ export type SchemaSha = string & {
18
+ readonly _tag: unique symbol;
19
+ };
20
+ export type CommitSha = string & {
21
+ readonly _tag: unique symbol;
22
+ };
23
+ export type AuthorId = string & {
24
+ readonly _tag: unique symbol;
25
+ };
26
+ export type ModulesError = {
27
+ message: string;
28
+ path?: ModuleFilePath;
29
+ };
30
+ export type Schemas = {
31
+ [key: ModuleFilePath]: Schema<SelectorSource>;
32
+ };
33
+ export type Sources = {
34
+ [key: ModuleFilePath]: Source;
35
+ };
36
+ export type ValOpsOptions = {
37
+ formatter?: (code: string, filePath: string) => string | Promise<string>;
38
+ statPollingInterval?: number;
39
+ statFilePollingInterval?: number;
40
+ disableFilePolling?: boolean;
41
+ disableFileWatcher?: boolean;
42
+ config: ValConfig;
43
+ };
44
+ export declare abstract class ValOps {
45
+ private readonly valModules;
46
+ protected readonly options?: ValOpsOptions | undefined;
47
+ /** Sources from val modules, immutable (without patches or anything) */
48
+ private sources;
49
+ /** The sha256 / hash of all sources + all schemas + config */
50
+ private baseSha;
51
+ /** The sha256 / hash of all sources */
52
+ private sourcesSha;
53
+ /** The sha256 / hash of config */
54
+ private configSha;
55
+ /** Schema from val modules, immutable */
56
+ private schemas;
57
+ /** The sha256 / hash of schema + config - if this changes users needs to reload */
58
+ private schemaSha;
59
+ private modulesErrors;
60
+ constructor(valModules: ValModules, options?: ValOpsOptions | undefined);
61
+ /**
62
+ * Get the status from Val
63
+ *
64
+ * This works differently in ValOpsFS and ValOpsHttp:
65
+ * - In ValOpsFS (for dev mode) works using long-polling operations since we cannot use WebSockets in the host Next.js server and we do not want to hammer the server with requests (though we could argue that it would be ok in dev, it is not up to our standards as a kick-ass CMS).
66
+ * - In ValOpsHttp (in production) it returns a WebSocket URL so that the client can connect directly.
67
+ *
68
+ * The reason we do not use long polling in production is that Vercel (a very likely host for Next.js), bills by wall time and long polling would therefore be very expensive.
69
+ */
70
+ abstract getStat(params: {
71
+ baseSha: BaseSha;
72
+ schemaSha: SchemaSha;
73
+ patches?: PatchId[];
74
+ profileId?: AuthorId;
75
+ } | null): Promise<{
76
+ type: "request-again" | "no-change" | "did-change";
77
+ baseSha: BaseSha;
78
+ schemaSha: SchemaSha;
79
+ sourcesSha: SourcesSha;
80
+ patches: PatchId[];
81
+ } | {
82
+ type: "use-websocket";
83
+ url: string;
84
+ nonce: string;
85
+ baseSha: BaseSha;
86
+ schemaSha: SchemaSha;
87
+ commitSha: CommitSha;
88
+ sourcesSha: SourcesSha;
89
+ patches: PatchId[];
90
+ } | {
91
+ type: "error";
92
+ error: GenericErrorMessage;
93
+ unauthorized?: boolean;
94
+ networkError?: boolean;
95
+ }>;
96
+ private initSources;
97
+ init(): Promise<void>;
98
+ getBaseSources(): Promise<Sources>;
99
+ getSchemas(): Promise<Schemas>;
100
+ getSerializedSchemas(): Promise<Record<ModuleFilePath, SerializedSchema>>;
101
+ getModuleErrors(): Promise<ModulesError[]>;
102
+ getBaseSha(): Promise<BaseSha>;
103
+ getConfigSha(): Promise<ConfigSha>;
104
+ getSourcesSha(): Promise<SourcesSha>;
105
+ getSchemaSha(): Promise<SchemaSha>;
106
+ analyzePatches(sortedPatches: OrderedPatches["patches"], commits?: ValCommit[], currentCommitSha?: CommitSha): PatchAnalysis;
107
+ getRenders(schemas: Schemas, sources: Sources): Promise<{
108
+ renders: Record<ModuleFilePath, ReifiedRender | null>;
109
+ }>;
110
+ getSources(analysis?: PatchAnalysis & OrderedPatches): Promise<{
111
+ sources: Sources;
112
+ errors: Record<ModuleFilePath, {
113
+ patchId: PatchId;
114
+ skipped: boolean;
115
+ error: GenericErrorMessage;
116
+ }[]>;
117
+ }>;
118
+ /**
119
+ * Every module's source, with the pending patches applied.
120
+ *
121
+ * `getSources(analysis)` returns ONLY the modules that had patches, which is
122
+ * not enough to validate with: cross-module checks (keyOf, router routes)
123
+ * resolve against other modules' sources and report spurious errors when they
124
+ * are absent. `/sources/~` overlays the two for exactly this reason.
125
+ */
126
+ getSourcesWithPatchesApplied(analysis: PatchAnalysis & OrderedPatches): Promise<Awaited<ReturnType<ValOps["getSources"]>>>;
127
+ validateSources(schemas: Schemas, sources: Sources, patchesByModule?: PatchAnalysis["patchesByModule"]): Promise<{
128
+ errors: Record<ModuleFilePath, {
129
+ invalidSource?: {
130
+ message: string;
131
+ };
132
+ validations: Record<SourcePath, ValidationError[]>;
133
+ }>;
134
+ files: Record<SourcePath, FileSource>;
135
+ remoteFiles: Record<SourcePath, RemoteSource>;
136
+ }>;
137
+ validateRemoteFiles(schemas: Schemas, sources: Sources, remoteFiles: Record<SourcePath, RemoteSource>): Promise<Record<SourcePath, ValidationError[]>>;
138
+ validateFiles(schemas: Schemas, sources: Sources, files: Record<SourcePath, FileSource>, fileLastUpdatedByPatchId?: PatchAnalysis["fileLastUpdatedByPatchId"]): Promise<Record<SourcePath, ValidationError[]>>;
139
+ /**
140
+ * Applies the pending patches to the source files so they can be committed.
141
+ *
142
+ * @param options.continueOnError Diagnosis only. By default a patch that
143
+ * cannot be applied aborts the rest of that module's chain, which is what
144
+ * /save requires: the commit is refused and nothing is written. With this
145
+ * flag the failing patch is recorded in `unappliablePatches` and the chain
146
+ * continues on the unchanged source file, so a single run reports *every*
147
+ * unappliable patch instead of only the first one per module. The commit is
148
+ * still refused (`hasErrors` stays true) - this only makes the report
149
+ * complete.
150
+ */
151
+ prepare(patchAnalysis: PatchAnalysis & OrderedPatches, options?: {
152
+ continueOnError?: boolean;
153
+ }): Promise<PreparedCommit>;
154
+ /**
155
+ * Reads a project file as text at whatever revision this ops instance points
156
+ * at: the deployed commit in http mode, the working tree in fs mode.
157
+ *
158
+ * Public counterpart of `getSourceFile`, for the CLI's debug snapshot. The
159
+ * snapshot has to capture the exact text `prepare` patches, which in http mode
160
+ * is NOT the local working copy.
161
+ */
162
+ readProjectFile(path: string): Promise<WithGenericError<{
163
+ data: string;
164
+ }>>;
165
+ createPatch(path: ModuleFilePath, patch: Patch, patchId: PatchId, parentRef: ParentRef, sessionId: string | null, authorId: AuthorId | null): Promise<result.Result<{
166
+ error?: undefined;
167
+ patchId: PatchId;
168
+ createdAt: string;
169
+ }, {
170
+ errorType: "other";
171
+ error: GenericErrorMessage;
172
+ } | {
173
+ errorType: "patch-head-conflict";
174
+ }>>;
175
+ abstract getCommitSummary(preparedCommit: PreparedCommit): Promise<{
176
+ commitSummary: string | null;
177
+ error?: undefined;
178
+ } | {
179
+ commitSummary?: undefined;
180
+ error: GenericErrorMessage;
181
+ }>;
182
+ abstract onInit(baseSha: BaseSha, schemaSha: SchemaSha): Promise<void>;
183
+ abstract fetchPatches<ExcludePatchOps extends boolean>(filters: {
184
+ patchIds?: PatchId[];
185
+ excludePatchOps: ExcludePatchOps;
186
+ }): Promise<ExcludePatchOps extends true ? OrderedPatchesMetadata : OrderedPatches>;
187
+ protected abstract saveSourceFilePatch(path: ModuleFilePath, patch: Patch, patchId: PatchId, parentRef: ParentRef | null, authorId: AuthorId | null, sessionId: string | null): Promise<SaveSourceFilePatchResult>;
188
+ protected abstract getSourceFile(path: string): Promise<WithGenericError<{
189
+ data: string;
190
+ }>>;
191
+ abstract saveBase64EncodedBinaryFileFromPatch(filePath: string, parentRef: ParentRef, patchId: PatchId, data: string | null, type: "file" | "image", metadata: MetadataOfType<"file" | "image"> | undefined): Promise<WithGenericError<{
192
+ patchId: PatchId;
193
+ filePath: string;
194
+ }>>;
195
+ abstract getBase64EncodedBinaryFileFromPatch(filePath: string, patchId: PatchId, remote: boolean): Promise<Buffer | null>;
196
+ protected abstract getBase64EncodedBinaryFileMetadataFromPatch<T extends "file" | "image">(filePath: string, type: T, patchId: PatchId, remote: boolean): Promise<OpsMetadata<T>>;
197
+ abstract getBinaryFile(filePathOrRef: string): Promise<Buffer | null>;
198
+ protected abstract getBinaryFileMetadata<T extends "file" | "image">(filePath: string, type: T): Promise<OpsMetadata<T>>;
199
+ abstract deletePatches(patchIds: PatchId[]): Promise<{
200
+ deleted: PatchId[];
201
+ errors?: undefined;
202
+ error?: undefined;
203
+ } | {
204
+ deleted: PatchId[];
205
+ errors: Record<PatchId, GenericErrorMessage>;
206
+ } | {
207
+ error: GenericErrorMessage;
208
+ errors?: undefined;
209
+ deleted?: undefined;
210
+ }>;
211
+ }
212
+ export type WithGenericError<T extends Record<string, unknown>> = (T & {
213
+ error?: undefined;
214
+ }) | GenericError;
215
+ export type GenericError = {
216
+ error: {
217
+ message: string;
218
+ };
219
+ };
220
+ export type GenericErrorMessage = {
221
+ message: string;
222
+ details?: unknown;
223
+ };
224
+ export type SaveSourceFilePatchResult = result.Result<{
225
+ patchId: PatchId;
226
+ }, ({
227
+ errorType: "other";
228
+ } & GenericErrorMessage) | {
229
+ errorType: "patch-head-conflict";
230
+ }>;
231
+ export type PatchAnalysis = {
232
+ patchesByModule: {
233
+ [path: ModuleFilePath]: {
234
+ patchId: PatchId;
235
+ }[];
236
+ };
237
+ fileLastUpdatedByPatchId: Record<string, {
238
+ patchId: PatchId;
239
+ remote: boolean;
240
+ isDelete: boolean;
241
+ }>;
242
+ };
243
+ export type PatchSourceError = {
244
+ message: string;
245
+ filePath?: string;
246
+ } | PatchError | ValSyntaxError | ValSyntaxErrorTree;
247
+ export declare function formatPatchSourceError(error: PatchSourceError): string;
248
+ export type MetadataOfType<T extends "file" | "image"> = T extends "image" ? Omit<ImageMetadata, "hotspot"> : FileMetadata;
249
+ export type OpsMetadata<T extends "file" | "image"> = {
250
+ metadata: MetadataOfType<T>;
251
+ errors?: undefined;
252
+ } | {
253
+ errors: ((GenericErrorMessage & {
254
+ field: string;
255
+ }) | (GenericErrorMessage & {
256
+ filePath?: string;
257
+ }))[];
258
+ };
259
+ export type BinaryFileType = "file" | "image";
260
+ export type PreparedCommit = {
261
+ /**
262
+ * Updated / new source files that are ready to be committed / saved.
263
+ * A null value signals that the file at that path should be deleted.
264
+ */
265
+ patchedSourceFiles: Record<string, string | null>;
266
+ /**
267
+ * Previous source files that were patched
268
+ */
269
+ previousSourceFiles: Record<ModuleFilePath, string>;
270
+ /**
271
+ * Diagnosis only: what the source file looks like with the appliable patches
272
+ * applied, for modules that had at least one unappliable patch. Populated
273
+ * only when `prepare` is called with `continueOnError`. Never committed.
274
+ */
275
+ partiallyPatchedSourceFiles: Record<ModuleFilePath, string>;
276
+ /**
277
+ * The file path and patch id in which they appear of binary files that are ready to be committed / saved
278
+ */
279
+ patchedBinaryFilesDescriptors: Record<string, {
280
+ patchId: PatchId;
281
+ remote: boolean;
282
+ }>;
283
+ /**
284
+ * Source file patches that were successfully applied to get to this result
285
+ */
286
+ appliedPatches: Record<ModuleFilePath, PatchId[]>;
287
+ hasErrors: boolean;
288
+ sourceFilePatchErrors: Record<ModuleFilePath, PatchSourceError[]>;
289
+ binaryFilePatchErrors: Record<string, {
290
+ message: string;
291
+ }>;
292
+ /**
293
+ * The patches that could not be applied, keyed by patch id.
294
+ *
295
+ * Same information as `sourceFilePatchErrors`, but attributed to the patch
296
+ * that caused it, which is what a caller needs in order to report or remove
297
+ * it. Without `continueOnError` this holds the first failing patch of each
298
+ * module (the rest of that module's chain is never tried); with it, all of
299
+ * them.
300
+ */
301
+ unappliablePatches: Record<PatchId, {
302
+ moduleFilePath: ModuleFilePath;
303
+ message: string;
304
+ }>;
305
+ skippedPatches: Record<ModuleFilePath, PatchId[]>;
306
+ triedPatches: Record<ModuleFilePath, PatchId[]>;
307
+ };
308
+ export type PatchErrors = Record<PatchId, GenericErrorMessage>;
309
+ export type PatchReadError = {
310
+ patchId: PatchId;
311
+ message: string;
312
+ } | {
313
+ parentPatchId: ParentPatchId;
314
+ message: string;
315
+ };
316
+ export type OrderedPatches = {
317
+ patches: {
318
+ path: ModuleFilePath;
319
+ patchId: PatchId;
320
+ patch: Patch;
321
+ createdAt: string;
322
+ authorId: AuthorId | null;
323
+ baseSha: BaseSha;
324
+ appliedAt: {
325
+ commitSha: CommitSha;
326
+ } | null;
327
+ }[];
328
+ commits?: ValCommit[];
329
+ error?: GenericErrorMessage;
330
+ errors?: PatchReadError[];
331
+ unauthorized?: boolean;
332
+ networkError?: boolean;
333
+ };
334
+ export type OrderedPatchesMetadata = {
335
+ patches: (Omit<OrderedPatches["patches"][number], "patch"> & {
336
+ patch?: undefined;
337
+ })[];
338
+ commits?: ValCommit[];
339
+ deployments?: ValDeployment[];
340
+ error?: GenericErrorMessage;
341
+ errors?: OrderedPatches["errors"];
342
+ unauthorized?: boolean;
343
+ networkError?: boolean;
344
+ };
345
+ export declare function getFieldsForType<T extends BinaryFileType>(type: T): (keyof MetadataOfType<T> & string)[];
346
+ export declare function createMetadataFromBuffer<T extends BinaryFileType>(type: BinaryFileType, mimeType: string, buffer: Buffer): OpsMetadata<T>;
347
+ export declare function getMimeTypeFromBase64(content: string): string | null;
348
+ export declare function guessMimeTypeFromPath(filePath: string): string | null;
349
+ export declare function bufferFromDataUrl(dataUrl: string): Buffer | undefined;
@@ -0,0 +1,143 @@
1
+ import { PatchId, ModuleFilePath, ValModules } from "@valbuild/core";
2
+ import { AuthorId, BaseSha, BinaryFileType, GenericErrorMessage, MetadataOfType, OpsMetadata, PreparedCommit, ValOps, ValOpsOptions, WithGenericError, SaveSourceFilePatchResult, SchemaSha, CommitSha, OrderedPatches, OrderedPatchesMetadata, PatchReadError, SourcesSha } from "./ValOps.js";
3
+ import { Patch, ParentRef, ValCommit } from "@valbuild/shared/internal";
4
+ import { ParentPatchId } from "@valbuild/core";
5
+ import { Buffer } from "buffer";
6
+ export declare class ValOpsFS extends ValOps {
7
+ private readonly contentUrl;
8
+ private readonly rootDir;
9
+ private static readonly VAL_DIR;
10
+ private readonly host;
11
+ constructor(contentUrl: string, rootDir: string, valModules: ValModules, options?: ValOpsOptions);
12
+ onInit(): Promise<void>;
13
+ getPresignedAuthNonce(project: string, corsOrigin: string, auth: {
14
+ pat: string;
15
+ } | {
16
+ apiKey: string;
17
+ }): Promise<{
18
+ status: "success";
19
+ data: {
20
+ nonce: string;
21
+ baseUrl: string;
22
+ };
23
+ } | {
24
+ status: "error";
25
+ statusCode: 401 | 500;
26
+ error: GenericErrorMessage;
27
+ }>;
28
+ getCommitSummary(): Promise<{
29
+ commitSummary: string | null;
30
+ error?: undefined;
31
+ } | {
32
+ commitSummary?: undefined;
33
+ error: GenericErrorMessage;
34
+ }>;
35
+ getStat(params: {
36
+ baseSha: BaseSha;
37
+ schemaSha: SchemaSha;
38
+ sourcesSha: SourcesSha;
39
+ patches: PatchId[];
40
+ profileId?: AuthorId;
41
+ } | null): Promise<{
42
+ type: "request-again" | "no-change" | "did-change";
43
+ baseSha: BaseSha;
44
+ schemaSha: SchemaSha;
45
+ sourcesSha: SourcesSha;
46
+ patches: PatchId[];
47
+ } | {
48
+ type: "use-websocket";
49
+ url: string;
50
+ nonce: string;
51
+ baseSha: BaseSha;
52
+ schemaSha: SchemaSha;
53
+ sourcesSha: SourcesSha;
54
+ commitSha: CommitSha;
55
+ commits: ValCommit[];
56
+ patches: PatchId[];
57
+ } | {
58
+ type: "error";
59
+ error: GenericErrorMessage;
60
+ unauthorized?: boolean;
61
+ networkError?: boolean;
62
+ }>;
63
+ private readPatches;
64
+ getParentPatchIdFromParentRef(parentRef: ParentRef): ParentPatchId;
65
+ fetchPatches<ExcludePatchOps extends boolean>(filters: {
66
+ patchIds?: PatchId[];
67
+ excludePatchOps: ExcludePatchOps;
68
+ }): Promise<ExcludePatchOps extends true ? OrderedPatchesMetadata : OrderedPatches>;
69
+ fetchPatchesFromFS<ExcludePatchOps extends boolean>(excludePatchOps: ExcludePatchOps): Promise<ExcludePatchOps extends true ? FSPatchesMetadata : FSPatches>;
70
+ private createPatchChain;
71
+ private parseJsonFile;
72
+ protected saveSourceFilePatch(path: ModuleFilePath, patch: Patch, patchId: PatchId, parentRef: ParentRef, authorId: AuthorId | null, sessionId: string | null): Promise<SaveSourceFilePatchResult>;
73
+ protected getSourceFile(path: string): Promise<WithGenericError<{
74
+ data: string;
75
+ }>>;
76
+ protected saveSourceFile(path: ModuleFilePath, data: string): Promise<WithGenericError<{
77
+ path: ModuleFilePath;
78
+ }>>;
79
+ saveBase64EncodedBinaryFileFromPatch(filePath: string, parentRef: ParentRef, patchId: PatchId, data: string | null, _type: BinaryFileType, metadata: MetadataOfType<BinaryFileType> | undefined): Promise<WithGenericError<{
80
+ patchId: PatchId;
81
+ filePath: string;
82
+ }>>;
83
+ protected getBase64EncodedBinaryFileMetadataFromPatch<T extends BinaryFileType>(filePath: string, type: T, patchId: PatchId): Promise<OpsMetadata<T>>;
84
+ getBase64EncodedBinaryFileFromPatch(filePath: string, patchId: PatchId): Promise<Buffer | null>;
85
+ deletePatches(patchIds: PatchId[]): Promise<{
86
+ deleted: PatchId[];
87
+ errors?: undefined;
88
+ error?: undefined;
89
+ } | {
90
+ deleted: PatchId[];
91
+ errors: Record<PatchId, GenericErrorMessage>;
92
+ } | {
93
+ error: GenericErrorMessage;
94
+ errors?: undefined;
95
+ deleted?: undefined;
96
+ }>;
97
+ deleteAllPatches(): Promise<{
98
+ error?: GenericErrorMessage;
99
+ }>;
100
+ private updateOrderedPatches;
101
+ saveOrUploadFiles(preparedCommit: PreparedCommit, mode: "skip-remote" | "upload-remote", auth?: {
102
+ apiKey: string;
103
+ } | {
104
+ pat: string;
105
+ }): Promise<{
106
+ updatedFiles: string[];
107
+ uploadedRemoteRefs: string[];
108
+ errors: Record<string, GenericErrorMessage & {
109
+ filePath?: string;
110
+ }>;
111
+ }>;
112
+ getBinaryFile(filePath: string): Promise<Buffer | null>;
113
+ protected getBinaryFileMetadata<T extends BinaryFileType>(filePath: string, type: T): Promise<OpsMetadata<T>>;
114
+ private getParentPatchIdFromPatchId;
115
+ private getParentPatchIdFromPatchIdMap;
116
+ private getPatchesDir;
117
+ private getFullPatchDir;
118
+ private getBinaryFilePath;
119
+ private getBinaryFileMetadataPath;
120
+ private getPatchFilePath;
121
+ private getPatchBaseFile;
122
+ }
123
+ type FSPatches = {
124
+ patches: Record<PatchId, {
125
+ path: ModuleFilePath;
126
+ patch: Patch;
127
+ parentRef: ParentRef;
128
+ createdAt: string;
129
+ authorId: AuthorId | null;
130
+ baseSha: BaseSha;
131
+ appliedAt: null;
132
+ }>;
133
+ error?: GenericErrorMessage;
134
+ errors?: PatchReadError[];
135
+ };
136
+ type FSPatchesMetadata = {
137
+ patches: Record<PatchId, Omit<FSPatches["patches"][PatchId], "patch"> & {
138
+ patch?: undefined;
139
+ }>;
140
+ error?: GenericErrorMessage;
141
+ errors?: FSPatches["errors"];
142
+ };
143
+ export {};
@@ -0,0 +1,147 @@
1
+ import { type PatchId, type ModuleFilePath, ValModules } from "@valbuild/core";
2
+ import type { Patch as PatchT, ParentRef as ParentRefT } from "@valbuild/core/patch";
3
+ import { type AuthorId, type BaseSha, BinaryFileType, type CommitSha, GenericErrorMessage, MetadataOfType, OpsMetadata, PreparedCommit, ValOps, ValOpsOptions, WithGenericError, SaveSourceFilePatchResult, SchemaSha, OrderedPatchesMetadata, OrderedPatches, SourcesSha } from "./ValOps.js";
4
+ import { z } from "zod";
5
+ import { ParentRef, ValCommit, ValDeployment } from "@valbuild/shared/internal";
6
+ declare const PatchId: z.ZodString & z.ZodType<PatchId, string, z.core.$ZodTypeInternals<PatchId, string>>;
7
+ declare const CommitSha: z.ZodString & z.ZodType<CommitSha, string, z.core.$ZodTypeInternals<CommitSha, string>>;
8
+ declare const BaseSha: z.ZodString & z.ZodType<BaseSha, string, z.core.$ZodTypeInternals<BaseSha, string>>;
9
+ declare const AuthorId: z.ZodString & z.ZodType<AuthorId, string, z.core.$ZodTypeInternals<AuthorId, string>>;
10
+ declare const ModuleFilePath: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
11
+ export declare class ValOpsHttp extends ValOps {
12
+ private readonly contentUrl;
13
+ private readonly project;
14
+ private readonly commitSha;
15
+ private readonly branch;
16
+ private readonly authHeaders;
17
+ private readonly root;
18
+ constructor(contentUrl: string, project: string, commitSha: string, // TODO: CommitSha
19
+ branch: string,
20
+ /**
21
+ * An api key (how the app itself authenticates) or a personal access token
22
+ * (how the CLI authenticates after `val login`). Same two shapes as
23
+ * getSettings / uploadRemoteFile / getPresignedAuthNonce.
24
+ */
25
+ auth: {
26
+ apiKey: string;
27
+ } | {
28
+ pat: string;
29
+ }, valModules: ValModules, options?: ValOpsOptions & {
30
+ /**
31
+ * Root of project relative to repository.
32
+ * E.g. if this is a monorepo and the current app is in the /apps/my-app folder,
33
+ * the root would be /apps/my-app
34
+ */
35
+ root?: string;
36
+ });
37
+ onInit(): Promise<void>;
38
+ getPresignedAuthNonce(profileId: string, corsOrigin: string): Promise<{
39
+ status: "success";
40
+ data: {
41
+ nonce: string;
42
+ baseUrl: string;
43
+ };
44
+ } | {
45
+ status: "error";
46
+ statusCode: 401 | 500;
47
+ error: GenericErrorMessage;
48
+ }>;
49
+ getCommitSummary(preparedCommit: PreparedCommit): Promise<{
50
+ commitSummary: string | null;
51
+ error?: undefined;
52
+ } | {
53
+ commitSummary?: undefined;
54
+ error: GenericErrorMessage;
55
+ }>;
56
+ getStat(params: {
57
+ baseSha: BaseSha;
58
+ schemaSha: SchemaSha;
59
+ patches?: PatchId[];
60
+ profileId?: AuthorId;
61
+ } | null): Promise<{
62
+ type: "request-again" | "no-change";
63
+ baseSha: BaseSha;
64
+ schemaSha: SchemaSha;
65
+ sourcesSha: SourcesSha;
66
+ patches: PatchId[];
67
+ } | {
68
+ type: "use-websocket";
69
+ url: string;
70
+ nonce: string;
71
+ baseSha: BaseSha;
72
+ schemaSha: SchemaSha;
73
+ sourcesSha: SourcesSha;
74
+ commitSha: CommitSha;
75
+ commits: ValCommit[];
76
+ deployments: ValDeployment[];
77
+ patches: PatchId[];
78
+ } | {
79
+ type: "error";
80
+ error: GenericErrorMessage;
81
+ unauthorized?: boolean;
82
+ networkError?: boolean;
83
+ }>;
84
+ getWebSocketNonce(profileId: string): Promise<{
85
+ status: "success";
86
+ data: {
87
+ nonce: string;
88
+ url: string;
89
+ };
90
+ } | {
91
+ status: "error";
92
+ error: GenericErrorMessage;
93
+ }>;
94
+ fetchPatches<ExcludePatchOps extends boolean>(filters: {
95
+ patchIds?: PatchId[];
96
+ excludePatchOps: ExcludePatchOps;
97
+ }): Promise<ExcludePatchOps extends true ? OrderedPatchesMetadata : OrderedPatches>;
98
+ fetchPatchesInternal<ExcludePatchOps extends boolean>(filters: {
99
+ patchIds?: PatchId[];
100
+ excludePatchOps: ExcludePatchOps;
101
+ }): Promise<ExcludePatchOps extends true ? OrderedPatchesMetadata : OrderedPatches>;
102
+ protected saveSourceFilePatch(path: ModuleFilePath, patch: PatchT, patchId: PatchId, parentRef: ParentRefT, authorId: AuthorId | null, sessionId: string | null): Promise<SaveSourceFilePatchResult>;
103
+ /**
104
+ * @deprecated For HTTP ops use direct upload instead (i.e. client should upload the files directly) since hosting platforms (Vercel) might have low limits on the size of the request body.
105
+ */
106
+ saveBase64EncodedBinaryFileFromPatch(filePathOrRef: string, parentRef: ParentRef, patchId: PatchId, data: string | null, type: BinaryFileType, metadata: MetadataOfType<BinaryFileType> | undefined): Promise<WithGenericError<{
107
+ patchId: PatchId;
108
+ filePath: string;
109
+ }>>;
110
+ private getHttpFiles;
111
+ protected getSourceFile(path: string): Promise<WithGenericError<{
112
+ data: string;
113
+ }>>;
114
+ getBinaryFile(filePath: string): Promise<Buffer | null>;
115
+ getBase64EncodedBinaryFileFromPatch(filePath: string, patchId: PatchId, remote: boolean): Promise<Buffer | null>;
116
+ protected getBase64EncodedBinaryFileMetadataFromPatch<T extends "file" | "image">(filePath: string, type: T, patchId: PatchId, remote: boolean): Promise<OpsMetadata<T>>;
117
+ protected getBinaryFileMetadata<T extends "file" | "image">(filePath: string, type: T): Promise<OpsMetadata<T>>;
118
+ deletePatches(patchIds: PatchId[]): Promise<{
119
+ deleted: PatchId[];
120
+ errors?: undefined;
121
+ error?: undefined;
122
+ } | {
123
+ deleted: PatchId[];
124
+ errors: Record<PatchId, GenericErrorMessage>;
125
+ } | {
126
+ error: GenericErrorMessage;
127
+ errors?: undefined;
128
+ deleted?: undefined;
129
+ }>;
130
+ getCommitMessage(preparedCommit: PreparedCommit): Promise<{
131
+ commitSummary: string;
132
+ error?: undefined;
133
+ } | {
134
+ error: GenericErrorMessage;
135
+ }>;
136
+ commit(prepared: PreparedCommit, message: string, committer: AuthorId, filesDirectory: string, newBranch?: string): Promise<{
137
+ isNotFastForward?: boolean;
138
+ updatedFiles: string[];
139
+ commit: CommitSha;
140
+ branch: string;
141
+ error?: undefined;
142
+ } | {
143
+ isNotFastForward?: boolean;
144
+ error: GenericErrorMessage;
145
+ }>;
146
+ }
147
+ export {};