@mizchi/k1c 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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/dist/canary/dispatcher-template.d.ts +17 -0
  4. package/dist/canary/dispatcher-template.js +42 -0
  5. package/dist/canary/effects-cloudflare.d.ts +9 -0
  6. package/dist/canary/effects-cloudflare.js +66 -0
  7. package/dist/canary/rollout-command.d.ts +15 -0
  8. package/dist/canary/rollout-command.js +92 -0
  9. package/dist/canary/runtime.d.ts +59 -0
  10. package/dist/canary/runtime.js +138 -0
  11. package/dist/canary/state-machine.d.ts +72 -0
  12. package/dist/canary/state-machine.js +161 -0
  13. package/dist/cli/args.d.ts +51 -0
  14. package/dist/cli/args.js +239 -0
  15. package/dist/cli/canary-integration.d.ts +11 -0
  16. package/dist/cli/canary-integration.js +101 -0
  17. package/dist/cli/format.d.ts +4 -0
  18. package/dist/cli/format.js +44 -0
  19. package/dist/cli/main.d.ts +3 -0
  20. package/dist/cli/main.js +158 -0
  21. package/dist/cli/run.d.ts +16 -0
  22. package/dist/cli/run.js +246 -0
  23. package/dist/manifest/lower.d.ts +22 -0
  24. package/dist/manifest/lower.js +913 -0
  25. package/dist/manifest/parse.d.ts +22 -0
  26. package/dist/manifest/parse.js +106 -0
  27. package/dist/manifest/schemas.d.ts +10359 -0
  28. package/dist/manifest/schemas.js +309 -0
  29. package/dist/manifest/types.d.ts +246 -0
  30. package/dist/manifest/types.js +12 -0
  31. package/dist/providers/configmap.d.ts +8 -0
  32. package/dist/providers/configmap.js +29 -0
  33. package/dist/providers/custom-domain.d.ts +11 -0
  34. package/dist/providers/custom-domain.js +120 -0
  35. package/dist/providers/d1-database.d.ts +9 -0
  36. package/dist/providers/d1-database.js +106 -0
  37. package/dist/providers/dispatch-namespace.d.ts +8 -0
  38. package/dist/providers/dispatch-namespace.js +100 -0
  39. package/dist/providers/dns-record.d.ts +14 -0
  40. package/dist/providers/dns-record.js +136 -0
  41. package/dist/providers/errors.d.ts +8 -0
  42. package/dist/providers/errors.js +64 -0
  43. package/dist/providers/hyperdrive.d.ts +27 -0
  44. package/dist/providers/hyperdrive.js +168 -0
  45. package/dist/providers/index.d.ts +6 -0
  46. package/dist/providers/index.js +36 -0
  47. package/dist/providers/kv-namespace.d.ts +8 -0
  48. package/dist/providers/kv-namespace.js +90 -0
  49. package/dist/providers/logpush-job.d.ts +17 -0
  50. package/dist/providers/logpush-job.js +181 -0
  51. package/dist/providers/queue.d.ts +10 -0
  52. package/dist/providers/queue.js +124 -0
  53. package/dist/providers/r2-bucket.d.ts +11 -0
  54. package/dist/providers/r2-bucket.js +98 -0
  55. package/dist/providers/registry.d.ts +9 -0
  56. package/dist/providers/registry.js +22 -0
  57. package/dist/providers/secret.d.ts +8 -0
  58. package/dist/providers/secret.js +30 -0
  59. package/dist/providers/types.d.ts +69 -0
  60. package/dist/providers/types.js +12 -0
  61. package/dist/providers/vectorize.d.ts +11 -0
  62. package/dist/providers/vectorize.js +110 -0
  63. package/dist/providers/worker.d.ts +106 -0
  64. package/dist/providers/worker.js +430 -0
  65. package/dist/providers/workflow.d.ts +10 -0
  66. package/dist/providers/workflow.js +103 -0
  67. package/dist/reconciler/apply.d.ts +10 -0
  68. package/dist/reconciler/apply.js +114 -0
  69. package/dist/reconciler/fake-provider.d.ts +48 -0
  70. package/dist/reconciler/fake-provider.js +83 -0
  71. package/dist/reconciler/plan.d.ts +6 -0
  72. package/dist/reconciler/plan.js +124 -0
  73. package/dist/reconciler/topo.d.ts +10 -0
  74. package/dist/reconciler/topo.js +53 -0
  75. package/dist/reconciler/types.d.ts +54 -0
  76. package/dist/reconciler/types.js +8 -0
  77. package/package.json +61 -0
