@alchemy.run/planetscale 0.0.0 → 2.0.0-beta.84

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 (123) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +83 -4
  3. package/lib/AuthProvider.d.ts +64 -0
  4. package/lib/AuthProvider.d.ts.map +1 -0
  5. package/lib/AuthProvider.js +384 -0
  6. package/lib/AuthProvider.js.map +1 -0
  7. package/lib/Branch.d.ts +128 -0
  8. package/lib/Branch.d.ts.map +1 -0
  9. package/lib/Branch.js +420 -0
  10. package/lib/Branch.js.map +1 -0
  11. package/lib/Contributions.d.ts +7 -0
  12. package/lib/Contributions.d.ts.map +1 -0
  13. package/lib/Contributions.js +6 -0
  14. package/lib/Contributions.js.map +1 -0
  15. package/lib/Credentials.d.ts +33 -0
  16. package/lib/Credentials.d.ts.map +1 -0
  17. package/lib/Credentials.js +65 -0
  18. package/lib/Credentials.js.map +1 -0
  19. package/lib/Database.d.ts +138 -0
  20. package/lib/Database.d.ts.map +1 -0
  21. package/lib/Database.js +1 -0
  22. package/lib/Database.js.map +1 -0
  23. package/lib/MySQL/MySQLBranch.d.ts +87 -0
  24. package/lib/MySQL/MySQLBranch.d.ts.map +1 -0
  25. package/lib/MySQL/MySQLBranch.js +15 -0
  26. package/lib/MySQL/MySQLBranch.js.map +1 -0
  27. package/lib/MySQL/MySQLClusterSize.d.ts +32 -0
  28. package/lib/MySQL/MySQLClusterSize.d.ts.map +1 -0
  29. package/lib/MySQL/MySQLClusterSize.js +111 -0
  30. package/lib/MySQL/MySQLClusterSize.js.map +1 -0
  31. package/lib/MySQL/MySQLDatabase.d.ts +141 -0
  32. package/lib/MySQL/MySQLDatabase.d.ts.map +1 -0
  33. package/lib/MySQL/MySQLDatabase.js +294 -0
  34. package/lib/MySQL/MySQLDatabase.js.map +1 -0
  35. package/lib/MySQL/MySQLMigrations.d.ts +24 -0
  36. package/lib/MySQL/MySQLMigrations.d.ts.map +1 -0
  37. package/lib/MySQL/MySQLMigrations.js +106 -0
  38. package/lib/MySQL/MySQLMigrations.js.map +1 -0
  39. package/lib/MySQL/MySQLOrigin.d.ts +15 -0
  40. package/lib/MySQL/MySQLOrigin.d.ts.map +1 -0
  41. package/lib/MySQL/MySQLOrigin.js +2 -0
  42. package/lib/MySQL/MySQLOrigin.js.map +1 -0
  43. package/lib/MySQL/MySQLPassword.d.ts +116 -0
  44. package/lib/MySQL/MySQLPassword.d.ts.map +1 -0
  45. package/lib/MySQL/MySQLPassword.js +212 -0
  46. package/lib/MySQL/MySQLPassword.js.map +1 -0
  47. package/lib/MySQL/index.d.ts +6 -0
  48. package/lib/MySQL/index.d.ts.map +1 -0
  49. package/lib/MySQL/index.js +6 -0
  50. package/lib/MySQL/index.js.map +1 -0
  51. package/lib/OAuthClient.d.ts +32 -0
  52. package/lib/OAuthClient.d.ts.map +1 -0
  53. package/lib/OAuthClient.js +52 -0
  54. package/lib/OAuthClient.js.map +1 -0
  55. package/lib/Postgres/PostgresBranch.d.ts +75 -0
  56. package/lib/Postgres/PostgresBranch.d.ts.map +1 -0
  57. package/lib/Postgres/PostgresBranch.js +15 -0
  58. package/lib/Postgres/PostgresBranch.js.map +1 -0
  59. package/lib/Postgres/PostgresClusterSize.d.ts +77 -0
  60. package/lib/Postgres/PostgresClusterSize.d.ts.map +1 -0
  61. package/lib/Postgres/PostgresClusterSize.js +89 -0
  62. package/lib/Postgres/PostgresClusterSize.js.map +1 -0
  63. package/lib/Postgres/PostgresDatabase.d.ts +95 -0
  64. package/lib/Postgres/PostgresDatabase.d.ts.map +1 -0
  65. package/lib/Postgres/PostgresDatabase.js +294 -0
  66. package/lib/Postgres/PostgresDatabase.js.map +1 -0
  67. package/lib/Postgres/PostgresDefaultRole.d.ts +94 -0
  68. package/lib/Postgres/PostgresDefaultRole.d.ts.map +1 -0
  69. package/lib/Postgres/PostgresDefaultRole.js +187 -0
  70. package/lib/Postgres/PostgresDefaultRole.js.map +1 -0
  71. package/lib/Postgres/PostgresMigrations.d.ts +24 -0
  72. package/lib/Postgres/PostgresMigrations.d.ts.map +1 -0
  73. package/lib/Postgres/PostgresMigrations.js +116 -0
  74. package/lib/Postgres/PostgresMigrations.js.map +1 -0
  75. package/lib/Postgres/PostgresOrigin.d.ts +15 -0
  76. package/lib/Postgres/PostgresOrigin.d.ts.map +1 -0
  77. package/lib/Postgres/PostgresOrigin.js +2 -0
  78. package/lib/Postgres/PostgresOrigin.js.map +1 -0
  79. package/lib/Postgres/PostgresRole.d.ts +142 -0
  80. package/lib/Postgres/PostgresRole.d.ts.map +1 -0
  81. package/lib/Postgres/PostgresRole.js +268 -0
  82. package/lib/Postgres/PostgresRole.js.map +1 -0
  83. package/lib/Postgres/index.d.ts +7 -0
  84. package/lib/Postgres/index.d.ts.map +1 -0
  85. package/lib/Postgres/index.js +7 -0
  86. package/lib/Postgres/index.js.map +1 -0
  87. package/lib/Providers.d.ts +24 -0
  88. package/lib/Providers.d.ts.map +1 -0
  89. package/lib/Providers.js +40 -0
  90. package/lib/Providers.js.map +1 -0
  91. package/lib/Util.d.ts +93 -0
  92. package/lib/Util.d.ts.map +1 -0
  93. package/lib/Util.js +135 -0
  94. package/lib/Util.js.map +1 -0
  95. package/lib/index.d.ts +9 -0
  96. package/lib/index.d.ts.map +1 -0
  97. package/lib/index.js +9 -0
  98. package/lib/index.js.map +1 -0
  99. package/package.json +79 -3
  100. package/src/AuthProvider.ts +571 -0
  101. package/src/Branch.ts +657 -0
  102. package/src/Contributions.ts +9 -0
  103. package/src/Credentials.ts +116 -0
  104. package/src/Database.ts +152 -0
  105. package/src/MySQL/MySQLBranch.ts +109 -0
  106. package/src/MySQL/MySQLClusterSize.ts +185 -0
  107. package/src/MySQL/MySQLDatabase.ts +521 -0
  108. package/src/MySQL/MySQLMigrations.ts +182 -0
  109. package/src/MySQL/MySQLOrigin.ts +15 -0
  110. package/src/MySQL/MySQLPassword.ts +428 -0
  111. package/src/MySQL/index.ts +5 -0
  112. package/src/OAuthClient.ts +59 -0
  113. package/src/Postgres/PostgresBranch.ts +97 -0
  114. package/src/Postgres/PostgresClusterSize.ts +262 -0
  115. package/src/Postgres/PostgresDatabase.ts +469 -0
  116. package/src/Postgres/PostgresDefaultRole.ts +340 -0
  117. package/src/Postgres/PostgresMigrations.ts +193 -0
  118. package/src/Postgres/PostgresOrigin.ts +15 -0
  119. package/src/Postgres/PostgresRole.ts +547 -0
  120. package/src/Postgres/index.ts +6 -0
  121. package/src/Providers.ts +67 -0
  122. package/src/Util.ts +205 -0
  123. package/src/index.ts +14 -0
