@o3co/create-auth-provider 0.17.0 → 0.18.0-rc.1
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 +2 -198
- package/main.js +4 -0
- package/package.json +8 -30
- package/README.ja.md +0 -200
- package/dist/cli.d.mts +0 -3
- package/dist/cli.d.mts.map +0 -1
- package/dist/cli.mjs +0 -18
- package/dist/index.d.mts +0 -48
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -325
- package/dist/internal/template-filter.d.mts +0 -14
- package/dist/internal/template-filter.d.mts.map +0 -1
- package/dist/internal/template-filter.mjs +0 -42
- package/templates/standalone/.dockerignore +0 -23
- package/templates/standalone/.env.example +0 -152
- package/templates/standalone/Dockerfile +0 -125
- package/templates/standalone/Makefile +0 -12
- package/templates/standalone/README.ja.md +0 -912
- package/templates/standalone/README.md +0 -1536
- package/templates/standalone/config/application.conf +0 -351
- package/templates/standalone/config/clients.yaml +0 -4
- package/templates/standalone/config/clients.yaml.example +0 -124
- package/templates/standalone/config/development.conf +0 -17
- package/templates/standalone/config/mailpit.conf +0 -13
- package/templates/standalone/config/production.conf +0 -15
- package/templates/standalone/config/reference.conf +0 -427
- package/templates/standalone/docker-compose.mailpit.yml +0 -39
- package/templates/standalone/docker-compose.production.yml +0 -229
- package/templates/standalone/docker-compose.test.yml +0 -16
- package/templates/standalone/docker-compose.yml +0 -67
- package/templates/standalone/gitignore +0 -23
- package/templates/standalone/package.json +0 -56
- package/templates/standalone/src/__tests__/adapters.test.mts +0 -425
- package/templates/standalone/src/__tests__/admission-lifecycle.test.mts +0 -87
- package/templates/standalone/src/__tests__/all-modules-composition.fixture.mts +0 -1188
- package/templates/standalone/src/__tests__/all-modules-composition.multi.test.mts +0 -285
- package/templates/standalone/src/__tests__/all-modules-composition.test.mts +0 -1154
- package/templates/standalone/src/__tests__/audit-sink.test.mts +0 -355
- package/templates/standalone/src/__tests__/backchannel-peer.fixture.mts +0 -64
- package/templates/standalone/src/__tests__/config-notices.test.mts +0 -157
- package/templates/standalone/src/__tests__/configPath.test.mts +0 -69
- package/templates/standalone/src/__tests__/configured-mfa-mode.fixture.mts +0 -48
- package/templates/standalone/src/__tests__/core-federations.test.mts +0 -252
- package/templates/standalone/src/__tests__/core-sections.test.mts +0 -192
- package/templates/standalone/src/__tests__/device-code-store-client-module.test.mts +0 -95
- package/templates/standalone/src/__tests__/documented-env-overrides.test.mts +0 -1291
- package/templates/standalone/src/__tests__/federation-grants-composition.test.mts +0 -787
- package/templates/standalone/src/__tests__/federation-grants-survive-logout.test.mts +0 -464
- package/templates/standalone/src/__tests__/federation-token-refresh-outage.test.mts +0 -141
- package/templates/standalone/src/__tests__/federation-types.test.mts +0 -239
- package/templates/standalone/src/__tests__/frontchannel-logout-csp.test.mts +0 -168
- package/templates/standalone/src/__tests__/google-session.fixture.mts +0 -318
- package/templates/standalone/src/__tests__/host-routes.test.mts +0 -134
- package/templates/standalone/src/__tests__/library-reference-resolution.smoke.test.mts +0 -29
- package/templates/standalone/src/__tests__/library-references.fixture.mts +0 -188
- package/templates/standalone/src/__tests__/lifecycle-pending-close.test.mts +0 -217
- package/templates/standalone/src/__tests__/listen.test.mts +0 -121
- package/templates/standalone/src/__tests__/logger-projection.test.mts +0 -77
- package/templates/standalone/src/__tests__/logout-session-cookie.test.mts +0 -113
- package/templates/standalone/src/__tests__/mail-sender.test.mts +0 -134
- package/templates/standalone/src/__tests__/mailpit-compose.test.mts +0 -393
- package/templates/standalone/src/__tests__/metrics.test.mts +0 -253
- package/templates/standalone/src/__tests__/mfa-routes-budget.test.mts +0 -122
- package/templates/standalone/src/__tests__/mfa-switch.redis.test.mts +0 -127
- package/templates/standalone/src/__tests__/mfa-switch.test.mts +0 -883
- package/templates/standalone/src/__tests__/own-modules.test.mts +0 -1480
- package/templates/standalone/src/__tests__/post-logout-redirect.test.mts +0 -183
- package/templates/standalone/src/__tests__/redis-assume-noeviction.test.mts +0 -283
- package/templates/standalone/src/__tests__/redis-connection-error-log.test.mts +0 -135
- package/templates/standalone/src/__tests__/redis-rate-limiter-config-survives.test.mts +0 -214
- package/templates/standalone/src/__tests__/redis-stand-in.fixture.mts +0 -98
- package/templates/standalone/src/__tests__/refresh-token-family-client-module.test.mts +0 -249
- package/templates/standalone/src/__tests__/replica-safety.test.mts +0 -657
- package/templates/standalone/src/__tests__/repositories-logger.test.mts +0 -119
- package/templates/standalone/src/__tests__/router-error-answers.test.mts +0 -146
- package/templates/standalone/src/__tests__/scaffold-assets.test.mts +0 -610
- package/templates/standalone/src/__tests__/sections.test.mts +0 -516
- package/templates/standalone/src/__tests__/session-lifecycle.test.mts +0 -213
- package/templates/standalone/src/__tests__/session-logout-invalidates-token.test.mts +0 -305
- package/templates/standalone/src/__tests__/session-logout-lifecycle.test.mts +0 -130
- package/templates/standalone/src/__tests__/session-requirements.test.mts +0 -382
- package/templates/standalone/src/__tests__/shipped-config-notices.test.mts +0 -274
- package/templates/standalone/src/__tests__/shutdown.test.mts +0 -622
- package/templates/standalone/src/__tests__/smoke.test.mts +0 -642
- package/templates/standalone/src/__tests__/startup-log-lines.test.mts +0 -164
- package/templates/standalone/src/__tests__/store-credential.test.mts +0 -314
- package/templates/standalone/src/__tests__/supertest-loopback.test.mts +0 -296
- package/templates/standalone/src/__tests__/three-tier-resolution.test.mts +0 -265
- package/templates/standalone/src/__tests__/two-phase-config.test.mts +0 -605
- package/templates/standalone/src/__tests__/upstream-amr.acceptance.test.mts +0 -385
- package/templates/standalone/src/adapters.mts +0 -162
- package/templates/standalone/src/app.mts +0 -127
- package/templates/standalone/src/bootRefusal.mts +0 -117
- package/templates/standalone/src/buildModules.mts +0 -358
- package/templates/standalone/src/configPath.mts +0 -487
- package/templates/standalone/src/listen.mts +0 -60
- package/templates/standalone/src/logger.mts +0 -80
- package/templates/standalone/src/metrics.mts +0 -167
- package/templates/standalone/src/mfaSwitch.mts +0 -284
- package/templates/standalone/src/modules.mts +0 -705
- package/templates/standalone/src/rootRenames.mts +0 -95
- package/templates/standalone/src/routes.mts +0 -89
- package/templates/standalone/src/sections.mts +0 -378
- package/templates/standalone/src/securityHeaders.mts +0 -36
- package/templates/standalone/src/shutdown.mts +0 -213
- package/templates/standalone/tests/Makefile +0 -5
- package/templates/standalone/tests/index.test.js +0 -283
- package/templates/standalone/tests/package-lock.json +0 -1617
- package/templates/standalone/tests/package.json +0 -16
- package/templates/standalone/tests/vitest.config.mjs +0 -26
- package/templates/standalone/tsconfig.json +0 -31
- package/templates/standalone/vitest.config.mts +0 -31
- package/templates/standalone/vitest.supertest-loopback.mts +0 -278
- package/templates/versions.json +0 -20
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "provider-api-test",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "provider REST API テスト用プロジェクト",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "vitest run"
|
|
8
|
-
},
|
|
9
|
-
"dependencies": {
|
|
10
|
-
"axios": "^1.18.0",
|
|
11
|
-
"jsonwebtoken": "^9.0.3"
|
|
12
|
-
},
|
|
13
|
-
"devDependencies": {
|
|
14
|
-
"vitest": "^5.0.3"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2026 1o1 Co. Ltd.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
// This directory is its own npm project, run against a live provider. Its own
|
|
18
|
-
// config fixes what this project collects; no config of the template's around
|
|
19
|
-
// it decides that, whichever vitest the lockfile carries.
|
|
20
|
-
import { defineConfig } from "vitest/config";
|
|
21
|
-
|
|
22
|
-
export default defineConfig({
|
|
23
|
-
test: {
|
|
24
|
-
include: ["*.test.js"],
|
|
25
|
-
},
|
|
26
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// `es2023` target (NOT esnext) with `lib: esnext` — mirrors the monorepo's
|
|
4
|
-
// tsconfig.base.json. This template is copied verbatim into scaffolded
|
|
5
|
-
// consumer projects (so it must stay self-contained and cannot `extends`
|
|
6
|
-
// ../../tsconfig.base.json). Capping the emit target at ES2023 — the newest
|
|
7
|
-
// edition Node 22 (this template's engine floor) parses natively — makes tsc
|
|
8
|
-
// downlevel any newer syntax (e.g. `await using`) into helpers, so the built
|
|
9
|
-
// server actually runs on the Node it advertises. Do NOT raise to `esnext`
|
|
10
|
-
// without also raising the engine floor.
|
|
11
|
-
"target": "es2023",
|
|
12
|
-
"lib": ["esnext"],
|
|
13
|
-
"module": "nodenext",
|
|
14
|
-
"moduleResolution": "nodenext",
|
|
15
|
-
"declarationMap": true,
|
|
16
|
-
"declaration": true,
|
|
17
|
-
"emitDeclarationOnly": false,
|
|
18
|
-
"strict": true,
|
|
19
|
-
"forceConsistentCasingInFileNames": true,
|
|
20
|
-
"allowArbitraryExtensions": true,
|
|
21
|
-
"esModuleInterop": true,
|
|
22
|
-
"skipLibCheck": true,
|
|
23
|
-
"rootDir": "./src",
|
|
24
|
-
"outDir": "./dist",
|
|
25
|
-
"paths": {
|
|
26
|
-
"#/*": ["./src/*"]
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"include": ["src/**/*"],
|
|
30
|
-
"exclude": ["node_modules", "dist"]
|
|
31
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vitest/config";
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
include: ["src/**/__tests__/**/*.test.mts"],
|
|
6
|
-
// The workspace-wide deadline floor, repeated as literals rather
|
|
7
|
-
// than imported from vitest.shared.mts — this template is copied
|
|
8
|
-
// verbatim into scaffolded projects, where that file does not exist.
|
|
9
|
-
// Rationale lives there: under a loaded parallel run, transform+import
|
|
10
|
-
// alone can exceed vitest's 5s default, and a real hang still fails at
|
|
11
|
-
// 20s.
|
|
12
|
-
testTimeout: 20_000,
|
|
13
|
-
hookTimeout: 20_000,
|
|
14
|
-
// Run the @o3co/auth-provider-* packages through vitest instead of
|
|
15
|
-
// letting Node load them natively. In a scaffolded project they are
|
|
16
|
-
// installed from npm under node_modules, which vitest externalizes by
|
|
17
|
-
// default — and an externalized package's own `import "ioredis"` /
|
|
18
|
-
// `import "redis"` never sees a `vi.mock` from a test file, so
|
|
19
|
-
// replica-safety.test.mts dialled a Redis that is not there. Inside the
|
|
20
|
-
// monorepo the same packages are symlinks to source and are inlined
|
|
21
|
-
// anyway; this makes the two layouts behave the same.
|
|
22
|
-
server: { deps: { inline: [/@o3co\/auth-provider-/] } },
|
|
23
|
-
// The supertest loopback guard: the server `request(app)` starts
|
|
24
|
-
// listens on 127.0.0.1, the address supertest dials. Unpatched, macOS
|
|
25
|
-
// can give it a port another process holds on 127.0.0.1, and the
|
|
26
|
-
// request hangs on that process until the test timeout. Rationale and
|
|
27
|
-
// mechanics in the file itself. The Dockerfile `test` stage copies it;
|
|
28
|
-
// scaffold-assets.test.mts checks that.
|
|
29
|
-
setupFiles: ["./vitest.supertest-loopback.mts"],
|
|
30
|
-
},
|
|
31
|
-
});
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2026 1o1 Co. Ltd.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* vitest setup file: the server supertest starts listens on the address
|
|
19
|
-
* supertest dials.
|
|
20
|
-
*
|
|
21
|
-
* `request(app)` / `request.agent(app)` start a server with `app.listen(0)`
|
|
22
|
-
* and send the request to `127.0.0.1:<port>`. A hostless `listen` binds the
|
|
23
|
-
* dual-stack wildcard `[::]:P`, and on macOS (BSD `SO_REUSEADDR` semantics;
|
|
24
|
-
* libuv sets it on every TCP listener) the kernel will choose a `P` that
|
|
25
|
-
* another process already holds as `127.0.0.1:P`. The more specific socket
|
|
26
|
-
* wins, so the request goes to that process; if it accepts and never answers,
|
|
27
|
-
* the test hangs until its timeout and passes on the next run. Linux refuses
|
|
28
|
-
* the conflicting bind (EADDRINUSE), so CI does not show it.
|
|
29
|
-
*
|
|
30
|
-
* Binding `127.0.0.1` explicitly removes both halves: the kernel will not
|
|
31
|
-
* give out a `127.0.0.1:P` someone else holds, and against a wildcard holder
|
|
32
|
-
* our specific socket is the one that receives. A specific-host `listen` is
|
|
33
|
-
* asynchronous (it goes through `dns.lookup`) and supertest reads the port
|
|
34
|
-
* synchronously in its constructor, so the URL is completed when the request
|
|
35
|
-
* is sent (`end`, which `then` and `expect(..., fn)` go through). A server the
|
|
36
|
-
* test started itself is never touched.
|
|
37
|
-
*
|
|
38
|
-
* supertest does not close a server bound here (7.3 counts requests only on
|
|
39
|
-
* servers in its own registry; 7.2 closed after the response of the request
|
|
40
|
-
* that bound it, resetting an agent's other requests on the shared server).
|
|
41
|
-
* So this file counts every request on such a server from `end`, and the last
|
|
42
|
-
* to settle closes the server before its own callback, the order supertest
|
|
43
|
-
* keeps. A request built before that close and sent after it binds the server
|
|
44
|
-
* again.
|
|
45
|
-
*
|
|
46
|
-
* supertest is loaded from the package that owns the running test file (the
|
|
47
|
-
* nearest `package.json` above it), so the patched class is the one that test
|
|
48
|
-
* imports. A package that does not declare supertest is left alone. Anything
|
|
49
|
-
* else this file cannot do (no test path, a declared supertest that does not
|
|
50
|
-
* load, internals that no longer look like this) throws, so the guard is
|
|
51
|
-
* never silently off. That load-time check sees only the two methods'
|
|
52
|
-
* presence; a supertest that moved the `listen` out of `serverAddress` would
|
|
53
|
-
* pass it, which `supertest-loopback.test.mts` here and its twin in the
|
|
54
|
-
* session package catch by asserting the address the server actually bound.
|
|
55
|
-
*
|
|
56
|
-
* Part of the project template, shipped with every scaffold; the
|
|
57
|
-
* auth.provider workspace loads it for its packages too
|
|
58
|
-
* (`WORKSPACE_TEST_SETUP` in its `vitest.shared.mts`).
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
import { once } from "node:events";
|
|
62
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
63
|
-
import { createRequire } from "node:module";
|
|
64
|
-
import type { Server } from "node:net";
|
|
65
|
-
import { dirname, join } from "node:path";
|
|
66
|
-
import { Server as TlsServer } from "node:tls";
|
|
67
|
-
import { expect } from "vitest";
|
|
68
|
-
|
|
69
|
-
const LOOPBACK = "127.0.0.1";
|
|
70
|
-
const PATCHED = Symbol.for("o3co.auth.provider.supertest-loopback");
|
|
71
|
-
const PENDING = Symbol("o3co.auth.provider.supertest-loopback.pending");
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* A server this file bound, from its `listen` until the last request on it
|
|
75
|
-
* settles. It is the server's current bind for as long as `bound` maps the
|
|
76
|
-
* server to it; a request built on one that no longer is — closed by its last
|
|
77
|
-
* request, or failed — binds again when it is sent.
|
|
78
|
-
*/
|
|
79
|
-
type Bound = {
|
|
80
|
-
/** Settles on `listening`, rejects on a listen `error`. */
|
|
81
|
-
readonly ready: Promise<unknown>;
|
|
82
|
-
/** The requests sent over it that have not settled. */
|
|
83
|
-
pending: number;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
type Pending = {
|
|
87
|
-
readonly server: Server;
|
|
88
|
-
readonly protocol: string;
|
|
89
|
-
readonly path: string;
|
|
90
|
-
readonly bound: Bound;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
type TestInstance = {
|
|
94
|
-
url: string;
|
|
95
|
-
[PENDING]?: Pending;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
type TestPrototype = {
|
|
99
|
-
serverAddress(this: TestInstance, app: Server, path: string): string;
|
|
100
|
-
end(this: TestInstance, fn?: (err: unknown, res?: unknown) => void): TestInstance;
|
|
101
|
-
[PATCHED]?: true;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const DEPENDENCY_FIELDS = [
|
|
105
|
-
"dependencies",
|
|
106
|
-
"devDependencies",
|
|
107
|
-
"peerDependencies",
|
|
108
|
-
"optionalDependencies",
|
|
109
|
-
] as const;
|
|
110
|
-
|
|
111
|
-
/** The nearest `package.json` at or above `dir`. */
|
|
112
|
-
function owningManifest(dir: string): string | undefined {
|
|
113
|
-
for (let current = dir; ; current = dirname(current)) {
|
|
114
|
-
const candidate = join(current, "package.json");
|
|
115
|
-
if (existsSync(candidate)) return candidate;
|
|
116
|
-
if (dirname(current) === current) return undefined;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** supertest's `Test.prototype` as the running test file sees it, or `undefined` when its package has no supertest. */
|
|
121
|
-
function supertestFor(testPath: string): TestPrototype | undefined {
|
|
122
|
-
const manifestPath = owningManifest(dirname(testPath));
|
|
123
|
-
if (!manifestPath) {
|
|
124
|
-
throw new Error(`vitest.supertest-loopback.mts: no package.json above ${testPath}.`);
|
|
125
|
-
}
|
|
126
|
-
const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as Record<string, unknown>;
|
|
127
|
-
const declared = DEPENDENCY_FIELDS.some(
|
|
128
|
-
(field) => (manifest[field] as Record<string, unknown> | undefined)?.supertest !== undefined,
|
|
129
|
-
);
|
|
130
|
-
if (!declared) return undefined;
|
|
131
|
-
|
|
132
|
-
let supertest: { Test?: { prototype: TestPrototype } };
|
|
133
|
-
try {
|
|
134
|
-
supertest = createRequire(manifestPath)("supertest");
|
|
135
|
-
} catch (cause) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
`vitest.supertest-loopback.mts: ${manifestPath} declares supertest, but it cannot be loaded from there; the supertest loopback guard would be off.`,
|
|
138
|
-
{ cause },
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
const proto = supertest.Test?.prototype;
|
|
142
|
-
if (typeof proto?.serverAddress !== "function" || typeof proto.end !== "function") {
|
|
143
|
-
throw new Error(
|
|
144
|
-
"vitest.supertest-loopback.mts: supertest no longer exposes Test.prototype.serverAddress/end; " +
|
|
145
|
-
"re-check the supertest loopback guard against the installed supertest before removing it.",
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
return proto;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* The servers this file bound, each until the last request on it closes it.
|
|
153
|
-
* A request on a server whose bind has not finished (an agent's requests sent
|
|
154
|
-
* together share one server) waits on that bind instead of calling `listen`
|
|
155
|
-
* twice, and one sent while the server is serving others joins their count.
|
|
156
|
-
*/
|
|
157
|
-
const bound = new WeakMap<Server, Bound>();
|
|
158
|
-
|
|
159
|
-
/** The server's bind in progress or in service, or a new one. */
|
|
160
|
-
function share(server: Server): Bound {
|
|
161
|
-
const current = bound.get(server);
|
|
162
|
-
if (current) return current;
|
|
163
|
-
server.listen(0, LOOPBACK);
|
|
164
|
-
// Subscribed now, not in `end`: a listen error emitted before the test
|
|
165
|
-
// sends the request must still reach it, not crash the worker as an
|
|
166
|
-
// unhandled 'error' event.
|
|
167
|
-
const fresh: Bound = { ready: once(server, "listening"), pending: 0 };
|
|
168
|
-
bound.set(server, fresh);
|
|
169
|
-
// Once it has failed, the bind is left to the requests already waiting on
|
|
170
|
-
// it, each of which fails with its error, and is no longer the server's:
|
|
171
|
-
// the next request sent binds again, one built on the failed bind included.
|
|
172
|
-
// Forgotten on the error event itself, and not on the rejection it becomes
|
|
173
|
-
// — that settles a few microtasks later, and a request built in between
|
|
174
|
-
// would join the failed bind.
|
|
175
|
-
const failed = (): void => {
|
|
176
|
-
if (bound.get(server) === fresh) bound.delete(server);
|
|
177
|
-
};
|
|
178
|
-
server.once("error", failed);
|
|
179
|
-
fresh.ready.then(
|
|
180
|
-
() => server.removeListener("error", failed),
|
|
181
|
-
() => {},
|
|
182
|
-
);
|
|
183
|
-
return fresh;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* A throw from the test's own callback, raised where it cannot propagate to
|
|
188
|
-
* the test: reported as an uncaught exception, which fails the run by name,
|
|
189
|
-
* instead of an unhandled rejection of a promise nobody holds.
|
|
190
|
-
*/
|
|
191
|
-
function rethrowOutsideThisChain(err: unknown): void {
|
|
192
|
-
process.nextTick(() => {
|
|
193
|
-
throw err;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function patch(proto: TestPrototype): void {
|
|
198
|
-
if (proto[PATCHED]) return;
|
|
199
|
-
const originalServerAddress = proto.serverAddress;
|
|
200
|
-
const originalEnd = proto.end;
|
|
201
|
-
|
|
202
|
-
proto.serverAddress = function serverAddress(app, path) {
|
|
203
|
-
// Listening, and not bound here: the test owns the server and chose its
|
|
204
|
-
// address.
|
|
205
|
-
if (!bound.has(app) && app.address()) return originalServerAddress.call(this, app, path);
|
|
206
|
-
|
|
207
|
-
// supertest is never told about this bind — neither 7.2's `_server` nor
|
|
208
|
-
// 7.3's registry — so neither closes the server; the patched `end` does.
|
|
209
|
-
const protocol = app instanceof TlsServer ? "https" : "http";
|
|
210
|
-
this[PENDING] = { server: app, protocol, path, bound: share(app) };
|
|
211
|
-
// No port yet; `end` fills it in before anything is sent.
|
|
212
|
-
return `${protocol}://${LOOPBACK}${path}`;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
proto.end = function end(fn) {
|
|
216
|
-
const pending = this[PENDING];
|
|
217
|
-
if (!pending) return originalEnd.call(this, fn);
|
|
218
|
-
this[PENDING] = undefined;
|
|
219
|
-
|
|
220
|
-
const { server, protocol, path } = pending;
|
|
221
|
-
// Built on a bind that is no longer the server's — closed by its last
|
|
222
|
-
// request, or failed — and sent now: bind it again, or join the bind
|
|
223
|
-
// another request has made since.
|
|
224
|
-
const shared = bound.get(server) === pending.bound ? pending.bound : share(server);
|
|
225
|
-
shared.pending += 1;
|
|
226
|
-
let called = false;
|
|
227
|
-
const callback = (err: unknown, res?: unknown) => {
|
|
228
|
-
called = true;
|
|
229
|
-
// The last request on the server closes it, before its own callback —
|
|
230
|
-
// the order supertest keeps. A bind that failed has nothing to close.
|
|
231
|
-
shared.pending -= 1;
|
|
232
|
-
if (shared.pending === 0 && bound.get(server) === shared) {
|
|
233
|
-
bound.delete(server);
|
|
234
|
-
if (server.listening) {
|
|
235
|
-
server.close(() => fn?.(err, res));
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
fn?.(err, res);
|
|
240
|
-
};
|
|
241
|
-
// Unpatched, whatever `end` throws while building the request (a header
|
|
242
|
-
// value Node refuses, a body that will not serialize) reaches the caller
|
|
243
|
-
// at once — and `then` runs `end` inside a promise executor, so the
|
|
244
|
-
// awaited request rejects with it. Deferred, there is no caller left: the
|
|
245
|
-
// throw, like a failed bind, is handed to the request's callback, which
|
|
246
|
-
// is what rejects that promise. Nothing here may reject: a rejection of
|
|
247
|
-
// this chain is one nobody awaits.
|
|
248
|
-
const fail = (err: unknown) => {
|
|
249
|
-
if (called) return rethrowOutsideThisChain(err);
|
|
250
|
-
// The request never went out; it still leaves the count, and closes
|
|
251
|
-
// the server if it was the last one on it.
|
|
252
|
-
try {
|
|
253
|
-
callback(err);
|
|
254
|
-
} catch (thrown) {
|
|
255
|
-
rethrowOutsideThisChain(thrown);
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
shared.ready
|
|
259
|
-
.then(() => {
|
|
260
|
-
const { port } = server.address() as { port: number };
|
|
261
|
-
this.url = `${protocol}://${LOOPBACK}:${port}${path}`;
|
|
262
|
-
originalEnd.call(this, callback);
|
|
263
|
-
})
|
|
264
|
-
.catch(fail);
|
|
265
|
-
return this;
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
proto[PATCHED] = true;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const { testPath } = expect.getState();
|
|
272
|
-
if (!testPath) {
|
|
273
|
-
throw new Error(
|
|
274
|
-
"vitest.supertest-loopback.mts: vitest did not say which test file this setup runs for, so the supertest loopback guard cannot find supertest.",
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
const proto = supertestFor(testPath);
|
|
278
|
-
if (proto) patch(proto);
|
package/templates/versions.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"@o3co/auth-provider-core": "0.17.0",
|
|
3
|
-
"@o3co/auth-provider-device-grant": "0.17.0",
|
|
4
|
-
"@o3co/auth-provider-dpop": "0.17.0",
|
|
5
|
-
"@o3co/auth-provider-mtls": "0.17.0",
|
|
6
|
-
"@o3co/auth-provider-federation-apple": "0.17.0",
|
|
7
|
-
"@o3co/auth-provider-federation-google": "0.17.0",
|
|
8
|
-
"@o3co/auth-provider-federation-github": "0.17.0",
|
|
9
|
-
"@o3co/auth-provider-federation-grants": "0.17.0",
|
|
10
|
-
"@o3co/auth-provider-federation-oidc": "0.17.0",
|
|
11
|
-
"@o3co/auth-provider-oauth": "0.17.0",
|
|
12
|
-
"@o3co/auth-provider-oauth-token-exchange": "0.17.0",
|
|
13
|
-
"@o3co/auth-provider-session": "0.17.0",
|
|
14
|
-
"@o3co/auth-provider-foundation": "0.17.0",
|
|
15
|
-
"@o3co/auth-provider-mfa": "0.17.0",
|
|
16
|
-
"@o3co/auth-provider-redis": "0.17.0",
|
|
17
|
-
"@o3co/auth-provider-standard": "0.17.0",
|
|
18
|
-
"@o3co/auth-provider-test-kit": "0.17.0",
|
|
19
|
-
"@o3co/auth-provider-webauthn": "0.17.0"
|
|
20
|
-
}
|