@astrale-os/adapter-cloudflare 0.4.10 → 0.5.0-beta.11

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 (134) hide show
  1. package/README.md +11 -0
  2. package/dist/build/codegen/identity.d.ts.map +1 -0
  3. package/dist/build/codegen/identity.js.map +1 -0
  4. package/dist/build/codegen/merge.d.ts.map +1 -0
  5. package/dist/build/codegen/merge.js.map +1 -0
  6. package/dist/build/codegen/worker.d.ts +12 -0
  7. package/dist/build/codegen/worker.d.ts.map +1 -0
  8. package/dist/build/codegen/worker.js +40 -0
  9. package/dist/build/codegen/worker.js.map +1 -0
  10. package/dist/{codegen → build/codegen}/wrangler.d.ts +6 -3
  11. package/dist/build/codegen/wrangler.d.ts.map +1 -0
  12. package/dist/{codegen → build/codegen}/wrangler.js +29 -10
  13. package/dist/build/codegen/wrangler.js.map +1 -0
  14. package/dist/build/frontend.d.ts +26 -0
  15. package/dist/build/frontend.d.ts.map +1 -0
  16. package/dist/build/frontend.js +263 -0
  17. package/dist/build/frontend.js.map +1 -0
  18. package/dist/{build.js → build/index.d.ts} +5 -4
  19. package/dist/build/index.d.ts.map +1 -0
  20. package/dist/{build.d.ts → build/index.js} +5 -5
  21. package/dist/build/index.js.map +1 -0
  22. package/dist/{parse-output.d.ts → build/parse-output.d.ts} +2 -0
  23. package/dist/build/parse-output.d.ts.map +1 -0
  24. package/dist/{parse-output.js → build/parse-output.js} +5 -0
  25. package/dist/build/parse-output.js.map +1 -0
  26. package/dist/build/prepare.d.ts +18 -0
  27. package/dist/build/prepare.d.ts.map +1 -0
  28. package/dist/build/prepare.js +117 -0
  29. package/dist/build/prepare.js.map +1 -0
  30. package/dist/build/worker.d.ts +15 -0
  31. package/dist/build/worker.d.ts.map +1 -0
  32. package/dist/build/worker.js +21 -0
  33. package/dist/build/worker.js.map +1 -0
  34. package/dist/{wrangler-cli.d.ts → build/wrangler-cli.d.ts} +10 -0
  35. package/dist/build/wrangler-cli.d.ts.map +1 -0
  36. package/dist/{wrangler-cli.js → build/wrangler-cli.js} +38 -6
  37. package/dist/build/wrangler-cli.js.map +1 -0
  38. package/dist/cloudflare.d.ts +21 -24
  39. package/dist/cloudflare.d.ts.map +1 -1
  40. package/dist/cloudflare.js +125 -191
  41. package/dist/cloudflare.js.map +1 -1
  42. package/dist/index.d.ts +4 -4
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +3 -3
  45. package/dist/index.js.map +1 -1
  46. package/dist/params.d.ts +13 -16
  47. package/dist/params.d.ts.map +1 -1
  48. package/dist/worker/fetch.d.ts +12 -0
  49. package/dist/worker/fetch.d.ts.map +1 -0
  50. package/dist/worker/fetch.js +32 -0
  51. package/dist/worker/fetch.js.map +1 -0
  52. package/dist/worker/index.d.ts +61 -0
  53. package/dist/worker/index.d.ts.map +1 -0
  54. package/dist/worker/index.js +212 -0
  55. package/dist/worker/index.js.map +1 -0
  56. package/package.json +13 -5
  57. package/src/build/codegen/worker.ts +53 -0
  58. package/src/{codegen → build/codegen}/wrangler.ts +34 -12
  59. package/src/build/frontend.ts +324 -0
  60. package/src/{build.ts → build/index.ts} +17 -4
  61. package/src/{parse-output.ts → build/parse-output.ts} +6 -0
  62. package/src/build/prepare.ts +161 -0
  63. package/src/build/worker.ts +37 -0
  64. package/src/{wrangler-cli.ts → build/wrangler-cli.ts} +56 -8
  65. package/src/cloudflare.ts +153 -223
  66. package/src/index.ts +4 -4
  67. package/src/params.ts +13 -17
  68. package/src/worker/fetch.ts +46 -0
  69. package/src/worker/index.ts +325 -0
  70. package/src/worker/tsconfig.json +10 -0
  71. package/template/astrale.config.ts +7 -7
  72. package/dist/assets-pack.d.ts +0 -8
  73. package/dist/assets-pack.d.ts.map +0 -1
  74. package/dist/assets-pack.js +0 -30
  75. package/dist/assets-pack.js.map +0 -1
  76. package/dist/build.d.ts.map +0 -1
  77. package/dist/build.js.map +0 -1
  78. package/dist/client.d.ts +0 -17
  79. package/dist/client.d.ts.map +0 -1
  80. package/dist/client.js +0 -59
  81. package/dist/client.js.map +0 -1
  82. package/dist/codegen/identity.d.ts.map +0 -1
  83. package/dist/codegen/identity.js.map +0 -1
  84. package/dist/codegen/merge.d.ts.map +0 -1
  85. package/dist/codegen/merge.js.map +0 -1
  86. package/dist/codegen/worker.d.ts +0 -51
  87. package/dist/codegen/worker.d.ts.map +0 -1
  88. package/dist/codegen/worker.js +0 -120
  89. package/dist/codegen/worker.js.map +0 -1
  90. package/dist/codegen/wrangler.d.ts.map +0 -1
  91. package/dist/codegen/wrangler.js.map +0 -1
  92. package/dist/parse-output.d.ts.map +0 -1
  93. package/dist/parse-output.js.map +0 -1
  94. package/dist/wrangler-cli.d.ts.map +0 -1
  95. package/dist/wrangler-cli.js.map +0 -1
  96. package/src/assets-pack.ts +0 -32
  97. package/src/client.ts +0 -89
  98. package/src/codegen/worker.ts +0 -136
  99. package/template/.env.example +0 -9
  100. package/template/.gitignore.template +0 -16
  101. package/template/CLAUDE.md +0 -13
  102. package/template/README.md +0 -47
  103. package/template/client/.gitignore.template +0 -4
  104. package/template/client/__tests__/app.test.tsx +0 -15
  105. package/template/client/components.json +0 -25
  106. package/template/client/index.html +0 -12
  107. package/template/client/package.json +0 -35
  108. package/template/client/src/app.tsx +0 -52
  109. package/template/client/src/components/ui/cn.ts +0 -6
  110. package/template/client/src/main.tsx +0 -9
  111. package/template/client/src/styles.css +0 -78
  112. package/template/client/tsconfig.json +0 -26
  113. package/template/client/vite.config.ts +0 -22
  114. package/template/client/vitest.config.ts +0 -13
  115. package/template/core/README.md +0 -7
  116. package/template/deps.ts +0 -9
  117. package/template/domain.ts +0 -11
  118. package/template/env.ts +0 -8
  119. package/template/icons.ts +0 -4
  120. package/template/integrations/README.md +0 -7
  121. package/template/oxlint.config.ts +0 -1
  122. package/template/package.json +0 -58
  123. package/template/pnpm-workspace.yaml +0 -31
  124. package/template/runtime/index.ts +0 -8
  125. package/template/schema/index.ts +0 -10
  126. package/template/simulation/README.md +0 -12
  127. package/template/tsconfig.json +0 -28
  128. package/template/vitest.config.ts +0 -7
  129. /package/dist/{codegen → build/codegen}/identity.d.ts +0 -0
  130. /package/dist/{codegen → build/codegen}/identity.js +0 -0
  131. /package/dist/{codegen → build/codegen}/merge.d.ts +0 -0
  132. /package/dist/{codegen → build/codegen}/merge.js +0 -0
  133. /package/src/{codegen → build/codegen}/identity.ts +0 -0
  134. /package/src/{codegen → build/codegen}/merge.ts +0 -0
