@astrale-os/sdk 0.6.0-beta.42 → 0.6.0-beta.43

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.
@@ -1,9 +1,8 @@
1
1
  /**
2
- * A recipe (spec § Recipes: the contract): an id, a `build` of one to eight stages of reads over
3
- * the Domain's handles, an optional `output` and the errors it declares. Stage n receives the
4
- * merged results of stages 1 to n - 1. A single stage returns one read or a record of facets read
5
- * together; each of several returns a record of facets. A stage cannot be a function facet inside one object literal (TS7031: its parameter
6
- * has no contextual type while the record's is inferred), so stages are a tuple.
2
+ * A recipe (spec § Recipes: the contract): an id, a `build` over the Domain's handles, an optional
3
+ * `output` and the errors it declares. `build` returns one read, a record of facets read together,
4
+ * or, when reads wait for others, `steps(first, (earlier) => next, …)`: two to eight records of
5
+ * facets, each function receiving the merged results of the steps before it.
7
6
  */
8
7
  import type { z } from 'zod';
9
8
  import type { DeclaredErrorDefinition } from '../../../platform/schema/error.js';
@@ -16,11 +15,11 @@ export type Facet = Read<unknown> | readonly Read<unknown>[] | undefined;
16
15
  export type Facets = {
17
16
  readonly [facet: string]: Facet;
18
17
  };
19
- /** What a single stage returns: one read, or a record of facets. */
18
+ /** What `build` returns without steps, and the first step: one read, or a record of facets. */
20
19
  export type Built = Read<unknown> | Facets;
21
20
  /** A read gives its answer; a list of reads a list of answers; nothing gives `undefined`. */
22
21
  export type FacetResult<F> = F extends Read<infer T> ? T : F extends readonly Read<infer T>[] ? readonly T[] : F extends undefined ? undefined : never;
23
- /** The results of one stage; a page read, a recipe's single read, gives its `Page`. */
22
+ /** The results of one step; a page read, a recipe's single read, gives its `Page`. */
24
23
  export type Results<B> = B extends Read<infer T> ? T : B extends PageRead<infer T> ? Page<T> : {
25
24
  readonly [K in keyof B]: FacetResult<B[K]>;
26
25
  };
@@ -31,14 +30,14 @@ type Flat<T> = T extends unknown ? {
31
30
  readonly [K in keyof T]: T[K];
32
31
  } : never;
33
32
  /**
34
- * A later stage's facets: none takes a name an earlier stage read, whose result the merge would
33
+ * A later step's facets: none takes a name an earlier step read, whose result the merge would
35
34
  * replace. An index signature (its `string` and `number` keys) names no facet in particular, so it
36
35
  * refuses none.
37
36
  */
38
37
  type Later<Earlier> = Facets & {
39
- readonly [K in keyof Earlier as string extends K ? never : number extends K ? never : K]?: '✗ an earlier stage read this facet: name it otherwise';
38
+ readonly [K in keyof Earlier as string extends K ? never : number extends K ? never : K]?: '✗ an earlier step read this facet: name it otherwise';
40
39
  };
41
- /** The results of the stages so far, merged. */
40
+ /** The results of the steps so far, merged. */
42
41
  export type Merged<B1, B2, B3 = {}, B4 = {}, B5 = {}, B6 = {}, B7 = {}, B8 = {}> = Flat<Results<B1> & Results<B2> & Results<B3> & Results<B4> & Results<B5> & Results<B6> & Results<B7> & Results<B8>>;
43
42
  /** The errors a recipe declares, by UPPER_SNAKE code: at most 32. */
