@blakearoberts/visage 0.0.1-rc.7 → 0.0.1-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/certs.d.ts.map +1 -1
- package/dist/compose.d.ts.map +1 -1
- package/dist/config.d.ts +13 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -68
- package/dist/render/nginx.d.ts.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -11
package/README.md
CHANGED
|
@@ -125,7 +125,7 @@ Do not treat the managed Dex and OAuth2 Proxy defaults as production auth infras
|
|
|
125
125
|
- If startup fails immediately, confirm Docker is running and `docker compose` works.
|
|
126
126
|
- If NGINX cannot start, check whether the configured `port` is already in use.
|
|
127
127
|
- If the hostname cannot be resolved, Visage may need permission to update `/etc/hosts`.
|
|
128
|
-
- If the browser rejects the certificate, allow the local certificate authority prompt from `mkcert
|
|
128
|
+
- If the browser rejects the certificate, allow the local certificate authority prompt from `mkcert`; CI test runners should be configured to ignore local HTTPS errors.
|
|
129
129
|
|
|
130
130
|
## TO-DO
|
|
131
131
|
|
package/dist/certs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certs.d.ts","sourceRoot":"","sources":["../src/certs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"certs.d.ts","sourceRoot":"","sources":["../src/certs.ts"],"names":[],"mappings":"AAcA,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C7E"}
|
package/dist/compose.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAIA,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAI9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAwCtD"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResolvedConfig } from 'vite';
|
|
2
|
-
import type { VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOptions, VisageService, VisageUpstream } from './types';
|
|
2
|
+
import type { VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOptions, VisageProxyPolicy, VisageService, VisageUpstream } from './types';
|
|
3
3
|
type Volume = readonly [from: string, to: string];
|
|
4
4
|
type ResolvedCookiePolicy = {
|
|
5
5
|
readonly cookie_name: string;
|
|
@@ -24,7 +24,7 @@ type ResolvedVisageOptions = {
|
|
|
24
24
|
readonly idp: ResolvedIdpOption;
|
|
25
25
|
readonly oauth2: ResolvedOAuth2Client;
|
|
26
26
|
readonly services: Readonly<Record<string, VisageService>>;
|
|
27
|
-
readonly upstreams
|
|
27
|
+
readonly upstreams: Record<string, VisageUpstream>;
|
|
28
28
|
};
|
|
29
29
|
type ResolvedBaseIdpConfig = {
|
|
30
30
|
readonly upstream: string;
|
|
@@ -44,10 +44,18 @@ type ResolvedExternalIdpConfig = ResolvedBaseIdpConfig & {
|
|
|
44
44
|
};
|
|
45
45
|
type ResolvedIdpConfig = ResolvedDexIdpConfig | ResolvedExternalIdpConfig;
|
|
46
46
|
type ResolvedService = Omit<VisageService, 'upstream'>;
|
|
47
|
-
type ResolvedUpstream =
|
|
47
|
+
type ResolvedUpstream = {
|
|
48
|
+
readonly scheme: 'http' | 'https';
|
|
48
49
|
readonly host: string;
|
|
49
50
|
readonly port: number;
|
|
50
|
-
readonly
|
|
51
|
+
readonly locations: Readonly<Record<string, VisageProxyPolicy>>;
|
|
52
|
+
};
|
|
53
|
+
type ResolvedProxyPolicy = {
|
|
54
|
+
readonly auth: Required<VisageProxyPolicy['auth']>;
|
|
55
|
+
readonly headers: VisageProxyPolicy['headers'];
|
|
56
|
+
};
|
|
57
|
+
type ResolvedConfigUpstream = Omit<ResolvedUpstream, 'locations'> & {
|
|
58
|
+
readonly locations: Readonly<Record<string, ResolvedProxyPolicy>>;
|
|
51
59
|
};
|
|
52
60
|
export type VisageConfig = {
|
|
53
61
|
readonly host: string;
|
|
@@ -65,7 +73,7 @@ export type VisageConfig = {
|
|
|
65
73
|
readonly oauth2ProxyClientSecret: Volume;
|
|
66
74
|
};
|
|
67
75
|
readonly services: Readonly<Record<string, ResolvedService>>;
|
|
68
|
-
readonly upstreams: Readonly<Record<string,
|
|
76
|
+
readonly upstreams: Readonly<Record<string, ResolvedConfigUpstream>>;
|
|
69
77
|
};
|
|
70
78
|
export declare function resolveOptions(options: VisageOptions): ResolvedVisageOptions;
|
|
71
79
|
export declare function resolveConfig(options: ResolvedVisageOptions, config: ResolvedConfig, vitePort: number): VisageConfig;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,aAAa,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,SAAS,CAAC;AAUjB,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgE1D;AAED,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
-
import {
|
|
1
|
+
import { join, dirname } from 'node:path';
|
|
2
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, openSync, chmodSync, rmSync, existsSync, createWriteStream, readFileSync, appendFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { Readable } from 'node:stream';
|
|
6
6
|
import { pipeline } from 'node:stream/promises';
|
|
@@ -9,83 +9,78 @@ import { hashSync } from 'bcryptjs';
|
|
|
9
9
|
import { Eta } from 'eta';
|
|
10
10
|
import { createHash } from 'node:crypto';
|
|
11
11
|
|
|
12
|
-
let
|
|
12
|
+
let stopRef;
|
|
13
13
|
function startCompose(file) {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
stopRef?.();
|
|
15
|
+
stopRef = undefined;
|
|
16
|
+
const logs = join(dirname(file), 'logs');
|
|
17
|
+
mkdirSync(logs, { recursive: true });
|
|
18
|
+
const output = openSync(join(logs, 'compose.log'), 'w');
|
|
19
|
+
const compose = [
|
|
20
|
+
'compose',
|
|
21
|
+
`--project-name=${process.env.COMPOSE_PROJECT_NAME ?? 'visage'}`,
|
|
22
|
+
`--file=${file}`,
|
|
23
|
+
];
|
|
24
|
+
const env = { ...process.env, COMPOSE_MENU: 'false' };
|
|
25
|
+
const opts = {
|
|
26
|
+
cwd: dirname(file),
|
|
27
|
+
stdio: ['ignore', output, output],
|
|
28
|
+
env,
|
|
29
|
+
};
|
|
30
|
+
const up = [
|
|
31
|
+
...compose,
|
|
32
|
+
'up',
|
|
33
|
+
'--abort-on-container-failure',
|
|
34
|
+
'--no-color',
|
|
35
|
+
'--remove-orphans',
|
|
36
|
+
];
|
|
37
|
+
const child = spawn('docker', up, opts);
|
|
16
38
|
const stop = () => {
|
|
17
|
-
if (
|
|
39
|
+
if (stopRef !== stop)
|
|
18
40
|
return;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
41
|
+
stopRef = undefined;
|
|
42
|
+
child.kill();
|
|
43
|
+
const down = [...compose, 'down', '--remove-orphans'];
|
|
44
|
+
spawnSync('docker', down, opts);
|
|
23
45
|
};
|
|
24
|
-
|
|
25
|
-
stopCompose = stop;
|
|
26
|
-
process.off('SIGINT', onSigInt);
|
|
27
|
-
process.off('SIGTERM', onSigTerm);
|
|
28
|
-
process.once('SIGINT', onSigInt);
|
|
29
|
-
process.once('SIGTERM', onSigTerm);
|
|
46
|
+
stopRef = stop;
|
|
30
47
|
return stop;
|
|
31
48
|
}
|
|
32
|
-
function run(file, args, message) {
|
|
33
|
-
const result = spawnSync('docker', ['compose', '-f', file, ...args], {
|
|
34
|
-
cwd: dirname(file),
|
|
35
|
-
stdio: 'inherit',
|
|
36
|
-
});
|
|
37
|
-
if (result.error)
|
|
38
|
-
throw result.error;
|
|
39
|
-
if (result.status !== 0)
|
|
40
|
-
throw new Error(message);
|
|
41
|
-
}
|
|
42
|
-
function onSigInt() {
|
|
43
|
-
try {
|
|
44
|
-
stopCompose?.();
|
|
45
|
-
}
|
|
46
|
-
finally {
|
|
47
|
-
process.exit(130);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function onSigTerm() {
|
|
51
|
-
try {
|
|
52
|
-
stopCompose?.();
|
|
53
|
-
}
|
|
54
|
-
finally {
|
|
55
|
-
process.exit(143);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
49
|
|
|
50
|
+
const CACHE_HOME = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');
|
|
59
51
|
async function ensureCerts({ certs, hostname }) {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return;
|
|
52
|
+
const CAROOT = join(CACHE_HOME, 'visage/ca');
|
|
53
|
+
mkdirSync(CAROOT, { recursive: true, mode: 0o700 });
|
|
54
|
+
chmodSync(CAROOT, 0o700);
|
|
64
55
|
const mkcert = await ensureMkCert();
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
const logs = join(dirname(certs), 'logs');
|
|
57
|
+
mkdirSync(logs, { recursive: true });
|
|
58
|
+
const log = join(logs, 'mkcert.log');
|
|
59
|
+
const output = openSync(log, 'w');
|
|
60
|
+
const env = { CAROOT, TRUST_STORES: 'system', ...process.env };
|
|
61
|
+
const tty = process.stdin.isTTY;
|
|
62
|
+
const stdio = [
|
|
63
|
+
tty ? 'inherit' : 'ignore',
|
|
64
|
+
output,
|
|
65
|
+
output,
|
|
66
|
+
];
|
|
67
|
+
if (process.env.CI !== 'true') {
|
|
68
|
+
// mkcert -install is idempotent; CA files alone do not prove trust-store state.
|
|
69
|
+
const result = spawnSync(mkcert, ['-install'], { env, stdio });
|
|
78
70
|
if (result.error)
|
|
79
71
|
throw result.error;
|
|
80
72
|
if (result.status !== 0) {
|
|
81
73
|
throw new Error('Failed to install CA');
|
|
82
74
|
}
|
|
83
75
|
}
|
|
84
|
-
|
|
76
|
+
const cert = join(certs, 'tls.crt');
|
|
77
|
+
const key = join(certs, 'tls.key');
|
|
85
78
|
mkdirSync(certs, { recursive: true });
|
|
79
|
+
rmSync(cert, { force: true });
|
|
80
|
+
rmSync(key, { force: true });
|
|
86
81
|
const names = [...new Set([hostname, 'localhost', '127.0.0.1', '::1'])];
|
|
87
82
|
const args = ['-cert-file', cert, '-key-file', key, ...names];
|
|
88
|
-
const result = spawnSync(mkcert, args, { env, stdio
|
|
83
|
+
const result = spawnSync(mkcert, args, { env, stdio });
|
|
89
84
|
if (result.error)
|
|
90
85
|
throw result.error;
|
|
91
86
|
if (result.status !== 0) {
|
|
@@ -93,7 +88,7 @@ async function ensureCerts({ certs, hostname }) {
|
|
|
93
88
|
}
|
|
94
89
|
}
|
|
95
90
|
async function ensureMkCert() {
|
|
96
|
-
const bin = join(
|
|
91
|
+
const bin = join(CACHE_HOME, 'visage/bin');
|
|
97
92
|
const file = join(bin, `mkcert-${process.platform}-${process.arch}`);
|
|
98
93
|
if (existsSync(file))
|
|
99
94
|
return file;
|
|
@@ -254,6 +249,9 @@ http {
|
|
|
254
249
|
ssl_certificate <%~ it.ssl.cert %>;
|
|
255
250
|
ssl_certificate_key <%~ it.ssl.key %>;
|
|
256
251
|
|
|
252
|
+
# Redirect accidental plaintext HTTP requests sent to the HTTPS port.
|
|
253
|
+
error_page 497 =301 https://$http_host$request_uri;
|
|
254
|
+
|
|
257
255
|
<%_ for (const [name, upstream] of Object.entries(it.upstreams)) { %>
|
|
258
256
|
<%_ for (const [path, location] of Object.entries(upstream.locations ?? {})) { %>
|
|
259
257
|
location <%~ path %> {
|
|
@@ -334,6 +332,8 @@ function renderOauth2ProxyConfig(config) {
|
|
|
334
332
|
cookie_httponly: true,
|
|
335
333
|
cookie_secure: true,
|
|
336
334
|
cookie_samesite: 'lax',
|
|
335
|
+
cookie_csrf_per_request: true,
|
|
336
|
+
cookie_csrf_per_request_limit: 16,
|
|
337
337
|
email_domains: ['*'],
|
|
338
338
|
scope: config.oauth2.scopes.join(' '),
|
|
339
339
|
upstreams: ['static://202'],
|
|
@@ -342,6 +342,7 @@ function renderOauth2ProxyConfig(config) {
|
|
|
342
342
|
pass_access_token: true,
|
|
343
343
|
pass_authorization_header: true,
|
|
344
344
|
skip_provider_button: true,
|
|
345
|
+
whitelist_domains: [config.host, `${config.host}:${config.port}`],
|
|
345
346
|
};
|
|
346
347
|
return `${Object.entries(data)
|
|
347
348
|
.map(([key, value]) => {
|
|
@@ -598,6 +599,7 @@ function resolveExternalIdpUpstream(idp) {
|
|
|
598
599
|
const issuer = new URL(idp.issuer);
|
|
599
600
|
return {
|
|
600
601
|
host: issuer.hostname,
|
|
602
|
+
locations: {},
|
|
601
603
|
scheme: issuer.protocol === 'https:' ? 'https' : 'http',
|
|
602
604
|
port: Number(issuer.port) || (issuer.protocol === 'https:' ? 443 : 80),
|
|
603
605
|
};
|
|
@@ -639,7 +641,7 @@ function resolveConfig(options, config, vitePort) {
|
|
|
639
641
|
...Object.fromEntries(Object.entries(options.services).map(([name, { upstream: _upstream, ...service }]) => [name, service])),
|
|
640
642
|
},
|
|
641
643
|
upstreams: Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => {
|
|
642
|
-
const external = options.upstreams
|
|
644
|
+
const external = options.upstreams[name] !== undefined &&
|
|
643
645
|
options.services[name] === undefined;
|
|
644
646
|
return [
|
|
645
647
|
name,
|
|
@@ -663,9 +665,20 @@ function resolveConfig(options, config, vitePort) {
|
|
|
663
665
|
};
|
|
664
666
|
}
|
|
665
667
|
|
|
668
|
+
function formatUrl(host, port) {
|
|
669
|
+
const AnsiGreen = '\x1b[32m';
|
|
670
|
+
const AnsiCyan = '\x1b[36m';
|
|
671
|
+
const AnsiBold = '\x1b[1m';
|
|
672
|
+
const AnsiReset = '\x1b[0m';
|
|
673
|
+
return ` ${AnsiGreen}➜${AnsiReset} ${AnsiBold}Visage${AnsiReset}: ${AnsiCyan}https://${host}:${AnsiBold}${port}${AnsiReset}${AnsiCyan}/${AnsiReset}`;
|
|
674
|
+
}
|
|
666
675
|
function visage(options = {}) {
|
|
667
676
|
const resolvedOptions = resolveOptions(options);
|
|
668
677
|
let stop;
|
|
678
|
+
const closeBundle = () => {
|
|
679
|
+
stop?.();
|
|
680
|
+
stop = undefined;
|
|
681
|
+
};
|
|
669
682
|
return {
|
|
670
683
|
name: 'visage',
|
|
671
684
|
apply: 'serve',
|
|
@@ -682,8 +695,17 @@ function visage(options = {}) {
|
|
|
682
695
|
};
|
|
683
696
|
},
|
|
684
697
|
configureServer(server) {
|
|
698
|
+
let url;
|
|
699
|
+
const printUrls = server.printUrls.bind(server);
|
|
700
|
+
server.printUrls = () => {
|
|
701
|
+
printUrls();
|
|
702
|
+
if (url)
|
|
703
|
+
server.config.logger.info(formatUrl(url.host, url.port));
|
|
704
|
+
};
|
|
685
705
|
async function startVisage(port) {
|
|
686
706
|
const config = resolveConfig(resolvedOptions, server.config, port);
|
|
707
|
+
url = { host: config.host, port: config.port };
|
|
708
|
+
rmSync(join(config.cache, 'logs'), { recursive: true, force: true });
|
|
687
709
|
await ensureCerts({
|
|
688
710
|
certs: join(config.cache, config.files.certs[0]),
|
|
689
711
|
hostname: config.host,
|
|
@@ -700,13 +722,11 @@ function visage(options = {}) {
|
|
|
700
722
|
throw new Error('Failed to resolve port for Visage');
|
|
701
723
|
}
|
|
702
724
|
stop = await startVisage(address.port);
|
|
725
|
+
server.httpServer?.once('close', closeBundle);
|
|
703
726
|
return result;
|
|
704
727
|
};
|
|
705
728
|
},
|
|
706
|
-
closeBundle
|
|
707
|
-
stop?.();
|
|
708
|
-
stop = undefined;
|
|
709
|
-
},
|
|
729
|
+
closeBundle,
|
|
710
730
|
};
|
|
711
731
|
}
|
|
712
732
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nginx.d.ts","sourceRoot":"","sources":["../../src/render/nginx.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"nginx.d.ts","sourceRoot":"","sources":["../../src/render/nginx.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AA0D9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAI3D"}
|
package/dist/types.d.ts
CHANGED
|
@@ -151,11 +151,15 @@ export type VisageDexExpiry = {
|
|
|
151
151
|
export type VisageDexUser = {
|
|
152
152
|
/**
|
|
153
153
|
* Email address used as the Dex login identifier.
|
|
154
|
+
*
|
|
155
|
+
* @defaultValue `'user@example.com'`
|
|
154
156
|
*/
|
|
155
157
|
readonly email: string;
|
|
156
158
|
/**
|
|
157
159
|
* Plain-text development password. Visage hashes this before rendering the
|
|
158
160
|
* Dex config.
|
|
161
|
+
*
|
|
162
|
+
* @defaultValue `'pass'`
|
|
159
163
|
*/
|
|
160
164
|
readonly password: string;
|
|
161
165
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,CAAC;IAC3D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAClD;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACvB;;WAEG;QACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC;;WAEG;QACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blakearoberts/visage",
|
|
3
|
-
"version": "0.0.1-rc.
|
|
3
|
+
"version": "0.0.1-rc.8",
|
|
4
4
|
"description": "Vite plugin for local development with HMR and OIDC session cookie lifecycle semantics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Blake Roberts",
|
|
@@ -14,14 +14,15 @@
|
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/blakearoberts/visage#readme",
|
|
16
16
|
"keywords": [
|
|
17
|
-
"
|
|
18
|
-
"plugin",
|
|
19
|
-
"oidc",
|
|
17
|
+
"authentication",
|
|
20
18
|
"hmr",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
19
|
+
"local-development",
|
|
20
|
+
"oauth2",
|
|
21
|
+
"oidc",
|
|
22
|
+
"pkce",
|
|
23
|
+
"session-cookie",
|
|
24
|
+
"vite",
|
|
25
|
+
"vite-plugin"
|
|
25
26
|
],
|
|
26
27
|
"main": "dist/index.js",
|
|
27
28
|
"types": "dist/index.d.ts",
|
|
@@ -44,11 +45,14 @@
|
|
|
44
45
|
"scripts": {
|
|
45
46
|
"build": "npm run clean && rollup -c",
|
|
46
47
|
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
47
|
-
"
|
|
48
|
+
"dev:example": "cd examples/managed-service && npm run dev",
|
|
49
|
+
"format": "prettier --write \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\"",
|
|
50
|
+
"format:check": "prettier --check \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\"",
|
|
51
|
+
"test": "npm run typecheck && npm run test:unit",
|
|
52
|
+
"test:all": "npm test && npm run test:e2e",
|
|
48
53
|
"test:e2e": "playwright test test/e2e",
|
|
49
54
|
"test:unit": "node --experimental-strip-types --test test/unit/*.test.ts",
|
|
50
|
-
"
|
|
51
|
-
"format:check": "prettier --check \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\""
|
|
55
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.test.json"
|
|
52
56
|
},
|
|
53
57
|
"devDependencies": {
|
|
54
58
|
"@playwright/test": "^1.59.1",
|