package/src/params.ts CHANGED
@@ -1,5 +1,3 @@
1
- import type { ClientConfig } from './client'
2
-
3
1
  /**
4
2
  * `CloudflareParams` — the provider-typed config for the Cloudflare adapter.
5
3
  *
@@ -13,18 +11,16 @@ import type { ClientConfig } from './client'
13
11
  * • remote (custom) — `deploy()` with `route`; URL = https://<route>
14
12
  */
15
13
  export interface CloudflareParams {
16
- /** Frontend assets to build and serve for this env's mounted `/ui` views. */
17
- client?: ClientConfig
18
14
  /**
19
15
  * Custom route / hostname for a routed deploy, e.g. `'crm.acme.dev'`. Omit to
20
16
  * deploy to `*.workers.dev`. Ignored by local `wrangler dev` (URL is
21
17
  * localhost) but still used as the placeholder base domain there.
22
18
  */
23
- route?: string
19
+ readonly route?: string
24
20
  /** Gitignored secrets file (whole contents = secrets), e.g. `'.env.dev'`. */
25
- secrets?: string
21
+ readonly secrets?: string
26
22
  /** Local dev port for `wrangler dev`. Default 8787. */
27
- port?: number
23
+ readonly port?: number
28
24
  /**
29
25
  * Public URL the dev server is reached through (tunnel / sandbox preview /
30
26
  * reverse proxy), e.g. `'https://my-box.preview.dev'`. Sets BOTH effects an
@@ -33,13 +29,13 @@ export interface CloudflareParams {
33
29
  * identity (`iss`) doesn't drift to the proxy's internal hostname.
34
30
  * Usually injected by `pnpm dev --host <url>` rather than written here.
35
31
  */
36
- host?: string
32
+ readonly host?: string
37
33
  /** Override the Worker name. Default: derived from the domain origin. */
38
- workerName?: string
34
+ readonly workerName?: string
39
35
  /** Run `wrangler dev --remote` (edge isolate) instead of local workerd. */
40
- remote?: boolean
36
+ readonly remote?: boolean
41
37
  /** Extra plain (non-secret) vars to inject as Worker vars. */
42
- vars?: Record<string, string>
38
+ readonly vars?: Record<string, string>
43
39
  /**
44
40
  * Escape hatch: raw wrangler config deep-merged over the generated base. Use
45
41
  * it to declare extra bindings the adapter has no typed field for — KV, R2,
@@ -58,7 +54,7 @@ export interface CloudflareParams {
58
54
  * the reserved binding names `SELF` and `ASSETS`. Durable Objects need extra
59
55
  * worker-entry codegen and aren't supported through this field yet.
60
56
  */
61
- wrangler?: Record<string, unknown>
57
+ readonly wrangler?: Record<string, unknown>
62
58
  /**
63
59
  * Route subrequests to platform INSTANCE hostnames through a service binding
64
60
  * instead of the public edge. A Cloudflare Worker can't fetch a same-zone
@@ -81,16 +77,16 @@ export interface CloudflareParams {
81
77
  * router: false // opt out
82
78
  * router: { service: 'my-router' } // override target
83
79
  */
84
- router?:
80
+ readonly router?:
85
81
  | false
86
82
  | {
87
83
  /** Router Worker the binding targets. Default `'admin-router'`. */
88
- service?: string
84
+ readonly service?: string
89
85
  /** Service-binding name the worker reads. Default `'ROUTER'`. */
90
- binding?: string
86
+ readonly binding?: string
91
87
  /** Host suffix that marks an instance host. Default `'.astrale.ai'`. */
92
- hostSuffix?: string
88
+ readonly hostSuffix?: string
93
89
  /** Min dot-separated label count for an instance host. Default `4` (`<slug>.<region>.astrale.ai`). */
94
- minLabels?: number
90
+ readonly minLabels?: number
95
91
  }
96
92
  }
