@prisma/compute-sdk 0.1.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.
Files changed (52) hide show
  1. package/README.md +638 -0
  2. package/dist/api-client.d.ts +181 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +193 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/archive.d.ts +11 -0
  7. package/dist/archive.d.ts.map +1 -0
  8. package/dist/archive.js +80 -0
  9. package/dist/archive.js.map +1 -0
  10. package/dist/build-strategy.d.ts +34 -0
  11. package/dist/build-strategy.d.ts.map +1 -0
  12. package/dist/build-strategy.js +33 -0
  13. package/dist/build-strategy.js.map +1 -0
  14. package/dist/bun-build.d.ts +14 -0
  15. package/dist/bun-build.d.ts.map +1 -0
  16. package/dist/bun-build.js +128 -0
  17. package/dist/bun-build.js.map +1 -0
  18. package/dist/callbacks.d.ts +44 -0
  19. package/dist/callbacks.d.ts.map +1 -0
  20. package/dist/callbacks.js +2 -0
  21. package/dist/callbacks.js.map +1 -0
  22. package/dist/compute-client.d.ts +136 -0
  23. package/dist/compute-client.d.ts.map +1 -0
  24. package/dist/compute-client.js +562 -0
  25. package/dist/compute-client.js.map +1 -0
  26. package/dist/errors.d.ts +101 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +56 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/index.d.ts +12 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +10 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/polling.d.ts +22 -0
  35. package/dist/polling.d.ts.map +1 -0
  36. package/dist/polling.js +64 -0
  37. package/dist/polling.js.map +1 -0
  38. package/dist/types.d.ts +46 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +17 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +43 -0
  43. package/src/api-client.ts +330 -0
  44. package/src/archive.ts +111 -0
  45. package/src/build-strategy.ts +66 -0
  46. package/src/bun-build.ts +184 -0
  47. package/src/callbacks.ts +50 -0
  48. package/src/compute-client.ts +985 -0
  49. package/src/errors.ts +148 -0
  50. package/src/index.ts +75 -0
  51. package/src/polling.ts +108 -0
  52. package/src/types.ts +65 -0
