@appshell/webpack-plugin 1.0.0-alpha.9 → 1.0.0-alpha.91
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 +21 -24
- package/dist/main.js +3 -3
- 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/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/dist/types/tokens/src/contract.d.ts +51 -0
- package/dist/types/tokens/src/contrast.d.ts +37 -0
- package/dist/types/tokens/src/index.d.ts +4 -0
- package/dist/types/tokens/src/presets.d.ts +4 -0
- package/dist/types/tokens/src/theme.d.ts +54 -0
- package/dist/types/webpack-plugin/src/AppshellPlugin.d.ts +46 -5
- package/dist/types/webpack-plugin/src/devHint.d.ts +45 -0
- package/dist/types/webpack-plugin/src/index.d.ts +3 -1
- package/dist/types/webpack-plugin/src/shared.d.ts +36 -0
- package/package.json +11 -4
- 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/webpack-plugin/src/AppshellPlugin.d.ts.map +0 -1
- package/dist/types/webpack-plugin/src/index.d.ts.map +0 -1
|
@@ -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
|
|
@@ -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>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The token contract: the complete, fixed vocabulary a package may consume and an
|
|
3
|
+
* Application must supply.
|
|
4
|
+
*
|
|
5
|
+
* Small and stable is the property that matters. A package authors against these names
|
|
6
|
+
* with fallbacks (`var(--appshell-primary, #0af)`) and renders standalone; an Application
|
|
7
|
+
* supplies the values and every package it composes moves together.
|
|
8
|
+
*/
|
|
9
|
+
export type Mode = 'light' | 'dark';
|
|
10
|
+
/** Colour roles an Application's *base* supplies — everything not tied to the accent. */
|
|
11
|
+
export declare const BASE_COLOR_ROLES: readonly ["surface", "on-surface", "surface-raised", "on-surface-raised", "text-muted", "border", "danger", "on-danger", "warning", "on-warning", "success", "on-success"];
|
|
12
|
+
/** Colour roles an Application's *accent* supplies. */
|
|
13
|
+
export declare const ACCENT_COLOR_ROLES: readonly ["primary", "on-primary", "secondary", "on-secondary"];
|
|
14
|
+
/**
|
|
15
|
+
* Derived rather than authored. Hover and active are computed from their accent with
|
|
16
|
+
* `color-mix`, and the focus ring is picked per base+accent so it stays visible. A theme
|
|
17
|
+
* may override any of them; none has to be supplied.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DERIVED_COLOR_ROLES: readonly ["primary-hover", "primary-active", "secondary-hover", "secondary-active", "focus-ring"];
|
|
20
|
+
/**
|
|
21
|
+
* Named for their role, not their size. A numeric scale would reintroduce exactly the
|
|
22
|
+
* divergence this contract exists to prevent — one author mapping `h1` to `2xl` and
|
|
23
|
+
* another to `xl` is how headings stop matching across a composed page.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TYPE_ROLES: readonly ["font-body", "font-mono", "font-size-h1", "font-size-h2", "font-size-h3", "font-size-h4", "font-size-h5", "font-size-h6", "font-size-body", "font-size-small", "line-height-tight", "line-height-normal"];
|
|
26
|
+
/** Genuinely a scale. Nobody wants `--appshell-space-card-padding`. */
|
|
27
|
+
export declare const DIMENSION_ROLES: readonly ["space-xs", "space-sm", "space-md", "space-lg", "space-xl", "radius-sm", "radius-md", "radius-lg"];
|
|
28
|
+
export type BaseColorRole = (typeof BASE_COLOR_ROLES)[number];
|
|
29
|
+
export type AccentColorRole = (typeof ACCENT_COLOR_ROLES)[number];
|
|
30
|
+
export type DerivedColorRole = (typeof DERIVED_COLOR_ROLES)[number];
|
|
31
|
+
export type TypeRole = (typeof TYPE_ROLES)[number];
|
|
32
|
+
export type DimensionRole = (typeof DIMENSION_ROLES)[number];
|
|
33
|
+
export type TokenRole = BaseColorRole | AccentColorRole | DerivedColorRole | TypeRole | DimensionRole;
|
|
34
|
+
export declare const TOKEN_ROLES: readonly TokenRole[];
|
|
35
|
+
export type BaseTokens = Record<BaseColorRole, string>;
|
|
36
|
+
export type AccentTokens = Record<AccentColorRole, string>;
|
|
37
|
+
export type Theme = Record<TokenRole, string>;
|
|
38
|
+
/** The custom property a role is published as. */
|
|
39
|
+
export declare const cssVar: (role: TokenRole) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Pairs the registry checks for contrast. Because every role that carries text has an
|
|
42
|
+
* `on-` partner, a theme cannot express illegible text without failing this list — which
|
|
43
|
+
* is the failure that actually reaches users, and the one a CSS parser alone never catches.
|
|
44
|
+
*/
|
|
45
|
+
export declare const TEXT_PAIRS: readonly (readonly [TokenRole, TokenRole])[];
|
|
46
|
+
/** Muted text has no `on-` partner; it is read against both surfaces. */
|
|
47
|
+
export declare const MUTED_AGAINST: readonly TokenRole[];
|
|
48
|
+
/** Non-text, so 3:1 rather than 4.5:1 — WCAG 1.4.11. */
|
|
49
|
+
export declare const NON_TEXT_PAIRS: readonly (readonly [TokenRole, TokenRole])[];
|
|
50
|
+
export declare const AA_TEXT = 4.5;
|
|
51
|
+
export declare const AA_NON_TEXT = 3;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contrast checking for a theme.
|
|
3
|
+
*
|
|
4
|
+
* Syntax validation on its own earns little: it catches `--appshell-primary: bananas` and
|
|
5
|
+
* misses `--appshell-on-primary: #fff` on `--appshell-primary: #fff`, which is valid CSS
|
|
6
|
+
* and invisible text. Checking the `on-` pairs catches the failure that reaches users, and
|
|
7
|
+
* subsumes syntax validation for free — a value that will not parse cannot be measured.
|
|
8
|
+
*/
|
|
9
|
+
import { type Theme, type TokenRole } from './contract';
|
|
10
|
+
type Rgb = [number, number, number];
|
|
11
|
+
/** Returns undefined rather than throwing — an unmeasurable value is reported, not fatal. */
|
|
12
|
+
export declare const parseColor: (value: string) => Rgb | undefined;
|
|
13
|
+
/** WCAG 2.1 contrast ratio, 1–21. */
|
|
14
|
+
export declare const contrastRatio: (a: Rgb, b: Rgb) => number;
|
|
15
|
+
/**
|
|
16
|
+
* A colour as `#rrggbb`.
|
|
17
|
+
*
|
|
18
|
+
* `<meta name="theme-color">` takes a CSS colour, but browser support for `oklch` there
|
|
19
|
+
* is not something to rely on for a hint the page cannot detect the failure of — a
|
|
20
|
+
* value the browser does not understand is simply ignored, silently.
|
|
21
|
+
*/
|
|
22
|
+
export declare const toHex: (value: string) => string | undefined;
|
|
23
|
+
export type ContrastFinding = {
|
|
24
|
+
roles: [TokenRole, TokenRole];
|
|
25
|
+
ratio?: number;
|
|
26
|
+
required: number;
|
|
27
|
+
reason: 'below-threshold' | 'unparseable';
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Every finding for a theme. Empty means it passes.
|
|
31
|
+
*
|
|
32
|
+
* `color-mix` values are skipped rather than failed: hover and active are derived from
|
|
33
|
+
* roles that are themselves checked, and resolving them needs a browser.
|
|
34
|
+
*/
|
|
35
|
+
export declare const validateTheme: (theme: Theme) => ContrastFinding[];
|
|
36
|
+
export declare const describeFinding: ({ roles, ratio, required, reason }: ContrastFinding) => string;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './contract';
|
|
2
|
+
export { contrastRatio, describeFinding, parseColor, toHex, validateTheme, type ContrastFinding, } from './contrast';
|
|
3
|
+
export { ACCENTS, BASES, FOCUS_RINGS } from './presets';
|
|
4
|
+
export { DEFAULT_TYPE_AND_DIMENSIONS, composeTheme, cssFrom, pinnedMode, resolveTheme, toCss, type ColorScheme, type CssOptions, type ResolvedTheme, type ThemeSelection, } from './theme';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AccentTokens, BaseTokens, Mode } from './contract';
|
|
2
|
+
export declare const BASES: Record<string, Record<Mode, BaseTokens>>;
|
|
3
|
+
export declare const ACCENTS: Record<string, AccentTokens>;
|
|
4
|
+
export declare const FOCUS_RINGS: Record<string, Record<string, Record<Mode, string>>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type AccentTokens, type BaseTokens, type Mode, type Theme } from './contract';
|
|
2
|
+
/**
|
|
3
|
+
* `system` follows the viewer's preference. Pinning a scheme is for an application that
|
|
4
|
+
* ships one look on purpose, and it is honoured all the way down: the palette stops
|
|
5
|
+
* varying, the root is stamped so the tokens cannot be swapped underneath it, and the
|
|
6
|
+
* browser is told which scheme to render its own scrollbars and form controls in.
|
|
7
|
+
*/
|
|
8
|
+
export type ColorScheme = 'system' | 'light' | 'dark';
|
|
9
|
+
export type ThemeSelection = {
|
|
10
|
+
/** A base preset name, or the base's own token values. */
|
|
11
|
+
base: string | Record<Mode, BaseTokens>;
|
|
12
|
+
/** An accent preset name, or the accent's own token values. */
|
|
13
|
+
accent: string | AccentTokens;
|
|
14
|
+
/** Defaults to `system`. */
|
|
15
|
+
colorScheme?: ColorScheme;
|
|
16
|
+
/** Overrides applied last, so an Application can adjust a preset without forking it. */
|
|
17
|
+
overrides?: Partial<Theme>;
|
|
18
|
+
};
|
|
19
|
+
/** The mode a pinned scheme resolves to, or undefined when it follows the viewer. */
|
|
20
|
+
export declare const pinnedMode: (selection: ThemeSelection) => Mode | undefined;
|
|
21
|
+
/** Type and dimensions do not vary by mode, and no preset currently changes them. */
|
|
22
|
+
export declare const DEFAULT_TYPE_AND_DIMENSIONS: Record<string, string>;
|
|
23
|
+
/** The full token map for one mode. */
|
|
24
|
+
export declare const composeTheme: (selection: ThemeSelection, mode: Mode) => Theme;
|
|
25
|
+
/**
|
|
26
|
+
* A theme with both modes already worked out.
|
|
27
|
+
*
|
|
28
|
+
* This is the shape a *published* theme stores. Resolving a selection and emitting CSS
|
|
29
|
+
* used to be one step, which meant the only way to render a theme was to re-resolve its
|
|
30
|
+
* preset names — so the values behind a name lived in whatever build was deployed, and an
|
|
31
|
+
* Application's recorded appearance moved when that build did. Materialising both modes
|
|
32
|
+
* lets the values be stored, versioned and rendered from, rather than looked up.
|
|
33
|
+
*/
|
|
34
|
+
export type ResolvedTheme = Record<Mode, Theme>;
|
|
35
|
+
/** Works out both modes of a selection, including any overrides it carries. */
|
|
36
|
+
export declare const resolveTheme: (selection: ThemeSelection) => ResolvedTheme;
|
|
37
|
+
export type CssOptions = {
|
|
38
|
+
/** Defaults to `system`. Belongs to whoever is rendering, not to the theme. */
|
|
39
|
+
colorScheme?: ColorScheme;
|
|
40
|
+
/** Applied over the resolved values, so a consumer can adjust without forking. */
|
|
41
|
+
overrides?: Partial<Theme>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Three states, not two: an explicit choice in either direction, and the system default
|
|
45
|
+
* when nothing is stamped on the root. A theme that only handled `prefers-color-scheme`
|
|
46
|
+
* would give a viewer no way to override it.
|
|
47
|
+
*/
|
|
48
|
+
export declare const cssFrom: (resolved: ResolvedTheme, options?: CssOptions) => string;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve and emit in one step. The authoring path — a preset name in hand, CSS wanted.
|
|
51
|
+
* The registry uses `cssFrom` against a stored theme instead, so what it renders cannot
|
|
52
|
+
* drift from what was published.
|
|
53
|
+
*/
|
|
54
|
+
export declare const toCss: (selection: ThemeSelection) => string;
|
|
@@ -3,7 +3,7 @@ import { Compiler, WebpackOptionsNormalized, WebpackPluginInstance } from 'webpa
|
|
|
3
3
|
type AppshellPluginOptions = {
|
|
4
4
|
config?: string;
|
|
5
5
|
registry?: string;
|
|
6
|
-
|
|
6
|
+
application?: string;
|
|
7
7
|
publish?: boolean;
|
|
8
8
|
force?: boolean;
|
|
9
9
|
};
|
|
@@ -24,14 +24,56 @@ export default class AppshellPlugin {
|
|
|
24
24
|
static findModuleFederationPlugin(webpackConfig: WebpackOptionsNormalized): ModuleFederationPluginInstance | undefined;
|
|
25
25
|
static createTemplate(config: AppshellConfig, plugin: ModuleFederationPluginInstance): AppshellTemplate;
|
|
26
26
|
static validate(template: AppshellTemplate): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Which tokens this package's output actually reaches for.
|
|
29
|
+
*
|
|
30
|
+
* Read from the emitted assets rather than declared. The CSS already states it, and a
|
|
31
|
+
* hand-kept list is a second copy that goes stale the first time somebody adds a token
|
|
32
|
+
* and forgets to update it. This cannot drift, because it *is* the usage.
|
|
33
|
+
*
|
|
34
|
+
* A role referenced both with and without a fallback counts as required: one place in
|
|
35
|
+
* the package has nothing to fall back to.
|
|
36
|
+
*
|
|
37
|
+
* The blind spot is a reference built at runtime from a constructed string, which no
|
|
38
|
+
* static scan sees — the same limit Tailwind has with dynamic class names. It fails
|
|
39
|
+
* toward under-reporting, never toward inventing a requirement.
|
|
40
|
+
*
|
|
41
|
+
* Takes file contents rather than webpack assets: by `afterEmit` the compilation has
|
|
42
|
+
* swapped its sources for `SizeOnlySource`, which knows a length and nothing else.
|
|
43
|
+
* The files are on disk by then, which is what the hook means.
|
|
44
|
+
*/
|
|
45
|
+
static tokenUsage(sources?: Record<string, string>): {
|
|
46
|
+
required: string[];
|
|
47
|
+
optional: string[];
|
|
48
|
+
unknown: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Whether a request is shared, and shared as a singleton. `shared` has four shapes —
|
|
52
|
+
* an object, an array of names, an array of objects, or a mix — and a bare name shares
|
|
53
|
+
* without making it a singleton, which for the vars store is the same as not sharing it.
|
|
54
|
+
*/
|
|
55
|
+
static sharedSingleton(shared: ModuleFederationPluginOptions['shared'], request: string): {
|
|
56
|
+
declared: boolean;
|
|
57
|
+
singleton: boolean;
|
|
58
|
+
};
|
|
27
59
|
/**
|
|
28
60
|
* Publish identity is the npm identity of the package being built, not the module
|
|
29
61
|
* federation name — the registry requires a lowercase name and has no other source
|
|
30
62
|
* for a version. The scope is taken from the caller's token, so it is stripped here.
|
|
31
63
|
*/
|
|
64
|
+
/**
|
|
65
|
+
* Points this package's remotes at the running dev server, for this developer only.
|
|
66
|
+
*
|
|
67
|
+
* Deliberately incapable of failing a build. A dev server that will not start because a
|
|
68
|
+
* registry is unreachable, a token expired, or a package was never published is worse
|
|
69
|
+
* than one serving code the browser cannot yet compose — the developer can still see
|
|
70
|
+
* their own output, and the message says what to do about the rest.
|
|
71
|
+
*/
|
|
72
|
+
private static redirectToDevServer;
|
|
32
73
|
static identify(context: string): {
|
|
33
|
-
name: string;
|
|
34
74
|
version: string;
|
|
75
|
+
scopeId?: string;
|
|
76
|
+
name: string;
|
|
35
77
|
};
|
|
36
78
|
/**
|
|
37
79
|
* Warns when an env var or explicit option points somewhere other than the
|
|
@@ -39,10 +81,10 @@ export default class AppshellPlugin {
|
|
|
39
81
|
*/
|
|
40
82
|
static overrideNotices(effective: {
|
|
41
83
|
registry?: string;
|
|
42
|
-
|
|
84
|
+
application?: string;
|
|
43
85
|
}, persisted: {
|
|
44
86
|
registry?: string;
|
|
45
|
-
|
|
87
|
+
application?: string;
|
|
46
88
|
}): string[];
|
|
47
89
|
/**
|
|
48
90
|
* Apply the plugin
|
|
@@ -52,4 +94,3 @@ export default class AppshellPlugin {
|
|
|
52
94
|
apply(compiler: Compiler): void;
|
|
53
95
|
}
|
|
54
96
|
export {};
|
|
55
|
-
//# sourceMappingURL=AppshellPlugin.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const DEV_HINT_FILE = ".appshell-dev.json";
|
|
2
|
+
export declare const DEV_HINT_VERSION = 1;
|
|
3
|
+
export type DevHint = {
|
|
4
|
+
version: number;
|
|
5
|
+
/** Where this package's dev server is reachable, as a browser on this machine would ask. */
|
|
6
|
+
origin: string;
|
|
7
|
+
/** From the federation `filename`, so a reader can probe without asking the registry. */
|
|
8
|
+
remoteEntryPath: string;
|
|
9
|
+
/**
|
|
10
|
+
* Diagnostics only. Deliberately not a liveness signal: a server running happily for
|
|
11
|
+
* hours writes an old timestamp, and one that crashed a second ago writes a fresh one.
|
|
12
|
+
* Whether the origin is live is answered by asking the origin.
|
|
13
|
+
*/
|
|
14
|
+
writtenAt: string;
|
|
15
|
+
};
|
|
16
|
+
type DevServerOptions = {
|
|
17
|
+
[index: string]: unknown;
|
|
18
|
+
} | false | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Whether this dev server's hot-reload client has an address a browser can actually dial.
|
|
21
|
+
*
|
|
22
|
+
* webpack-dev-server normalizes `client.webSocketURL` into an object before a plugin ever
|
|
23
|
+
* sees it, filling the hostname from whatever the server **bound**. So a server listening
|
|
24
|
+
* on every interface hands its client `0.0.0.0`, which nothing can open a socket to, and
|
|
25
|
+
* asking whether the option is *set* cannot tell that apart from a deliberate choice —
|
|
26
|
+
* it is always set. The dialable address is the property that matters, so that is what is
|
|
27
|
+
* checked, against the same host list `devServerOrigin` already rejects for the same
|
|
28
|
+
* reason one line down.
|
|
29
|
+
*
|
|
30
|
+
* The cost of getting this wrong is silence: the bundle renders, the server reports a
|
|
31
|
+
* successful recompile, and edits never arrive.
|
|
32
|
+
*/
|
|
33
|
+
export declare const hotSocketIsDialable: (devServer: DevServerOptions) => boolean;
|
|
34
|
+
export declare const devServerOrigin: (devServer: DevServerOptions) => string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Records where this package is being served from while a dev server is running, so tooling
|
|
37
|
+
* can offer it instead of asking a developer to repeat a port they have already
|
|
38
|
+
* configured. Written on every serve build and left to be cleaned with the output
|
|
39
|
+
* directory; nothing removes it when the server stops, which is exactly why a reader
|
|
40
|
+
* must confirm the origin rather than trust the file.
|
|
41
|
+
*/
|
|
42
|
+
export declare const writeDevHint: (outputDir: string, devServer: DevServerOptions, remoteEntryPath: string, now?: Date) => DevHint | undefined;
|
|
43
|
+
/** webpack-dev-server sets this itself, however webpack was invoked. */
|
|
44
|
+
export declare const isServing: () => boolean;
|
|
45
|
+
export {};
|
|
@@ -3,4 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type { AppshellManifest } from '@appshell/config';
|
|
5
5
|
export { default as AppshellPlugin } from './AppshellPlugin';
|
|
6
|
-
|
|
6
|
+
export { DEV_HINT_FILE, DEV_HINT_VERSION, devServerOrigin, writeDevHint } from './devHint';
|
|
7
|
+
export type { DevHint } from './devHint';
|
|
8
|
+
export { appshellShared, type AppshellSharedOptions } from './shared';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SharedObject } from '@appshell/config';
|
|
2
|
+
export type AppshellSharedOptions = {
|
|
3
|
+
/** Include the React bindings and React itself. */
|
|
4
|
+
react?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Usually your package.json `dependencies`. Anything named here is pinned to the range
|
|
7
|
+
* you depend on; anything absent is left for module federation to infer, which it does
|
|
8
|
+
* from the installed package.
|
|
9
|
+
*/
|
|
10
|
+
dependencies?: Record<string, string>;
|
|
11
|
+
/** Merged last, so a package can still say something the preset does not. */
|
|
12
|
+
extra?: SharedObject;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The `shared` block an Appshell package needs, so it is not written out by hand in every
|
|
16
|
+
* webpack config and wrong in one of them.
|
|
17
|
+
*
|
|
18
|
+
* It exists because the alternative failed in practice: the examples in this repo declared
|
|
19
|
+
* `@appshell/react` as a singleton in three configs and omitted it in a fourth, which is
|
|
20
|
+
* silent until a root package calls `useRemote()` and gets `undefined`.
|
|
21
|
+
*
|
|
22
|
+
* `AppshellPlugin` cannot inject this itself — `ModuleFederationPlugin` reads its own
|
|
23
|
+
* options during its `apply`, which webpack has already run by the time it reaches ours.
|
|
24
|
+
* Spread into your own config, it sidesteps plugin ordering entirely:
|
|
25
|
+
*
|
|
26
|
+
* ```js
|
|
27
|
+
* const { appshellShared } = require('@appshell/webpack-plugin');
|
|
28
|
+
* const { dependencies } = require('./package.json');
|
|
29
|
+
*
|
|
30
|
+
* new ModuleFederationPlugin({
|
|
31
|
+
* shared: appshellShared({ react: true, dependencies }),
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare const appshellShared: ({ react, dependencies, extra, }?: AppshellSharedOptions) => SharedObject;
|
|
36
|
+
export default appshellShared;
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appshell/webpack-plugin",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.91",
|
|
4
4
|
"description": "Webpack plugin used to generate a global Appshell configuration for micro-frontends built with Module Federation",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/types/webpack-plugin/src/index.d.ts",
|
|
7
|
-
"repository":
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/appshellhq/appshell.git"
|
|
10
|
+
},
|
|
8
11
|
"author": "Robert Hamilton <rh@navaris.com>",
|
|
9
12
|
"publishConfig": {
|
|
10
13
|
"access": "public",
|
|
@@ -17,7 +20,8 @@
|
|
|
17
20
|
"clean": "rm -rf dist",
|
|
18
21
|
"prebuild": "npm run clean",
|
|
19
22
|
"start": "webpack --watch --mode development && npm run build:types",
|
|
20
|
-
"stats": "webpack --json > stats.json"
|
|
23
|
+
"stats": "webpack --json > stats.json",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
21
25
|
},
|
|
22
26
|
"files": [
|
|
23
27
|
"dist"
|
|
@@ -29,5 +33,8 @@
|
|
|
29
33
|
"plugin"
|
|
30
34
|
],
|
|
31
35
|
"license": "MIT",
|
|
32
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "beb3e1dc02a4c32424f163da35e9ce43ee3bdb82",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@appshell/tokens": "^1.0.0-alpha.91"
|
|
39
|
+
}
|
|
33
40
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../../../config/src/axios.ts"],"names":[],"mappings":";AAEA,wBAA8B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configmap.d.ts","sourceRoot":"","sources":["../../../../../config/src/configmap.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;;YA0BrC,CAAC,SAAS,MAAM,OAAO,CAAC,aAAa,SAAS,KAAG,CAAC;qBAuBzC,cAAc;;AAEtC,wBAGE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../config/src/context.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAaF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,eAQjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAK5E,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../../config/src/credentials.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,eAAO,MAAM,eAAe,cAC6D,CAAC;AAqB1F,eAAO,MAAM,cAAc,aAAc,MAAM,cAAc,UAAU,SAEtE,CAAC;AAEF,eAAO,MAAM,eAAe,aAAc,MAAM,SAI/C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,MAAM,GAAG,SAexD,CAAC;AAEF,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,MAO/C,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deregister.d.ts","sourceRoot":"","sources":["../../../../../config/src/deregister.ts"],"names":[],"mappings":"qCAoGkC,MAAM,YAAY,MAAM;AAA1D,wBAeE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.env.d.ts","sourceRoot":"","sources":["../../../../../config/src/generate.env.ts"],"names":[],"mappings":";AAGA,wBAuBK"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { AppshellGlobalConfig } from './types';
|
|
2
|
-
type GenerateGlobalConfigOptions = {
|
|
3
|
-
insecure: boolean;
|
|
4
|
-
apiKey?: string;
|
|
5
|
-
apiKeyHeader?: string;
|
|
6
|
-
proxyUrl?: string;
|
|
7
|
-
};
|
|
8
|
-
declare const _default: (registries: string[], options?: GenerateGlobalConfigOptions) => Promise<AppshellGlobalConfig>;
|
|
9
|
-
export default _default;
|
|
10
|
-
//# sourceMappingURL=generate.global-config.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.global-config.d.ts","sourceRoot":"","sources":["../../../../../config/src/generate.global-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAK/C,KAAK,2BAA2B,GAAG;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;qCAGY,MAAM,EAAE,YACX,2BAA2B,KACnC,OAAO,CAAC,oBAAoB,CAAC;AAHhC,wBA8CE"}
|