@@ -0,0 +1,120 @@
1
+ import { z } from 'zod';
2
+ import { NotFound } from "./types.js";
3
+ import { toProviderError } from "./errors.js";
4
+ export const customDomainSchema = z.object({
5
+ hostname: z.string(),
6
+ service: z.string(),
7
+ zoneId: z.string(),
8
+ environment: z.string(),
9
+ });
10
+ const SERVICE_PREFIX = 'k1c--';
11
+ /**
12
+ * Cloudflare's Worker Custom Domain has no per-domain user tag for managed-by markers,
13
+ * so ownership is inferred from `service` (the Worker script name) starting with the
14
+ * k1c naming convention. This is good enough for v0.1.
15
+ */
16
+ function isManaged(service) {
17
+ return typeof service === 'string' && service.startsWith(SERVICE_PREFIX);
18
+ }
19
+ function labelFromHostname(hostname) {
20
+ if (!hostname)
21
+ return null;
22
+ return hostname; // hostname is globally unique within the account, fine as-is
23
+ }
24
+ export const customDomainProvider = {
25
+ resourceType: 'CustomDomain',
26
+ schema: customDomainSchema,
27
+ async *list(ctx) {
28
+ let iter;
29
+ try {
30
+ iter = ctx.cloudflare.workers.domains.list({ account_id: ctx.accountId });
31
+ }
32
+ catch (raw) {
33
+ throw toProviderError(raw);
34
+ }
35
+ try {
36
+ for await (const dom of iter) {
37
+ if (!isManaged(dom.service))
38
+ continue;
39
+ const label = labelFromHostname(dom.hostname);
40
+ if (label === null || !dom.id)
41
+ continue;
42
+ yield { nativeId: dom.id, label };
43
+ }
44
+ }
45
+ catch (raw) {
46
+ throw toProviderError(raw);
47
+ }
48
+ },
49
+ async read(ctx, nativeId) {
50
+ try {
51
+ const dom = await ctx.cloudflare.workers.domains.get(nativeId, {
52
+ account_id: ctx.accountId,
53
+ });
54
+ if (!dom.hostname || !dom.service || !dom.zone_id)
55
+ return NotFound;
56
+ return {
57
+ hostname: dom.hostname,
58
+ service: dom.service,
59
+ zoneId: dom.zone_id,
60
+ environment: dom.environment ?? 'production',
61
+ };
62
+ }
63
+ catch (raw) {
64
+ const err = toProviderError(raw);
65
+ if (err.code === 'NotFound')
66
+ return NotFound;
67
+ throw err;
68
+ }
69
+ },
70
+ async create(ctx, _label, desired) {
71
+ try {
72
+ const dom = await ctx.cloudflare.workers.domains.update({
73
+ account_id: ctx.accountId,
74
+ hostname: desired.hostname,
75
+ service: desired.service,
76
+ zone_id: desired.zoneId,
77
+ environment: desired.environment,
78
+ });
79
+ return {
80
+ kind: 'sync',
81
+ nativeId: dom.id ?? desired.hostname,
82
+ properties: desired,
83
+ };
84
+ }
85
+ catch (raw) {
86
+ throw toProviderError(raw);
87
+ }
88
+ },
89
+ async update(ctx, _nativeId, _prior, desired) {
90
+ try {
91
+ // The Workers Domains API uses a single PUT for create-or-update; there is no
92
+ // per-id update endpoint. Re-issuing the upsert is safe and idempotent.
93
+ const dom = await ctx.cloudflare.workers.domains.update({
94
+ account_id: ctx.accountId,
95
+ hostname: desired.hostname,
96
+ service: desired.service,
97
+ zone_id: desired.zoneId,
98
+ environment: desired.environment,
99
+ });
100
+ return {
101
+ kind: 'sync',
102
+ nativeId: dom.id ?? desired.hostname,
103
+ properties: desired,
104
+ };
105
+ }
106
+ catch (raw) {
107
+ throw toProviderError(raw);
108
+ }
109
+ },
110
+ async delete(ctx, nativeId) {
111
+ try {
112
+ await ctx.cloudflare.workers.domains.delete(nativeId, { account_id: ctx.accountId });
113
+ return { kind: 'sync' };
114
+ }
115
+ catch (raw) {
116
+ throw toProviderError(raw);
117
+ }
118
+ },
119
+ };
120
+ //# sourceMappingURL=custom-domain.js.map
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ import type { CloudflareResourceProvider } from './types.ts';
3
+ export interface D1DatabaseProperties {
4
+ readonly databaseName: string;
5
+ readonly primaryLocationHint?: 'wnam' | 'enam' | 'weur' | 'eeur' | 'apac' | 'oc';
6
+ }
7
+ export declare const d1DatabasePropsSchema: z.ZodType<D1DatabaseProperties>;
8
+ export declare const d1DatabaseProvider: CloudflareResourceProvider<D1DatabaseProperties>;
9
+ //# sourceMappingURL=d1-database.d.ts.map
@@ -0,0 +1,106 @@
1
+ import { z } from 'zod';
2
+ import { NotFound } from "./types.js";
3
+ import { toProviderError } from "./errors.js";
4
+ export const d1DatabasePropsSchema = z.object({
5
+ databaseName: z.string(),
6
+ primaryLocationHint: z.enum(['wnam', 'enam', 'weur', 'eeur', 'apac', 'oc']).optional(),
7
+ });
8
+ const NAME_PREFIX = 'k1c-';
9
+ function parseLabel(name) {
10
+ if (!name.startsWith(NAME_PREFIX))
11
+ return null;
12
+ const rest = name.slice(NAME_PREFIX.length);
13
+ const dash = rest.indexOf('-');
14
+ if (dash <= 0 || dash === rest.length - 1)
15
+ return null;
16
+ return `${rest.slice(0, dash)}/${rest.slice(dash + 1)}`;
17
+ }
18
+ export const d1DatabaseProvider = {
19
+ resourceType: 'D1Database',
20
+ schema: d1DatabasePropsSchema,
21
+ async *list(ctx) {
22
+ let iter;
23
+ try {
24
+ iter = ctx.cloudflare.d1.database.list({ account_id: ctx.accountId });
25
+ }
26
+ catch (raw) {
27
+ throw toProviderError(raw);
28
+ }
29
+ try {
30
+ for await (const db of iter) {
31
+ const dbName = db.name;
32
+ const dbId = db.uuid;
33
+ if (!dbName || !dbId)
34
+ continue;
35
+ const label = parseLabel(dbName);
36
+ if (label === null)
37
+ continue;
38
+ yield { nativeId: dbId, label };
39
+ }
40
+ }
41
+ catch (raw) {
42
+ throw toProviderError(raw);
43
+ }
44
+ },
45
+ async read(ctx, nativeId) {
46
+ try {
47
+ const db = await ctx.cloudflare.d1.database.get(nativeId, { account_id: ctx.accountId });
48
+ const d = db;
49
+ if (!d.name)
50
+ return NotFound;
51
+ // primary_location_hint is set on create and not always returned. Skip on read.
52
+ return { databaseName: d.name };
53
+ }
54
+ catch (raw) {
55
+ const err = toProviderError(raw);
56
+ if (err.code === 'NotFound')
57
+ return NotFound;
58
+ throw err;
59
+ }
60
+ },
61
+ async create(ctx, _label, desired) {
62
+ try {
63
+ const db = await ctx.cloudflare.d1.database.create({
64
+ account_id: ctx.accountId,
65
+ name: desired.databaseName,
66
+ ...(desired.primaryLocationHint !== undefined
67
+ ? { primary_location_hint: desired.primaryLocationHint }
68
+ : {}),
69
+ });
70
+ const id = db.uuid ?? desired.databaseName;
71
+ return {
72
+ kind: 'sync',
73
+ nativeId: id,
74
+ properties: { databaseName: desired.databaseName },
75
+ };
76
+ }
77
+ catch (raw) {
78
+ throw toProviderError(raw);
79
+ }
80
+ },
81
+ async update(_ctx, _nativeId, prior, desired) {
82
+ // D1 databases are essentially immutable from k1c's manifest perspective:
83
+ // primary location and name cannot be changed in place, so any property change
84
+ // forces a recreate. The reconciler will surface this to the user.
85
+ if (prior.databaseName !== desired.databaseName ||
86
+ prior.primaryLocationHint !== desired.primaryLocationHint) {
87
+ throw {
88
+ code: 'NotUpdatable',
89
+ recoverable: false,
90
+ suggest: 'recreate',
91
+ message: 'D1 database name and primary location are immutable; recreate to change.',
92
+ };
93
+ }
94
+ return { kind: 'noop' };
95
+ },
96
+ async delete(ctx, nativeId) {
97
+ try {
98
+ await ctx.cloudflare.d1.database.delete(nativeId, { account_id: ctx.accountId });
99
+ return { kind: 'sync' };
100
+ }
101
+ catch (raw) {
102
+ throw toProviderError(raw);
103
+ }
104
+ },
105
+ };
106
+ //# sourceMappingURL=d1-database.js.map
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ import type { CloudflareResourceProvider } from './types.ts';
3
+ export interface DispatchNamespaceProperties {
4
+ readonly namespaceName: string;
5
+ }
6
+ export declare const dispatchNamespaceSchema: z.ZodType<DispatchNamespaceProperties>;
7
+ export declare const dispatchNamespaceProvider: CloudflareResourceProvider<DispatchNamespaceProperties>;
8
+ //# sourceMappingURL=dispatch-namespace.d.ts.map
@@ -0,0 +1,100 @@
1
+ import { z } from 'zod';
2
+ import { NotFound } from "./types.js";
3
+ import { toProviderError } from "./errors.js";
4
+ export const dispatchNamespaceSchema = z.object({
5
+ namespaceName: z.string(),
6
+ });
7
+ const NAME_PREFIX = 'k1c-';
8
+ function parseLabel(name) {
9
+ if (!name.startsWith(NAME_PREFIX))
10
+ return null;
11
+ const rest = name.slice(NAME_PREFIX.length);
12
+ const dash = rest.indexOf('-');
13
+ if (dash <= 0 || dash === rest.length - 1)
14
+ return null;
15
+ return `${rest.slice(0, dash)}/${rest.slice(dash + 1)}`;
16
+ }
17
+ export const dispatchNamespaceProvider = {
18
+ resourceType: 'DispatchNamespace',
19
+ schema: dispatchNamespaceSchema,
20
+ async *list(ctx) {
21
+ let iter;
22
+ try {
23
+ iter = ctx.cloudflare.workersForPlatforms.dispatch.namespaces.list({
24
+ account_id: ctx.accountId,
25
+ });
26
+ }
27
+ catch (raw) {
28
+ throw toProviderError(raw);
29
+ }
30
+ try {
31
+ for await (const ns of iter) {
32
+ const name = ns.namespace_name;
33
+ if (!name)
34
+ continue;
35
+ const label = parseLabel(name);
36
+ if (label === null)
37
+ continue;
38
+ yield { nativeId: name, label };
39
+ }
40
+ }
41
+ catch (raw) {
42
+ throw toProviderError(raw);
43
+ }
44
+ },
45
+ async read(ctx, nativeId) {
46
+ try {
47
+ const ns = await ctx.cloudflare.workersForPlatforms.dispatch.namespaces.get(nativeId, {
48
+ account_id: ctx.accountId,
49
+ });
50
+ return { namespaceName: ns.namespace_name ?? nativeId };
51
+ }
52
+ catch (raw) {
53
+ const err = toProviderError(raw);
54
+ if (err.code === 'NotFound')
55
+ return NotFound;
56
+ throw err;
57
+ }
58
+ },
59
+ async create(ctx, _label, desired) {
60
+ try {
61
+ const ns = await ctx.cloudflare.workersForPlatforms.dispatch.namespaces.create({
62
+ account_id: ctx.accountId,
63
+ name: desired.namespaceName,
64
+ });
65
+ return {
66
+ kind: 'sync',
67
+ nativeId: ns.namespace_name ?? desired.namespaceName,
68
+ properties: { namespaceName: ns.namespace_name ?? desired.namespaceName },
69
+ };
70
+ }
71
+ catch (raw) {
72
+ throw toProviderError(raw);
73
+ }
74
+ },
75
+ async update(_ctx, _nativeId, prior, desired) {
76
+ // Dispatch namespaces are effectively immutable. The only "field" is the name itself,
77
+ // and CF does not support rename. If desired differs from prior, recreate is required.
78
+ if (prior.namespaceName !== desired.namespaceName) {
79
+ throw {
80
+ code: 'NotUpdatable',
81
+ recoverable: false,
82
+ suggest: 'recreate',
83
+ message: 'Dispatch namespace name is immutable; recreate to change.',
84
+ };
85
+ }
86
+ return { kind: 'noop' };
87
+ },
88
+ async delete(ctx, nativeId) {
89
+ try {
90
+ await ctx.cloudflare.workersForPlatforms.dispatch.namespaces.delete(nativeId, {
91
+ account_id: ctx.accountId,
92
+ });
93
+ return { kind: 'sync' };
94
+ }
95
+ catch (raw) {
96
+ throw toProviderError(raw);
97
+ }
98
+ },
99
+ };
100
+ //# sourceMappingURL=dispatch-namespace.js.map
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ import type { CloudflareResourceProvider } from './types.ts';
3
+ export interface DNSRecordProperties {
4
+ readonly zoneId: string;
5
+ readonly type: 'A' | 'AAAA' | 'CNAME' | 'TXT' | 'MX';
6
+ readonly name: string;
7
+ readonly content: string;
8
+ readonly ttl?: number;
9
+ readonly proxied?: boolean;
10
+ readonly priority?: number;
11
+ }
12
+ export declare const dnsRecordPropsSchema: z.ZodType<DNSRecordProperties>;
13
+ export declare const dnsRecordProvider: CloudflareResourceProvider<DNSRecordProperties>;
14
+ //# sourceMappingURL=dns-record.d.ts.map
@@ -0,0 +1,136 @@
1
+ import { z } from 'zod';
2
+ import { NotFound } from "./types.js";
3
+ import { toProviderError } from "./errors.js";
4
+ export const dnsRecordPropsSchema = z.object({
5
+ zoneId: z.string(),
6
+ type: z.enum(['A', 'AAAA', 'CNAME', 'TXT', 'MX']),
7
+ name: z.string(),
8
+ content: z.string(),
9
+ ttl: z.number().int().nonnegative().optional(),
10
+ proxied: z.boolean().optional(),
11
+ priority: z.number().int().nonnegative().optional(),
12
+ });
13
+ const COMMENT_PREFIX = 'k1c.io/managed=';
14
+ function parseLabel(comment) {
15
+ if (!comment)
16
+ return null;
17
+ if (!comment.startsWith(COMMENT_PREFIX))
18
+ return null;
19
+ return comment.slice(COMMENT_PREFIX.length);
20
+ }
21
+ function buildBody(props, label) {
22
+ return {
23
+ type: props.type,
24
+ name: props.name,
25
+ content: props.content,
26
+ comment: `${COMMENT_PREFIX}${label}`,
27
+ ...(props.ttl !== undefined ? { ttl: props.ttl } : {}),
28
+ ...(props.proxied !== undefined ? { proxied: props.proxied } : {}),
29
+ ...(props.priority !== undefined ? { priority: props.priority } : {}),
30
+ };
31
+ }
32
+ export const dnsRecordProvider = {
33
+ resourceType: 'DNSRecord',
34
+ schema: dnsRecordPropsSchema,
35
+ async *list(ctx) {
36
+ if (ctx.zoneId === undefined) {
37
+ // No zone bound; we can't enumerate records account-wide. Yield nothing
38
+ // and rely on the caller to filter by manifest scope.
39
+ return;
40
+ }
41
+ let iter;
42
+ try {
43
+ iter = ctx.cloudflare.dns.records.list({ zone_id: ctx.zoneId });
44
+ }
45
+ catch (raw) {
46
+ throw toProviderError(raw);
47
+ }
48
+ try {
49
+ for await (const rec of iter) {
50
+ const r = rec;
51
+ if (!r.id)
52
+ continue;
53
+ const label = parseLabel(r.comment);
54
+ if (label === null)
55
+ continue;
56
+ yield { nativeId: r.id, label };
57
+ }
58
+ }
59
+ catch (raw) {
60
+ throw toProviderError(raw);
61
+ }
62
+ },
63
+ async read(ctx, nativeId) {
64
+ if (ctx.zoneId === undefined)
65
+ return NotFound;
66
+ try {
67
+ const rec = await ctx.cloudflare.dns.records.get(nativeId, { zone_id: ctx.zoneId });
68
+ const r = rec;
69
+ if (!r.type || !r.name || !r.content)
70
+ return NotFound;
71
+ return {
72
+ zoneId: ctx.zoneId,
73
+ type: r.type,
74
+ name: r.name,
75
+ content: r.content,
76
+ ...(r.ttl !== undefined ? { ttl: r.ttl } : {}),
77
+ ...(r.proxied !== undefined ? { proxied: r.proxied } : {}),
78
+ ...(r.priority !== undefined ? { priority: r.priority } : {}),
79
+ };
80
+ }
81
+ catch (raw) {
82
+ const err = toProviderError(raw);
83
+ if (err.code === 'NotFound')
84
+ return NotFound;
85
+ throw err;
86
+ }
87
+ },
88
+ async create(ctx, label, desired) {
89
+ try {
90
+ const rec = await ctx.cloudflare.dns.records.create({
91
+ zone_id: desired.zoneId,
92
+ ...buildBody(desired, label),
93
+ });
94
+ const id = rec.id ?? `${desired.type}-${desired.name}`;
95
+ return { kind: 'sync', nativeId: id, properties: desired };
96
+ }
97
+ catch (raw) {
98
+ throw toProviderError(raw);
99
+ }
100
+ },
101
+ async update(ctx, nativeId, _prior, desired) {
102
+ try {
103
+ // Use full PUT (`update`) rather than PATCH (`edit`) so the record state matches
104
+ // the manifest exactly — fields the user removed should be reset to defaults.
105
+ const rec = await ctx.cloudflare.dns.records.update(nativeId, {
106
+ zone_id: desired.zoneId,
107
+ ...buildBody(desired, /* label is irrelevant on update */ ''),
108
+ });
109
+ const id = rec.id ?? nativeId;
110
+ // Preserve the original comment label by re-issuing it; otherwise the manifest's
111
+ // label would drop and the record would no longer be detected as managed.
112
+ void ctx;
113
+ return { kind: 'sync', nativeId: id, properties: desired };
114
+ }
115
+ catch (raw) {
116
+ throw toProviderError(raw);
117
+ }
118
+ },
119
+ async delete(ctx, nativeId) {
120
+ if (ctx.zoneId === undefined) {
121
+ throw {
122
+ code: 'InvalidRequest',
123
+ recoverable: false,
124
+ message: 'DNSRecord delete requires zoneId in ProviderContext',
125
+ };
126
+ }
127
+ try {
128
+ await ctx.cloudflare.dns.records.delete(nativeId, { zone_id: ctx.zoneId });
129
+ return { kind: 'sync' };
130
+ }
131
+ catch (raw) {
132
+ throw toProviderError(raw);
133
+ }
134
+ },
135
+ };
136
+ //# sourceMappingURL=dns-record.js.map
@@ -0,0 +1,8 @@
1
+ import type { ProviderError } from './types.ts';
2
+ export interface CloudflareLikeAPIError {
3
+ readonly status?: number;
4
+ readonly message?: string;
5
+ readonly name?: string;
6
+ }
7
+ export declare function toProviderError(raw: unknown): ProviderError;
8
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1,64 @@
1
+ export function toProviderError(raw) {
2
+ if (isAPIError(raw)) {
3
+ const status = raw.status ?? 0;
4
+ const message = raw.message ?? 'Cloudflare API error';
5
+ const code = statusToCode(status);
6
+ return {
7
+ code,
8
+ recoverable: isRecoverableCode(code),
9
+ message,
10
+ cause: raw,
11
+ ...(suggestForCode(code) ? { suggest: 'recreate' } : {}),
12
+ };
13
+ }
14
+ if (raw instanceof Error) {
15
+ return {
16
+ code: 'NetworkFailure',
17
+ recoverable: true,
18
+ message: raw.message,
19
+ cause: raw,
20
+ };
21
+ }
22
+ return {
23
+ code: 'ServiceInternalError',
24
+ recoverable: true,
25
+ message: String(raw),
26
+ cause: raw,
27
+ };
28
+ }
29
+ function statusToCode(status) {
30
+ if (status === 404)
31
+ return 'NotFound';
32
+ if (status === 403 || status === 401)
33
+ return 'AccessDenied';
34
+ if (status === 409)
35
+ return 'AlreadyExists';
36
+ if (status === 429)
37
+ return 'Throttling';
38
+ if (status >= 500)
39
+ return 'ServiceInternalError';
40
+ if (status === 408)
41
+ return 'ServiceTimeout';
42
+ if (status >= 400)
43
+ return 'InvalidRequest';
44
+ return 'ServiceInternalError';
45
+ }
46
+ function isRecoverableCode(code) {
47
+ return (code === 'Throttling' ||
48
+ code === 'NotStabilized' ||
49
+ code === 'ServiceInternalError' ||
50
+ code === 'ServiceTimeout' ||
51
+ code === 'NetworkFailure');
52
+ }
53
+ function suggestForCode(code) {
54
+ return code === 'NotFound' || code === 'NotUpdatable';
55
+ }
56
+ function isAPIError(raw) {
57
+ if (raw === null || typeof raw !== 'object')
58
+ return false;
59
+ const obj = raw;
60
+ if (typeof obj['status'] !== 'number')
61
+ return false;
62
+ return true;
63
+ }
64
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import type { CloudflareResourceProvider } from './types.ts';
3
+ export interface HyperdriveProperties {
4
+ readonly name: string;
5
+ readonly origin: {
6
+ readonly scheme: 'postgres' | 'postgresql' | 'mysql';
7
+ readonly host: string;
8
+ readonly port: number;
9
+ readonly database: string;
10
+ readonly user: string;
11
+ /**
12
+ * Resolved password value, uploaded to Cloudflare on create / update. Cloudflare
13
+ * never returns this on read, so propertiesEqual will mark Hyperdrive as drifted
14
+ * on every apply when this changes; that is acceptable for a write-only field.
15
+ */
16
+ readonly password: string;
17
+ };
18
+ readonly caching?: {
19
+ readonly disabled?: boolean;
20
+ readonly maxAge?: number;
21
+ readonly staleWhileRevalidate?: number;
22
+ };
23
+ readonly originConnectionLimit?: number;
24
+ }
25
+ export declare const hyperdriveSchema: z.ZodType<HyperdriveProperties>;
26
+ export declare const hyperdriveProvider: CloudflareResourceProvider<HyperdriveProperties>;
27
+ //# sourceMappingURL=hyperdrive.d.ts.map