package/src/errors.ts ADDED
@@ -0,0 +1,148 @@
1
+ import { TaggedError } from "better-result";
2
+
3
+ export class AuthenticationError extends TaggedError("AuthenticationError")<{
4
+ statusCode: 401;
5
+ message: string;
6
+ }>() {}
7
+
8
+ export class ApiError extends TaggedError("ApiError")<{
9
+ statusCode: number;
10
+ statusText: string;
11
+ code?: string;
12
+ message: string;
13
+ hint?: string;
14
+ traceHeaders: Record<string, string>;
15
+ }>() {}
16
+
17
+ export class MissingArgumentError extends TaggedError("MissingArgumentError")<{
18
+ field: string;
19
+ message: string;
20
+ }>() {
21
+ constructor(args: { field: string }) {
22
+ super({
23
+ field: args.field,
24
+ message: `Missing required argument: ${args.field}`,
25
+ });
26
+ }
27
+ }
28
+
29
+ export class BuildError extends TaggedError("BuildError")<{
30
+ message: string;
31
+ logs?: string[];
32
+ }>() {}
33
+
34
+ export class ArtifactError extends TaggedError("ArtifactError")<{
35
+ message: string;
36
+ cause?: unknown;
37
+ }>() {}
38
+
39
+ export class TimeoutError extends TaggedError("TimeoutError")<{
40
+ versionId: string;
41
+ elapsedMs: number;
42
+ lastStatus: string;
43
+ message: string;
44
+ }>() {
45
+ constructor(args: {
46
+ versionId: string;
47
+ elapsedMs: number;
48
+ lastStatus: string;
49
+ }) {
50
+ super({
51
+ ...args,
52
+ message: `Timed out waiting for version ${args.versionId} to reach target state (last status: ${args.lastStatus}, elapsed: ${Math.round(args.elapsedMs / 1000)}s)`,
53
+ });
54
+ }
55
+ }
56
+
57
+ export class VersionFailedError extends TaggedError("VersionFailedError")<{
58
+ versionId: string;
59
+ message: string;
60
+ }>() {
61
+ constructor(args: { versionId: string }) {
62
+ super({
63
+ versionId: args.versionId,
64
+ message: `Version ${args.versionId} transitioned to failed status`,
65
+ });
66
+ }
67
+ }
68
+
69
+ export class NoExistingVersionError extends TaggedError(
70
+ "NoExistingVersionError",
71
+ )<{
72
+ serviceId: string;
73
+ message: string;
74
+ }>() {
75
+ constructor(args: { serviceId: string }) {
76
+ super({
77
+ serviceId: args.serviceId,
78
+ message: `Service ${args.serviceId} has no existing versions. Environment-only updates require at least one prior deployment.`,
79
+ });
80
+ }
81
+ }
82
+
83
+ export class CancelledError extends TaggedError("CancelledError")<{
84
+ message: string;
85
+ }>() {
86
+ constructor(args?: { message?: string }) {
87
+ super({ message: args?.message ?? "Operation cancelled" });
88
+ }
89
+ }
90
+
91
+ export class DestroyAggregateError extends TaggedError(
92
+ "DestroyAggregateError",
93
+ )<{
94
+ message: string;
95
+ succeededVersionIds: string[];
96
+ failures: Array<{ versionId: string; error: ComputeError }>;
97
+ serviceDeleted: boolean;
98
+ }>() {
99
+ constructor(args: {
100
+ succeededVersionIds: string[];
101
+ failures: Array<{ versionId: string; error: ComputeError }>;
102
+ serviceDeleted: boolean;
103
+ }) {
104
+ const failedIds = args.failures.map((f) => f.versionId).join(", ");
105
+ super({
106
+ ...args,
107
+ message: `Failed to destroy ${args.failures.length} version(s): ${failedIds}`,
108
+ });
109
+ }
110
+ }
111
+
112
+ export type ComputeError =
113
+ | AuthenticationError
114
+ | ApiError
115
+ | MissingArgumentError
116
+ | BuildError
117
+ | ArtifactError
118
+ | TimeoutError
119
+ | VersionFailedError
120
+ | NoExistingVersionError
121
+ | CancelledError
122
+ | DestroyAggregateError;
123
+
124
+ export type DeployError =
125
+ | AuthenticationError
126
+ | ApiError
127
+ | MissingArgumentError
128
+ | BuildError
129
+ | ArtifactError
130
+ | TimeoutError
131
+ | VersionFailedError
132
+ | CancelledError;
133
+
134
+ export type UpdateEnvError =
135
+ | AuthenticationError
136
+ | ApiError
137
+ | MissingArgumentError
138
+ | NoExistingVersionError
139
+ | TimeoutError
140
+ | VersionFailedError
141
+ | CancelledError;
142
+
143
+ export type DestroyError =
144
+ | AuthenticationError
145
+ | ApiError
146
+ | MissingArgumentError
147
+ | CancelledError
148
+ | DestroyAggregateError;
package/src/index.ts ADDED
@@ -0,0 +1,75 @@
1
+ // Re-export Result utilities so consumers don't need a direct better-result dependency
2
+ export {
3
+ Err,
4
+ matchError,
5
+ matchErrorPartial,
6
+ Ok,
7
+ type Result,
8
+ TaggedError,
9
+ } from "better-result";
10
+ // Build strategy
11
+ export type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
12
+ export { PreBuilt } from "./build-strategy.ts";
13
+ export { BunBuild } from "./bun-build.ts";
14
+ // Callbacks
15
+ export type {
16
+ DeployInteraction,
17
+ DeployProgress,
18
+ DestroyServiceProgress,
19
+ DestroyVersionInteraction,
20
+ DestroyVersionProgress,
21
+ UpdateEnvProgress,
22
+ } from "./callbacks.ts";
23
+ export type {
24
+ CreateServiceOptions,
25
+ DeleteServiceOptions,
26
+ DeleteVersionOptions,
27
+ DeployOptions,
28
+ DeployResult,
29
+ DestroyServiceOptions,
30
+ DestroyServiceResult,
31
+ DestroyVersionOptions,
32
+ DestroyVersionResult,
33
+ ListProjectsOptions,
34
+ ListServicesOptions,
35
+ ListVersionsOptions,
36
+ ShowServiceOptions,
37
+ ShowVersionOptions,
38
+ StartVersionOptions,
39
+ StopVersionOptions,
40
+ UpdateEnvOptions,
41
+ UpdateEnvResult,
42
+ } from "./compute-client.ts";
43
+ // Core client
44
+ export { ComputeClient } from "./compute-client.ts";
45
+ export type {
46
+ ComputeError,
47
+ DeployError,
48
+ DestroyError,
49
+ UpdateEnvError,
50
+ } from "./errors.ts";
51
+ // Errors
52
+ export {
53
+ ApiError,
54
+ ArtifactError,
55
+ AuthenticationError,
56
+ BuildError,
57
+ CancelledError,
58
+ DestroyAggregateError,
59
+ MissingArgumentError,
60
+ NoExistingVersionError,
61
+ TimeoutError,
62
+ VersionFailedError,
63
+ } from "./errors.ts";
64
+ // Domain types
65
+ export type {
66
+ PortMapping,
67
+ ProjectInfo,
68
+ RegionInfo,
69
+ ResolvedConfig,
70
+ ServiceDetail,
71
+ ServiceInfo,
72
+ VersionDetail,
73
+ VersionInfo,
74
+ } from "./types.ts";
75
+ export { KNOWN_REGION_IDS, REGIONS } from "./types.ts";
package/src/polling.ts ADDED
@@ -0,0 +1,108 @@
1
+ import { Result } from "better-result";
2
+ import type { ApiClientError, InternalApiClient } from "./api-client.ts";
3
+ import {
4
+ ApiError,
5
+ CancelledError,
6
+ TimeoutError,
7
+ VersionFailedError,
8
+ } from "./errors.ts";
9
+
10
+ export type PollOptions = {
11
+ targetStatus: "running" | "stopped";
12
+ timeoutSeconds: number;
13
+ pollIntervalMs: number;
14
+ signal?: AbortSignal;
15
+ onStatusChange?(status: string): void;
16
+ };
17
+
18
+ export type PollResult = {
19
+ previewDomain: string;
20
+ lastStatus: string;
21
+ };
22
+
23
+ export type PollError =
24
+ | CancelledError
25
+ | TimeoutError
26
+ | VersionFailedError
27
+ | ApiClientError;
28
+
29
+ /**
30
+ * Polls a compute version until it reaches the target status, fails, or times out.
31
+ *
32
+ * Returns a Result with the preview domain on success or a typed error.
33
+ */
34
+ export async function pollVersionStatus(
35
+ api: InternalApiClient,
36
+ versionId: string,
37
+ options: PollOptions,
38
+ ): Promise<Result<PollResult, PollError>> {
39
+ return Result.gen(async function* () {
40
+ const deadline = Date.now() + options.timeoutSeconds * 1_000;
41
+ let lastStatus = "";
42
+
43
+ while (Date.now() <= deadline) {
44
+ if (options.signal?.aborted) {
45
+ return Result.err(new CancelledError());
46
+ }
47
+
48
+ const version = yield* Result.await(api.getVersion(versionId));
49
+
50
+ if (version.status !== lastStatus) {
51
+ lastStatus = version.status;
52
+ options.onStatusChange?.(version.status);
53
+ }
54
+
55
+ if (version.status === options.targetStatus) {
56
+ if (options.targetStatus === "running" && !version.previewDomain) {
57
+ return Result.err(
58
+ new ApiError({
59
+ statusCode: 0,
60
+ statusText: "",
61
+ message: "Version reached running state without a previewDomain",
62
+ traceHeaders: {},
63
+ }),
64
+ );
65
+ }
66
+ return Result.ok({
67
+ previewDomain: version.previewDomain ?? "",
68
+ lastStatus: version.status,
69
+ });
70
+ }
71
+
72
+ if (version.status === "failed") {
73
+ return Result.err(new VersionFailedError({ versionId }));
74
+ }
75
+
76
+ await sleep(options.pollIntervalMs, options.signal);
77
+ }
78
+
79
+ return Result.err(
80
+ new TimeoutError({
81
+ versionId,
82
+ elapsedMs: Date.now() - (deadline - options.timeoutSeconds * 1_000),
83
+ lastStatus,
84
+ }),
85
+ );
86
+ });
87
+ }
88
+
89
+ function sleep(ms: number, signal?: AbortSignal): Promise<void> {
90
+ return new Promise((resolve) => {
91
+ if (signal?.aborted) {
92
+ resolve();
93
+ return;
94
+ }
95
+
96
+ const onAbort = () => {
97
+ clearTimeout(timer);
98
+ resolve();
99
+ };
100
+
101
+ const timer = setTimeout(() => {
102
+ signal?.removeEventListener("abort", onAbort);
103
+ resolve();
104
+ }, ms);
105
+
106
+ signal?.addEventListener("abort", onAbort, { once: true });
107
+ });
108
+ }
package/src/types.ts ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Domain types for the Compute SDK.
3
+ */
4
+
5
+ export interface PortMapping {
6
+ http?: number | null;
7
+ }
8
+
9
+ export interface ProjectInfo {
10
+ id: string;
11
+ name: string;
12
+ defaultRegion?: string;
13
+ }
14
+
15
+ export interface ServiceInfo {
16
+ id: string;
17
+ name: string;
18
+ region: string;
19
+ projectId: string;
20
+ createdAt?: string;
21
+ }
22
+
23
+ export interface ServiceDetail extends ServiceInfo {
24
+ latestVersionId?: string | null;
25
+ }
26
+
27
+ export interface VersionInfo {
28
+ id: string;
29
+ status: string;
30
+ createdAt: string;
31
+ previewDomain?: string | null;
32
+ }
33
+
34
+ export interface VersionDetail extends VersionInfo {
35
+ envVars?: Record<string, string | null>;
36
+ foundryVersionId?: string;
37
+ }
38
+
39
+ export interface RegionInfo {
40
+ id: string;
41
+ displayName: string;
42
+ }
43
+
44
+ export interface ResolvedConfig {
45
+ projectId: string;
46
+ serviceId: string;
47
+ serviceName: string;
48
+ region: string;
49
+ portMapping?: PortMapping;
50
+ }
51
+
52
+ /** Known compute region identifiers, used by the CLI for interactive prompts. */
53
+ export const KNOWN_REGION_IDS = [
54
+ "us-east-1",
55
+ "us-west-1",
56
+ "eu-west-3",
57
+ "eu-central-1",
58
+ "ap-northeast-1",
59
+ "ap-southeast-1",
60
+ ] as const;
61
+
62
+ export const REGIONS: RegionInfo[] = KNOWN_REGION_IDS.map((id) => ({
63
+ id,
64
+ displayName: id,
65
+ }));