44
43
  export type Errors = {
@@ -85,7 +84,6 @@ export type PageRecipe<Id extends string = string, Input = unknown, Output = unk
85
84
  export type InputOf<R> = R extends Recipe<string, infer I, unknown, Errors> ? I : never;
86
85
  /** The output a recipe answers. */
87
86
  export type OutputOf<R> = R extends Recipe<string, unknown, infer O, Errors> ? O : never;
88
- type Stage<S, I, Earlier, B> = (earlier: Earlier, input: I, d: Handles<S>) => B;
89
87
  type Output<S, Results, I, O, E extends Errors> = (results: Results, input: I, context: OutputContext<S, E>) => O;
90
88
  /**
91
89
  * Whether a type is portable JSON as far as its type can tell: a function, or an object that
@@ -97,38 +95,40 @@ type Portable<T, Depth extends readonly unknown[] = []> = unknown extends T ? tr
97
95
  }[keyof T] extends true ? true : false;
98
96
  /** `output` returns portable JSON, checked by type (spec § API reference: Recipes). */
99
97
  type PortableOutput<O> = [Portable<O>] extends [true] ? unknown : '✗ output returns portable JSON: no function, Promise, Date, Map or other object with methods';
100
- /** `defineQuery<Schema>()`'s v7 forms: a string id first. */
98
+ /** What `steps(…)` returns: the merged results of its steps, for `output`. */
99
+ export interface Stepped<out R> {
100
+ readonly '~stepped': R;
101
+ }
102
+ /** The results of what `build` returns: a read's, a page's, a record of facets', or the steps'. */
103
+ export type BuiltResults<B> = B extends Stepped<infer R> ? R : Results<B>;
104
+ /**
105
+ * `build`'s third parameter: reads that wait for others. The first step is a record of facets;
106
+ * each next one a function of the merged results of the steps before it, returning a record of
107
+ * facets none of them read. Two to eight steps, one overload per count, so a call's error is its
108
+ * own count's.
109
+ */
110
+ export interface Steps {
111
+ <B1 extends Facets, B2 extends Later<Results<B1>>>(first: B1, second: (earlier: Results<B1>) => B2): Stepped<Merged<B1, B2>>;
112
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3): Stepped<Merged<B1, B2, B3>>;
113
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>, B4 extends Later<Merged<B1, B2, B3>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3, fourth: (earlier: Merged<B1, B2, B3>) => B4): Stepped<Merged<B1, B2, B3, B4>>;
114
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>, B4 extends Later<Merged<B1, B2, B3>>, B5 extends Later<Merged<B1, B2, B3, B4>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3, fourth: (earlier: Merged<B1, B2, B3>) => B4, fifth: (earlier: Merged<B1, B2, B3, B4>) => B5): Stepped<Merged<B1, B2, B3, B4, B5>>;
115
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>, B4 extends Later<Merged<B1, B2, B3>>, B5 extends Later<Merged<B1, B2, B3, B4>>, B6 extends Later<Merged<B1, B2, B3, B4, B5>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3, fourth: (earlier: Merged<B1, B2, B3>) => B4, fifth: (earlier: Merged<B1, B2, B3, B4>) => B5, sixth: (earlier: Merged<B1, B2, B3, B4, B5>) => B6): Stepped<Merged<B1, B2, B3, B4, B5, B6>>;
116
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>, B4 extends Later<Merged<B1, B2, B3>>, B5 extends Later<Merged<B1, B2, B3, B4>>, B6 extends Later<Merged<B1, B2, B3, B4, B5>>, B7 extends Later<Merged<B1, B2, B3, B4, B5, B6>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3, fourth: (earlier: Merged<B1, B2, B3>) => B4, fifth: (earlier: Merged<B1, B2, B3, B4>) => B5, sixth: (earlier: Merged<B1, B2, B3, B4, B5>) => B6, seventh: (earlier: Merged<B1, B2, B3, B4, B5, B6>) => B7): Stepped<Merged<B1, B2, B3, B4, B5, B6, B7>>;
117
+ <B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>>, B4 extends Later<Merged<B1, B2, B3>>, B5 extends Later<Merged<B1, B2, B3, B4>>, B6 extends Later<Merged<B1, B2, B3, B4, B5>>, B7 extends Later<Merged<B1, B2, B3, B4, B5, B6>>, B8 extends Later<Merged<B1, B2, B3, B4, B5, B6, B7>>>(first: B1, second: (earlier: Results<B1>) => B2, third: (earlier: Merged<B1, B2>) => B3, fourth: (earlier: Merged<B1, B2, B3>) => B4, fifth: (earlier: Merged<B1, B2, B3, B4>) => B5, sixth: (earlier: Merged<B1, B2, B3, B4, B5>) => B6, seventh: (earlier: Merged<B1, B2, B3, B4, B5, B6>) => B7, eighth: (earlier: Merged<B1, B2, B3, B4, B5, B6, B7>) => B8): Stepped<Merged<B1, B2, B3, B4, B5, B6, B7, B8>>;
118
+ }
119
+ /** `defineQuery<Schema>()`'s v7 form: a string id first. */
101
120
  export interface RecipeDefinitions<S> {
102
121
  /**
103
- * One stage: one read, a record of facets, or a page as its single read, whose `output` keeps
104
- * the page shape (the cursor stays the Kernel's). The page is not an overload of its own: a
105
- * callback keeps the contextual type of the first overload tried. Its type is spelled out, not
122
+ * `build` returns one read, a record of facets, `steps(…)`, or a page as its single read, whose
123
+ * `output` keeps the page shape (the cursor stays the Kernel's). Its type is spelled out, not
106
124
  * `PageRecipe`: a Domain's exported declarations then name only `Recipe`.
107
125
  */
108
- <const Id extends string, I, B extends Built | PageRead<unknown>, O = Results<B>, E extends Errors = {}>(id: Id, spec: {
109
- readonly build: (input: I, d: Handles<S>) => B;
110
- readonly output?: Output<S, Results<B>, I, O & PageShape<B>, E> & PortableOutput<O>;
126
+ <const Id extends string, I, B extends Built | PageRead<unknown> | Stepped<unknown>, O = BuiltResults<B>, E extends Errors = {}>(id: Id, spec: {
127
+ readonly build: (input: I, d: Handles<S>, steps: Steps) => B;
128
+ readonly output?: Output<S, BuiltResults<B>, I, O & PageShape<B>, E> & PortableOutput<O>;
111
129
  readonly errors?: E;
112
130
  }): B extends PageRead<infer T> ? Recipe<Id, I, O, E> & {
113
131
  readonly '~page'?: T;
114
132
  } : Recipe<Id, I, O, E>;
115
- /**
116
- * Two to eight stages, each returning a record of facets: stage n receives the merged results of
117
- * stages 1 to n - 1, and names facets none of them read.
118
- */
119
- <const Id extends string, I, B1 extends Facets, B2 extends Later<Results<B1>>, B3 extends Later<Merged<B1, B2>> = {}, B4 extends Later<Merged<B1, B2, B3>> = {}, B5 extends Later<Merged<B1, B2, B3, B4>> = {}, B6 extends Later<Merged<B1, B2, B3, B4, B5>> = {}, B7 extends Later<Merged<B1, B2, B3, B4, B5, B6>> = {}, B8 extends Later<Merged<B1, B2, B3, B4, B5, B6, B7>> = {}, O = Merged<B1, B2, B3, B4, B5, B6, B7, B8>, E extends Errors = {}>(id: Id, spec: {
120
- readonly build: readonly [
121
- (input: I, d: Handles<S>) => B1,
122
- Stage<S, I, Results<B1>, B2>,
123
- Stage<S, I, Merged<B1, B2>, B3>?,
124
- Stage<S, I, Merged<B1, B2, B3>, B4>?,
125
- Stage<S, I, Merged<B1, B2, B3, B4>, B5>?,
126
- Stage<S, I, Merged<B1, B2, B3, B4, B5>, B6>?,
127
- Stage<S, I, Merged<B1, B2, B3, B4, B5, B6>, B7>?,
128
- Stage<S, I, Merged<B1, B2, B3, B4, B5, B6, B7>, B8>?
129
- ];
130
- readonly output?: Output<S, Merged<B1, B2, B3, B4, B5, B6, B7, B8>, I, O, E> & PortableOutput<O>;
131
- readonly errors?: E;
132
- }): Recipe<Id, I, O, E>;
133
133
  }
134
134
  export {};
@@ -7,12 +7,19 @@ export interface Build<Schema extends schema.DomainSchema = schema.DomainSchema,
7
7
  readonly schema: BuildSchema<Schema>;
8
8
  readonly runtime: RuntimeValue;
9
9
  readonly callables: readonly Key.Callable[];
10
- readonly requirements: release.Requirements;
10
+ readonly requirements: BuildRequirements;
11
11
  readonly routes: routes.Plan;
12
12
  readonly frontend?: FrontendCompilation;
13
13
  /** What the release manifest shows of the application: its icon. */
14
14
  readonly presentation?: BuildPresentation;
15
15
  }
16
+ /**
17
+ * What a build requires of the Instance. The SDK declares capabilities in the legacy shape only
18
+ * (`functions`, `classes`, `authority`, `core`), never roles or scopes.
19
+ */
20
+ export interface BuildRequirements extends release.Requirements {
21
+ readonly capabilities: release.LegacyCapabilityRequirements;
22
+ }
16
23
  export interface BuildPresentation {
17
24
  /** One self-contained inline SVG. */
18
25
  readonly icon?: string;
@@ -58,6 +58,9 @@ export function restoreBuild(input, runtime) {
58
58
  }
59
59
  const registry = bindRuntime(domain, runtime, input.callables);
60
60
  const requirements = admitRequirements(input.requirements);
61
+ // A build declares its capabilities in the legacy shape only: never roles or scopes.
62
+ if ('roles' in requirements.capabilities || 'scopes' in requirements.capabilities)
63
+ invalid();
61
64
  validateRequirements(decoded.root, decoded.closure, requirements);
62
65
  const plan = admitRoutePlan(input.routes, domain);
63
66
  const compiled = deepFreeze(input.schema.compiled);
@@ -1,2 +1,2 @@
1
- /** Generated from the Kernel Schema of @astrale-os/kernel-core 1.0.0-beta.23, reduced to its Classes. Regenerate with pnpm sync:kernel-schema. */
1
+ /** Generated from the Kernel Schema of @astrale-os/kernel-core 1.0.0-beta.24, reduced to its Classes. Regenerate with pnpm sync:kernel-schema. */
2
2
  export declare const kernelCompiledSchema: string;