@@ -0,0 +1,262 @@
1
+ import * as planetscale from "@distilled.cloud/planetscale";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Schedule from "effect/Schedule";
4
+ import { pollUntil, waitForBranchReady } from "../Util.ts";
5
+
6
+ /**
7
+ * Published PlanetScale Metal SKUs for Postgres (AWS).
8
+ *
9
+ * Short display names (`"M-10"`, `"M_10"`) are **not** valid SKUs. Each
10
+ * Metal SKU encodes CPU series, compute size, provider, architecture, and
11
+ * NVMe storage size.
12
+ *
13
+ * Hyphenated SKUs copied from PlanetScale's pricing docs
14
+ * (`"M1-10-AWS-ARM-D-METAL-10"`) are accepted and normalized to
15
+ * underscores by {@link toPostgresClusterSku}. GCP and custom SKUs are
16
+ * still valid via {@link PostgresClusterSize}'s open-string fallback.
17
+ *
18
+ * @see https://planetscale.com/docs/postgres/pricing
19
+ * @see https://planetscale.com/docs/metal
20
+ */
21
+ export type PostgresMetalClusterSize =
22
+ | "M1_10_AWS_ARM_D_METAL_10"
23
+ | "M1_10_AWS_AMD_D_METAL_10"
24
+ | "M1_10_AWS_ARM_D_METAL_25"
25
+ | "M1_10_AWS_AMD_D_METAL_25"
26
+ | "M1_10_AWS_ARM_D_METAL_50"
27
+ | "M1_10_AWS_AMD_D_METAL_50"
28
+ | "M1_10_AWS_ARM_D_METAL_100"
29
+ | "M1_10_AWS_AMD_D_METAL_100"
30
+ | "M1_10_AWS_ARM_D_METAL_200"
31
+ | "M1_10_AWS_AMD_D_METAL_200"
32
+ | "M1_20_AWS_ARM_D_METAL_10"
33
+ | "M1_20_AWS_AMD_D_METAL_10"
34
+ | "M1_20_AWS_ARM_D_METAL_25"
35
+ | "M1_20_AWS_AMD_D_METAL_25"
36
+ | "M1_20_AWS_ARM_D_METAL_50"
37
+ | "M1_20_AWS_AMD_D_METAL_50"
38
+ | "M1_20_AWS_ARM_D_METAL_100"
39
+ | "M1_20_AWS_AMD_D_METAL_100"
40
+ | "M1_20_AWS_ARM_D_METAL_200"
41
+ | "M1_20_AWS_AMD_D_METAL_200"
42
+ | "M1_40_AWS_ARM_D_METAL_10"
43
+ | "M1_40_AWS_AMD_D_METAL_10"
44
+ | "M1_40_AWS_ARM_D_METAL_25"
45
+ | "M1_40_AWS_AMD_D_METAL_25"
46
+ | "M1_40_AWS_ARM_D_METAL_50"
47
+ | "M1_40_AWS_AMD_D_METAL_50"
48
+ | "M1_40_AWS_ARM_D_METAL_100"
49
+ | "M1_40_AWS_AMD_D_METAL_100"
50
+ | "M1_40_AWS_ARM_D_METAL_200"
51
+ | "M1_40_AWS_AMD_D_METAL_200"
52
+ | "M1_40_AWS_ARM_D_METAL_400"
53
+ | "M1_40_AWS_AMD_D_METAL_400"
54
+ | "M1_40_AWS_ARM_D_METAL_800"
55
+ | "M1_40_AWS_AMD_D_METAL_800"
56
+ | "M1_40_AWS_ARM_D_METAL_1200"
57
+ | "M1_40_AWS_AMD_D_METAL_1200"
58
+ | "M1_80_AWS_ARM_D_METAL_100"
59
+ | "M1_80_AWS_AMD_D_METAL_100"
60
+ | "M1_80_AWS_ARM_D_METAL_200"
61
+ | "M1_80_AWS_AMD_D_METAL_200"
62
+ | "M1_80_AWS_ARM_D_METAL_400"
63
+ | "M1_80_AWS_AMD_D_METAL_400"
64
+ | "M1_80_AWS_ARM_D_METAL_800"
65
+ | "M1_80_AWS_AMD_D_METAL_800"
66
+ | "M1_80_AWS_ARM_D_METAL_1200"
67
+ | "M1_80_AWS_AMD_D_METAL_1200"
68
+ | "M1_160_AWS_ARM_D_METAL_100"
69
+ | "M1_160_AWS_AMD_D_METAL_100"
70
+ | "M1_160_AWS_ARM_D_METAL_200"
71
+ | "M1_160_AWS_AMD_D_METAL_200"
72
+ | "M1_160_AWS_ARM_D_METAL_400"
73
+ | "M1_160_AWS_AMD_D_METAL_400"
74
+ | "M1_160_AWS_ARM_D_METAL_800"
75
+ | "M1_160_AWS_AMD_D_METAL_800"
76
+ | "M1_160_AWS_ARM_D_METAL_1200"
77
+ | "M1_160_AWS_AMD_D_METAL_1200"
78
+ | "M8_160_AWS_ARM_D_METAL_118"
79
+ | "M6_160_AWS_INTEL_D_METAL_118"
80
+ | "M7_160_AWS_INTEL_D_METAL_468"
81
+ | "M7_160_AWS_INTEL_D_METAL_1250"
82
+ | "M8_320_AWS_ARM_D_METAL_237"
83
+ | "M6_320_AWS_INTEL_D_METAL_237"
84
+ | "M7_320_AWS_INTEL_D_METAL_937"
85
+ | "M7_320_AWS_INTEL_D_METAL_2500"
86
+ | "M8_640_AWS_ARM_D_METAL_474"
87
+ | "M6_640_AWS_INTEL_D_METAL_474"
88
+ | "M7_640_AWS_INTEL_D_METAL_1875"
89
+ | "M7_640_AWS_INTEL_D_METAL_5000"
90
+ | "M7_960_AWS_INTEL_D_METAL_7500"
91
+ | "M8_1280_AWS_ARM_D_METAL_950"
92
+ | "M6_1280_AWS_INTEL_D_METAL_950"
93
+ | "M7_1280_AWS_INTEL_D_METAL_3750"
94
+ | "M7_1920_AWS_INTEL_D_METAL_15000"
95
+ | "M8_2560_AWS_ARM_D_METAL_1900"
96
+ | "M6_2560_AWS_INTEL_D_METAL_1900"
97
+ | "M7_2560_AWS_INTEL_D_METAL_7500"
98
+ | "M8_3840_AWS_ARM_D_METAL_2850"
99
+ | "M6_3840_AWS_INTEL_D_METAL_2850"
100
+ | "M7_3840_AWS_INTEL_D_METAL_11250"
101
+ | "M7_3840_AWS_INTEL_D_METAL_30000"
102
+ | "M8_5120_AWS_ARM_D_METAL_3800"
103
+ | "M6_5120_AWS_INTEL_D_METAL_3800"
104
+ | "M7_5120_AWS_INTEL_D_METAL_15000"
105
+ | "M7_5760_AWS_INTEL_D_METAL_45000"
106
+ | "M8_7680_AWS_ARM_D_METAL_5700"
107
+ | "M6_7680_AWS_INTEL_D_METAL_5700"
108
+ | "M7_7680_AWS_INTEL_D_METAL_22500"
109
+ | "M7_7680_AWS_INTEL_D_METAL_60000"
110
+ | "M6_10240_AWS_INTEL_D_METAL_7600"
111
+ | "M8_15360_AWS_ARM_D_METAL_11400"
112
+ | "M7_15360_AWS_INTEL_D_METAL_45000"
113
+ | "M7_15360_AWS_INTEL_D_METAL_120000";
114
+
115
+ /**
116
+ * Available PlanetScale PostgreSQL cluster sizes.
117
+ *
118
+ * ## Network-attached storage (NAS)
119
+ *
120
+ * `PS_*` sizes are backed by network-attached storage and can be specified
121
+ * either as the short size (`"PS_10"`) or the API SKU (`"PS_10_AWS_X86"`).
122
+ * Short NAS sizes are expanded to a SKU by {@link toPostgresClusterSku}
123
+ * using the target region and arch.
124
+ *
125
+ * ## Metal
126
+ *
127
+ * [PlanetScale Metal](https://planetscale.com/docs/metal) sizes are backed
128
+ * by locally-attached NVMe. Pass a **full Metal SKU** from
129
+ * {@link PostgresMetalClusterSize} — short `M-*` names are not valid on
130
+ * their own because Metal SKUs also encode CPU series, architecture, and
131
+ * drive size. See [Postgres pricing](https://planetscale.com/docs/postgres/pricing).
132
+ *
133
+ * @see https://planetscale.com/docs/postgres/pricing
134
+ * @see https://planetscale.com/docs/metal
135
+ */
136
+ export type PostgresClusterSize =
137
+ | "PS_DEV"
138
+ | "PS_5"
139
+ | "PS_10"
140
+ | "PS_20"
141
+ | "PS_40"
142
+ | "PS_80"
143
+ | "PS_160"
144
+ | "PS_320"
145
+ | "PS_640"
146
+ | "PS_1280"
147
+ | "PS_2560"
148
+ | PostgresMetalClusterSize
149
+ | (string & {});
150
+
151
+ /**
152
+ * Converts a {@link PostgresClusterSize} into the SKU string expected by
153
+ * the PlanetScale API.
154
+ *
155
+ * Hyphens are normalized to underscores so SKUs copied from PlanetScale
156
+ * docs (`"PS-10"`, `"M1-10-AWS-ARM-D-METAL-10"`) match the API form.
157
+ *
158
+ * For NAS-backed clusters, the API expects a suffixed name like
159
+ * `PS_<size>_<provider>_<arch>`. Short `PS_*` sizes are expanded using the
160
+ * supplied region and arch.
161
+ *
162
+ * Metal-backed sizes (anything starting with `M`) are passed through after
163
+ * hyphen normalization. The short `M_*` / `M-*` form is not a valid SKU on
164
+ * its own — the API requires the full Metal SKU (e.g.
165
+ * `M1_10_AWS_ARM_D_METAL_10`), which encodes the CPU series, provider,
166
+ * arch, and storage size.
167
+ *
168
+ * Already-suffixed NAS sizes are also passed through unchanged.
169
+ */
170
+ export function toPostgresClusterSku(input: {
171
+ size: PostgresClusterSize;
172
+ arch?: "x86" | "arm";
173
+ region?: string;
174
+ }): string {
175
+ const size = input.size.replaceAll("-", "_");
176
+ if (!size.startsWith("PS_") || size.match(/(AWS|GCP)/)) return size;
177
+ // Not all AWS regions start with "aws-", but all GCP regions start with "gcp-".
178
+ const provider = input.region?.startsWith("gcp") ? "GCP" : "AWS";
179
+ const arch = (input.arch ?? "x86").toUpperCase();
180
+ return `${size}_${provider}_${arch}`;
181
+ }
182
+
183
+ export function toPostgresClusterArch(
184
+ architecture: planetscale.DatabaseBranch["cluster_architecture"],
185
+ ): "arm" | "x86" {
186
+ return architecture === "aarch64" ? "arm" : "x86";
187
+ }
188
+
189
+ /**
190
+ * Schedule for polling branch change requests. Postgres cluster resizes
191
+ * routinely take longer than the default 10-minute polling budget, so
192
+ * give change requests a 60-minute budget (720 × 5s).
193
+ */
194
+ const changeRequestSchedule = Schedule.max([Schedule.spaced("5 seconds"), Schedule.recurs(720)]);
195
+
196
+ /**
197
+ * Polls branch change requests until all visible changes are in a terminal
198
+ * state (`completed` or `canceled`), or — if `changeId` is provided — until
199
+ * that specific change reaches a terminal state.
200
+ */
201
+ export const waitForPendingPostgresChanges = Effect.fn(function* (
202
+ organization: string,
203
+ database: string,
204
+ branch: string,
205
+ changeId?: string,
206
+ ) {
207
+ yield* pollUntil(
208
+ `changes for branch "${branch}"`,
209
+ planetscale.listBranchChangeRequests({
210
+ organization,
211
+ database,
212
+ branch,
213
+ page: 1,
214
+ per_page: 25,
215
+ }),
216
+ (page) => {
217
+ const isTerminal = (state: string) => state === "completed" || state === "canceled";
218
+
219
+ if (changeId) {
220
+ const change = page.data.find((change) => change.id === changeId);
221
+ return change ? isTerminal(change.state) : false;
222
+ }
223
+
224
+ return page.data.every((change) => isTerminal(change.state));
225
+ },
226
+ changeRequestSchedule,
227
+ );
228
+ });
229
+
230
+ /**
231
+ * Ensures a PostgreSQL production branch has the expected cluster size,
232
+ * queuing the change via the change-request API if it doesn't.
233
+ */
234
+ export const ensurePostgresProductionBranchClusterSize = Effect.fn(function* (
235
+ organization: string,
236
+ database: string,
237
+ branch: string,
238
+ expectedClusterSize: PostgresClusterSize,
239
+ ) {
240
+ // A freshly-forked branch can't accept (or complete) change requests
241
+ // until it has finished provisioning — queueing a resize against it
242
+ // just leaves the change pending until the poll budget runs out.
243
+ const data = yield* waitForBranchReady(organization, database, branch);
244
+
245
+ const sku = toPostgresClusterSku({
246
+ size: expectedClusterSize,
247
+ arch: toPostgresClusterArch(data.cluster_architecture),
248
+ region: data.region.slug,
249
+ });
250
+
251
+ if (data.cluster_name === sku) {
252
+ return;
253
+ }
254
+ yield* waitForPendingPostgresChanges(organization, database, branch);
255
+ const change = yield* planetscale.updateBranchChangeRequest({
256
+ organization,
257
+ database,
258
+ branch,
259
+ cluster_size: sku,
260
+ });
261
+ yield* waitForPendingPostgresChanges(organization, database, branch, change.id);
262
+ });