@@ -0,0 +1,46 @@
1
+ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308])
2
+
3
+ export type RequestDispatcher = (request: Request) => Response | Promise<Response>
4
+
5
+ export interface CloudflareRequest {
6
+ readonly request: Request
7
+ readonly rejectRedirect: boolean
8
+ }
9
+
10
+ /** Construct a Cloudflare-compatible transport request without weakening redirect:error. */
11
+ export function prepareCloudflareRequest(
12
+ input: Parameters<typeof fetch>[0],
13
+ init?: Parameters<typeof fetch>[1],
14
+ ): CloudflareRequest {
15
+ const rejectRedirect =
16
+ init?.redirect === 'error' ||
17
+ (init?.redirect === undefined && input instanceof Request && input.redirect === 'error')
18
+ const request = new Request(input, rejectRedirect ? { ...init, redirect: 'manual' } : init)
19
+ return Object.freeze({ request, rejectRedirect })
20
+ }
21
+
22
+ /** Preserve Fetch redirect:error semantics on Cloudflare, whose transport rejects that mode. */
23
+ export async function dispatchCloudflareRequest(
24
+ request: Request,
25
+ rejectRedirect: boolean,
26
+ dispatch: RequestDispatcher,
27
+ ): Promise<Response> {
28
+ const response = adaptCloudflareResponse(request, await dispatch(request))
29
+ if (!rejectRedirect) return response
30
+ if (!response.redirected && !REDIRECT_STATUSES.has(response.status)) return response
31
+
32
+ await response.body?.cancel()
33
+ throw new TypeError('Redirects are not allowed for this request.')
34
+ }
35
+
36
+ /** Restore the requested URL omitted by Cloudflare service-binding Responses. */
37
+ export function adaptCloudflareResponse(request: Request, response: Response): Response {
38
+ if (response.url !== '') return response
39
+ return new Proxy(response, {
40
+ get(target, property) {
41
+ if (property === 'url') return request.url
42
+ const value = Reflect.get(target, property, target) as unknown
43
+ return typeof value === 'function' ? value.bind(target) : value
44
+ },
45
+ })
46
+ }
@@ -0,0 +1,325 @@
1
+ import type { schema } from '@astrale-os/kernel-dsl/v1'
2
+ import type { DomainDefinition, FrontendRoute } from '@astrale-os/sdk'
3
+ import type {
4
+ Application,
5
+ RemoteDeploymentInput,
6
+ RemoteIdentityInput,
7
+ } from '@astrale-os/sdk/server'
8
+ import type { ExecutionContext, Hono } from 'hono'
9
+
10
+ import { issuer } from '@astrale-os/kernel-core/auth'
11
+ import { createRemoteApplication } from '@astrale-os/sdk/server'
12
+ import { Hono as HonoApplication } from 'hono'
13
+
14
+ import { dispatchCloudflareRequest, prepareCloudflareRequest } from './fetch.js'
15
+
16
+ const MAXIMUM_CACHED_APPLICATIONS = 4
17
+ const APPLICATION_CLOSE_TIMEOUT_MS = 5_000
18
+
19
+ /** SDK-owned Publication manifest passed through without adapter interpretation. */
20
+ export type CloudflareManifest = NonNullable<RemoteDeploymentInput['manifest']>
21
+
22
+ export interface Fetcher {
23
+ fetch(request: Request): Response | Promise<Response>
24
+ }
25
+
26
+ /** Adapter-owned bindings generated into every Cloudflare deployment. */
27
+ export interface CloudflareAdapterBindings {
28
+ /** Native Cloudflare deployment metadata (direct Wrangler deployments). */
29
+ readonly ASTRALE_VERSION_METADATA?: {
30
+ readonly id: string
31
+ readonly tag: string
32
+ readonly timestamp: string
33
+ }
34
+ /** Content-derived generation supplied by providers without version metadata. */
35
+ readonly ASTRALE_DEPLOYMENT_VERSION?: string
36
+ readonly WORKER_URL?: string
37
+ readonly ASSETS?: Fetcher
38
+ readonly SELF?: Fetcher
39
+ readonly FRONTEND_DEV_URL?: string
40
+ readonly DISPATCHER?: { get(name: string): Fetcher }
41
+ }
42
+
43
+ interface CloudflareWorkerSharedConfig<Bindings extends CloudflareAdapterBindings, Environment> {
44
+ readonly privateKey:
45
+ | RemoteIdentityInput['privateKey']
46
+ | ((bindings: Bindings) => RemoteIdentityInput['privateKey'])
47
+ /** Compose provider bindings into the exact Domain environment once per deployment generation. */
48
+ readonly resolveEnvironment?: (bindings: Bindings) => Environment | Promise<Environment>
49
+ readonly manifest?: CloudflareManifest
50
+ /** Maximum time allowed for one Domain invocation. Defaults to 30 seconds. */
51
+ readonly invocationTimeoutMs?: number
52
+ readonly resolveUrl?: (bindings: Bindings, requestOrigin: string) => string
53
+ readonly selfBinding?: (bindings: Bindings) => Fetcher | null | undefined
54
+ readonly routeSubrequest?: (url: URL, bindings: Bindings) => Fetcher | null | undefined
55
+ }
56
+
57
+ /**
58
+ * Resolve a Domain lazily when its module graph is too expensive for provider startup admission.
59
+ * The adapter resolves at most once concurrently and retries after a rejected resolution.
60
+ */
61
+ export type CloudflareWorkerConfig<
62
+ S extends schema.DomainSchema,
63
+ Bindings extends CloudflareAdapterBindings,
64
+ Environment,
65
+ > = CloudflareWorkerSharedConfig<Bindings, Environment> &
66
+ (
67
+ | {
68
+ readonly definition: DomainDefinition<S>
69
+ readonly resolveDefinition?: never
70
+ }
71
+ | {
72
+ readonly definition?: never
73
+ readonly resolveDefinition: (
74
+ bindings: Bindings,
75
+ ) => DomainDefinition<S> | Promise<DomainDefinition<S>>
76
+ }
77
+ )
78
+
79
+ export interface CloudflareWorker<Environment> {
80
+ fetch(
81
+ request: Request,
82
+ environment: Environment,
83
+ executionContext?: ExecutionContext,
84
+ ): Response | Promise<Response>
85
+ }
86
+
87
+ interface CachedApplication<Environment> {
88
+ readonly origin: string
89
+ readonly application: Application<Hono>
90
+ readonly environment: Environment
91
+ }
92
+
93
+ /**
94
+ * Compose one Cloudflare module Worker without request-global mutation.
95
+ * Environment bindings are captured once per immutable serving URL/version generation.
96
+ */
97
+ export function cloudflareWorkerEntry<
98
+ Bindings extends CloudflareAdapterBindings,
99
+ Environment = Bindings,
100
+ >() {
101
+ return function <const S extends schema.DomainSchema>(
102
+ config: CloudflareWorkerConfig<S, Bindings, Environment>,
103
+ ): CloudflareWorker<Bindings> {
104
+ const applications = new Map<string, CachedApplication<Environment>>()
105
+ let resolvedDefinition: DomainDefinition<S> | undefined = config.definition
106
+ let pendingDefinition: Promise<DomainDefinition<S>> | undefined
107
+
108
+ const definitionFor = async (bindings: Bindings): Promise<DomainDefinition<S>> => {
109
+ if (resolvedDefinition !== undefined) return resolvedDefinition
110
+ if (pendingDefinition !== undefined) return pendingDefinition
111
+ const resolve = config.resolveDefinition
112
+ if (resolve === undefined)
113
+ throw new TypeError('Cloudflare Worker Domain definition is unavailable.')
114
+ const current = Promise.resolve().then(() => resolve(bindings))
115
+ pendingDefinition = current
116
+ try {
117
+ const definition = await current
118
+ resolvedDefinition = definition
119
+ return definition
120
+ } finally {
121
+ if (pendingDefinition === current) pendingDefinition = undefined
122
+ }
123
+ }
124
+
125
+ const applicationFor = async (
126
+ url: string,
127
+ bindings: Bindings,
128
+ definition: DomainDefinition<S>,
129
+ ): Promise<CachedApplication<Environment>> => {
130
+ const version = deploymentVersion(bindings)
131
+ const key = `${url}\u0000${version}`
132
+ const cached = applications.get(key)
133
+ if (cached !== undefined) return cached
134
+ const environment =
135
+ config.resolveEnvironment === undefined
136
+ ? (bindings as unknown as Environment)
137
+ : await config.resolveEnvironment(bindings)
138
+
139
+ const routedFetch: typeof fetch = async (input, init) => {
140
+ const { request, rejectRedirect } = prepareCloudflareRequest(input, init)
141
+ const destination = new URL(request.url)
142
+ if (destination.origin === new URL(url).origin) {
143
+ const self = config.selfBinding?.(bindings)
144
+ return dispatchCloudflareRequest(request, rejectRedirect, (transportRequest) =>
145
+ self !== null && self !== undefined
146
+ ? self.fetch(transportRequest)
147
+ : serving.app.fetch(transportRequest, environment),
148
+ )
149
+ }
150
+ const route = config.routeSubrequest?.(destination, bindings)
151
+ return dispatchCloudflareRequest(request, rejectRedirect, (transportRequest) =>
152
+ route === null || route === undefined
153
+ ? fetch(transportRequest)
154
+ : route.fetch(transportRequest),
155
+ )
156
+ }
157
+
158
+ const deploymentQuery = `deployment=${encodeURIComponent(version)}`
159
+ const issuerId = issuer.accept(url)
160
+ const host = new HonoApplication()
161
+ host.get('/meta', (context) =>
162
+ context.json({
163
+ origin: definition.schema.origin,
164
+ issuer: issuerId,
165
+ schemaRevision: definition.domain.$.revision,
166
+ deploymentVersion: version,
167
+ }),
168
+ )
169
+ const serving: Application<Hono> = createRemoteApplication({
170
+ definition,
171
+ environment,
172
+ identity: {
173
+ issuer: issuerId,
174
+ subject: definition.schema.origin,
175
+ privateKey:
176
+ typeof config.privateKey === 'function'
177
+ ? config.privateKey(bindings)
178
+ : config.privateKey,
179
+ fetch: routedFetch,
180
+ ...(new URL(url).protocol === 'http:' ? { allowInsecureHttp: true } : {}),
181
+ },
182
+ deployment: {
183
+ bundleHref: `${url}/.well-known/astrale/domain.bundle.json?${deploymentQuery}`,
184
+ endpoint: { http: `${url}/invoke` },
185
+ ...(definition.frontend === undefined
186
+ ? {}
187
+ : { frontendBaseHref: url, frontendCacheKey: version }),
188
+ ...(config.manifest === undefined ? {} : { manifest: config.manifest }),
189
+ delivery: {
190
+ href: `${url}/install`,
191
+ method: 'POST',
192
+ authentication: { kind: 'public' },
193
+ },
194
+ },
195
+ app: host,
196
+ server: {
197
+ path: '/invoke',
198
+ health: { probe: { check: () => true } },
199
+ limits: {
200
+ maximumRequestBytes: 1024 * 1024,
201
+ maximumPublicationBytes: 1024 * 1024,
202
+ maximumBundleBytes: 8 * 1024 * 1024,
203
+ maximumDeliveryBytes: 8 * 1024 * 1024,
204
+ invocationTimeoutMs: config.invocationTimeoutMs ?? 30_000,
205
+ },
206
+ },
207
+ })
208
+ const created = Object.freeze({
209
+ origin: new URL(url).origin,
210
+ application: serving,
211
+ environment,
212
+ })
213
+ if (applications.size >= MAXIMUM_CACHED_APPLICATIONS) {
214
+ const oldest = applications.keys().next().value
215
+ if (oldest !== undefined) {
216
+ const evicted = applications.get(oldest)
217
+ applications.delete(oldest)
218
+ if (evicted !== undefined) {
219
+ try {
220
+ await closeEvictedApplication(evicted.application)
221
+ } catch (cause) {
222
+ await serving
223
+ .close({ deadline: Date.now() + APPLICATION_CLOSE_TIMEOUT_MS })
224
+ .catch(() => undefined)
225
+ throw cause
226
+ }
227
+ }
228
+ }
229
+ }
230
+ applications.set(key, created)
231
+ return created
232
+ }
233
+
234
+ return Object.freeze({
235
+ async fetch(request: Request, bindings: Bindings, executionContext?: ExecutionContext) {
236
+ const requestUrl = new URL(request.url)
237
+ const definition = await definitionFor(bindings)
238
+ if (definition.frontend !== undefined) {
239
+ const asset = await frontendAsset(definition, bindings, requestUrl, request)
240
+ if (asset !== undefined) return asset
241
+ }
242
+ const publicUrl = canonicalServingUrl(
243
+ config.resolveUrl?.(bindings, requestOrigin(requestUrl, request)) ??
244
+ bindings.WORKER_URL ??
245
+ requestOrigin(requestUrl, request),
246
+ )
247
+ const serving = await applicationFor(publicUrl, bindings, definition)
248
+ return serving.application.app.fetch(request, serving.environment, executionContext)
249
+ },
250
+ })
251
+ }
252
+ }
253
+
254
+ /** Close an evicted Application before its environment bindings leave the cache. */
255
+ export function closeEvictedApplication(
256
+ application: Pick<Application, 'close'>,
257
+ now: () => number = Date.now,
258
+ ): Promise<void> {
259
+ return application.close({ deadline: now() + APPLICATION_CLOSE_TIMEOUT_MS })
260
+ }
261
+
262
+ async function frontendAsset<S extends schema.DomainSchema>(
263
+ definition: DomainDefinition<S>,
264
+ environment: CloudflareAdapterBindings,
265
+ url: URL,
266
+ request: Request,
267
+ ): Promise<Response | undefined> {
268
+ const frontend = definition.frontend
269
+ if (frontend === undefined || frontend.source.kind === 'external') return undefined
270
+ const routes = frontend.routes as Readonly<Record<string, FrontendRoute>>
271
+ const route = Object.values(routes).find((candidate) => candidate.path === url.pathname)
272
+ const staticAsset = url.pathname.startsWith('/assets/')
273
+ if (route === undefined && !staticAsset) return undefined
274
+ if (request.method !== 'GET' && request.method !== 'HEAD') return undefined
275
+ const binding = environment.ASSETS
276
+ if (binding === undefined) return undefined
277
+ const dev = environment.FRONTEND_DEV_URL?.replace(/\/+$/u, '')
278
+ if (dev !== undefined && dev.length > 0) {
279
+ return fetch(new Request(`${dev}${url.pathname}${url.search}`, request))
280
+ }
281
+ const path =
282
+ route === undefined ? `${url.pathname}${url.search}` : `/${route.document}${url.search}`
283
+ return binding.fetch(new Request(new URL(path, url.origin), request))
284
+ }
285
+
286
+ function requestOrigin(url: URL, request: Request): string {
287
+ if (url.protocol !== 'http:') return url.origin
288
+ const forwarded = request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim().toLowerCase()
289
+ return forwarded === 'https' ? `https://${url.host}` : url.origin
290
+ }
291
+
292
+ function canonicalServingUrl(input: string): string {
293
+ let url: URL
294
+ try {
295
+ url = new URL(input)
296
+ } catch (cause) {
297
+ throw new TypeError('Cloudflare Worker serving URL is invalid.', { cause })
298
+ }
299
+ if (
300
+ (url.protocol !== 'https:' && url.protocol !== 'http:') ||
301
+ url.username !== '' ||
302
+ url.password !== '' ||
303
+ url.pathname !== '/' ||
304
+ url.search !== '' ||
305
+ url.hash !== ''
306
+ ) {
307
+ throw new TypeError('Cloudflare Worker serving URL must be one HTTP(S) origin.')
308
+ }
309
+ return url.origin
310
+ }
311
+
312
+ function deploymentVersion(environment: CloudflareAdapterBindings): string {
313
+ const input = environment.ASTRALE_VERSION_METADATA
314
+ if (
315
+ input !== null &&
316
+ typeof input === 'object' &&
317
+ typeof input.id === 'string' &&
318
+ input.id.length > 0
319
+ ) {
320
+ return input.id
321
+ }
322
+ const fallback = environment.ASTRALE_DEPLOYMENT_VERSION
323
+ if (typeof fallback === 'string' && fallback.length > 0) return fallback
324
+ throw new TypeError('Cloudflare Worker deployment version is unavailable.')
325
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "types": [],
6
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true
8
+ },
9
+ "include": ["index.ts"]
10
+ }
@@ -1,8 +1,8 @@
1
1
  /**
2
- * astrale.config.ts — binds the worker-safe domain (`domain.ts`) to its deploy
2
+ * astrale.config.ts — binds the worker-safe composition (`implementation.ts`) to its deploy
3
3
  * adapter for the `astrale-domain` CLI. This is a NODE-only module: it imports
4
4
  * the adapter (wrangler + filesystem). The generated worker never imports this
5
- * file — it imports `domain.ts` directly — so the adapter stays out of the bundle.
5
+ * file — it imports `implementation.ts` directly — so the adapter stays out of the bundle.
6
6
  *
7
7
  * This variant deploys to YOUR OWN Cloudflare account (the `cloudflare` adapter).
8
8
  *
@@ -18,19 +18,19 @@ import { deploy } from '@astrale-os/sdk'
18
18
  //
19
19
  // import { astrale } from '@astrale-os/adapter-astrale'
20
20
  // export default deploy(domain, astrale({
21
- // dev: { client: { dir: 'client' }, secrets: '.env.dev' }, // local wrangler dev
22
- // prod: { client: { dir: 'client' }, instance: '<your-instance-slug>' }, // managed deploy
21
+ // dev: { secrets: '.env.dev' }, // local wrangler dev
22
+ // prod: { instance: '<your-instance-slug>' }, // managed deploy
23
23
  // }))
24
24
 
25
- import { domain } from './domain'
25
+ import { domain } from './implementation'
26
26
 
27
27
  export default deploy(
28
28
  domain,
29
29
  cloudflare({
30
30
  // Local dev: `wrangler dev`. No route → URL is http://localhost:8787.
31
- dev: { client: { dir: 'client' }, secrets: '.env.dev' },
31
+ dev: { secrets: '.env.dev' },
32
32
  // Custom-domain prod. Drop `route` to ship to *.workers.dev instead.
33
- prod: { client: { dir: 'client' }, route: 'astrale-domain.example.dev', secrets: '.env.prod' },
33
+ prod: { route: 'astrale-domain.example.dev', secrets: '.env.prod' },
34
34
  // Author secrets ship via `secrets: '.env.prod'` on any env. Extra bindings
35
35
  // (KV, R2, D1, queues, …) ride a `wrangler` block on any env (deep-merged).
36
36
  }),
@@ -1,8 +0,0 @@
1
- /**
2
- * Pack a built client SPA (the `CLIENT_DIST_DIR` build) into the host box's asset-archive
3
- * format: `gzip(JSON [{ path, contentBase64 }])` — the exact shape
4
- * `downloadAssets` on the box consumes (kernel/host workerd service layout).
5
- */
6
- /** Gzip the SPA dir into the box's asset archive. Returns null when empty. */
7
- export declare function packAssets(distClientDir: string): Buffer | null;
8
- //# sourceMappingURL=assets-pack.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assets-pack.d.ts","sourceRoot":"","sources":["../src/assets-pack.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D"}
@@ -1,30 +0,0 @@
1
- /**
2
- * Pack a built client SPA (the `CLIENT_DIST_DIR` build) into the host box's asset-archive
3
- * format: `gzip(JSON [{ path, contentBase64 }])` — the exact shape
4
- * `downloadAssets` on the box consumes (kernel/host workerd service layout).
5
- */
6
- import { readdirSync, readFileSync, statSync } from 'node:fs';
7
- import { join, relative } from 'node:path';
8
- import { gzipSync } from 'node:zlib';
9
- function walk(dir, root, out) {
10
- for (const name of readdirSync(dir)) {
11
- const full = join(dir, name);
12
- if (statSync(full).isDirectory())
13
- walk(full, root, out);
14
- else {
15
- out.push({
16
- path: relative(root, full).split('\\').join('/'),
17
- contentBase64: readFileSync(full).toString('base64'),
18
- });
19
- }
20
- }
21
- }
22
- /** Gzip the SPA dir into the box's asset archive. Returns null when empty. */
23
- export function packAssets(distClientDir) {
24
- const files = [];
25
- walk(distClientDir, distClientDir, files);
26
- if (files.length === 0)
27
- return null;
28
- return gzipSync(Buffer.from(JSON.stringify(files)));
29
- }
30
- //# sourceMappingURL=assets-pack.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assets-pack.js","sourceRoot":"","sources":["../src/assets-pack.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAIpC,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAgB;IACvD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAC5B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;aAClD,CAAC;YACJ,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAChD,aAAa,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;aACrD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,aAAqB;IAC9C,MAAM,KAAK,GAAgB,EAAE,CAAA;IAC7B,IAAI,CAAC,aAAa,EAAE,aAAa,EAAE,KAAK,CAAC,CAAA;IACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACnC,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/build.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEzE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/client.d.ts DELETED
@@ -1,17 +0,0 @@
1
- /** Client SPA build helpers. The source dir is adapter env config, not domain config. */
2
- import type { DomainInfo } from '@astrale-os/sdk';
3
- export type ClientConfig = {
4
- /** Vite project directory, relative to the domain project root unless absolute. */
5
- dir: string;
6
- };
7
- /** Built client output, relative to the project root. The Vite config must emit here. */
8
- export declare const CLIENT_DIST_DIR = ".dist";
9
- export declare function resolveClientDir(args: {
10
- adapterName: string;
11
- env: string;
12
- projectDir: string;
13
- client?: ClientConfig;
14
- domain: DomainInfo;
15
- }): string | undefined;
16
- export declare function buildClient(clientDir: string, projectDir: string, onLog?: (line: string) => void): Promise<void>;
17
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAEzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAMjD,MAAM,MAAM,YAAY,GAAG;IACzB,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,yFAAyF;AACzF,eAAO,MAAM,eAAe,UAAU,CAAA;AAEtC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,MAAM,EAAE,UAAU,CAAA;CACnB,GAAG,MAAM,GAAG,SAAS,CAoBrB;AAMD,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAef"}
package/dist/client.js DELETED
@@ -1,59 +0,0 @@
1
- /** Client SPA build helpers. The source dir is adapter env config, not domain config. */
2
- import { spawn } from 'node:child_process';
3
- import { existsSync } from 'node:fs';
4
- import { isAbsolute, join } from 'node:path';
5
- /** Built client output, relative to the project root. The Vite config must emit here. */
6
- export const CLIENT_DIST_DIR = '.dist';
7
- export function resolveClientDir(args) {
8
- const { adapterName, projectDir, client, domain } = args;
9
- for (const view of domain.mountedViews) {
10
- if (!isUiMount(view.mount)) {
11
- throw new Error(`${adapterName} adapter: mounted view "${view.slug}" uses mount "${view.mount}", ` +
12
- 'but adapter-managed client assets currently serve only /ui routes.');
13
- }
14
- }
15
- if (domain.mountedViews.length > 0 && !client) {
16
- const mounts = domain.mountedViews.map((v) => `${v.slug}:${v.mount}`).join(', ');
17
- throw new Error(`${adapterName} adapter: ${domain.origin} declares mounted view(s) (${mounts}) ` +
18
- `but env "${args.env}" has no \`client: { dir: ... }\` config. ` +
19
- 'Add `client` to the selected adapter env in astrale.config.ts.');
20
- }
21
- if (!client)
22
- return undefined;
23
- return isAbsolute(client.dir) ? client.dir : join(projectDir, client.dir);
24
- }
25
- function isUiMount(mount) {
26
- return mount === '/ui' || mount.startsWith('/ui/');
27
- }
28
- export async function buildClient(clientDir, projectDir, onLog) {
29
- const viteBin = [
30
- join(clientDir, 'node_modules', '.bin', 'vite'),
31
- join(projectDir, 'node_modules', '.bin', 'vite'),
32
- ].find((p) => existsSync(p));
33
- if (!viteBin) {
34
- throw new Error(`client build: vite not found in ${clientDir}. Run \`pnpm install\` at the project root ` +
35
- `first.`);
36
- }
37
- const { code, out } = await runCapture(viteBin, ['build'], clientDir, onLog);
38
- if (code !== 0) {
39
- throw new Error(`client build failed (code ${code}):\n${out.slice(-1500)}`);
40
- }
41
- }
42
- function runCapture(cmd, args, cwd, onLog) {
43
- return new Promise((resolve, reject) => {
44
- const child = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
45
- let out = '';
46
- const onData = (buf) => {
47
- const text = buf.toString();
48
- out += text;
49
- for (const line of text.split('\n'))
50
- if (line.trim())
51
- onLog?.(line);
52
- };
53
- child.stdout?.on('data', onData);
54
- child.stderr?.on('data', onData);
55
- child.on('exit', (code) => resolve({ code: code ?? 1, out }));
56
- child.on('error', reject);
57
- });
58
- }
59
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAIzF,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAO5C,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA;AAEtC,MAAM,UAAU,gBAAgB,CAAC,IAMhC;IACC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACxD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,2BAA2B,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC,KAAK,KAAK;gBAChF,oEAAoE,CACvE,CAAA;QACH,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChF,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,aAAa,MAAM,CAAC,MAAM,8BAA8B,MAAM,IAAI;YAC9E,YAAY,IAAI,CAAC,GAAG,4CAA4C;YAChE,gEAAgE,CACnE,CAAA;IACH,CAAC;IACD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,OAAO,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;AAC3E,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,UAAkB,EAClB,KAA8B;IAE9B,MAAM,OAAO,GAAG;QACd,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/C,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC;KACjD,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mCAAmC,SAAS,6CAA6C;YACvF,QAAQ,CACX,CAAA;IACH,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IAC5E,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC7E,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,GAAW,EACX,IAAc,EACd,GAAW,EACX,KAA8B;IAE9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;QAC1E,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAA;YAC3B,GAAG,IAAI,IAAI,CAAA;YACX,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,IAAI,IAAI,CAAC,IAAI,EAAE;oBAAE,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;QACrE,CAAC,CAAA;QACD,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/codegen/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBtF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/codegen/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB,EAAE,MAAc;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;IAC5C,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAM;IAE5B,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5E,MAAM,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,UAAU,CAAC,CAA4B,CAAA;IACpE,GAAG,CAAC,GAAG,GAAG,OAAO,CAAA;IACjB,GAAG,CAAC,GAAG,GAAG,GAAG,MAAM,MAAM,CAAA;IAEzB,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5C,MAAM,SAAS,CACb,IAAI,EACJ,kDAAkD,MAAM,mCAAmC;QACzF,8BAA8B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,aAAa,CAC1E,CAAA;IAED,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gFAAgF,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;QACnG,kBAAkB,MAAM,+DAA+D;QACvF,gGAAgG,CACnG,CAAA;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/codegen/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/codegen/merge.ts"],"names":[],"mappings":"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"}