@astrale-os/sdk 0.1.6 → 0.1.8
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.
- package/dist/cli/bin.d.ts +7 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +15 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/dotenv.d.ts +13 -0
- package/dist/cli/dotenv.d.ts.map +1 -0
- package/dist/cli/dotenv.js +46 -0
- package/dist/cli/dotenv.js.map +1 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/run.d.ts +84 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +603 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spec.d.ts +19 -0
- package/dist/cli/spec.d.ts.map +1 -0
- package/dist/cli/spec.js +31 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/config/adapter.d.ts +140 -0
- package/dist/config/adapter.d.ts.map +1 -0
- package/dist/config/adapter.js +40 -0
- package/dist/config/adapter.js.map +1 -0
- package/dist/config/define-domain.d.ts +112 -0
- package/dist/config/define-domain.d.ts.map +1 -0
- package/dist/config/define-domain.js +98 -0
- package/dist/config/define-domain.js.map +1 -0
- package/dist/config/deploy.d.ts +28 -0
- package/dist/config/deploy.d.ts.map +1 -0
- package/dist/config/deploy.js +24 -0
- package/dist/config/deploy.js.map +1 -0
- package/dist/config/index.d.ts +21 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/define/remote-function.d.ts +19 -11
- package/dist/define/remote-function.d.ts.map +1 -1
- package/dist/define/remote-function.js.map +1 -1
- package/dist/dispatch/call-remote.d.ts +7 -3
- package/dist/dispatch/call-remote.d.ts.map +1 -1
- package/dist/dispatch/call-remote.js.map +1 -1
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +8 -4
- package/dist/dispatch/dispatcher.js.map +1 -1
- package/dist/dispatch/index.d.ts +1 -1
- package/dist/dispatch/index.d.ts.map +1 -1
- package/dist/dispatch/index.js.map +1 -1
- package/dist/dispatch/self.d.ts +46 -10
- package/dist/dispatch/self.d.ts.map +1 -1
- package/dist/dispatch/self.js +65 -8
- package/dist/dispatch/self.js.map +1 -1
- package/dist/domain/define.d.ts +3 -3
- package/dist/domain/define.js +3 -3
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/method/class.d.ts.map +1 -1
- package/dist/method/class.js.map +1 -1
- package/dist/method/context.d.ts +32 -7
- package/dist/method/context.d.ts.map +1 -1
- package/dist/method/index.d.ts +1 -1
- package/dist/method/index.d.ts.map +1 -1
- package/dist/method/single.d.ts +16 -11
- package/dist/method/single.d.ts.map +1 -1
- package/dist/method/single.js.map +1 -1
- package/dist/server/domain-entry.d.ts +67 -0
- package/dist/server/domain-entry.d.ts.map +1 -0
- package/dist/server/domain-entry.js +58 -0
- package/dist/server/domain-entry.js.map +1 -0
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/worker-entry.d.ts +80 -5
- package/dist/server/worker-entry.d.ts.map +1 -1
- package/dist/server/worker-entry.js +105 -24
- package/dist/server/worker-entry.js.map +1 -1
- package/package.json +12 -3
- package/src/cli/bin.ts +15 -0
- package/src/cli/dotenv.ts +45 -0
- package/src/cli/index.ts +15 -0
- package/src/cli/run.ts +710 -0
- package/src/cli/spec.ts +42 -0
- package/src/config/adapter.ts +172 -0
- package/src/config/define-domain.ts +218 -0
- package/src/config/deploy.ts +35 -0
- package/src/config/index.ts +31 -0
- package/src/define/remote-function.ts +42 -13
- package/src/dispatch/call-remote.ts +7 -2
- package/src/dispatch/dispatcher.ts +8 -4
- package/src/dispatch/index.ts +1 -1
- package/src/dispatch/self.ts +96 -10
- package/src/domain/define.ts +3 -3
- package/src/index.ts +25 -4
- package/src/method/class.ts +4 -3
- package/src/method/context.ts +38 -7
- package/src/method/index.ts +1 -1
- package/src/method/single.ts +30 -11
- package/src/server/domain-entry.ts +113 -0
- package/src/server/index.ts +3 -1
- package/src/server/worker-entry.ts +128 -24
package/dist/cli/spec.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a diagnostic spec (wire graph + schema hash) from the project's
|
|
3
|
+
* `defineDomain` definition. This mirrors what the codegen'd worker assembles —
|
|
4
|
+
* but only for inspection / `/meta` provenance. The live install bundle is
|
|
5
|
+
* always produced by the worker at request time, so a failure here is non-fatal
|
|
6
|
+
* for dev/deploy (the CLI logs and continues) and fatal only for
|
|
7
|
+
* `astrale-domain build`, where the spec IS the product.
|
|
8
|
+
*
|
|
9
|
+
* The modules (`schema` / `methods` / `views` / `functions`) come straight off
|
|
10
|
+
* the definition — the SAME values the author wired into `defineDomain`, which
|
|
11
|
+
* the adapter codegen also assembles. One source, no second filesystem probe to
|
|
12
|
+
* drift from it.
|
|
13
|
+
*/
|
|
14
|
+
import { hashInstallGraph } from '@astrale-os/kernel-core/domain';
|
|
15
|
+
import { buildInstallGraph, defineRemoteDomain } from '../domain';
|
|
16
|
+
export async function buildProjectSpec(def, url) {
|
|
17
|
+
// The definition's module values are untyped against `RemoteDomainConfig` by
|
|
18
|
+
// nature (deps/schema generics erased on `DomainDefinition`); funnel them
|
|
19
|
+
// through ONE cast into the config shape `defineRemoteDomain` validates.
|
|
20
|
+
const config = {
|
|
21
|
+
schema: def.schema,
|
|
22
|
+
methods: def.methods,
|
|
23
|
+
...(def.views ? { views: def.views } : {}),
|
|
24
|
+
...(def.functions ? { remoteFunctions: def.functions } : {}),
|
|
25
|
+
};
|
|
26
|
+
const domain = defineRemoteDomain()(config);
|
|
27
|
+
const wire = buildInstallGraph(domain, url);
|
|
28
|
+
const schemaHash = await hashInstallGraph(wire);
|
|
29
|
+
return { wire: wire, schemaHash };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/cli/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAKjE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEjE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAqB,EACrB,GAAW;IAEX,6EAA6E;IAC7E,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtB,CAAA;IAExC,MAAM,MAAM,GAAG,kBAAkB,EAAW,CAAC,MAAM,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/C,OAAO,EAAE,IAAI,EAAE,IAA0C,EAAE,UAAU,EAAE,CAAA;AACzE,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deployment-adapter contract.
|
|
3
|
+
*
|
|
4
|
+
* A deployment target = one npm package implementing `DomainAdapter<Params>`.
|
|
5
|
+
* The adapter is GENERIC over its own `Params` so envs AND provider settings
|
|
6
|
+
* stay 100% adapter-specific (a Cloudflare adapter's `{ route, secrets }` is
|
|
7
|
+
* nothing like a Node adapter's `{ port }`). The CLI resolves
|
|
8
|
+
* `envs[<env>] → Params` via `adapter.params(env)` and then drives the adapter
|
|
9
|
+
* with the resolved params — install of the resulting URL and the `requires`
|
|
10
|
+
* check are generic and live in the CLI, never in the adapter.
|
|
11
|
+
*
|
|
12
|
+
* The central guarantee: `watch()` and `deploy()` both return a `url` — that's
|
|
13
|
+
* what the CLI prints, what `astrale domain install <url>` consumes, and
|
|
14
|
+
* the worker's `iss` identity. The URL is an OUTPUT of watch/deploy; nothing
|
|
15
|
+
* in the contract asks an adapter to predict it ahead of time.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Generic, target-independent domain metadata the CLI hands every adapter so
|
|
19
|
+
* it can codegen the worker entry. (Extends the bare `WatchCtx`/`DeployCtx` of
|
|
20
|
+
* the spec with the fields a real codegen needs.)
|
|
21
|
+
*/
|
|
22
|
+
export interface DomainInfo {
|
|
23
|
+
/**
|
|
24
|
+
* The domain's addressing name — the graph slug it mounts under (e.g.
|
|
25
|
+
* `'crm.acme.dev'`). NOT the cryptographic identity: the JWT `iss` is the
|
|
26
|
+
* worker's serving URL, pinned by the kernel at install time.
|
|
27
|
+
*/
|
|
28
|
+
origin: string;
|
|
29
|
+
/** Cross-domain deps by origin — verified at install (CLI/kernel), not here. */
|
|
30
|
+
requires: readonly string[];
|
|
31
|
+
/** Optional Astrale Path called by the kernel after install (as __SYSTEM__). */
|
|
32
|
+
postInstall?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the domain declares any Views / standalone Functions / a client SPA
|
|
35
|
+
* — read from the `defineDomain` definition, NOT probed from the filesystem.
|
|
36
|
+
* The adapter codegen imports the corresponding module / mounts the SPA hook
|
|
37
|
+
* only when true. `hasClient` governs the WORKER's `/ui` hook specifically
|
|
38
|
+
* (present whenever the domain has a client, even on managed deploys that ship
|
|
39
|
+
* the built assets separately and pass no `clientDir`); the wrangler
|
|
40
|
+
* `assets.directory` binding tracks `clientDir` instead.
|
|
41
|
+
*/
|
|
42
|
+
hasViews: boolean;
|
|
43
|
+
hasFunctions: boolean;
|
|
44
|
+
hasClient: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the domain declares a `deps` mapper (`defineDomain({ deps })`).
|
|
47
|
+
* When true the adapter codegen imports it from the domain's fixed `deps`
|
|
48
|
+
* module and passes it to the worker entry; when false the worker passes the
|
|
49
|
+
* raw env straight through as `ctx.deps`. Read from the definition, never
|
|
50
|
+
* probed from the filesystem.
|
|
51
|
+
*/
|
|
52
|
+
hasDeps: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface WatchCtx {
|
|
55
|
+
/** Absolute path to the domain project root. */
|
|
56
|
+
projectDir: string;
|
|
57
|
+
/** Absolute path where the CLI writes the diagnostic `spec.json`. */
|
|
58
|
+
specPath: string;
|
|
59
|
+
/** Absolute path to the client SPA dir, when the domain declares a `client`. */
|
|
60
|
+
clientDir?: string;
|
|
61
|
+
/** Flat secret map loaded from the env's `secrets` file — injected locally in dev. */
|
|
62
|
+
secrets: Record<string, string>;
|
|
63
|
+
/** Domain metadata for codegen. */
|
|
64
|
+
domain: DomainInfo;
|
|
65
|
+
/** The env key being watched (e.g. 'dev'). */
|
|
66
|
+
env: string;
|
|
67
|
+
/** Invoked by the adapter on every hot-reload so the CLI can re-log. */
|
|
68
|
+
onReload(): void;
|
|
69
|
+
}
|
|
70
|
+
export interface DeployCtx {
|
|
71
|
+
projectDir: string;
|
|
72
|
+
specPath: string;
|
|
73
|
+
/** Flat secret map loaded from the env's `secrets` file (gitignored). */
|
|
74
|
+
secrets: Record<string, string>;
|
|
75
|
+
clientDir?: string;
|
|
76
|
+
domain: DomainInfo;
|
|
77
|
+
/** The env key being deployed (e.g. 'dev' | 'prod' | 'canary'). */
|
|
78
|
+
env: string;
|
|
79
|
+
}
|
|
80
|
+
/** A running local watch — exposes its URL and a stop handle. */
|
|
81
|
+
export interface WatchHandle {
|
|
82
|
+
/** Local URL the worker is reachable at (e.g. http://localhost:8787). */
|
|
83
|
+
url: string;
|
|
84
|
+
stop(): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
/** A completed deploy — the authoritative public URL. */
|
|
87
|
+
export interface DeployResult {
|
|
88
|
+
url: string;
|
|
89
|
+
/**
|
|
90
|
+
* Adapter-specific next-steps block printed INSTEAD of the CLI's default
|
|
91
|
+
* "install on an instance" footer — managed deploys already installed the
|
|
92
|
+
* domain, so the default hint is wrong there. Pre-indented plain lines.
|
|
93
|
+
*/
|
|
94
|
+
nextSteps?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface DomainAdapter<Params> {
|
|
97
|
+
/** 'astrale-host' | 'cloudflare' | 'node' | … */
|
|
98
|
+
name: string;
|
|
99
|
+
/** Resolve an env key to this adapter's typed params. Throws on unknown key. */
|
|
100
|
+
params(env: string): Params;
|
|
101
|
+
/** Local + hot-reload (watch) → controllable handle. Orthogonal to env. */
|
|
102
|
+
watch(params: Params, ctx: WatchCtx): Promise<WatchHandle>;
|
|
103
|
+
/**
|
|
104
|
+
* Optional: re-run codegen for an ALREADY-RUNNING `watch` after
|
|
105
|
+
* `astrale.config.ts` changed — same shape as `watch` but it must NOT spawn
|
|
106
|
+
* anything: it only rewrites the generated files, and the running dev server
|
|
107
|
+
* (which watches them, e.g. `wrangler dev` on its `--config`) picks them up.
|
|
108
|
+
* Adapters without it fall back to "restart to apply config changes".
|
|
109
|
+
*/
|
|
110
|
+
regenerate?(params: Params, ctx: WatchCtx): Promise<void>;
|
|
111
|
+
/** Build + bundle + ship (the adapter owns ITS build) → authoritative URL. */
|
|
112
|
+
deploy(params: Params, ctx: DeployCtx): Promise<DeployResult>;
|
|
113
|
+
/**
|
|
114
|
+
* Optional: the path (relative to the project root) of the gitignored secrets
|
|
115
|
+
* file for these params. The CLI loads it and passes the parsed map as
|
|
116
|
+
* `ctx.secrets` — keeping secret-file loading generic while the path stays
|
|
117
|
+
* provider-typed. Return `undefined` for "no secrets file".
|
|
118
|
+
*/
|
|
119
|
+
secretsFile?(params: Params): string | undefined;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Spec passed to `defineAdapter` — identical to `DomainAdapter` minus the
|
|
123
|
+
* `params(env)` resolver, which the helper attaches from `envs`. Custom adapter
|
|
124
|
+
* authors use this so they never re-implement env→params resolution.
|
|
125
|
+
*/
|
|
126
|
+
export interface AdapterSpec<Params> {
|
|
127
|
+
name: string;
|
|
128
|
+
/** The provider-typed env map (`{ dev: {...}, prod: {...}, … }`). */
|
|
129
|
+
envs: Record<string, Params>;
|
|
130
|
+
watch(params: Params, ctx: WatchCtx): Promise<WatchHandle>;
|
|
131
|
+
regenerate?(params: Params, ctx: WatchCtx): Promise<void>;
|
|
132
|
+
deploy(params: Params, ctx: DeployCtx): Promise<DeployResult>;
|
|
133
|
+
secretsFile?(params: Params): string | undefined;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build a `DomainAdapter` from a spec + an env map, attaching a `params(env)`
|
|
137
|
+
* resolver that throws a clear error on an unknown key (listing the valid ones).
|
|
138
|
+
*/
|
|
139
|
+
export declare function defineAdapter<Params>(spec: AdapterSpec<Params>): DomainAdapter<Params>;
|
|
140
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/config/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deployment-adapter contract.
|
|
3
|
+
*
|
|
4
|
+
* A deployment target = one npm package implementing `DomainAdapter<Params>`.
|
|
5
|
+
* The adapter is GENERIC over its own `Params` so envs AND provider settings
|
|
6
|
+
* stay 100% adapter-specific (a Cloudflare adapter's `{ route, secrets }` is
|
|
7
|
+
* nothing like a Node adapter's `{ port }`). The CLI resolves
|
|
8
|
+
* `envs[<env>] → Params` via `adapter.params(env)` and then drives the adapter
|
|
9
|
+
* with the resolved params — install of the resulting URL and the `requires`
|
|
10
|
+
* check are generic and live in the CLI, never in the adapter.
|
|
11
|
+
*
|
|
12
|
+
* The central guarantee: `watch()` and `deploy()` both return a `url` — that's
|
|
13
|
+
* what the CLI prints, what `astrale domain install <url>` consumes, and
|
|
14
|
+
* the worker's `iss` identity. The URL is an OUTPUT of watch/deploy; nothing
|
|
15
|
+
* in the contract asks an adapter to predict it ahead of time.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Build a `DomainAdapter` from a spec + an env map, attaching a `params(env)`
|
|
19
|
+
* resolver that throws a clear error on an unknown key (listing the valid ones).
|
|
20
|
+
*/
|
|
21
|
+
export function defineAdapter(spec) {
|
|
22
|
+
const keys = Object.keys(spec.envs);
|
|
23
|
+
return {
|
|
24
|
+
name: spec.name,
|
|
25
|
+
params(env) {
|
|
26
|
+
const params = spec.envs[env];
|
|
27
|
+
if (params === undefined) {
|
|
28
|
+
const known = keys.length ? keys.join(', ') : '(none)';
|
|
29
|
+
throw new Error(`Adapter "${spec.name}": unknown env "${env}". Known envs: ${known}. ` +
|
|
30
|
+
`Add it to the adapter's env map in astrale.config.ts.`);
|
|
31
|
+
}
|
|
32
|
+
return params;
|
|
33
|
+
},
|
|
34
|
+
watch: spec.watch,
|
|
35
|
+
deploy: spec.deploy,
|
|
36
|
+
...(spec.regenerate ? { regenerate: spec.regenerate } : {}),
|
|
37
|
+
...(spec.secretsFile ? { secretsFile: spec.secretsFile } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/config/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAoIH;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAS,IAAyB;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,CAAC,GAAW;YAChB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;gBACtD,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,CAAC,IAAI,mBAAmB,GAAG,kBAAkB,KAAK,IAAI;oBACpE,uDAAuD,CAC1D,CAAA;YACH,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QACD,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineDomain` — the WORKER-SAFE definition of a domain: what the domain *is*
|
|
3
|
+
* (its `schema`, `methods`, `deps`, `views`, standalone `functions`, `client`
|
|
4
|
+
* SPA) plus its addressing identity (`origin`, `requires`, `postInstall`). It
|
|
5
|
+
* deliberately carries NO deployment adapter — the adapter (`cloudflare(...)`,
|
|
6
|
+
* `astrale(...)`) is node-only code (filesystem, wrangler) that must never enter
|
|
7
|
+
* the worker bundle. The author wires this in a `domain.ts` the generated worker
|
|
8
|
+
* imports directly, then attaches the adapter separately with `deploy(domain,
|
|
9
|
+
* adapter)` in `astrale.config.ts` (see `./deploy`).
|
|
10
|
+
*
|
|
11
|
+
* The modules are wired EXPLICITLY here — imported and passed in — not
|
|
12
|
+
* discovered from magic folder names. A renamed or mistyped module is a compile
|
|
13
|
+
* error at this call site, never a silently-missing worker route. The adapter
|
|
14
|
+
* reads this one definition for everything it codegens; there is no second
|
|
15
|
+
* filesystem probe to drift from it. `defineDomain` itself builds no server and
|
|
16
|
+
* boots no kernel — it validates and packages the declaration.
|
|
17
|
+
*/
|
|
18
|
+
import type { Schema } from '@astrale-os/kernel-dsl';
|
|
19
|
+
import type { RemoteFunctionDef, ViewDef } from '../define';
|
|
20
|
+
import type { SchemaMethodsImpl } from '../method';
|
|
21
|
+
type AnyViewDef = ViewDef<any>;
|
|
22
|
+
type AnyFunctionDef = RemoteFunctionDef<any, any, any>;
|
|
23
|
+
/**
|
|
24
|
+
* The domain's client SPA binding. Its presence is the whole signal — there is
|
|
25
|
+
* no `existsSync('client/')` probe. `dir` is the project-relative source folder
|
|
26
|
+
* (e.g. `'client'`); the worker serves its built SPA under `/ui` via its Assets
|
|
27
|
+
* binding. Always written out explicitly (`client: { dir: 'client' }`) — there
|
|
28
|
+
* is no boolean shorthand, so the source folder is never implicit.
|
|
29
|
+
*/
|
|
30
|
+
export type ClientBinding = {
|
|
31
|
+
dir: string;
|
|
32
|
+
};
|
|
33
|
+
export interface DefineDomainConfig<S extends Schema, TDeps, TEnv = unknown> {
|
|
34
|
+
/** The domain schema (from `schema/`). Its `.domain` seeds the default origin. */
|
|
35
|
+
schema: S;
|
|
36
|
+
/**
|
|
37
|
+
* The domain's method implementations (from `methods/`), one per schema
|
|
38
|
+
* method. Typed against `schema` — an unimplemented or misnamed method is a
|
|
39
|
+
* compile error here.
|
|
40
|
+
*/
|
|
41
|
+
methods: SchemaMethodsImpl<S, TDeps>;
|
|
42
|
+
/**
|
|
43
|
+
* Map the worker `env` to the handler dependency container (`ctx.deps`).
|
|
44
|
+
* Run ONCE per cold isolate per serving URL (the built app is cached), NOT
|
|
45
|
+
* per request — so it's the place to construct ports/clients once instead of
|
|
46
|
+
* re-deriving them in every handler. Its return type IS `TDeps`: type it the
|
|
47
|
+
* shape your `methods` read (e.g. `(env) => ({ platform: buildPlatform(env) })`)
|
|
48
|
+
* and the methods get the rich container, not raw env. The same value reaches
|
|
49
|
+
* view/function handlers and the `install.authorize` hook.
|
|
50
|
+
*
|
|
51
|
+
* Omit for the common case: `env` is passed straight through (`TDeps = TEnv`),
|
|
52
|
+
* so existing domains are unaffected. The function itself is imported by the
|
|
53
|
+
* generated worker from a fixed `deps` module, mirroring `methods` — wire it
|
|
54
|
+
* here so the type check binds `env → TDeps` and the adapter knows to emit it.
|
|
55
|
+
*/
|
|
56
|
+
deps?: (env: TEnv, url: string) => TDeps;
|
|
57
|
+
/**
|
|
58
|
+
* The domain's Views (iframe-mountable UIs), keyed by slug. Omit when the
|
|
59
|
+
* domain has none. Each becomes a `View` node + a worker route.
|
|
60
|
+
*/
|
|
61
|
+
views?: Record<string, AnyViewDef>;
|
|
62
|
+
/**
|
|
63
|
+
* The domain's standalone Functions (callables not bound to a class), keyed
|
|
64
|
+
* by slug. Omit when the domain has none.
|
|
65
|
+
*/
|
|
66
|
+
functions?: Record<string, AnyFunctionDef>;
|
|
67
|
+
/**
|
|
68
|
+
* The domain's client SPA, e.g. `{ dir: 'client' }`. Its presence enables it
|
|
69
|
+
* (no folder probing); `dir` is the project-relative source folder, built and
|
|
70
|
+
* served under `/ui`. Omit for a domain with no SPA.
|
|
71
|
+
*/
|
|
72
|
+
client?: ClientBinding;
|
|
73
|
+
/**
|
|
74
|
+
* The domain's **addressing name** (the graph slug it mounts under, e.g.
|
|
75
|
+
* `'crm.acme.dev'`). Defaults to `schema.domain`. Must be a name, never a
|
|
76
|
+
* URL. This is **NOT** the cryptographic identity: the `iss` is the worker's
|
|
77
|
+
* **serving URL**, pinned by the kernel to the URL it fetched the domain at
|
|
78
|
+
* during install (and verified against that URL's JWKS). `origin` is a free
|
|
79
|
+
* addressing label, only required to be unique in the graph.
|
|
80
|
+
*/
|
|
81
|
+
origin?: string;
|
|
82
|
+
/** Cross-domain deps, by origin. Verified present on the instance at install. */
|
|
83
|
+
requires?: readonly string[];
|
|
84
|
+
/**
|
|
85
|
+
* Astrale Path (usually an AbsolutePath to a `functions/` entry) the kernel
|
|
86
|
+
* calls once after install, as __SYSTEM__ — where the domain posts its own
|
|
87
|
+
* grants / seed.
|
|
88
|
+
*/
|
|
89
|
+
postInstall?: string;
|
|
90
|
+
}
|
|
91
|
+
export interface DomainDefinition {
|
|
92
|
+
schema: Schema;
|
|
93
|
+
methods: SchemaMethodsImpl<Schema, any>;
|
|
94
|
+
/**
|
|
95
|
+
* env → deps mapper, when the author supplied one. Held loosely (the worker
|
|
96
|
+
* imports the real function from its own `deps` module); the CLI reads only
|
|
97
|
+
* its PRESENCE to set `DomainInfo.hasDeps`, the codegen signal.
|
|
98
|
+
*/
|
|
99
|
+
deps?: (env: any, url: string) => any;
|
|
100
|
+
views?: Record<string, ViewDef>;
|
|
101
|
+
functions?: Record<string, AnyFunctionDef>;
|
|
102
|
+
/** Normalized client binding (resolved `dir`), or absent when the domain has no SPA. */
|
|
103
|
+
client?: {
|
|
104
|
+
dir: string;
|
|
105
|
+
};
|
|
106
|
+
origin: string;
|
|
107
|
+
requires: readonly string[];
|
|
108
|
+
postInstall?: string;
|
|
109
|
+
}
|
|
110
|
+
export declare function defineDomain<S extends Schema, TDeps, TEnv = unknown>(config: DefineDomainConfig<S, TDeps, TEnv>): DomainDefinition;
|
|
111
|
+
export {};
|
|
112
|
+
//# sourceMappingURL=define-domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-domain.d.ts","sourceRoot":"","sources":["../../src/config/define-domain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAIpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAQlD,KAAK,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;AAC9B,KAAK,cAAc,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAGtD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3C,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO;IACzE,kFAAkF;IAClF,MAAM,EAAE,CAAC,CAAA;IACT;;;;OAIG;IACH,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACpC;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,KAAK,CAAA;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IAC1C;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IAEd,OAAO,EAAE,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvC;;;;OAIG;IAEH,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,KAAK,GAAG,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IAC1C,wFAAwF;IACxF,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,EAClE,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GACzC,gBAAgB,CAsDlB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineDomain` — the WORKER-SAFE definition of a domain: what the domain *is*
|
|
3
|
+
* (its `schema`, `methods`, `deps`, `views`, standalone `functions`, `client`
|
|
4
|
+
* SPA) plus its addressing identity (`origin`, `requires`, `postInstall`). It
|
|
5
|
+
* deliberately carries NO deployment adapter — the adapter (`cloudflare(...)`,
|
|
6
|
+
* `astrale(...)`) is node-only code (filesystem, wrangler) that must never enter
|
|
7
|
+
* the worker bundle. The author wires this in a `domain.ts` the generated worker
|
|
8
|
+
* imports directly, then attaches the adapter separately with `deploy(domain,
|
|
9
|
+
* adapter)` in `astrale.config.ts` (see `./deploy`).
|
|
10
|
+
*
|
|
11
|
+
* The modules are wired EXPLICITLY here — imported and passed in — not
|
|
12
|
+
* discovered from magic folder names. A renamed or mistyped module is a compile
|
|
13
|
+
* error at this call site, never a silently-missing worker route. The adapter
|
|
14
|
+
* reads this one definition for everything it codegens; there is no second
|
|
15
|
+
* filesystem probe to drift from it. `defineDomain` itself builds no server and
|
|
16
|
+
* boots no kernel — it validates and packages the declaration.
|
|
17
|
+
*/
|
|
18
|
+
import { DomainOrigin, extractDomainSlug } from '@astrale-os/kernel-core/domain';
|
|
19
|
+
export function defineDomain(config) {
|
|
20
|
+
const rawOrigin = config.origin ?? schemaDomain(config.schema);
|
|
21
|
+
if (!rawOrigin) {
|
|
22
|
+
throw new Error('defineDomain: could not resolve `origin`. Set it explicitly or give the ' +
|
|
23
|
+
'schema a base domain (`defineSchema("crm.acme.dev", …)`).');
|
|
24
|
+
}
|
|
25
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(rawOrigin)) {
|
|
26
|
+
throw new Error(`defineDomain: \`origin\` must be a stable name (e.g. "crm.acme.dev"), not a URL — got "${rawOrigin}". ` +
|
|
27
|
+
'The deployment URL is an output of deploy, not the identity.');
|
|
28
|
+
}
|
|
29
|
+
// Canonicalize + validate the origin exactly as the kernel does (lowercased,
|
|
30
|
+
// FQDN-like, matches DOMAIN_ORIGIN_RE). Failing HERE gives a clear authoring-
|
|
31
|
+
// time error instead of a cryptic failure deep in codegen / install, and makes
|
|
32
|
+
// `origin` the same lowercased form the kernel stores graph nodes under.
|
|
33
|
+
let origin;
|
|
34
|
+
try {
|
|
35
|
+
origin = DomainOrigin(rawOrigin);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new Error(`defineDomain: invalid \`origin\` "${rawOrigin}". Use a lowercase FQDN-like slug ` +
|
|
39
|
+
'(letters, digits, ".", "_", "-"), e.g. "crm.acme.dev".');
|
|
40
|
+
}
|
|
41
|
+
// `requires` entries are domain origins — validate them with the same rule as
|
|
42
|
+
// `origin` so a URL or mixed-case entry fails at authoring time, not install.
|
|
43
|
+
const requires = (config.requires ?? []).map((dep) => {
|
|
44
|
+
try {
|
|
45
|
+
return DomainOrigin(dep);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw new Error(`defineDomain: invalid \`requires\` entry "${dep}". Use the dependency's origin slug ` +
|
|
49
|
+
'(lowercase FQDN-like, e.g. "dist.astrale.ai"), not a URL.');
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
schema: config.schema,
|
|
54
|
+
methods: config.methods,
|
|
55
|
+
...(config.deps ? { deps: config.deps } : {}),
|
|
56
|
+
...(config.views ? { views: config.views } : {}),
|
|
57
|
+
...(config.functions ? { functions: config.functions } : {}),
|
|
58
|
+
...(config.client ? { client: config.client } : {}),
|
|
59
|
+
origin,
|
|
60
|
+
requires,
|
|
61
|
+
...(config.postInstall
|
|
62
|
+
? { postInstall: normalizePostInstall(config.postInstall, origin) }
|
|
63
|
+
: {}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate a `postInstall` hook path and align its leading origin segment with
|
|
68
|
+
* the canonical (lowercased) origin. Only the typed colon forms are accepted
|
|
69
|
+
* (`/:<origin>:class.X:seed`, `/:<origin>:interface.Ops:seed`) — mirroring the
|
|
70
|
+
* kernel's own origin guard, which refuses absolute tree paths because they
|
|
71
|
+
* cannot prove their origin from the string alone. The hook is often authored
|
|
72
|
+
* as `` `/:${schema.domain}:…` `` where `schema.domain` keeps its source
|
|
73
|
+
* casing, but the kernel stores graph nodes (and runs its guard) under the
|
|
74
|
+
* lowercased origin — so the origin segment is re-stamped canonical. Rejects a
|
|
75
|
+
* tree path or one pointing at a different domain (the kernel calls the hook
|
|
76
|
+
* as __SYSTEM__ and refuses a foreign target).
|
|
77
|
+
*/
|
|
78
|
+
function normalizePostInstall(postInstall, origin) {
|
|
79
|
+
const slug = extractDomainSlug(postInstall);
|
|
80
|
+
if (slug === null) {
|
|
81
|
+
throw new Error(`defineDomain: \`postInstall\` must be a typed colon-path under "/:${origin}" ` +
|
|
82
|
+
`(e.g. "/:${origin}:class.Note:seed" or "/:${origin}:interface.Ops:seed"); ` +
|
|
83
|
+
`absolute tree paths are not accepted — got "${postInstall}".`);
|
|
84
|
+
}
|
|
85
|
+
if (slug.toLowerCase() !== origin) {
|
|
86
|
+
throw new Error(`defineDomain: \`postInstall\` "${postInstall}" must resolve under the domain origin ` +
|
|
87
|
+
`"/${origin}" — the kernel calls it as __SYSTEM__ and refuses a hook pointing at another domain.`);
|
|
88
|
+
}
|
|
89
|
+
// Re-stamp the origin segment with its canonical (lowercased) form.
|
|
90
|
+
return postInstall.startsWith('/:')
|
|
91
|
+
? `/:${origin}${postInstall.slice(2 + slug.length)}`
|
|
92
|
+
: `/${origin}${postInstall.slice(1 + slug.length)}`;
|
|
93
|
+
}
|
|
94
|
+
function schemaDomain(schema) {
|
|
95
|
+
const value = schema.domain;
|
|
96
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=define-domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-domain.js","sourceRoot":"","sources":["../../src/config/define-domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `deploy` — bind a worker-safe `DomainDefinition` to a deployment adapter,
|
|
3
|
+
* producing the value `astrale.config.ts` default-exports for the CLI.
|
|
4
|
+
*
|
|
5
|
+
* The split exists to keep the worker bundle clean: `defineDomain` (in the
|
|
6
|
+
* author's `domain.ts`) carries only worker-safe modules and is what the
|
|
7
|
+
* generated worker imports; the adapter (`cloudflare(...)` / `astrale(...)`) is
|
|
8
|
+
* node-only code that the worker must never pull in. `deploy(domain, adapter)`
|
|
9
|
+
* is authored in `astrale.config.ts` — a Node-only module the CLI loads but the
|
|
10
|
+
* worker never imports — so the adapter stays out of the bundle.
|
|
11
|
+
*
|
|
12
|
+
* export const domain = defineDomain({ schema, methods, deps, views, client })
|
|
13
|
+
*
|
|
14
|
+
* import { domain } from './domain'
|
|
15
|
+
* export default deploy(domain, cloudflare({ dev, prod }))
|
|
16
|
+
*
|
|
17
|
+
* The returned shape is just the definition with `adapter` attached — exactly
|
|
18
|
+
* what the CLI already reads (`def.adapter`, `def.origin`, `def.schema`, …), so
|
|
19
|
+
* the loader is unchanged.
|
|
20
|
+
*/
|
|
21
|
+
import type { DomainAdapter } from './adapter';
|
|
22
|
+
import type { DomainDefinition } from './define-domain';
|
|
23
|
+
/** A domain definition bound to its deployment adapter — the CLI's input. */
|
|
24
|
+
export interface DeployConfig<Params = unknown> extends DomainDefinition {
|
|
25
|
+
adapter: DomainAdapter<Params>;
|
|
26
|
+
}
|
|
27
|
+
export declare function deploy<Params>(domain: DomainDefinition, adapter: DomainAdapter<Params>): DeployConfig<Params>;
|
|
28
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/config/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,6EAA6E;AAC7E,MAAM,WAAW,YAAY,CAAC,MAAM,GAAG,OAAO,CAAE,SAAQ,gBAAgB;IACtE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAC/B;AAED,wBAAgB,MAAM,CAAC,MAAM,EAC3B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAC7B,YAAY,CAAC,MAAM,CAAC,CAEtB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `deploy` — bind a worker-safe `DomainDefinition` to a deployment adapter,
|
|
3
|
+
* producing the value `astrale.config.ts` default-exports for the CLI.
|
|
4
|
+
*
|
|
5
|
+
* The split exists to keep the worker bundle clean: `defineDomain` (in the
|
|
6
|
+
* author's `domain.ts`) carries only worker-safe modules and is what the
|
|
7
|
+
* generated worker imports; the adapter (`cloudflare(...)` / `astrale(...)`) is
|
|
8
|
+
* node-only code that the worker must never pull in. `deploy(domain, adapter)`
|
|
9
|
+
* is authored in `astrale.config.ts` — a Node-only module the CLI loads but the
|
|
10
|
+
* worker never imports — so the adapter stays out of the bundle.
|
|
11
|
+
*
|
|
12
|
+
* export const domain = defineDomain({ schema, methods, deps, views, client })
|
|
13
|
+
*
|
|
14
|
+
* import { domain } from './domain'
|
|
15
|
+
* export default deploy(domain, cloudflare({ dev, prod }))
|
|
16
|
+
*
|
|
17
|
+
* The returned shape is just the definition with `adapter` attached — exactly
|
|
18
|
+
* what the CLI already reads (`def.adapter`, `def.origin`, `def.schema`, …), so
|
|
19
|
+
* the loader is unchanged.
|
|
20
|
+
*/
|
|
21
|
+
export function deploy(domain, adapter) {
|
|
22
|
+
return { ...domain, adapter };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/config/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAUH,MAAM,UAAU,MAAM,CACpB,MAAwB,EACxB,OAA8B;IAE9B,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAA;AAC/B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@astrale-os/sdk` config surface — the author-facing declaration of a
|
|
3
|
+
* standalone domain (`astrale.config.ts`) and the deployment-adapter contract.
|
|
4
|
+
*
|
|
5
|
+
* import { defineDomain, deploy } from '@astrale-os/sdk'
|
|
6
|
+
* import { cloudflare } from '@astrale-os/adapter-cloudflare'
|
|
7
|
+
*
|
|
8
|
+
* `defineDomain` (in `domain.ts`) declares the WORKER-SAFE domain — what it is +
|
|
9
|
+
* its identity, no adapter. `deploy(domain, adapter)` (in `astrale.config.ts`)
|
|
10
|
+
* binds it to a deployment target; the `astrale-domain` bin (folded into this
|
|
11
|
+
* package — see `../cli`) reads that default export and drives the adapter.
|
|
12
|
+
* Neither builds a server nor boots a kernel — they validate and package the
|
|
13
|
+
* declaration.
|
|
14
|
+
*/
|
|
15
|
+
export { defineDomain } from './define-domain';
|
|
16
|
+
export type { ClientBinding, DefineDomainConfig, DomainDefinition } from './define-domain';
|
|
17
|
+
export { deploy } from './deploy';
|
|
18
|
+
export type { DeployConfig } from './deploy';
|
|
19
|
+
export { defineAdapter } from './adapter';
|
|
20
|
+
export type { AdapterSpec, DeployCtx, DeployResult, DomainAdapter, DomainInfo, WatchCtx, WatchHandle, } from './adapter';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAE1F,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,YAAY,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,GACZ,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@astrale-os/sdk` config surface — the author-facing declaration of a
|
|
3
|
+
* standalone domain (`astrale.config.ts`) and the deployment-adapter contract.
|
|
4
|
+
*
|
|
5
|
+
* import { defineDomain, deploy } from '@astrale-os/sdk'
|
|
6
|
+
* import { cloudflare } from '@astrale-os/adapter-cloudflare'
|
|
7
|
+
*
|
|
8
|
+
* `defineDomain` (in `domain.ts`) declares the WORKER-SAFE domain — what it is +
|
|
9
|
+
* its identity, no adapter. `deploy(domain, adapter)` (in `astrale.config.ts`)
|
|
10
|
+
* binds it to a deployment target; the `astrale-domain` bin (folded into this
|
|
11
|
+
* package — see `../cli`) reads that default export and drives the adapter.
|
|
12
|
+
* Neither builds a server nor boots a kernel — they validate and package the
|
|
13
|
+
* declaration.
|
|
14
|
+
*/
|
|
15
|
+
export { defineDomain } from './define-domain';
|
|
16
|
+
export { deploy } from './deploy';
|
|
17
|
+
export { defineAdapter } from './adapter';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -22,7 +22,8 @@ import type { AuthContext } from '@astrale-os/kernel-core';
|
|
|
22
22
|
import type { Context } from 'hono';
|
|
23
23
|
import type { z } from 'zod';
|
|
24
24
|
import type { CallRemoteFn } from '../dispatch/call-remote';
|
|
25
|
-
|
|
25
|
+
import type { KernelForAuth } from '../method/context';
|
|
26
|
+
export type RemoteFunctionContext<TParams, TDeps = unknown, TKernel = BoundClientSessionView<FnMap> | null> = {
|
|
26
27
|
/** Validated params (Zod-checked against `inputSchema`). */
|
|
27
28
|
params: TParams;
|
|
28
29
|
/** Hono request context — escape hatch for headers, raw body, etc. */
|
|
@@ -34,10 +35,12 @@ export type RemoteFunctionContext<TParams, TDeps = unknown> = {
|
|
|
34
35
|
/**
|
|
35
36
|
* `BoundClientSessionView` to the parent kernel, bound to the composed
|
|
36
37
|
* credential `union(delegation, self)` — same shape as `RemoteContext.kernel`
|
|
37
|
-
* for `remoteMethod`.
|
|
38
|
-
*
|
|
38
|
+
* for `remoteMethod`. Nullability follows {@link KernelForAuth} of the
|
|
39
|
+
* function's `auth`: non-null for the default `'required'`, `… | null` for
|
|
40
|
+
* `'optional'`, `null` for `'public'` (use {@link RemoteFunctionContext.selfKernel}
|
|
41
|
+
* there, after verifying the upstream).
|
|
39
42
|
*/
|
|
40
|
-
kernel:
|
|
43
|
+
kernel: TKernel;
|
|
41
44
|
/**
|
|
42
45
|
* Call another worker's remote method, re-minting the credential for the
|
|
43
46
|
* target's audience. Same contract as {@link RemoteContext.callRemote}: throws
|
|
@@ -56,7 +59,7 @@ export type RemoteFunctionContext<TParams, TDeps = unknown> = {
|
|
|
56
59
|
*/
|
|
57
60
|
selfKernel: (kernelUrl?: string) => Promise<BoundClientSessionView<FnMap>>;
|
|
58
61
|
};
|
|
59
|
-
export type RemoteFunctionDef<TParams = unknown, TResult = unknown, TDeps = unknown> = {
|
|
62
|
+
export type RemoteFunctionDef<TParams = unknown, TResult = unknown, TDeps = unknown, TAuth extends AuthPolicy = 'required'> = {
|
|
60
63
|
/**
|
|
61
64
|
* Canonical callable identity. Auto-derived as `function.<slug>` (where
|
|
62
65
|
* `<slug>` is the map key) when omitted. Stored as `Function.ref` on the
|
|
@@ -78,19 +81,24 @@ export type RemoteFunctionDef<TParams = unknown, TResult = unknown, TDeps = unkn
|
|
|
78
81
|
* placeholders both supported.
|
|
79
82
|
*/
|
|
80
83
|
binding?: FunctionBinding;
|
|
81
|
-
/**
|
|
82
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Authentication policy. Defaults to `'required'`. Captured as a literal type
|
|
86
|
+
* so it drives {@link KernelForAuth} on the `execute`/`authorize` context:
|
|
87
|
+
* omit it (or `'required'`) → `ctx.kernel` non-null; `'optional'` → `… | null`;
|
|
88
|
+
* `'public'` → `null` (webhooks reach the graph via `ctx.selfKernel`).
|
|
89
|
+
*/
|
|
90
|
+
auth?: TAuth;
|
|
83
91
|
/** Optional pre-execute authorization. Throw to deny. */
|
|
84
|
-
authorize?: (ctx: RemoteFunctionContext<TParams, TDeps
|
|
92
|
+
authorize?: (ctx: RemoteFunctionContext<TParams, TDeps, KernelForAuth<TAuth>>) => void | Promise<void>;
|
|
85
93
|
/** The function body. May be async. */
|
|
86
|
-
execute: (ctx: RemoteFunctionContext<TParams, TDeps
|
|
94
|
+
execute: (ctx: RemoteFunctionContext<TParams, TDeps, KernelForAuth<TAuth>>) => TResult | Promise<TResult>;
|
|
87
95
|
/** Optional human-readable description. */
|
|
88
96
|
description?: string;
|
|
89
97
|
};
|
|
90
|
-
export type AnyRemoteFunctionDef = RemoteFunctionDef<any, any, any>;
|
|
98
|
+
export type AnyRemoteFunctionDef = RemoteFunctionDef<any, any, any, AuthPolicy>;
|
|
91
99
|
/**
|
|
92
100
|
* Identity helper for authoring a RemoteFunction. Returns its argument
|
|
93
101
|
* unchanged — `defineRemoteDomain` consumes the typed shape.
|
|
94
102
|
*/
|
|
95
|
-
export declare function defineRemoteFunction<TParams, TResult, TDeps = unknown>(def: RemoteFunctionDef<TParams, TResult, TDeps>): RemoteFunctionDef<TParams, TResult, TDeps>;
|
|
103
|
+
export declare function defineRemoteFunction<TParams, TResult, TDeps = unknown, TAuth extends AuthPolicy = 'required'>(def: RemoteFunctionDef<TParams, TResult, TDeps, TAuth>): RemoteFunctionDef<TParams, TResult, TDeps, TAuth>;
|
|
96
104
|
//# sourceMappingURL=remote-function.d.ts.map
|