@relyio/sdk 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/automations/index.cjs +18 -17
- package/dist/automations/index.d.cts +289 -8
- package/dist/automations/index.d.ts +289 -8
- package/dist/automations/index.js +3 -2
- package/dist/{chunk-ZHTJ7GXH.js → chunk-356SF5Y2.js} +84 -26
- package/dist/{chunk-ZAMAR3X2.cjs → chunk-5F3YYPLZ.cjs} +11249 -10771
- package/dist/{chunk-LSI26ZN2.cjs → chunk-DBYMG6MQ.cjs} +5 -5
- package/dist/{chunk-SHSK7UUY.cjs → chunk-NN45CSPZ.cjs} +177 -11
- package/dist/{chunk-IFKF72VJ.cjs → chunk-P23G5NXD.cjs} +122 -63
- package/dist/{chunk-W7JFHSFM.js → chunk-PZCDJFMA.js} +11249 -10772
- package/dist/{chunk-EDE2H37D.js → chunk-T7LGREB3.js} +174 -12
- package/dist/{chunk-R6E4HE7R.js → chunk-W2GRVXDG.js} +3 -3
- package/dist/client/index.cjs +4 -4
- package/dist/client/index.d.cts +4 -4
- package/dist/client/index.d.ts +4 -4
- package/dist/client/index.js +2 -2
- package/dist/{define-content-type-NEQDrvdq.d.cts → define-content-type-BZ6X8GvL.d.cts} +1324 -156
- package/dist/{define-content-type-fb-WCD5e.d.ts → define-content-type-C12jh8cY.d.ts} +1324 -156
- package/dist/{define-schema-Dlwh6l_J.d.ts → define-schema-BPlZl4a2.d.cts} +104 -3
- package/dist/{define-schema-DZhtvLiK.d.cts → define-schema-CK7TtYot.d.ts} +104 -3
- package/dist/extensions/index.cjs +26 -6
- package/dist/extensions/index.d.cts +5 -791
- package/dist/extensions/index.d.ts +5 -791
- package/dist/extensions/index.js +24 -4
- package/dist/functions/index.cjs +7 -4
- package/dist/functions/index.d.cts +4 -4
- package/dist/functions/index.d.ts +4 -4
- package/dist/functions/index.js +5 -2
- package/dist/{index-M3luH06A.d.ts → index-BxNnlc5D.d.ts} +91 -73
- package/dist/{index-C4LqrNd1.d.ts → index-C-MymZTe.d.ts} +1 -1
- package/dist/{index-DwHcL6x5.d.cts → index-D5jyIeQ5.d.cts} +91 -73
- package/dist/{index-Dnmt_UOo.d.cts → index-DN0l8RHw.d.cts} +1 -1
- package/dist/index.cjs +88 -84
- package/dist/index.d.cts +64 -14
- package/dist/index.d.ts +64 -14
- package/dist/index.js +4 -4
- package/dist/preview/index.cjs +3 -3
- package/dist/preview/index.js +1 -1
- package/dist/{register-B53i97A9.d.ts → register-BiMQKVp-.d.ts} +24 -8
- package/dist/{register-BYCs0FpF.d.cts → register-DeMsaurp.d.cts} +24 -8
- package/dist/rich-text/index.d.cts +2 -2
- package/dist/rich-text/index.d.ts +2 -2
- package/dist/schema/index.cjs +41 -40
- package/dist/schema/index.d.cts +7 -120
- package/dist/schema/index.d.ts +7 -120
- package/dist/schema/index.js +2 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { ConditionScalar, ConditionTest, ConditionTree, ConditionTests } from '../
|
|
1
|
+
import { cH as ConditionScalar, cI as ConditionTest, cK as ConditionTree, cJ as ConditionTests, r as KeyedMembers, an as FieldValues, ao as DeclaredFields, s as KeyedMembersOf, cM as ExtensionSurfaces, cN as ExtensionSettingField, cO as ExtensionSurface, cP as ActionField, cQ as ExtensionValueField, y as ReferenceConfig, o as KeyedFieldOptions, n as KeyedField, cx as FileUpload } from '../define-content-type-C12jh8cY.js';
|
|
2
|
+
import { A as AnySchemaDefinition, R as RegisteredSchema, B as BaseRecord, a as RecordBatchTarget, b as RecordBatchResult, c as Register, d as RecordConditionValue } from '../register-BiMQKVp-.js';
|
|
3
|
+
import { i as SchemaRecordTypeNames, I as InferRecordType, b as SchemaContentTypeNames, j as SchemaEntry, f as SchemaLocaleCodes, r as RecordWriteFieldsOf, q as RecordUpdateFieldsOf } from '../define-schema-CK7TtYot.js';
|
|
2
4
|
export { fields } from '../schema/index.js';
|
|
3
|
-
import { A as AnySchemaDefinition, R as RegisteredSchema, B as BaseRecord, a as RecordBatchTarget, b as RecordBatchResult, c as RecordConditionValue } from '../register-B53i97A9.js';
|
|
4
|
-
import { S as SchemaRecordTypeNames, I as InferRecordType, a as SchemaContentTypeNames, b as SchemaEntry, c as SchemaLocaleCodes, R as RecordWriteFieldsOf, d as RecordUpdateFieldsOf } from '../define-schema-Dlwh6l_J.js';
|
|
5
|
-
import { K as KeyedMembers, F as FieldValues, D as DeclaredFields, a as KeyedMembersOf, b as FileUpload } from '../define-content-type-fb-WCD5e.js';
|
|
6
5
|
import '../rich-text.d-BWc-5gX1.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -600,7 +599,7 @@ interface StepWithOutput<O> extends StepHandle {
|
|
|
600
599
|
readonly output: Ref<O>;
|
|
601
600
|
}
|
|
602
601
|
/** A Field set's values, as a Function's and an Agent step's output Fields declare them. */
|
|
603
|
-
type ValuesOf$
|
|
602
|
+
type ValuesOf$2<F extends KeyedMembers> = FieldValues<DeclaredFields<{
|
|
604
603
|
readonly fields: readonly KeyedMembersOf<F>[];
|
|
605
604
|
}>>;
|
|
606
605
|
/** What `step.agent` takes. */
|
|
@@ -770,9 +769,9 @@ interface StepBuilder {
|
|
|
770
769
|
* Ask an agent to read, answer the declared Fields and propose one change to the types `propose`
|
|
771
770
|
* names. Nothing it proposes is written until an Ask approves it (`step.ask(…, { approve })`).
|
|
772
771
|
*/
|
|
773
|
-
agent<const O extends KeyedMembers>(name: string, config: ProposingAgentStepConfig<O>): StepWithOutput<ProposingOutput<ValuesOf$
|
|
772
|
+
agent<const O extends KeyedMembers>(name: string, config: ProposingAgentStepConfig<O>): StepWithOutput<ProposingOutput<ValuesOf$2<O>>>;
|
|
774
773
|
/** Ask an agent to read and answer the declared Fields. It reads; it never writes or sends. */
|
|
775
|
-
agent<const O extends KeyedMembers>(name: string, config: AgentStepConfig<O>): StepWithOutput<ValuesOf$
|
|
774
|
+
agent<const O extends KeyedMembers>(name: string, config: AgentStepConfig<O>): StepWithOutput<ValuesOf$2<O>>;
|
|
776
775
|
/** Send through an Extension's Action, from the events worker; Recorded in a Preview without its Connection. */
|
|
777
776
|
action<I, O>(name: string, action: AutomationAction<I, O>, input: StepInput<I>): StepWithOutput<O>;
|
|
778
777
|
/**
|
|
@@ -863,6 +862,249 @@ declare function isAutomationFile(value: unknown): value is AutomationFile;
|
|
|
863
862
|
*/
|
|
864
863
|
declare function resolveAutomation(file: AutomationFile, nameOf: (fn: FunctionDefinition) => string | undefined): AutomationDefinition;
|
|
865
864
|
|
|
865
|
+
/**
|
|
866
|
+
* `@relyio/sdk/extensions` — the Extensions a Project uses (spec 3, REL-3846; ADR 0019).
|
|
867
|
+
*
|
|
868
|
+
* One file, `relyio/extensions.ts`, names each Extension the Project uses and its settings — set once
|
|
869
|
+
* for the Project, never per Environment — and hands out a typed handle for each. An Automation
|
|
870
|
+
* imports the handle: its Triggers start an Automation (`on: vercel.deploymentSucceeded()`), and its
|
|
871
|
+
* Actions are what `step.action` sends through, their input and output typed by the Extension.
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* // relyio/extensions.ts
|
|
875
|
+
* import { defineExtensions } from '@relyio/sdk/extensions'
|
|
876
|
+
*
|
|
877
|
+
* const extensions = defineExtensions({
|
|
878
|
+
* slack: { defaultChannel: '#orders' },
|
|
879
|
+
* vercel: {},
|
|
880
|
+
* })
|
|
881
|
+
* export const { slack, vercel } = extensions
|
|
882
|
+
* export default extensions
|
|
883
|
+
*
|
|
884
|
+
* **Never a secret here.** A Connection — an API key, a signing secret, a webhook URL — is made in
|
|
885
|
+
* the Dashboard, once per Environment, and sealed. A setting is text anyone reading the repository
|
|
886
|
+
* may see. Declaring an Extension connects nothing: `relyio plan` says which still need connecting
|
|
887
|
+
* in Production, and which Automations will deploy paused there until they are. Preview never pauses:
|
|
888
|
+
* an Action with no Preview Connection is Recorded with its sample result.
|
|
889
|
+
*
|
|
890
|
+
* **Typed.** Each Extension's settings, Actions and Triggers are RelyIO's own declaration of it
|
|
891
|
+
* (`@relyio/api-contract`'s `EXTENSION_SURFACES`, which the Extension catalog delivers): an Extension
|
|
892
|
+
* RelyIO does not have, a setting it does not declare, or a value its setting does not take — a
|
|
893
|
+
* Slack channel without its `#` — is a type error, and the plan refuses it again for a Manifest read
|
|
894
|
+
* as data.
|
|
895
|
+
*/
|
|
896
|
+
|
|
897
|
+
/** One Extension a Project uses: its settings, by key. */
|
|
898
|
+
interface ExtensionUse {
|
|
899
|
+
readonly settings: Readonly<Record<string, string>>;
|
|
900
|
+
}
|
|
901
|
+
/** What `relyio/extensions.ts` declares, as data: every Extension the Project uses, by slug. */
|
|
902
|
+
type ExtensionsDeclaration = Readonly<Record<string, ExtensionUse>>;
|
|
903
|
+
/** Every Extension a Project may declare, and what its code may name of each. */
|
|
904
|
+
type Surfaces = ExtensionSurfaces;
|
|
905
|
+
/** The value one setting takes: one of its options, text starting with its prefix, or text. */
|
|
906
|
+
type SettingValue<F extends ExtensionSettingField> = F extends {
|
|
907
|
+
readonly type: 'select';
|
|
908
|
+
readonly options: ReadonlyArray<infer Option>;
|
|
909
|
+
} ? Option : F extends {
|
|
910
|
+
readonly type: 'text';
|
|
911
|
+
readonly prefix: infer Prefix extends string;
|
|
912
|
+
} ? `${Prefix}${string}` : string;
|
|
913
|
+
type Flatten<T> = {
|
|
914
|
+
readonly [K in keyof T]: T[K];
|
|
915
|
+
};
|
|
916
|
+
/** The settings an Extension takes: its required ones required, the rest optional, nothing else. */
|
|
917
|
+
type SettingsFrom<F extends ExtensionSettingField> = Flatten<{
|
|
918
|
+
readonly [Field in F as Field extends {
|
|
919
|
+
readonly required: true;
|
|
920
|
+
} ? Field['key'] : never]: SettingValue<Field>;
|
|
921
|
+
} & {
|
|
922
|
+
readonly [Field in F as Field extends {
|
|
923
|
+
readonly required: true;
|
|
924
|
+
} ? never : Field['key']]?: SettingValue<Field>;
|
|
925
|
+
}>;
|
|
926
|
+
/**
|
|
927
|
+
* The settings `defineExtensions` takes for Extension `S`. An Extension with none takes `{}` and
|
|
928
|
+
* nothing in it.
|
|
929
|
+
*/
|
|
930
|
+
type ExtensionSettings<S extends keyof Surfaces> = [
|
|
931
|
+
Surfaces[S]['settings'][number]
|
|
932
|
+
] extends [never] ? Readonly<Record<string, never>> : SettingsFrom<Surfaces[S]['settings'][number]>;
|
|
933
|
+
/** What `defineExtensions` takes: each Extension the Project uses, by slug, with its settings. */
|
|
934
|
+
type ExtensionsConfig = {
|
|
935
|
+
readonly [S in keyof Surfaces]?: ExtensionSettings<S>;
|
|
936
|
+
};
|
|
937
|
+
/** A value field's JSON type, as TypeScript reads it. */
|
|
938
|
+
type JsonOf<T extends ExtensionValueField['type']> = T extends 'string' ? string : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'array' ? readonly unknown[] : Readonly<Record<string, unknown>>;
|
|
939
|
+
/** A dot-separated path's first segment. */
|
|
940
|
+
type Head<P extends string> = P extends `${infer First}.${string}` ? First : P;
|
|
941
|
+
/** The fields whose path starts with segment `K`. */
|
|
942
|
+
type Under<F extends ExtensionValueField, K extends string> = F extends ExtensionValueField ? Head<F['path']> extends K ? F : never : never;
|
|
943
|
+
/** The fields under `K`, their paths with `K.` taken off; never for the field at `K` itself. */
|
|
944
|
+
type Rebased<F extends ExtensionValueField, K extends string> = F extends ExtensionValueField ? F['path'] extends `${K}.${infer Rest}` ? Omit<F, 'path'> & {
|
|
945
|
+
readonly path: Rest;
|
|
946
|
+
} : never : never;
|
|
947
|
+
/** A field's value: its JSON type, and an object of strings for one declaring string values. */
|
|
948
|
+
type FieldValueOf<F extends ExtensionValueField> = F extends {
|
|
949
|
+
readonly values: 'string';
|
|
950
|
+
} ? Readonly<Record<string, string>> : JsonOf<F['type']>;
|
|
951
|
+
/** The value at `K`: the field there, or an object of the fields under it. */
|
|
952
|
+
type ValueAt<F extends ExtensionValueField, K extends string> = [
|
|
953
|
+
Extract<F, {
|
|
954
|
+
readonly path: K;
|
|
955
|
+
}>
|
|
956
|
+
] extends [never] ? ValuesOf$1<Rebased<F, K>> : FieldValueOf<Extract<F, {
|
|
957
|
+
readonly path: K;
|
|
958
|
+
}>>;
|
|
959
|
+
/**
|
|
960
|
+
* Value fields as an object: `payload.data.object.id` a `string` at `payload.data.object.id`. A
|
|
961
|
+
* segment is required when a field under it is.
|
|
962
|
+
*/
|
|
963
|
+
type ValuesOf$1<F extends ExtensionValueField> = Flatten<{
|
|
964
|
+
readonly [K in Head<F['path']> as true extends Under<F, K>['required'] ? K : never]: ValueAt<F, K>;
|
|
965
|
+
} & {
|
|
966
|
+
readonly [K in Head<F['path']> as true extends Under<F, K>['required'] ? never : K]?: ValueAt<F, K>;
|
|
967
|
+
}>;
|
|
968
|
+
/** A Trigger's payload, as an object; one that declares nothing, `{}`. */
|
|
969
|
+
type ValuesOfList<L extends readonly ExtensionValueField[]> = [L[number]] extends [never] ? Record<string, never> : ValuesOf$1<L[number]>;
|
|
970
|
+
/** An action field's value, as TypeScript reads it (`@relyio/api-contract`'s `ACTION_FIELD_TYPES`). */
|
|
971
|
+
type ActionValueOf<T extends ActionField['type']> = T extends 'text' | 'url' ? string : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'headers' ? Readonly<Record<string, string>> : AutomationJson;
|
|
972
|
+
/** An Action's input or output fields as an object: required ones required, the rest optional. */
|
|
973
|
+
type ActionValuesOf<L extends readonly ActionField[]> = Flatten<{
|
|
974
|
+
readonly [F in L[number] as F extends {
|
|
975
|
+
readonly required: true;
|
|
976
|
+
} ? F['key'] : never]: ActionValueOf<F['type']>;
|
|
977
|
+
} & {
|
|
978
|
+
readonly [F in L[number] as F extends {
|
|
979
|
+
readonly required: true;
|
|
980
|
+
} ? never : F['key']]?: ActionValueOf<F['type']>;
|
|
981
|
+
}>;
|
|
982
|
+
/** A Trigger's handle: call it for the Automation's `on`, with a `where` over its event if needed. */
|
|
983
|
+
type ExtensionTriggerHandle<P> = (options?: {
|
|
984
|
+
readonly where?: (event: Ref<ExtensionTriggerEvent<P>>) => ConditionTree;
|
|
985
|
+
}) => AutomationTriggerHandle<ExtensionTriggerEvent<P>>;
|
|
986
|
+
/**
|
|
987
|
+
* The handle an Extension's declaration gives: each of its Actions and Triggers, by the name it gives
|
|
988
|
+
* them, typed by their fields.
|
|
989
|
+
*/
|
|
990
|
+
type HandleOf<X extends ExtensionSurface, S extends string = string> = {
|
|
991
|
+
readonly [A in keyof X['actions']]: X['actions'][A] extends {
|
|
992
|
+
readonly action: infer N extends string;
|
|
993
|
+
readonly step: {
|
|
994
|
+
readonly input: infer I extends readonly ActionField[];
|
|
995
|
+
readonly output: infer O extends readonly ActionField[];
|
|
996
|
+
};
|
|
997
|
+
} ? AutomationAction<ActionValuesOf<I>, ActionValuesOf<O>, S, N> : never;
|
|
998
|
+
} & {
|
|
999
|
+
readonly [T in keyof X['triggers']]: X['triggers'][T] extends {
|
|
1000
|
+
readonly payload: infer P extends readonly ExtensionValueField[];
|
|
1001
|
+
} ? ExtensionTriggerHandle<ValuesOfList<P>> : never;
|
|
1002
|
+
};
|
|
1003
|
+
/**
|
|
1004
|
+
* A contributed field kind's options (spec 4, REL-3894): its base reference's, without `to`, which
|
|
1005
|
+
* the kind names, and never `localized` — a user is no translation.
|
|
1006
|
+
*/
|
|
1007
|
+
type ContributedFieldOptions<TTo extends string, TMulti extends boolean, TRequired extends boolean> = Omit<ReferenceConfig<TTo, TMulti>, 'to'> & {
|
|
1008
|
+
readonly required?: TRequired;
|
|
1009
|
+
readonly to?: never;
|
|
1010
|
+
} & KeyedFieldOptions<never>;
|
|
1011
|
+
/**
|
|
1012
|
+
* A contributed field kind's builder — `clerk.userRef()`: a reference to the Extension's Managed
|
|
1013
|
+
* Record type, typed exactly as `fields.reference` types a reference to it, which the Studio picks through
|
|
1014
|
+
* the kind's picker. The schema, reads, writes and Policies treat it as that reference.
|
|
1015
|
+
*/
|
|
1016
|
+
type ContributedFieldKindBuilder<TTo extends string> = <TMulti extends boolean = false, TRequired extends boolean = false>(options?: ContributedFieldOptions<TTo, TMulti, TRequired>) => KeyedField<'reference', ReferenceConfig<TTo, TMulti> & {
|
|
1017
|
+
required?: TRequired;
|
|
1018
|
+
}>;
|
|
1019
|
+
/** An Extension's contributed field kinds, by the name its declaration gives them. */
|
|
1020
|
+
type FieldKindsOf<X extends ExtensionSurface> = {
|
|
1021
|
+
readonly [K in keyof X['fieldKinds']]: X['fieldKinds'][K] extends {
|
|
1022
|
+
readonly base: {
|
|
1023
|
+
readonly to: infer To extends string;
|
|
1024
|
+
};
|
|
1025
|
+
} ? ContributedFieldKindBuilder<To> : never;
|
|
1026
|
+
};
|
|
1027
|
+
/** An Extension's Managed Record types, by the name its declaration gives them (REL-3863). */
|
|
1028
|
+
type RecordTypesOf<X extends ExtensionSurface> = {
|
|
1029
|
+
readonly [K in keyof X['recordTypes']]: X['recordTypes'][K];
|
|
1030
|
+
};
|
|
1031
|
+
/** Extension `S`'s handle. */
|
|
1032
|
+
type ExtensionHandle<S extends keyof Surfaces> = HandleOf<Surfaces[S], S & string> & FieldKindsOf<Surfaces[S]> & RecordTypesOf<Surfaces[S]>;
|
|
1033
|
+
/** Where the declaration rides on what `defineExtensions` returns. */
|
|
1034
|
+
declare const DECLARED = "declared";
|
|
1035
|
+
/**
|
|
1036
|
+
* Where an {@link ExtensionsFile}'s type keeps the settings it was declared with, for
|
|
1037
|
+
* {@link ClaimsOf} to read. Type-level only: no value carries it.
|
|
1038
|
+
*/
|
|
1039
|
+
declare const DECLARED_SETTINGS: unique symbol;
|
|
1040
|
+
/**
|
|
1041
|
+
* What `relyio/extensions.ts` default-exports: the declaration the CLI reads into the Manifest, and
|
|
1042
|
+
* a handle for each Extension it declares.
|
|
1043
|
+
*/
|
|
1044
|
+
type ExtensionsFile<C> = ExtensionsFileData & {
|
|
1045
|
+
readonly [S in keyof C & keyof Surfaces]: ExtensionHandle<S>;
|
|
1046
|
+
} & {
|
|
1047
|
+
readonly [DECLARED_SETTINGS]?: C;
|
|
1048
|
+
};
|
|
1049
|
+
/** The setting an identity Extension declares its Claims in (`@relyio/api-contract`'s `IDENTITY_CLAIMS_SETTING`). */
|
|
1050
|
+
type ClaimsSetting = 'claims';
|
|
1051
|
+
/** `S` without the whitespace `String.prototype.trim` takes off either end. */
|
|
1052
|
+
type Trimmed<S extends string> = S extends `${' ' | '\n' | '\t' | '\r'}${infer Rest}` ? Trimmed<Rest> : S extends `${infer Rest}${' ' | '\n' | '\t' | '\r'}` ? Trimmed<Rest> : S;
|
|
1053
|
+
/**
|
|
1054
|
+
* The Claim names a `claims` setting declares, read as `claimNamesOf` reads it at deploy: split on
|
|
1055
|
+
* commas, each trimmed, empty ones dropped. Text TypeScript does not know (`string`) may name any.
|
|
1056
|
+
*/
|
|
1057
|
+
type ClaimNames<S extends string> = string extends S ? string : S extends `${infer First},${infer Rest}` ? ClaimNames<First> | ClaimNames<Rest> : Trimmed<S> extends '' ? never : Trimmed<S>;
|
|
1058
|
+
/** Every Claim name the Extensions in `C` declare: an identity Extension's `claims` setting. */
|
|
1059
|
+
type DeclaredClaimNames<C> = {
|
|
1060
|
+
readonly [S in keyof C]: C[S] extends {
|
|
1061
|
+
readonly [K in ClaimsSetting]: infer T extends string;
|
|
1062
|
+
} ? ClaimNames<T> : never;
|
|
1063
|
+
}[keyof C];
|
|
1064
|
+
/**
|
|
1065
|
+
* The Claims a Project relies on, typed from its `relyio/extensions.ts`: `ClaimsOf<typeof
|
|
1066
|
+
* extensions>` is an object with one optional key per Claim its identity Extension's `claims`
|
|
1067
|
+
* setting names — `claims: 'plan, role'` is `{ plan?: unknown; role?: unknown }`. A Claim named and
|
|
1068
|
+
* missing from a token is absent, and a setting is text, so each value is `unknown`: what a Claim may
|
|
1069
|
+
* hold is for the Policy that tests it to say.
|
|
1070
|
+
*
|
|
1071
|
+
* Type a Policy's `claims` root with it, so a misspelt Claim is a compile error:
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* import type { ClaimsOf } from '@relyio/sdk/extensions'
|
|
1075
|
+
* import { conditionRoot } from '@relyio/sdk/schema'
|
|
1076
|
+
* import extensions from './extensions'
|
|
1077
|
+
*
|
|
1078
|
+
* const claims = conditionRoot<ClaimsOf<typeof extensions>>('claims')
|
|
1079
|
+
* claims.plan.eq('paid') // ✓
|
|
1080
|
+
* claims.plna.eq('paid') // ✗ `plna` is no Claim the Project declares
|
|
1081
|
+
*/
|
|
1082
|
+
type ClaimsOf<F> = F extends {
|
|
1083
|
+
readonly [DECLARED_SETTINGS]?: infer C;
|
|
1084
|
+
} ? {
|
|
1085
|
+
readonly [N in DeclaredClaimNames<C>]?: unknown;
|
|
1086
|
+
} : never;
|
|
1087
|
+
/** `C`, refusing a key no Extension declares — at the top and in each Extension's settings. */
|
|
1088
|
+
type Exactly<C> = {
|
|
1089
|
+
readonly [S in keyof C]: S extends keyof Surfaces ? C[S] & {
|
|
1090
|
+
readonly [K in Exclude<keyof C[S], keyof ExtensionSettings<S>>]: never;
|
|
1091
|
+
} : never;
|
|
1092
|
+
};
|
|
1093
|
+
/**
|
|
1094
|
+
* Declare the Extensions the Project uses, with their settings, and take a typed handle for each.
|
|
1095
|
+
* The file is `relyio/extensions.ts`; `relyio deploy` reads its default export into the Manifest.
|
|
1096
|
+
*/
|
|
1097
|
+
declare function defineExtensions<const C extends ExtensionsConfig>(config: C & Exactly<C>): ExtensionsFile<C>;
|
|
1098
|
+
/** What the CLI reads of `relyio/extensions.ts`' default export, whatever it declares. */
|
|
1099
|
+
interface ExtensionsFileData {
|
|
1100
|
+
readonly _tag: 'extensions';
|
|
1101
|
+
readonly [DECLARED]: ExtensionsDeclaration;
|
|
1102
|
+
}
|
|
1103
|
+
/** Whether `value` is what `defineExtensions` returns: how the CLI reads `relyio/extensions.ts`. */
|
|
1104
|
+
declare function isExtensionsFile(value: unknown): value is ExtensionsFileData;
|
|
1105
|
+
/** The declaration as the Manifest carries it. */
|
|
1106
|
+
declare function extensionsDeclarationOf(file: ExtensionsFileData): ExtensionsDeclaration;
|
|
1107
|
+
|
|
866
1108
|
/**
|
|
867
1109
|
* `@relyio/sdk/functions` — a Function, declared (spec 2, REL-3819; ADR 0021).
|
|
868
1110
|
*
|
|
@@ -979,6 +1221,8 @@ interface FunctionDeclaration {
|
|
|
979
1221
|
readonly secrets: Readonly<Record<string, FunctionSecretDeclaration>>;
|
|
980
1222
|
/** The Actions it may send (REL-3856); absent when it declares none. */
|
|
981
1223
|
readonly actions?: readonly FunctionActionReach[];
|
|
1224
|
+
/** Who besides a secret key may call its SDK Way in (spec 4, REL-3892); absent when undeclared. */
|
|
1225
|
+
readonly endUsers?: FunctionEndUsers;
|
|
982
1226
|
readonly route?: FunctionRoute;
|
|
983
1227
|
readonly tool?: FunctionTool;
|
|
984
1228
|
readonly schedule?: FunctionSchedule;
|
|
@@ -1124,6 +1368,31 @@ type FunctionRecords<R extends string, W extends string> = {
|
|
|
1124
1368
|
* the person's own Preview branch.
|
|
1125
1369
|
*/
|
|
1126
1370
|
type FunctionWayIn = 'sdk' | 'route' | 'tool' | 'schedule' | 'automation' | 'editor';
|
|
1371
|
+
/**
|
|
1372
|
+
* Whether a publishable key may call a Function from a browser (spec 4, REL-3892): `'required'` for
|
|
1373
|
+
* a signed-in End user only — the call carries their token — or `'optional'` with or without one.
|
|
1374
|
+
*/
|
|
1375
|
+
type FunctionEndUsers = 'required' | 'optional';
|
|
1376
|
+
/**
|
|
1377
|
+
* The Claims a run's End user carries: those the registered `relyio/extensions.ts` declares
|
|
1378
|
+
* (`ClaimsOf`), once `Register` names it — `declare module '@relyio/sdk' { interface Register {
|
|
1379
|
+
* extensions: typeof extensions } }` — else any name, each `unknown`.
|
|
1380
|
+
*/
|
|
1381
|
+
type FunctionEndUserClaims = Register extends {
|
|
1382
|
+
extensions: infer F;
|
|
1383
|
+
} ? ClaimsOf<F> : {
|
|
1384
|
+
readonly [claim: string]: unknown;
|
|
1385
|
+
};
|
|
1386
|
+
/**
|
|
1387
|
+
* The End user a run's call carried a verified token for (spec 4, REL-3892): their subject — the
|
|
1388
|
+
* `sub` an Owner field stores — and the Claims the Project declares, as the token carries them. A
|
|
1389
|
+
* Record the run creates naming no owner is theirs; what the run may touch is still its reach, never
|
|
1390
|
+
* their Policies.
|
|
1391
|
+
*/
|
|
1392
|
+
interface FunctionEndUser {
|
|
1393
|
+
readonly subject: string;
|
|
1394
|
+
readonly claims: FunctionEndUserClaims;
|
|
1395
|
+
}
|
|
1127
1396
|
/** What a run knows of itself: its id survives every retry. */
|
|
1128
1397
|
interface FunctionRunInfo {
|
|
1129
1398
|
readonly id: string;
|
|
@@ -1146,6 +1415,11 @@ interface FunctionRunInfo {
|
|
|
1146
1415
|
* Absent from a run an SDK call, a route or a tool started.
|
|
1147
1416
|
*/
|
|
1148
1417
|
readonly event?: Readonly<Record<string, unknown>>;
|
|
1418
|
+
/**
|
|
1419
|
+
* The End user whose token the call carried, verified (spec 4, REL-3892) — with any key on the SDK
|
|
1420
|
+
* Way in or a keyed route, and on a Public route that was sent one. Absent otherwise.
|
|
1421
|
+
*/
|
|
1422
|
+
readonly endUser?: FunctionEndUser;
|
|
1149
1423
|
}
|
|
1150
1424
|
/** Published content, read through the read core: present when the reach declares `content: 'published'`. */
|
|
1151
1425
|
interface FunctionContent {
|
|
@@ -1272,6 +1546,13 @@ interface FunctionConfig<I extends KeyedMembers, O extends KeyedMembers, R exten
|
|
|
1272
1546
|
* type error, and refused at run time.
|
|
1273
1547
|
*/
|
|
1274
1548
|
actions?: readonly A[];
|
|
1549
|
+
/**
|
|
1550
|
+
* Who besides a secret key may call it through `relyio.functions.<name>(input)` (spec 4,
|
|
1551
|
+
* REL-3892): `'required'` lets a publishable key call it for a signed-in End user, whose token it
|
|
1552
|
+
* carries; `'optional'` lets a publishable key call it with or without one. Left out, a secret key
|
|
1553
|
+
* alone. Either way the run is bound by its reach, and `run.endUser` names who called.
|
|
1554
|
+
*/
|
|
1555
|
+
endUsers?: FunctionEndUsers;
|
|
1275
1556
|
route?: FunctionRoute;
|
|
1276
1557
|
tool?: FunctionTool;
|
|
1277
1558
|
schedule?: FunctionSchedule;
|
|
@@ -1306,4 +1587,4 @@ declare function defineFunction<const I extends KeyedMembers = Record<never, nev
|
|
|
1306
1587
|
/** Whether `value` is what `defineFunction` returns: how the CLI reads a Function file's default export. */
|
|
1307
1588
|
declare function isFunctionDefinition(value: unknown): value is FunctionDefinition;
|
|
1308
1589
|
|
|
1309
|
-
export { type
|
|
1590
|
+
export { type FunctionOutputOf as $, type FunctionCounterMove as A, type Accepts, type AgentStepConfig, type AnyEntryEvent, type AnyEntryTriggers, type ApproveCounts, type ApproveOutput, type ApproveStepConfig, type AskOutput, type AskStepConfig, type AutomationAction, type AutomationBecomesTest, type AutomationConfig, type AutomationDefinition, type AutomationDuration, type AutomationEntryAction, type AutomationFile, type AutomationInput, type AutomationItemHandle, type AutomationItemRef, type AutomationJson, type AutomationLookupState, type AutomationProposal, type AutomationProposeTarget, type AutomationRecordAction, type AutomationRef, type AutomationStep, type AutomationStepDraft, type AutomationTemplate, type AutomationTrigger, type AutomationTriggerHandle, type AutomationValue, type AutomationWhere, type FunctionRecordReader as B, type ContributedFieldOptions as C, type FunctionRecordWriter as D, type ExtensionUse as E, type EntryEvent, type EntryTriggers, type ExtensionTriggerEvent, type FunctionRuntime as F, type FunctionRecordBatch as G, type HandleOf as H, type FunctionBatchResult as I, type FunctionBatchRefused as J, isBatchRefused as K, type FunctionRecords as L, type LookedUp, type LookedUpEntry, type LookedUpEntryItem, type LookedUpRecord, type LookupOptions, type FunctionWayIn as M, type FunctionEndUsers as N, type FunctionEndUserClaims as O, type FunctionEndUser as P, type ProposingAgentStepConfig, type ProposingOutput, type FunctionRunInfo as Q, type FunctionContent as R, type RecordEvent, type RecordTriggers, type Ref, type RunFailedEvent, type RunFailedWhere, type FunctionActions as S, type StepBuilder, type StepHandle, type StepInput, type StepWithOutput, type FunctionActionRefused as T, type TriggerWhere, isActionRefused as U, type UidRef, type FunctionCapabilities as V, type FunctionResponse as W, respond as X, type FunctionConfig as Y, type FunctionDefinition as Z, type FunctionInputOf as _, type ExtensionsDeclaration as a, defineFunction as a0, isFunctionDefinition as a1, and, anyEntry, automations, type ExtensionSettings as b, type ExtensionsConfig as c, type ExtensionTriggerHandle as d, defineAutomation, type ContributedFieldKindBuilder as e, entries, extensionTrigger, type ExtensionHandle as f, type ExtensionsFile as g, type ClaimsOf as h, defineExtensions as i, isAutomationFile, type ExtensionsFileData as j, isExtensionsFile as k, extensionsDeclarationOf as l, type FunctionContainerSize as m, type FunctionDuration as n, not, type FunctionRouteMethod as o, on, or, type FunctionNetworkHost as p, type FunctionActionReach as q, type FunctionActionHandle as r, records, resolveAutomation, type FunctionSecretDeclaration as s, schedule, type FunctionRoute as t, tpl, type FunctionTool as u, type FunctionSchedule as v, type FunctionFieldDeclaration as w, type FunctionDeclaration as x, type FunctionRecordTypeName as y, type FunctionFile as z };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { and, anyEntry, automations, defineAutomation, entries, extensionTrigger, isAutomationFile, not, on, or, records, resolveAutomation, schedule, tpl } from '../chunk-
|
|
2
|
-
export { fields } from '../chunk-
|
|
1
|
+
export { and, anyEntry, automations, defineAutomation, entries, extensionTrigger, isAutomationFile, not, on, or, records, resolveAutomation, schedule, tpl } from '../chunk-W2GRVXDG.js';
|
|
2
|
+
export { fields } from '../chunk-PZCDJFMA.js';
|
|
3
|
+
import '../chunk-T7LGREB3.js';
|
|
3
4
|
import '../chunk-DI6KFDBO.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isBrowser } from './chunk-NJQK5STK.js';
|
|
2
2
|
import { parseDevEnv, DEV_CONTEXT_DIR, DEV_CONTEXT_FILENAME, parseDevContextFile } from './chunk-W2A4OTCI.js';
|
|
3
3
|
import { UNKNOWN_PREVIEW_RECHECK_MS, previewAtRequest } from './chunk-HDHBYYEY.js';
|
|
4
|
-
import { VISITOR_CLOSE_CODES, HEADER_RETRY_AFTER, HEADER_IDEMPOTENCY_KEY, entityTag, HEADER_IF_MATCH, FRESH_PARAMETER, VISITOR_KEEPALIVE, parseVisitorFrame, VISITOR_FRAMES, VISITOR_POLL_INTERVAL_MS, VISITOR_CLOSE_RETRY, readVisitorPollAnswer, VISITOR_POLL_RETRY, VISITOR_LIVE_PATH, VISITOR_QUERY, previewDatasetSlug } from './chunk-
|
|
4
|
+
import { HEADER_END_USER, VISITOR_CLOSE_CODES, HEADER_RETRY_AFTER, END_USER_TOKEN_REFUSAL_REASONS, HEADER_IDEMPOTENCY_KEY, entityTag, HEADER_IF_MATCH, FRESH_PARAMETER, VISITOR_KEEPALIVE, parseVisitorFrame, VISITOR_FRAMES, VISITOR_POLL_INTERVAL_MS, VISITOR_CLOSE_RETRY, readVisitorPollAnswer, VISITOR_POLL_RETRY, VISITOR_LIVE_PATH, VISITOR_QUERY, previewDatasetSlug } from './chunk-T7LGREB3.js';
|
|
5
5
|
import { __name, __publicField } from './chunk-DI6KFDBO.js';
|
|
6
6
|
|
|
7
7
|
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
@@ -169,13 +169,13 @@ var _ReadOnlyKeyError = class _ReadOnlyKeyError extends SDKError {
|
|
|
169
169
|
__name(_ReadOnlyKeyError, "ReadOnlyKeyError");
|
|
170
170
|
var ReadOnlyKeyError = _ReadOnlyKeyError;
|
|
171
171
|
var _PublishableKeyRefusedError = class _PublishableKeyRefusedError extends SDKError {
|
|
172
|
-
constructor(message = "A publishable key
|
|
172
|
+
constructor(message = "A publishable key writes a Record only for a signed-in End user", context) {
|
|
173
173
|
super(message, 403, void 0, context);
|
|
174
174
|
__publicField(this, "code", "PUBLISHABLE_KEY_REFUSED");
|
|
175
175
|
__publicField(this, "retryable", false);
|
|
176
176
|
}
|
|
177
177
|
getUserMessage() {
|
|
178
|
-
return "A publishable key
|
|
178
|
+
return "A publishable key writes a Record only with a signed-in End user's token, and runs only a Function declaring endUsers. Send the End user's token, declare endUsers on the Function, or call it from your server with a secret key.";
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
181
|
__name(_PublishableKeyRefusedError, "PublishableKeyRefusedError");
|
|
@@ -392,6 +392,19 @@ var _InvalidApiKeyError = class _InvalidApiKeyError extends SDKError {
|
|
|
392
392
|
};
|
|
393
393
|
__name(_InvalidApiKeyError, "InvalidApiKeyError");
|
|
394
394
|
var InvalidApiKeyError = _InvalidApiKeyError;
|
|
395
|
+
var _EndUserTokenInvalidError = class _EndUserTokenInvalidError extends SDKError {
|
|
396
|
+
constructor(message, reason, context) {
|
|
397
|
+
super(message, 401, void 0, context);
|
|
398
|
+
this.reason = reason;
|
|
399
|
+
__publicField(this, "code", "END_USER_TOKEN_INVALID");
|
|
400
|
+
__publicField(this, "retryable", false);
|
|
401
|
+
}
|
|
402
|
+
getUserMessage() {
|
|
403
|
+
return "Your session is not valid. Please sign in again.";
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
__name(_EndUserTokenInvalidError, "EndUserTokenInvalidError");
|
|
407
|
+
var EndUserTokenInvalidError = _EndUserTokenInvalidError;
|
|
395
408
|
|
|
396
409
|
// src/errors/network-errors.ts
|
|
397
410
|
var _NetworkError = class _NetworkError extends SDKError {
|
|
@@ -593,6 +606,9 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
593
606
|
case "INVALID_API_KEY": {
|
|
594
607
|
return new InvalidApiKeyError(message, void 0, context);
|
|
595
608
|
}
|
|
609
|
+
case "END_USER_TOKEN_INVALID": {
|
|
610
|
+
return new EndUserTokenInvalidError(message, endUserTokenReasonOf(refusal), context);
|
|
611
|
+
}
|
|
596
612
|
case "ACCESS_DENIED": {
|
|
597
613
|
return new AuthorizationError(message, 403, void 0, context);
|
|
598
614
|
}
|
|
@@ -800,6 +816,15 @@ function violationsOf(refusal) {
|
|
|
800
816
|
}));
|
|
801
817
|
}
|
|
802
818
|
__name(violationsOf, "violationsOf");
|
|
819
|
+
function endUserTokenReasonOf(refusal) {
|
|
820
|
+
const reason = detailString(refusal, "reason");
|
|
821
|
+
return isEndUserTokenReason(reason) ? reason : void 0;
|
|
822
|
+
}
|
|
823
|
+
__name(endUserTokenReasonOf, "endUserTokenReasonOf");
|
|
824
|
+
function isEndUserTokenReason(value) {
|
|
825
|
+
return value !== void 0 && END_USER_TOKEN_REFUSAL_REASONS.includes(value);
|
|
826
|
+
}
|
|
827
|
+
__name(isEndUserTokenReason, "isEndUserTokenReason");
|
|
803
828
|
|
|
804
829
|
// src/http/api-routes.ts
|
|
805
830
|
function fillPath(template, params) {
|
|
@@ -1172,22 +1197,33 @@ var _HttpClient = class _HttpClient {
|
|
|
1172
1197
|
* constructor accepts one so that a module-scope client can be evaluated by a
|
|
1173
1198
|
* build that holds no key (REL-1120) — and so does one whose `setApiKey` was
|
|
1174
1199
|
* given none.
|
|
1200
|
+
*
|
|
1201
|
+
* The End user's token is asked for once, after the key is known to be there and before the first
|
|
1202
|
+
* attempt — of `getToken`, the nearest view's function, or the configuration's — so every retry
|
|
1203
|
+
* of one call sends the token its first attempt sent. See `RelyIOConfig.getToken`.
|
|
1175
1204
|
*/
|
|
1176
|
-
async request(config) {
|
|
1205
|
+
async request(config, getToken) {
|
|
1177
1206
|
if (this.view !== void 0) {
|
|
1178
|
-
return this.view.client.request(
|
|
1179
|
-
...config,
|
|
1180
|
-
|
|
1181
|
-
|
|
1207
|
+
return this.view.client.request(
|
|
1208
|
+
{ ...config, headers: layerHeaders(this.view.headers, config.headers) },
|
|
1209
|
+
getToken ?? this.view.getToken
|
|
1210
|
+
);
|
|
1182
1211
|
}
|
|
1183
1212
|
if (config.timeout !== void 0) assertRequestTimeout(config.timeout);
|
|
1184
1213
|
const mergedConfig = this.mergeRequestConfig(config);
|
|
1185
|
-
if (
|
|
1214
|
+
if (presentCredential(headerValue(mergedConfig.headers, API_KEY_HEADER)) === void 0) {
|
|
1186
1215
|
throw new MissingApiKeyError(
|
|
1187
1216
|
"`apiKey` is missing: this client holds no API key, so the request was not sent. Pass `apiKey` to createClient \u2014 the documented setup reads it from RELYIO_API_KEY.",
|
|
1188
1217
|
{ url: mergedConfig.url, method: mergedConfig.method, sent: false }
|
|
1189
1218
|
);
|
|
1190
1219
|
}
|
|
1220
|
+
const tokenSource = getToken ?? this.connection.config.getToken;
|
|
1221
|
+
if (tokenSource !== void 0) {
|
|
1222
|
+
const token = presentCredential(await tokenSource());
|
|
1223
|
+
mergedConfig.headers = layerHeaders(mergedConfig.headers ?? {}, {
|
|
1224
|
+
[END_USER_HEADER]: token ?? null
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1191
1227
|
this.log("debug", "Making request", {
|
|
1192
1228
|
method: mergedConfig.method,
|
|
1193
1229
|
url: mergedConfig.url
|
|
@@ -1231,7 +1267,7 @@ var _HttpClient = class _HttpClient {
|
|
|
1231
1267
|
});
|
|
1232
1268
|
if (preview !== void 0 && answersUnknownDataset(sdkError, preview)) {
|
|
1233
1269
|
rememberUnknownPreview(preview);
|
|
1234
|
-
return this.request(config);
|
|
1270
|
+
return this.request(config, getToken);
|
|
1235
1271
|
}
|
|
1236
1272
|
this.log("error", "Request failed after all retries", {
|
|
1237
1273
|
error: sdkError.toJSON(),
|
|
@@ -1452,10 +1488,17 @@ var _ControlledHttpClient = class _ControlledHttpClient extends HttpClient {
|
|
|
1452
1488
|
* retries and `fetch` are this client's as they are when each request is sent, so a later
|
|
1453
1489
|
* `configure()` or `setApiKey()` on this client reaches the view, and one on the view reaches
|
|
1454
1490
|
* this client. `client.with({ dataset })` is one (REL-2417).
|
|
1491
|
+
*
|
|
1492
|
+
* `options.getToken` is the End user's token function the view asks in place of this client's,
|
|
1493
|
+
* and of any view it is made from: `client.with({ getToken })` (REL-3882).
|
|
1455
1494
|
*/
|
|
1456
|
-
withHeaders(headers) {
|
|
1495
|
+
withHeaders(headers, options = {}) {
|
|
1457
1496
|
const view = new _ControlledHttpClient(this.connection.config);
|
|
1458
|
-
view.view = {
|
|
1497
|
+
view.view = {
|
|
1498
|
+
client: this,
|
|
1499
|
+
headers: { ...headers },
|
|
1500
|
+
...options.getToken === void 0 ? {} : { getToken: options.getToken }
|
|
1501
|
+
};
|
|
1459
1502
|
return view;
|
|
1460
1503
|
}
|
|
1461
1504
|
/**
|
|
@@ -1477,7 +1520,7 @@ var _ControlledHttpClient = class _ControlledHttpClient extends HttpClient {
|
|
|
1477
1520
|
* Replace the key every later request sends as `X-API-Key`, and the `apiKey` the configuration
|
|
1478
1521
|
* reports.
|
|
1479
1522
|
*
|
|
1480
|
-
* The key is read the way construction reads it (`
|
|
1523
|
+
* The key is read the way construction reads it (`presentCredential`): an absent, empty or blank key is
|
|
1481
1524
|
* no key, so the header is dropped and the next request is refused with `MissingApiKeyError`
|
|
1482
1525
|
* before anything is sent. A key header of any other spelling — one given in `headers` — goes
|
|
1483
1526
|
* too, from the headers sent and from the headers the configuration reports, so the old key is
|
|
@@ -1498,7 +1541,7 @@ var _ControlledHttpClient = class _ControlledHttpClient extends HttpClient {
|
|
|
1498
1541
|
this.connection = {
|
|
1499
1542
|
...this.connection,
|
|
1500
1543
|
defaultHeaders: layerHeaders(this.connection.defaultHeaders, {
|
|
1501
|
-
[API_KEY_HEADER]:
|
|
1544
|
+
[API_KEY_HEADER]: presentCredential(apiKey) ?? null
|
|
1502
1545
|
})
|
|
1503
1546
|
};
|
|
1504
1547
|
}
|
|
@@ -1507,6 +1550,7 @@ __name(_ControlledHttpClient, "ControlledHttpClient");
|
|
|
1507
1550
|
var ControlledHttpClient = _ControlledHttpClient;
|
|
1508
1551
|
var API_KEY_HEADER = "X-API-Key";
|
|
1509
1552
|
var DATASET_HEADER = "X-RelyIO-Dataset";
|
|
1553
|
+
var END_USER_HEADER = HEADER_END_USER.name;
|
|
1510
1554
|
function derivedPreviewIn(headers) {
|
|
1511
1555
|
const dataset = headerValue(headers, DATASET_HEADER);
|
|
1512
1556
|
return dataset !== void 0 && isDerivedPreview(dataset) ? dataset : void 0;
|
|
@@ -1525,7 +1569,7 @@ function connectionFor(config) {
|
|
|
1525
1569
|
const defaultHeaders = layerHeaders(
|
|
1526
1570
|
layerHeaders({ "Content-Type": "application/json" }, config.headers),
|
|
1527
1571
|
{
|
|
1528
|
-
[API_KEY_HEADER]:
|
|
1572
|
+
[API_KEY_HEADER]: presentCredential(config.apiKey),
|
|
1529
1573
|
[DATASET_HEADER]: config.dataset,
|
|
1530
1574
|
// Only outside a browser, which controls this header. "A browser" is the core's one
|
|
1531
1575
|
// definition, `isBrowser()` — every environment question in this file asks it.
|
|
@@ -1557,10 +1601,10 @@ function layerHeaders(base, over) {
|
|
|
1557
1601
|
return layered;
|
|
1558
1602
|
}
|
|
1559
1603
|
__name(layerHeaders, "layerHeaders");
|
|
1560
|
-
function
|
|
1604
|
+
function presentCredential(value) {
|
|
1561
1605
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
1562
1606
|
}
|
|
1563
|
-
__name(
|
|
1607
|
+
__name(presentCredential, "presentCredential");
|
|
1564
1608
|
function credentialsModeFor(includeCredentials) {
|
|
1565
1609
|
return includeCredentials ? "include" : "same-origin";
|
|
1566
1610
|
}
|
|
@@ -2876,7 +2920,8 @@ var _RecordsClient = class _RecordsClient {
|
|
|
2876
2920
|
* Store a Record, live the moment it lands. Values that break the Record type's fields are
|
|
2877
2921
|
* refused with `ValidationError` naming each field, and nothing is stored. Values a unique set of
|
|
2878
2922
|
* the type claims, held by another Record, are refused with `ResourceConflictError` — its
|
|
2879
|
-
* `blockage` is `{ kind: 'value-taken', facts: { fields, recordId } }` (REL-3782)
|
|
2923
|
+
* `blockage` is `{ kind: 'value-taken', facts: { fields, recordId } }` (REL-3782) — with no
|
|
2924
|
+
* `recordId` for an End user's write, whose read Policy may hide the holder (REL-3863).
|
|
2880
2925
|
*/
|
|
2881
2926
|
async create(fields, options = {}) {
|
|
2882
2927
|
return this.httpClient.fetchPayload(
|
|
@@ -4117,6 +4162,9 @@ function validateConfig(config) {
|
|
|
4117
4162
|
if (config.webSocket != null && typeof config.webSocket !== "function") {
|
|
4118
4163
|
throw new Error("webSocket must be a WebSocket class");
|
|
4119
4164
|
}
|
|
4165
|
+
if (config.getToken != null && typeof config.getToken !== "function") {
|
|
4166
|
+
throw new Error("getToken must be a function that answers the End user\u2019s token, or null");
|
|
4167
|
+
}
|
|
4120
4168
|
if (config.timeout != null) assertRequestTimeout(config.timeout);
|
|
4121
4169
|
if (config.retryAttempts != null && !(Number.isInteger(config.retryAttempts) && config.retryAttempts >= 1)) {
|
|
4122
4170
|
throw new Error(
|
|
@@ -4245,7 +4293,10 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4245
4293
|
* `createClient()` made, which reads its own.
|
|
4246
4294
|
*/
|
|
4247
4295
|
__publicField(this, "parent");
|
|
4248
|
-
/**
|
|
4296
|
+
/**
|
|
4297
|
+
* What `with()` gave this client over its parent's: the locale, dataset and End user's token
|
|
4298
|
+
* function it names, and no other.
|
|
4299
|
+
*/
|
|
4249
4300
|
__publicField(this, "defaults", {});
|
|
4250
4301
|
/** The live edge's poll client id: chosen once, when first needed, and kept for this client's life. */
|
|
4251
4302
|
__publicField(this, "_liveClientId");
|
|
@@ -4256,7 +4307,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4256
4307
|
* all or none (REL-3774).
|
|
4257
4308
|
*
|
|
4258
4309
|
* A Record is an app's data, written by your server with a secret key and live the moment it
|
|
4259
|
-
* lands
|
|
4310
|
+
* lands. A publishable key reads the Records a Record type's read Policy grants it (spec 4,
|
|
4311
|
+
* REL-3883), and writes them only for the End user whose token it carries, as the type's write
|
|
4312
|
+
* Policy allows (REL-3884); with no token it writes nothing (`PUBLISHABLE_KEY_REFUSED`).
|
|
4260
4313
|
*
|
|
4261
4314
|
* @example
|
|
4262
4315
|
* ```typescript
|
|
@@ -4740,6 +4793,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4740
4793
|
* const { data } = await staging.content('post').list({ limit: 10 })
|
|
4741
4794
|
*
|
|
4742
4795
|
* const french = relyio.with({ locale: 'fr-FR' }) // ← autocompletes the schema's locales
|
|
4796
|
+
*
|
|
4797
|
+
* // Every request this one sends carries the signed-in End user's token (REL-3882)
|
|
4798
|
+
* const visitor = relyio.with({ getToken: () => session.getToken() })
|
|
4743
4799
|
* ```
|
|
4744
4800
|
*/
|
|
4745
4801
|
with(defaults) {
|
|
@@ -4753,14 +4809,16 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4753
4809
|
}
|
|
4754
4810
|
/** Make this client one `with()` made from `parent`: see {@link with}. */
|
|
4755
4811
|
follow(parent, defaults) {
|
|
4756
|
-
const { locale, dataset } = defaults;
|
|
4812
|
+
const { locale, dataset, getToken } = defaults;
|
|
4757
4813
|
this.parent = parent;
|
|
4758
4814
|
this.defaults = {
|
|
4759
4815
|
...locale === void 0 ? {} : { locale },
|
|
4760
|
-
...dataset === void 0 ? {} : { dataset }
|
|
4816
|
+
...dataset === void 0 ? {} : { dataset },
|
|
4817
|
+
...getToken === void 0 ? {} : { getToken }
|
|
4761
4818
|
};
|
|
4762
4819
|
this.httpClient = parent.httpClient.withHeaders(
|
|
4763
|
-
dataset === void 0 ? {} : { [DATASET_HEADER]: dataset }
|
|
4820
|
+
dataset === void 0 ? {} : { [DATASET_HEADER]: dataset },
|
|
4821
|
+
getToken === void 0 ? {} : { getToken }
|
|
4764
4822
|
);
|
|
4765
4823
|
}
|
|
4766
4824
|
/**
|
|
@@ -4811,6 +4869,6 @@ function randomClientId() {
|
|
|
4811
4869
|
}
|
|
4812
4870
|
__name(randomClientId, "randomClientId");
|
|
4813
4871
|
|
|
4814
|
-
export { AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthorizationError, BaseValidationError, ChangesExpiredError, ConnectionError, ContentClient, DefaultRetryPolicy, ErrorMapper, FileUploadError, FileValidationError, FunctionContainersBusyError, FunctionRunFailedError, FunctionRunTimedOutError, HttpClient, InvalidApiKeyError, InvalidPayloadError, LIVE_KEEPALIVE_INTERVAL_MS, LIVE_SOCKET_OPEN_TIMEOUT_MS, LiveEdgeError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PREVIEW_KEY_PREFIX, PUBLISHABLE_KEY_PREFIX, PayloadTooLargeError, PlanFeatureUnavailableError, PublishableKeyRefusedError, RateLimitError, ReadOnlyKeyError, RecordsClient, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, SettingsClient, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, isAborted, isAssetEntry, isMissingEntry, isPreviewKey, isPublishableKey, isReplaySafe, isResourceNotFound, matchRoute, refusedOperationOf, retryPolicyFor, serviceInstructedDelayMs, sleep, validateFile, versionCheckOf };
|
|
4815
|
-
//# sourceMappingURL=chunk-
|
|
4816
|
-
//# sourceMappingURL=chunk-
|
|
4872
|
+
export { AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthorizationError, BaseValidationError, ChangesExpiredError, ConnectionError, ContentClient, DefaultRetryPolicy, EndUserTokenInvalidError, ErrorMapper, FileUploadError, FileValidationError, FunctionContainersBusyError, FunctionRunFailedError, FunctionRunTimedOutError, HttpClient, InvalidApiKeyError, InvalidPayloadError, LIVE_KEEPALIVE_INTERVAL_MS, LIVE_SOCKET_OPEN_TIMEOUT_MS, LiveEdgeError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PREVIEW_KEY_PREFIX, PUBLISHABLE_KEY_PREFIX, PayloadTooLargeError, PlanFeatureUnavailableError, PublishableKeyRefusedError, RateLimitError, ReadOnlyKeyError, RecordsClient, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, SettingsClient, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, isAborted, isAssetEntry, isMissingEntry, isPreviewKey, isPublishableKey, isReplaySafe, isResourceNotFound, matchRoute, refusedOperationOf, retryPolicyFor, serviceInstructedDelayMs, sleep, validateFile, versionCheckOf };
|
|
4873
|
+
//# sourceMappingURL=chunk-356SF5Y2.js.map
|
|
4874
|
+
//# sourceMappingURL=chunk-356SF5Y2.js.map
|