@appshell/loader 1.0.0-alpha.9 → 1.0.0-alpha.90
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/README.md +19 -21
- package/dist/main.js +1 -1
- package/dist/types/config/src/axios.d.ts +0 -1
- package/dist/types/config/src/configmap.d.ts +0 -1
- package/dist/types/config/src/context.d.ts +3 -4
- package/dist/types/config/src/credentials.d.ts +35 -3
- package/dist/types/config/src/generate.manifest.d.ts +30 -2
- package/dist/types/config/src/index.d.ts +9 -10
- package/dist/types/config/src/loader.d.ts +18 -0
- package/dist/types/config/src/mappers/appshell.config.d.ts +9 -3
- package/dist/types/config/src/outdated.d.ts +0 -1
- package/dist/types/config/src/package-name.d.ts +20 -0
- package/dist/types/config/src/publish.d.ts +89 -7
- package/dist/types/config/src/sync.d.ts +0 -1
- package/dist/types/config/src/tls.d.ts +23 -0
- package/dist/types/config/src/types.d.ts +164 -30
- package/dist/types/config/src/utils/blur.d.ts +0 -1
- package/dist/types/config/src/utils/compare.d.ts +0 -1
- package/dist/types/config/src/utils/config.d.ts +0 -1
- package/dist/types/config/src/utils/copy.d.ts +0 -1
- package/dist/types/config/src/utils/dump.d.ts +10 -0
- package/dist/types/config/src/utils/index.d.ts +1 -4
- package/dist/types/config/src/utils/list.d.ts +0 -1
- package/dist/types/config/src/utils/load.d.ts +0 -1
- package/dist/types/config/src/validators/AppshellTemplateValidator.d.ts +0 -1
- package/dist/types/config/src/validators/index.d.ts +0 -3
- package/dist/types/loader/src/index.d.ts +0 -1
- package/dist/types/loader/src/loadAppshellComponent.d.ts +13 -14
- package/dist/types/loader/src/remoteLoader.d.ts +2 -3
- package/dist/types/loader/src/resolvers.d.ts +4 -12
- package/dist/types/loader/src/types.d.ts +0 -1
- package/dist/types/runtime/src/errors.d.ts +32 -0
- package/dist/types/runtime/src/identity.d.ts +47 -0
- package/dist/types/runtime/src/index.d.ts +6 -0
- package/dist/types/runtime/src/store.d.ts +25 -0
- package/dist/types/runtime/src/types.d.ts +9 -0
- package/dist/types/runtime/src/wire.d.ts +58 -0
- package/package.json +15 -4
- package/CHANGELOG.md +0 -197
- package/__tests__/fetchDynamicScript.spec.ts +0 -44
- package/__tests__/fixtures/TestComponent.ts +0 -3
- package/__tests__/loadAppshellComponent.spec.ts +0 -102
- package/__tests__/remoteLoader.spec.ts +0 -144
- package/__tests__/resolvers.spec.ts +0 -128
- package/dist/types/config/src/axios.d.ts.map +0 -1
- package/dist/types/config/src/configmap.d.ts.map +0 -1
- package/dist/types/config/src/context.d.ts.map +0 -1
- package/dist/types/config/src/credentials.d.ts.map +0 -1
- package/dist/types/config/src/deregister.d.ts +0 -3
- package/dist/types/config/src/deregister.d.ts.map +0 -1
- package/dist/types/config/src/generate.env.d.ts +0 -3
- package/dist/types/config/src/generate.env.d.ts.map +0 -1
- package/dist/types/config/src/generate.global-config.d.ts +0 -10
- package/dist/types/config/src/generate.global-config.d.ts.map +0 -1
- package/dist/types/config/src/generate.manifest.d.ts.map +0 -1
- package/dist/types/config/src/index.d.ts.map +0 -1
- package/dist/types/config/src/mappers/appshell.config.d.ts.map +0 -1
- package/dist/types/config/src/outdated.d.ts.map +0 -1
- package/dist/types/config/src/publish.d.ts.map +0 -1
- package/dist/types/config/src/register.d.ts +0 -4
- package/dist/types/config/src/register.d.ts.map +0 -1
- package/dist/types/config/src/sync.d.ts.map +0 -1
- package/dist/types/config/src/types.d.ts.map +0 -1
- package/dist/types/config/src/utils/blur.d.ts.map +0 -1
- package/dist/types/config/src/utils/compare.d.ts.map +0 -1
- package/dist/types/config/src/utils/config.d.ts.map +0 -1
- package/dist/types/config/src/utils/copy.d.ts.map +0 -1
- package/dist/types/config/src/utils/index.d.ts.map +0 -1
- package/dist/types/config/src/utils/isValidUrl.d.ts +0 -3
- package/dist/types/config/src/utils/isValidUrl.d.ts.map +0 -1
- package/dist/types/config/src/utils/list.d.ts.map +0 -1
- package/dist/types/config/src/utils/load.d.ts.map +0 -1
- package/dist/types/config/src/utils/loadJson.d.ts +0 -10
- package/dist/types/config/src/utils/loadJson.d.ts.map +0 -1
- package/dist/types/config/src/utils/merge.d.ts +0 -4
- package/dist/types/config/src/utils/merge.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellGlobalConfigValidator.d.ts +0 -4
- package/dist/types/config/src/validators/AppshellGlobalConfigValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellManifestValidator.d.ts +0 -4
- package/dist/types/config/src/validators/AppshellManifestValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellTemplateValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/index.d.ts.map +0 -1
- package/dist/types/loader/src/fetchDynamicScript.d.ts +0 -3
- package/dist/types/loader/src/fetchDynamicScript.d.ts.map +0 -1
- package/dist/types/loader/src/index.d.ts.map +0 -1
- package/dist/types/loader/src/loadAppshellComponent.d.ts.map +0 -1
- package/dist/types/loader/src/remoteLoader.d.ts.map +0 -1
- package/dist/types/loader/src/resolvers.d.ts.map +0 -1
- package/dist/types/loader/src/types.d.ts.map +0 -1
- package/src/fetchDynamicScript.ts +0 -49
- package/src/index.ts +0 -7
- package/src/loadAppshellComponent.ts +0 -48
- package/src/remoteLoader.ts +0 -80
- package/src/resolvers.ts +0 -110
- package/src/types.ts +0 -10
- package/tsconfig.json +0 -7
- package/webpack.config.js +0 -37
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
/**
|
|
3
|
+
* An extra CA bundle to trust, from `ca-file` in the cli config or `APPSHELL_CA_FILE`.
|
|
4
|
+
*
|
|
5
|
+
* A registry behind a private CA — a corporate root, a TLS-inspecting proxy, or a local
|
|
6
|
+
* cluster using mkcert — fails with "unable to verify the first certificate", which says
|
|
7
|
+
* nothing about which host or what to do. Node can be told through `NODE_EXTRA_CA_CERTS`
|
|
8
|
+
* or `--use-system-ca`, but both are environment variables a user has to remember in
|
|
9
|
+
* every new terminal, and neither travels with the registry they apply to.
|
|
10
|
+
*
|
|
11
|
+
* npm draws the same conclusion with `cafile` in .npmrc: trust is configuration of the
|
|
12
|
+
* registry you talk to, not of the shell you happen to be in.
|
|
13
|
+
*/
|
|
14
|
+
export declare const caFile: () => string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* The agent to use for registry and issuer requests, or undefined when no CA is
|
|
17
|
+
* configured and Node's defaults apply.
|
|
18
|
+
*
|
|
19
|
+
* A configured file that does not exist throws rather than being skipped: falling back
|
|
20
|
+
* silently would reproduce the original certificate error, having been told exactly how
|
|
21
|
+
* to avoid it.
|
|
22
|
+
*/
|
|
23
|
+
export declare const httpsAgent: () => https.Agent | undefined;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { AppshellIndex, AppshellRemote, Metadata, RemoteLoader } from '@appshell/runtime';
|
|
1
2
|
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
3
|
+
export type { AppshellIndex, AppshellRemote, Metadata, ModuleFederationLoader, RemoteLoader, } from '@appshell/runtime';
|
|
2
4
|
export type Schema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
3
5
|
export type ConfigValidator = {
|
|
4
6
|
validate: <T>(...config: T[]) => void;
|
|
@@ -43,58 +45,165 @@ export type ComparisonTarget = {
|
|
|
43
45
|
name: string;
|
|
44
46
|
dependencies: Record<string, string | undefined>;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Every key `appshell config set` accepts, kept adjacent to the type it must agree with.
|
|
50
|
+
*
|
|
51
|
+
* It used to live in the set handler, and adding `caFile` to CliConfig without touching it
|
|
52
|
+
* produced a setting the cli could read and refuse to write.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CLI_SETTINGS: readonly ["registry", "application", "scopeId", "authIssuer", "clientId", "apiKey", "apiKeyHeader", "caFile"];
|
|
55
|
+
export type CliSetting = (typeof CLI_SETTINGS)[number];
|
|
46
56
|
export type CliConfig = Record<string, string> & {
|
|
47
57
|
apiKey: string;
|
|
58
|
+
/**
|
|
59
|
+
* PEM bundle to trust in addition to Node's built-ins, for a registry behind a private
|
|
60
|
+
* CA. Optional, and absent from `config init` output: an empty path is not a default
|
|
61
|
+
* worth writing, and its absence means "use Node's defaults".
|
|
62
|
+
*/
|
|
63
|
+
caFile?: string;
|
|
48
64
|
registry: string;
|
|
49
|
-
|
|
65
|
+
application: string;
|
|
50
66
|
scopeId: string;
|
|
51
67
|
authIssuer: string;
|
|
52
68
|
clientId: string;
|
|
53
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Neither `url` nor `filename`.
|
|
72
|
+
*
|
|
73
|
+
* `url` is an origin, and an origin belongs to a deployment: a package is published once
|
|
74
|
+
* and deployed many times, so a url here would freeze one environment's answer into an
|
|
75
|
+
* immutable version and make the artifact's digest depend on where it was built.
|
|
76
|
+
*
|
|
77
|
+
* `filename` was a hand-written copy of the Module Federation `filename`, which is what
|
|
78
|
+
* actually decides the file webpack emits. Two statements of one fact, and only one of
|
|
79
|
+
* them is enforced by anything.
|
|
80
|
+
*/
|
|
54
81
|
export type AppshellConfigRemote<TMetadata = Metadata> = {
|
|
55
82
|
id: string;
|
|
56
|
-
url: string;
|
|
57
|
-
filename: string;
|
|
58
83
|
metadata: TMetadata;
|
|
59
84
|
};
|
|
60
85
|
export type AppshellConfig<TMetadata = Metadata> = {
|
|
61
86
|
name?: string;
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
/**
|
|
88
|
+
* What the registry should publish this package as. `--visibility` overrides it.
|
|
89
|
+
*
|
|
90
|
+
* Declared here but deliberately absent from the manifest, as `name` already is: the
|
|
91
|
+
* manifest is hashed into the package digest, and visibility is not a property of the
|
|
92
|
+
* artifact. Keeping it out is what lets a package be made public later without its
|
|
93
|
+
* content changing identity.
|
|
94
|
+
*/
|
|
95
|
+
visibility?: 'public' | 'private';
|
|
96
|
+
/**
|
|
97
|
+
* What this package publishes, keyed by federation entrypoint.
|
|
98
|
+
*
|
|
99
|
+
* Appshell's own word rather than a framework's. It was `remotes`, which is MF's word
|
|
100
|
+
* for the opposite — what a package consumes — so the file read inverted to anyone who
|
|
101
|
+
* knew the framework. `exposes` would fix that and put MF's vocabulary at the top level
|
|
102
|
+
* of appshell's model, which is what the loader recipe exists to prevent.
|
|
103
|
+
*/
|
|
104
|
+
components?: Record<string, AppshellConfigRemote<TMetadata>>;
|
|
105
|
+
/**
|
|
106
|
+
* What this package consumes, by the name it refers to them by.
|
|
107
|
+
*
|
|
108
|
+
* A flat list because a referenced remote is required by definition: unbound, the region
|
|
109
|
+
* renders an error. `RemoteSlot`'s `fallback` is a loading placeholder — it shows while
|
|
110
|
+
* the remote arrives, not when it is absent — so unlike a design token's `var()`
|
|
111
|
+
* fallback it describes no degraded-but-working state.
|
|
112
|
+
*
|
|
113
|
+
* The application binds each name to a registry address, so a package never states the
|
|
114
|
+
* scope its siblings were published into — which it cannot know, since scope is assigned
|
|
115
|
+
* by whoever publishes.
|
|
116
|
+
*/
|
|
117
|
+
remotes?: string[];
|
|
118
|
+
vars?: Record<string, unknown>;
|
|
64
119
|
overrides?: AppshellOverrides;
|
|
65
120
|
};
|
|
66
121
|
export type AppshellTemplate<TMetadata = Metadata> = {
|
|
67
122
|
name?: string;
|
|
68
|
-
|
|
123
|
+
/** Carried from the yaml for publish to read; never mapped into the manifest. */
|
|
124
|
+
visibility?: 'public' | 'private';
|
|
125
|
+
components?: Record<string, AppshellConfigRemote<TMetadata>>;
|
|
126
|
+
remotes?: string[];
|
|
69
127
|
module: ModuleFederationPluginOptions;
|
|
70
|
-
|
|
128
|
+
vars?: Record<string, unknown>;
|
|
129
|
+
tokens?: Record<string, AppshellTokenUsage>;
|
|
71
130
|
overrides?: AppshellOverrides;
|
|
72
131
|
};
|
|
73
132
|
/** Appshell manifest types */
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
scope: string;
|
|
79
|
-
module: string;
|
|
80
|
-
shareScope?: string;
|
|
81
|
-
metadata: TMetadata;
|
|
133
|
+
/** The parts of a remote an application may point somewhere else. */
|
|
134
|
+
export type RemoteOverride = {
|
|
135
|
+
remoteEntryUrl?: string;
|
|
136
|
+
manifestUrl?: string;
|
|
82
137
|
};
|
|
83
138
|
export type AppshellOverrides = {
|
|
84
|
-
|
|
139
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
140
|
+
/**
|
|
141
|
+
* Where an application loads a remote from, keyed by registry address.
|
|
142
|
+
*
|
|
143
|
+
* A package is published once; an application is deployed many times, per environment.
|
|
144
|
+
* The origin a bundle is served from is a property of a deployment, so it belongs to
|
|
145
|
+
* whoever deploys rather than being frozen into an immutable artifact at publish — which
|
|
146
|
+
* is also what makes adopting someone else's package and serving it yourself a spec edit
|
|
147
|
+
* rather than a republish.
|
|
148
|
+
*
|
|
149
|
+
* `filename` stays in the manifest: `remoteEntry.js` is genuinely build output. Only the
|
|
150
|
+
* origin varies by environment.
|
|
151
|
+
*/
|
|
152
|
+
remotes?: Record<string, RemoteOverride>;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Which design tokens a package's own output reaches for. Observed from the emitted
|
|
156
|
+
* assets rather than declared: the CSS already says it, and a hand-kept list is a copy
|
|
157
|
+
* that drifts the first time someone adds a token and forgets the yaml.
|
|
158
|
+
*
|
|
159
|
+
* `required` is a reference with no fallback — the package has no plan B. `optional` is
|
|
160
|
+
* `var(--appshell-x, something)`, which degrades on its own. That split is read off what
|
|
161
|
+
* the author wrote rather than asked of them.
|
|
162
|
+
*/
|
|
163
|
+
export type AppshellTokenUsage = {
|
|
164
|
+
required: string[];
|
|
165
|
+
optional: string[];
|
|
166
|
+
};
|
|
167
|
+
/** A shared-dependency contract, named as one framework's model among possible models. */
|
|
168
|
+
export type SharedContract = {
|
|
169
|
+
apiVersion: 'federation.appshell.org/v1';
|
|
170
|
+
kind: 'ModuleFederation';
|
|
171
|
+
/** Keyed by share scope, as Module Federation groups them. */
|
|
172
|
+
scopes: Record<string, SharedObject>;
|
|
85
173
|
};
|
|
86
174
|
export type AppshellManifest<TMetadata = Metadata> = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
175
|
+
/** What this package publishes, keyed by federation entrypoint. */
|
|
176
|
+
components: Record<string, PublishedRemote<TMetadata>>;
|
|
177
|
+
/** What it consumes, by local name; the application binds each to an address. */
|
|
178
|
+
remotes?: string[];
|
|
179
|
+
/**
|
|
180
|
+
* The shared-dependency contract this package was built against.
|
|
181
|
+
*
|
|
182
|
+
* Tagged like the loader recipe, and for the same reason: share scopes, singletons and
|
|
183
|
+
* version ranges are Module Federation's model of the problem, which single-spa and
|
|
184
|
+
* import maps solve differently. This replaced `modules`, which stored MF's plugin
|
|
185
|
+
* options verbatim — one reader took two fields from it, while its source paths and
|
|
186
|
+
* type-generation flags sat inside the package digest.
|
|
187
|
+
*/
|
|
188
|
+
shared?: SharedContract;
|
|
189
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
190
|
+
/** Keyed by federation scope, so a merged manifest still says which package needs what. */
|
|
191
|
+
tokens?: Record<string, AppshellTokenUsage>;
|
|
90
192
|
overrides?: AppshellOverrides;
|
|
91
193
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
194
|
+
/**
|
|
195
|
+
* A remote as a package publishes it: what the build knows about itself, and nothing
|
|
196
|
+
* about where it ends up.
|
|
197
|
+
*
|
|
198
|
+
* Distinct from `AppshellRemote`, which is the same remote after the registry has
|
|
199
|
+
* resolved it for the browser. They were one type, which is why the origin ended up in
|
|
200
|
+
* the artifact: the browser genuinely needs a url, so the published form appeared to as
|
|
201
|
+
* well. The registry supplies it at composition, from the address and its serving plane.
|
|
202
|
+
*/
|
|
203
|
+
export type PublishedRemote<TMetadata = Metadata> = {
|
|
204
|
+
id: string;
|
|
205
|
+
loader: RemoteLoader;
|
|
206
|
+
metadata: TMetadata;
|
|
98
207
|
};
|
|
99
208
|
/** An `AppshellRemote` the registry already resolved, so the browser needs no manifest fetch. */
|
|
100
209
|
export type ResolvedRemote<TMetadata = Metadata> = AppshellRemote<TMetadata>;
|
|
@@ -102,19 +211,45 @@ export type ResolvedRemote<TMetadata = Metadata> = AppshellRemote<TMetadata>;
|
|
|
102
211
|
* The wire contract for `window.__appshell_config__`. Deliberately not an
|
|
103
212
|
* `AppshellManifest`: that is a build artifact, and reusing it left it unclear
|
|
104
213
|
* which fields the browser actually needs. `modules` is build-time webpack
|
|
105
|
-
* config and never crosses the wire; `
|
|
106
|
-
*
|
|
214
|
+
* config and never crosses the wire; `vars` arrives already merged with the
|
|
215
|
+
* application's overrides, leaving the browser only local overrides to apply.
|
|
107
216
|
*/
|
|
108
217
|
export type AppshellComposition<TMetadata = Metadata> = {
|
|
109
218
|
/** `scope/name` — makes the payload self-describing for fetch-on-miss and for `env diff`. */
|
|
110
|
-
|
|
219
|
+
applicationId: string;
|
|
111
220
|
revision: number;
|
|
112
221
|
/** The remote key the host mounts at the root, and the props it is given. */
|
|
113
222
|
root: string;
|
|
114
223
|
rootProps: Record<string, unknown>;
|
|
115
224
|
index: AppshellIndex;
|
|
116
225
|
remotes: Record<string, ResolvedRemote<TMetadata>>;
|
|
117
|
-
|
|
226
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
227
|
+
/**
|
|
228
|
+
* Present whenever a per-developer overlay changed anything about this render — a
|
|
229
|
+
* redirected remote, a different shell bundle, a substituted theme, or any combination.
|
|
230
|
+
* The shell is expected to surface it: a page that quietly runs code from somewhere
|
|
231
|
+
* else is the one thing this feature must never be, and swapping the shell or the theme
|
|
232
|
+
* out counts.
|
|
233
|
+
*
|
|
234
|
+
* `shellFlavor` is what was actually served, not what was asked for. `theme` is the ref
|
|
235
|
+
* the overlay substituted, present only when it substituted one.
|
|
236
|
+
*/
|
|
237
|
+
overlay?: {
|
|
238
|
+
id: string;
|
|
239
|
+
remotes: string[];
|
|
240
|
+
/**
|
|
241
|
+
* Those of `remotes` the overlay introduced rather than redirected — components the
|
|
242
|
+
* application does not publish, running for this developer and nobody else.
|
|
243
|
+
*
|
|
244
|
+
* Separate from `remotes` because the two are not the same claim. A redirected
|
|
245
|
+
* component exists for everyone and this browser runs a different copy of it; an
|
|
246
|
+
* added one does not exist outside this overlay at all, so a feature built on top of
|
|
247
|
+
* one works here and is absent everywhere else.
|
|
248
|
+
*/
|
|
249
|
+
added?: string[];
|
|
250
|
+
shellFlavor: 'prod' | 'dev';
|
|
251
|
+
theme?: string;
|
|
252
|
+
};
|
|
118
253
|
};
|
|
119
254
|
/**
|
|
120
255
|
* Advanced configuration for modules that should be exposed by this container.
|
|
@@ -293,4 +428,3 @@ export interface ModuleFederationPluginOptions {
|
|
|
293
428
|
*/
|
|
294
429
|
shared?: (string | SharedObject)[] | SharedObject;
|
|
295
430
|
}
|
|
296
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -5,4 +5,3 @@ export declare const compareDependencies: (sample: ComparisonTarget, baseline: C
|
|
|
5
5
|
export declare const compareSharedDependencies: (packageSpec: PackageSpec, sharedModule: SharedModuleSpec) => ComparisonResults;
|
|
6
6
|
export declare const compareSharedModules: (sampleSpec: SharedModuleSpec, baselineSpec: SharedModuleSpec) => ComparisonResults;
|
|
7
7
|
export declare const printResults: (results: ComparisonResults) => void;
|
|
8
|
-
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -3,4 +3,3 @@ import { CliConfig } from '../types';
|
|
|
3
3
|
export declare const readConfig: (configPath: string) => CliConfig;
|
|
4
4
|
export declare const writeConfig: (configPath: string, config: CliConfig) => void;
|
|
5
5
|
export declare const mergeConfigWithArgs: (config: CliConfig, argv: yargs.ArgumentsCamelCase<unknown>) => void;
|
|
6
|
-
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialises a value to YAML.
|
|
3
|
+
*
|
|
4
|
+
* The counterpart to `load`, and here rather than at each call site so the YAML library
|
|
5
|
+
* stays in one package. `appshell theme init` writes a file an author then edits, so the
|
|
6
|
+
* output is line-wrapped generously — a colour value broken across lines is technically
|
|
7
|
+
* valid and horrible to read.
|
|
8
|
+
*/
|
|
9
|
+
declare const dump: (value: unknown) => string;
|
|
10
|
+
export default dump;
|
|
@@ -2,9 +2,6 @@ export { default as blur } from './blur';
|
|
|
2
2
|
export { compareDependencies, compareDependency, compareSharedDependencies, compareSharedModules, extractDependencies, printResults, } from './compare';
|
|
3
3
|
export { mergeConfigWithArgs, readConfig, writeConfig } from './config';
|
|
4
4
|
export { default as copy } from './copy';
|
|
5
|
-
export { default as
|
|
5
|
+
export { default as dump } from './dump';
|
|
6
6
|
export { default as list } from './list';
|
|
7
7
|
export { default as load, loadAll } from './load';
|
|
8
|
-
export { default as loadJson } from './loadJson';
|
|
9
|
-
export { default as merge } from './merge';
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export { default as AppshellGlobalConfigValidator } from './AppshellGlobalConfigValidator';
|
|
2
|
-
export { default as AppshellManifestValidator } from './AppshellManifestValidator';
|
|
3
1
|
export { default as AppshellTemplateValidator } from './AppshellTemplateValidator';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export default
|
|
14
|
-
//# sourceMappingURL=loadAppshellComponent.d.ts.map
|
|
1
|
+
import type { RemoteLoader } from '@appshell/runtime';
|
|
2
|
+
/**
|
|
3
|
+
* Dispatches on the loader's kind rather than assuming federation.
|
|
4
|
+
*
|
|
5
|
+
* There is one kind today. Naming it is what lets a second — single-spa, import maps —
|
|
6
|
+
* arrive without reinterpreting manifests already published, and what stops federation's
|
|
7
|
+
* vocabulary reading as though it were appshell's.
|
|
8
|
+
*/
|
|
9
|
+
export declare const load: <TComponent>(remote: {
|
|
10
|
+
loader: RemoteLoader;
|
|
11
|
+
remoteEntryUrl: string;
|
|
12
|
+
}) => Promise<TComponent>;
|
|
13
|
+
export default load;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppshellComposition
|
|
1
|
+
import type { AppshellComposition } from '@appshell/config';
|
|
2
2
|
import { type RemoteResolver } from './resolvers';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
@@ -10,6 +10,5 @@ export type RemoteLoaderOptions = {
|
|
|
10
10
|
/** Replaces the resolver chain outright; a seam for tests and embedders. */
|
|
11
11
|
resolver?: RemoteResolver;
|
|
12
12
|
};
|
|
13
|
-
declare const _default: (
|
|
13
|
+
declare const _default: (options?: RemoteLoaderOptions) => <TComponent>(key: string) => Promise<readonly [Awaited<TComponent>, import("@appshell/config").ResolvedRemote]>;
|
|
14
14
|
export default _default;
|
|
15
|
-
//# sourceMappingURL=remoteLoader.d.ts.map
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
import type { AppshellComposition,
|
|
1
|
+
import type { AppshellComposition, ResolvedRemote } from '@appshell/config';
|
|
2
2
|
export type RemoteResolution = {
|
|
3
3
|
remote: ResolvedRemote;
|
|
4
|
-
/** Already merged with the
|
|
5
|
-
|
|
6
|
-
/** Back-compat payload for `ManifestProvider`; synthesized when the source was a composition. */
|
|
7
|
-
manifest: AppshellManifest;
|
|
4
|
+
/** Already merged with the application's overrides — nothing left for the browser to layer on. */
|
|
5
|
+
vars: Record<string, string | number | undefined>;
|
|
8
6
|
};
|
|
9
7
|
export type RemoteResolver = (key: string) => Promise<RemoteResolution | undefined>;
|
|
10
8
|
/** The registry inlined the composition into the page, so no network call is needed. */
|
|
11
9
|
export declare const inlineResolver: (composition?: AppshellComposition) => RemoteResolver;
|
|
12
|
-
/** Fetch-on-miss: covers
|
|
10
|
+
/** Fetch-on-miss: covers a package activated after this page was served. */
|
|
13
11
|
export declare const registryResolver: (composition?: AppshellComposition, origin?: string) => RemoteResolver;
|
|
14
|
-
/**
|
|
15
|
-
* Pre-registry hosts: follow `index[key]` to the app's own manifest. The override
|
|
16
|
-
* merge stays here because in this mode no server has done it.
|
|
17
|
-
*/
|
|
18
|
-
export declare const legacyManifestResolver: (config: AppshellGlobalConfig) => RemoteResolver;
|
|
19
12
|
export declare const chainResolvers: (...resolvers: RemoteResolver[]) => RemoteResolver;
|
|
20
|
-
//# sourceMappingURL=resolvers.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A package asked for vars that were never delivered.
|
|
3
|
+
*
|
|
4
|
+
* Almost always one of three things: the package was loaded outside `remoteLoader`
|
|
5
|
+
* (a test, a storybook, a direct import), the host and the package resolved separate
|
|
6
|
+
* copies of `@appshell/runtime` because one of them failed to declare it as a
|
|
7
|
+
* singleton, or the scope compiled into the package is not the scope the registry
|
|
8
|
+
* knows it by.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MissingVarsError extends Error {
|
|
11
|
+
readonly scope: string;
|
|
12
|
+
constructor(scope: string, known: string[]);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Something tried to replace vars that were already delivered for a scope.
|
|
16
|
+
*
|
|
17
|
+
* The first write wins and is final. Within one page load a scope has exactly one
|
|
18
|
+
* vars object — both resolvers read it from the same `composition.vars[scope]` — so a
|
|
19
|
+
* differing second write is a bug or a package reaching for a scope that is not its own,
|
|
20
|
+
* and neither should be applied quietly.
|
|
21
|
+
*/
|
|
22
|
+
export declare class VarsConflictError extends Error {
|
|
23
|
+
readonly scope: string;
|
|
24
|
+
constructor(scope: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The package was built without `AppshellPlugin`, so nothing substituted the scope the
|
|
28
|
+
* `@appshell/runtime/vars` accessor needs to know which vars are its own.
|
|
29
|
+
*/
|
|
30
|
+
export declare class MissingScopeError extends Error {
|
|
31
|
+
constructor();
|
|
32
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who is looking at the page, as the registry was told by the gateway.
|
|
3
|
+
*
|
|
4
|
+
* Unlike vars this is not scope-specific — there is one visitor per page, not one
|
|
5
|
+
* per package — so it lives in the main entry rather than needing the subpath
|
|
6
|
+
* trick `@appshell/runtime/vars` uses to get a per-package scope substituted.
|
|
7
|
+
*
|
|
8
|
+
* It is also not delivered through the vars store, and that is a constraint rather
|
|
9
|
+
* than a preference: `setVars` freezes on first write and throws on replacement,
|
|
10
|
+
* which is what stops one package overwriting another's configuration. Identity
|
|
11
|
+
* changes — sign-in, sign-out, token refresh — so it cannot live behind a
|
|
12
|
+
* write-once door without either breaking that guarantee or never updating.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* A discriminated union rather than an optional user, so `username` cannot be read
|
|
16
|
+
* without the anonymous case having been handled. The compiler enforces what a
|
|
17
|
+
* convention would only ask for.
|
|
18
|
+
*/
|
|
19
|
+
export type Identity = {
|
|
20
|
+
authenticated: false;
|
|
21
|
+
} | {
|
|
22
|
+
authenticated: true;
|
|
23
|
+
subject: string;
|
|
24
|
+
username: string;
|
|
25
|
+
roles: string[];
|
|
26
|
+
};
|
|
27
|
+
export declare const ANONYMOUS: Identity;
|
|
28
|
+
declare global {
|
|
29
|
+
interface Window {
|
|
30
|
+
__appshell_identity__?: unknown;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The visitor, or the anonymous identity when there is none.
|
|
35
|
+
*
|
|
36
|
+
* Never throws and never returns undefined — an absent or malformed value is
|
|
37
|
+
* anonymous, which is a state every caller already has to handle. That is the
|
|
38
|
+
* opposite of `readVars`, which throws when a scope is missing, and the difference
|
|
39
|
+
* is deliberate: a package with no configuration cannot do its job, while a package
|
|
40
|
+
* with no signed-in user usually can and simply renders differently.
|
|
41
|
+
*
|
|
42
|
+
* This is a typed accessor, not a boundary. The value is inlined into the document
|
|
43
|
+
* and any script on the page can read it directly, exactly as with vars. Treat it
|
|
44
|
+
* as what the server said about the visitor, never as proof of anything: it carries
|
|
45
|
+
* no token and grants nothing. Anything that matters is re-checked server-side.
|
|
46
|
+
*/
|
|
47
|
+
export declare const getIdentity: () => Identity;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { MissingScopeError, MissingVarsError, VarsConflictError } from './errors';
|
|
2
|
+
export { ANONYMOUS, getIdentity } from './identity';
|
|
3
|
+
export type { Identity } from './identity';
|
|
4
|
+
export { hasVars, readVars, resetVars, setVars } from './store';
|
|
5
|
+
export type { Vars } from './types';
|
|
6
|
+
export type { AppshellIndex, AppshellRemote, Metadata, ModuleFederationLoader, RemoteLoader, } from './wire';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Vars } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Delivers a scope's vars. Called by `@appshell/loader` immediately before the remote
|
|
4
|
+
* is loaded, so they are in place before the package's modules evaluate.
|
|
5
|
+
*
|
|
6
|
+
* The first write for a scope wins and is frozen. Re-delivering the identical vars is a
|
|
7
|
+
* no-op — the same remote can be mounted more than once — but replacing them throws.
|
|
8
|
+
* That is what keeps one package from overwriting another's: by the time any package
|
|
9
|
+
* evaluates, the host has already written for it.
|
|
10
|
+
*
|
|
11
|
+
* It does not make a scope's vars *private*. Any code on the page can still read another
|
|
12
|
+
* scope by name, and nothing short of a separate realm would change that.
|
|
13
|
+
*/
|
|
14
|
+
export declare const setVars: (scope: string, vars: Vars) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Reads a scope's vars, throwing rather than handing back an empty object — a package
|
|
17
|
+
* that silently renders with no configuration is the failure this replaced.
|
|
18
|
+
*
|
|
19
|
+
* Prefer `getVars()` from `@appshell/runtime/vars`, which supplies the scope for you.
|
|
20
|
+
*/
|
|
21
|
+
export declare const readVars: <TVars extends Vars = Vars>(scope: string) => TVars;
|
|
22
|
+
/** Whether a scope has been delivered, for callers that want to branch instead of catch. */
|
|
23
|
+
export declare const hasVars: (scope: string) => boolean;
|
|
24
|
+
/** Test seam. Not part of the contract a package should build on. */
|
|
25
|
+
export declare const resetVars: () => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A package's runtime configuration, already merged by the registry — a package's
|
|
3
|
+
* declared vars, then the application's `overrides.vars`.
|
|
4
|
+
*
|
|
5
|
+
* Structurally identical to `AppshellComposition['vars'][scope]` in `@appshell/config`,
|
|
6
|
+
* but declared here rather than imported. This package is a shared singleton loaded
|
|
7
|
+
* into every micro-frontend on the page, so it carries no dependencies at all.
|
|
8
|
+
*/
|
|
9
|
+
export type Vars = Record<string, string | number | undefined>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the browser is told about a remote.
|
|
3
|
+
*
|
|
4
|
+
* These live here rather than in `@appshell/config` because config is build tooling — it
|
|
5
|
+
* carries yaml, lodash and axios — and a package that only wants to type a remote should
|
|
6
|
+
* not install a compiler to get it. This package is already the one every micro-frontend
|
|
7
|
+
* on the page shares, and it has no dependencies of its own to pass on.
|
|
8
|
+
*
|
|
9
|
+
* `AppshellManifest` deliberately stays in `@appshell/config`. It is a build artifact, and
|
|
10
|
+
* its `modules` field is Module Federation plugin options — build-time webpack
|
|
11
|
+
* configuration the browser never sees and this package should never drag in.
|
|
12
|
+
*/
|
|
13
|
+
/** Arbitrary, application-defined description of a remote. Appshell never reads it. */
|
|
14
|
+
export type Metadata = Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* How a host loads a remote, named as one kind among possible kinds.
|
|
17
|
+
*
|
|
18
|
+
* scope, module and shareScope are Module Federation's vocabulary, and they used to sit
|
|
19
|
+
* at the top level of a remote where nothing said so — which is what would have made a
|
|
20
|
+
* second framework awkward, not the words themselves. Nested under a kind they are
|
|
21
|
+
* exactly correct, and something like single-spa slots beside them without reinterpreting
|
|
22
|
+
* anything already published.
|
|
23
|
+
*
|
|
24
|
+
* apiVersion follows the house style set by appshell.app.yaml, and the group is appshell's
|
|
25
|
+
* because appshell owns this schema: it decides which fields it stores, even though the
|
|
26
|
+
* fields describe federation concepts. If federation ever needs a different recipe that is
|
|
27
|
+
* a v2, and manifests published under v1 keep meaning what they meant — which matters,
|
|
28
|
+
* because they are immutable and hashed.
|
|
29
|
+
*/
|
|
30
|
+
export type ModuleFederationLoader = {
|
|
31
|
+
apiVersion: 'federation.appshell.org/v1';
|
|
32
|
+
kind: 'ModuleFederation';
|
|
33
|
+
scope: string;
|
|
34
|
+
module: string;
|
|
35
|
+
shareScope?: string;
|
|
36
|
+
/** The entry file the build emits, conventionally remoteEntry.js. */
|
|
37
|
+
filename: string;
|
|
38
|
+
/**
|
|
39
|
+
* What built this, recorded as a fact rather than a constraint.
|
|
40
|
+
*
|
|
41
|
+
* Deliberately not a version range. A range is a claim about the environment, and a
|
|
42
|
+
* package cannot make it: it knows what built it and not what will load it, and the
|
|
43
|
+
* host is what registers the remote. Freezing one into an immutable artifact is the
|
|
44
|
+
* same mistake as freezing its origin.
|
|
45
|
+
*/
|
|
46
|
+
builtWith?: string;
|
|
47
|
+
};
|
|
48
|
+
export type RemoteLoader = ModuleFederationLoader;
|
|
49
|
+
/** A remote the registry has already resolved, so the browser needs no manifest fetch. */
|
|
50
|
+
export type AppshellRemote<TMetadata = Metadata> = {
|
|
51
|
+
id: string;
|
|
52
|
+
manifestUrl: string;
|
|
53
|
+
remoteEntryUrl: string;
|
|
54
|
+
loader: RemoteLoader;
|
|
55
|
+
metadata: TMetadata;
|
|
56
|
+
};
|
|
57
|
+
/** Remote key to manifest url. */
|
|
58
|
+
export type AppshellIndex = Record<string, string>;
|