@o3co/create-auth-provider 0.16.0 → 0.17.0-rc.2
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.ja.md +66 -21
- package/README.md +76 -31
- package/dist/index.d.mts +33 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +118 -59
- package/dist/internal/template-filter.d.mts +7 -10
- package/dist/internal/template-filter.d.mts.map +1 -1
- package/dist/internal/template-filter.mjs +7 -10
- package/package.json +6 -4
- package/templates/standalone/.dockerignore +15 -2
- package/templates/standalone/.env.example +59 -29
- package/templates/standalone/Dockerfile +6 -2
- package/templates/standalone/README.ja.md +324 -169
- package/templates/standalone/README.md +618 -208
- package/templates/standalone/config/application.conf +211 -352
- package/templates/standalone/config/clients.yaml +2 -0
- package/templates/standalone/config/clients.yaml.example +4 -0
- package/templates/standalone/config/development.conf +13 -4
- package/templates/standalone/config/mailpit.conf +8 -0
- package/templates/standalone/config/production.conf +5 -6
- package/templates/standalone/config/reference.conf +418 -0
- package/templates/standalone/docker-compose.mailpit.yml +36 -0
- package/templates/standalone/docker-compose.production.yml +63 -32
- package/templates/standalone/docker-compose.yml +13 -3
- package/templates/standalone/gitignore +1 -0
- package/templates/standalone/package.json +9 -6
- package/templates/standalone/src/__tests__/adapters.test.mts +419 -0
- package/templates/standalone/src/__tests__/admission-lifecycle.test.mts +87 -0
- package/templates/standalone/src/__tests__/all-modules-composition.fixture.mts +287 -198
- package/templates/standalone/src/__tests__/all-modules-composition.multi.test.mts +71 -35
- package/templates/standalone/src/__tests__/all-modules-composition.test.mts +148 -94
- package/templates/standalone/src/__tests__/audit-sink.test.mts +84 -81
- package/templates/standalone/src/__tests__/config-notices.test.mts +154 -0
- package/templates/standalone/src/__tests__/configPath.test.mts +13 -11
- package/templates/standalone/src/__tests__/core-federations.test.mts +249 -0
- package/templates/standalone/src/__tests__/core-sections.test.mts +190 -0
- package/templates/standalone/src/__tests__/device-code-store-client-module.test.mts +10 -15
- package/templates/standalone/src/__tests__/documented-env-overrides.test.mts +970 -288
- package/templates/standalone/src/__tests__/federation-grants-composition.test.mts +421 -86
- package/templates/standalone/src/__tests__/federation-grants-survive-logout.test.mts +87 -72
- package/templates/standalone/src/__tests__/federation-token-refresh-outage.test.mts +16 -8
- package/templates/standalone/src/__tests__/federation-types.test.mts +239 -0
- package/templates/standalone/src/__tests__/google-session.fixture.mts +97 -93
- package/templates/standalone/src/__tests__/host-routes.test.mts +4 -11
- package/templates/standalone/src/__tests__/library-reference-resolution.smoke.test.mts +1 -1
- package/templates/standalone/src/__tests__/library-references.fixture.mts +188 -0
- package/templates/standalone/src/__tests__/lifecycle-pending-close.test.mts +216 -0
- package/templates/standalone/src/__tests__/listen.test.mts +6 -13
- package/templates/standalone/src/__tests__/logger-projection.test.mts +1 -1
- package/templates/standalone/src/__tests__/mail-sender.test.mts +134 -0
- package/templates/standalone/src/__tests__/mailpit-compose.test.mts +326 -0
- package/templates/standalone/src/__tests__/metrics.test.mts +4 -9
- package/templates/standalone/src/__tests__/mfa-routes-budget.test.mts +122 -0
- package/templates/standalone/src/__tests__/mfa-switch.redis.test.mts +123 -0
- package/templates/standalone/src/__tests__/mfa-switch.test.mts +825 -0
- package/templates/standalone/src/__tests__/own-modules.test.mts +1486 -0
- package/templates/standalone/src/__tests__/post-logout-redirect.test.mts +10 -14
- package/templates/standalone/src/__tests__/redis-connection-error-log.test.mts +1 -5
- package/templates/standalone/src/__tests__/redis-rate-limiter-config-survives.test.mts +116 -81
- package/templates/standalone/src/__tests__/refresh-token-family-client-module.test.mts +25 -31
- package/templates/standalone/src/__tests__/replica-safety.test.mts +265 -146
- package/templates/standalone/src/__tests__/router-error-answers.test.mts +4 -7
- package/templates/standalone/src/__tests__/scaffold-assets.test.mts +278 -103
- package/templates/standalone/src/__tests__/sections.test.mts +480 -0
- package/templates/standalone/src/__tests__/session-lifecycle.test.mts +215 -0
- package/templates/standalone/src/__tests__/session-logout-invalidates-token.test.mts +69 -61
- package/templates/standalone/src/__tests__/session-logout-lifecycle.test.mts +130 -0
- package/templates/standalone/src/__tests__/session-requirements.test.mts +382 -0
- package/templates/standalone/src/__tests__/shipped-config-notices.test.mts +270 -0
- package/templates/standalone/src/__tests__/shutdown.test.mts +163 -96
- package/templates/standalone/src/__tests__/smoke.test.mts +176 -258
- package/templates/standalone/src/__tests__/store-credential.test.mts +88 -52
- package/templates/standalone/src/__tests__/supertest-loopback.test.mts +182 -11
- package/templates/standalone/src/__tests__/three-tier-resolution.test.mts +131 -102
- package/templates/standalone/src/__tests__/two-phase-config.test.mts +604 -0
- package/templates/standalone/src/__tests__/upstream-amr.acceptance.test.mts +382 -0
- package/templates/standalone/src/adapters.mts +162 -0
- package/templates/standalone/src/app.mts +65 -79
- package/templates/standalone/src/bootRefusal.mts +117 -0
- package/templates/standalone/src/buildModules.mts +220 -309
- package/templates/standalone/src/configPath.mts +449 -29
- package/templates/standalone/src/listen.mts +12 -18
- package/templates/standalone/src/logger.mts +31 -60
- package/templates/standalone/src/metrics.mts +24 -47
- package/templates/standalone/src/mfaSwitch.mts +285 -0
- package/templates/standalone/src/modules.mts +423 -629
- package/templates/standalone/src/rootRenames.mts +96 -0
- package/templates/standalone/src/routes.mts +8 -14
- package/templates/standalone/src/sections.mts +367 -0
- package/templates/standalone/src/shutdown.mts +45 -123
- package/templates/standalone/tests/index.test.js +6 -5
- package/templates/standalone/tests/package-lock.json +1615 -2223
- package/templates/standalone/tests/package.json +2 -2
- package/templates/standalone/tests/vitest.config.mjs +26 -0
- package/templates/standalone/vitest.config.mts +8 -7
- package/templates/standalone/vitest.supertest-loopback.mts +97 -69
- package/templates/versions.json +18 -15
- package/templates/standalone/src/__tests__/access-token-lifetime-alias.test.mts +0 -135
- package/templates/standalone/src/__tests__/google-federation-config-module.test.mts +0 -199
- package/templates/standalone/src/__tests__/oidc-federation-config-module.test.mts +0 -138
package/README.ja.md
CHANGED
|
@@ -1,35 +1,49 @@
|
|
|
1
1
|
# @o3co/create-auth-provider
|
|
2
2
|
|
|
3
|
-
最終更新: 2026-
|
|
3
|
+
最終更新: 2026-10-03
|
|
4
4
|
|
|
5
|
-
auth.provider 用の CLI
|
|
5
|
+
auth.provider 用の CLI スキャフォルダーです。内包するテンプレートの 1 つから新しいサーバープロジェクトを生成します。
|
|
6
6
|
|
|
7
7
|
## 責務と役割
|
|
8
8
|
|
|
9
|
-
**役割。**
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
**役割。** リポジトリ内の [`templates/`](../templates) にあるテンプレート
|
|
10
|
+
(それぞれがデプロイ可能なコンポジションルート)の 1 つを、独立した新しい
|
|
11
|
+
プロジェクトに変換する `npx` の入口です。運用者のマシン上で一度だけ実行されます。生成された
|
|
12
12
|
プロジェクトはこのパッケージを import せず、このパッケージも `packages/*` の
|
|
13
13
|
ライブラリを一切 import しません。
|
|
14
14
|
|
|
15
|
-
**担うもの。**
|
|
15
|
+
**担うもの。** プロジェクト名・ディレクトリ名・テンプレート名の検証、選んだテンプレートのコピー、生成された
|
|
16
16
|
`package.json` の書き換え(名前、`workspace:*` → 公開バージョン)、プロジェクトの
|
|
17
17
|
`pnpm-workspace.yaml` の書き出し、そして一度きりの `pnpm-lock.yaml` の解決。
|
|
18
18
|
|
|
19
19
|
**担わないもの。** 生成されるプロジェクトの中身 — ソース、設定、Dockerfile、
|
|
20
|
-
テスト — はテンプレートのものです(このパッケージではなく `templates
|
|
21
|
-
|
|
20
|
+
テスト — はテンプレートのものです(このパッケージではなく `templates/<name>` を
|
|
21
|
+
編集してください)。どのテンプレートがあり、それぞれ何のためにあるかは
|
|
22
|
+
[コンポジションテンプレートの ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md)
|
|
23
|
+
のものです。実行時の振る舞いは `@o3co/auth-provider-core` と、テンプレートが
|
|
22
24
|
依存するライブラリのものです。
|
|
23
25
|
|
|
24
26
|
**別パッケージである理由。** `bin` 付きで単独公開されるため、provider をインストール
|
|
25
27
|
せずに `npx` で実行できます。公開 tarball にはモノレポが含まれないので、このパッケージは
|
|
26
|
-
|
|
28
|
+
すべてのテンプレートのコピーと、それらが固定するライブラリのバージョンを自前で持ちます
|
|
27
29
|
([テンプレートの同梱方法](#テンプレートの同梱方法))。
|
|
28
30
|
|
|
29
31
|
## 使い方
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
|
-
npx @o3co/create-auth-provider <project-name> [--dir <dir-name>] [--no-lockfile]
|
|
34
|
+
npx @o3co/create-auth-provider <project-name> [--template <name>] [--dir <dir-name>] [--no-lockfile] [--no-mfa]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`--template` はコピーするテンプレートを指定します(デフォルトは `standalone`)。
|
|
38
|
+
テンプレートは [`templates/`](../templates) 配下で `package.json` を持つディレクトリ
|
|
39
|
+
(シンボリックリンクでも、ドットで始まる名前でもないもの)で、それ以外の名前は、
|
|
40
|
+
使えるテンプレートの一覧を示して拒否されます。各テンプレートが
|
|
41
|
+
何のためにあるかはそれぞれの README に、テンプレートの分け方 — 機能ごとではなく
|
|
42
|
+
コンポジションの形ごとに 1 つ — は
|
|
43
|
+
[コンポジションテンプレートの ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md) にあります。
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx @o3co/create-auth-provider my-auth-server --template standalone
|
|
33
47
|
```
|
|
34
48
|
|
|
35
49
|
`<project-name>` はスコープ付き npm 名 (`@scope/pkg`) とスコープなしの名前 (`pkg`) のどちらでも指定できます。
|
|
@@ -59,6 +73,20 @@ cd provider
|
|
|
59
73
|
|
|
60
74
|
`--no-lockfile` を付けると lockfile の生成(下記の手順 7)を省略します。
|
|
61
75
|
|
|
76
|
+
スキャフォールドは、すべてのパスワードログインに第二要素を求めます: テンプレートの
|
|
77
|
+
MFA スイッチ `mfaMode`(`MFA_MODE`)のデフォルトは `required` です。development では
|
|
78
|
+
ほかに何も要りません。それ以外では、MFA に要るもの(2 つのストアを Redis に、鍵、
|
|
79
|
+
SMTP リレー)を設定するか、`MFA_MODE=off` で MFA を無効にするまで、
|
|
80
|
+
プロジェクトの起動は拒否されます。MFA ページのデフォルトは `/mfa` で、プロジェクトが
|
|
81
|
+
そこでページを用意しなければ、すべてのパスワードログインはそこで止まります。
|
|
82
|
+
スイッチが何をインストールし、何を要するかはテンプレートの README にあります。
|
|
83
|
+
|
|
84
|
+
`--no-mfa` を付けると、代わりにスイッチをスキャフォールド上で off と書きます。
|
|
85
|
+
`config/application.conf` の末尾に `mfaMode = "off"` と
|
|
86
|
+
`mfaMode = ${?MFA_MODE}` をこの順に追記するので、後のテンプレートがデフォルトを
|
|
87
|
+
変えてもプロジェクトは off のままで、`MFA_MODE` を設定すれば作り直さずに MFA を
|
|
88
|
+
有効にできます。MFA パッケージは依存に残り、ほかには何も削除・変更しません。
|
|
89
|
+
|
|
62
90
|
生成されるプロジェクトは pnpm のプロジェクトです。`Dockerfile` は
|
|
63
91
|
`pnpm install --frozen-lockfile` でインストールし、ビルドの許可リストは
|
|
64
92
|
`pnpm-workspace.yaml` にあります。
|
|
@@ -67,7 +95,7 @@ CLI は最後のメッセージで次に `pnpm run debug` を実行するよう
|
|
|
67
95
|
スキャフォールドのデフォルトのままでは、これは起動しません: `.env` ファイルは
|
|
68
96
|
読まず(読むのは compose ファイルだけ)、シェルの環境変数から issuer
|
|
69
97
|
(`OAUTH_JWT_ISSUER`)、署名鍵のペア、セッションシークレット、ユーザーサービスの
|
|
70
|
-
2 つの URL(`
|
|
98
|
+
2 つの URL(`REPOSITORIES_USER_HTTP_AUTHENTICATE_URL`、`REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL`)、
|
|
71
99
|
そして `localhost:6379` の Redis を必要とします。コマンドは、プロジェクトに含まれる
|
|
72
100
|
テンプレートの README の[使い方](../templates/standalone/README.ja.md#使い方)にあります。
|
|
73
101
|
|
|
@@ -75,8 +103,8 @@ CLI は最後のメッセージで次に `pnpm run debug` を実行するよう
|
|
|
75
103
|
|
|
76
104
|
1. `<project-name>` を検証する([バリデーションルール](#バリデーションルール) 参照)。
|
|
77
105
|
2. 生成先ディレクトリ名を決定する: `--dir <value>` が指定されていればその値、そうでなければスコープ付き名のパッケージ部分、最終的には入力値そのもの。
|
|
78
|
-
3.
|
|
79
|
-
4.
|
|
106
|
+
3. `--template`(デフォルト `standalone`)が内包するテンプレートの名前であることを確かめ、生成先ディレクトリを `<cwd>/<dir-name>` として解決し、すでに存在する場合はエラーで終了する。
|
|
107
|
+
4. 指定したテンプレートを生成先ディレクトリにコピーし(`node_modules/` と `dist/` は除外)、`.gitignore` を復元する(npm は公開パッケージから `.gitignore` という名前のファイルを落とすため、tarball には `gitignore` として入っている)。`--no-mfa` のときは、その `config/application.conf` に MFA スイッチの行を追記する。
|
|
80
108
|
5. 生成されたディレクトリの `package.json` を書き換える:
|
|
81
109
|
- `name` を `<project-name>` そのままに設定する(スコープを保持)。
|
|
82
110
|
- `"private": true` は意図的に残す: スキャフォールドされた ID プロバイダーが誤って公開できてはならないため。本当に公開するつもりなら自分でこのフィールドを削除する。
|
|
@@ -100,12 +128,21 @@ lockfile をテンプレートに同梱することはできません: 手順 5
|
|
|
100
128
|
|
|
101
129
|
パッケージの `prebuild` と `prepack` スクリプトが
|
|
102
130
|
[`scripts/copy-templates.mjs`](scripts/copy-templates.mjs) を実行し、
|
|
103
|
-
|
|
104
|
-
`node_modules/` と `dist/`
|
|
131
|
+
すべてのテンプレートを `create-app/templates/<name>` にコピーし(git 管理外。
|
|
132
|
+
`node_modules/` と `dist/` は除外。コピー先は丸ごと作り直すので、リポジトリから
|
|
133
|
+
消したテンプレートは残らない)、`create-app/templates/versions.json` —
|
|
105
134
|
公開される `@o3co/auth-provider-*` 全パッケージの現在のバージョン — を書き出します。
|
|
106
135
|
tarball には両方が入り(`files: ["dist", "templates"]`)、`scaffold()` はそこから
|
|
107
136
|
読みます。したがってスキャフォールドされるのは、このパッケージをビルドした時点の
|
|
108
137
|
テンプレートで、同じビルド時点のライブラリバージョンに固定されます。
|
|
138
|
+
テンプレートとは何か — `templates/` 配下のディレクトリで、シンボリックリンクでも
|
|
139
|
+
ドットで始まる名前でもなく、`package.json` を持ち、小文字のケバブケースで名付けられた
|
|
140
|
+
もの — は [`scripts/templates.mjs`](scripts/templates.mjs) の 1 か所で定義され、
|
|
141
|
+
コピーと CI の全テンプレートのビルドの両方がそれを使います。スキャフォルダーの
|
|
142
|
+
`availableTemplates()` は同じ規則でコピーを読みます。
|
|
143
|
+
[`published-package.test.mts`](src/__tests__/published-package.test.mts) は
|
|
144
|
+
パッケージを pack し、tarball がリポジトリのテンプレートをすべて含み、それぞれが
|
|
145
|
+
そこからスキャフォールドできることを確かめます。
|
|
109
146
|
|
|
110
147
|
CI は [`scripts/check-versions-json.mjs`](scripts/check-versions-json.mjs) を
|
|
111
148
|
実行します。`packages/` 配下の公開パッケージが `copy-templates.mjs` のバージョン
|
|
@@ -124,15 +161,20 @@ CI は [`scripts/check-versions-json.mjs`](scripts/check-versions-json.mjs) を
|
|
|
124
161
|
|
|
125
162
|
`--dir <value>` はスコープなしのパターンと同じ制約です。
|
|
126
163
|
|
|
164
|
+
`--template <name>` は内包するテンプレートの名前と完全に一致する必要があります。パスは
|
|
165
|
+
テンプレート名になりません。テンプレート名は小文字のケバブケース
|
|
166
|
+
`^[a-z0-9]+(?:-[a-z0-9]+)*$`(英小文字と数字の並びを 1 つのハイフンでつなぐ)で、
|
|
167
|
+
それ以外の名前のテンプレートはビルドが拒否します。
|
|
168
|
+
|
|
127
169
|
## 既知の制約
|
|
128
170
|
|
|
129
|
-
-
|
|
171
|
+
- 内包されている各テンプレートの `README.md` / `README.ja.md` の見出しは上流の名前(たとえば `@o3co/auth-provider-standalone`)のままです。スコープ付きでプロジェクトを生成した場合、この見出しは `package.json` の名前と一致しません。必要に応じて手動で修正してください。
|
|
130
172
|
- テンプレートの README は、このリポジトリ内を相対パス(`../../docs/…`、`../../packages/…`)でリンクしています。これはモノレポ内では解決しますが、横に `docs/` も `packages/` もないスキャフォールド先のプロジェクトでは解決しません。GitHub 上で参照してください。
|
|
131
173
|
|
|
132
174
|
## 生成される構造
|
|
133
175
|
|
|
134
|
-
|
|
135
|
-
|
|
176
|
+
生成されるプロジェクトは、選んだテンプレート(たとえば
|
|
177
|
+
[`templates/standalone`](../templates/standalone))の完全なコピー(`node_modules/` と `dist/` を除く)に、`pnpm-workspace.yaml`(手順 6)と、
|
|
136
178
|
`--no-lockfile` を指定せず lockfile の手順が失敗しなかった場合は `pnpm-lock.yaml`(手順 7)を加えたものです。どの
|
|
137
179
|
ファイルがモジュール構成で、どれがホストプロセスで、スキャフォールドが何を
|
|
138
180
|
持つかは、テンプレートの README に記述されています。
|
|
@@ -142,12 +184,15 @@ CI は [`scripts/check-versions-json.mjs`](scripts/check-versions-json.mjs) を
|
|
|
142
184
|
モジュールは CLI を構成する関数を export しています。シグネチャは
|
|
143
185
|
[`src/index.mts`](src/index.mts) にあります。
|
|
144
186
|
|
|
145
|
-
- `scaffold(targetDir, projectName)` — 手順 4〜6
|
|
187
|
+
- `scaffold(targetDir, projectName, template?, options?)` — 手順 4〜6。`template`(デフォルトは `DEFAULT_TEMPLATE` = `"standalone"`)からコピーする。`options.noMfa` は `--no-mfa` にあたる。コピーできないときは何も書かずに `templateRefusal` のメッセージで例外を投げる。`workspace:*` 依存が `versions.json` に見つからない場合も例外を投げる。
|
|
188
|
+
- `availableTemplates(templatesRoot?)` — 内包するテンプレートの名前(ソート済み)。
|
|
189
|
+
- `templateRefusal(template, templates)` — `template` からスキャフォールドできない理由(1 つも内包されていない、またはそのどれでもない)。できるときは `undefined`。
|
|
146
190
|
- `generateLockfile(targetDir)` — 手順 7。例外を投げず、`{ ok: true, command }` か `{ ok: false, reason }` を返す。
|
|
147
|
-
- `main()` — CLI 本体。`process.argv`
|
|
191
|
+
- `main()` — CLI 本体。`process.argv` を読み、不正な引数、未知のテンプレート、既存のディレクトリに対しては非ゼロで終了する。
|
|
148
192
|
- `isValidProjectName(name)` / `isValidDirName(name)` — [バリデーションルール](#バリデーションルール)。
|
|
149
193
|
|
|
150
194
|
## 関連
|
|
151
195
|
|
|
152
|
-
- [`@o3co/auth-provider-standalone`](../templates/standalone)
|
|
196
|
+
- [`templates/`](../templates) — このツールが生成元とするテンプレート。[`@o3co/auth-provider-standalone`](../templates/standalone) がデフォルト
|
|
197
|
+
- [コンポジションテンプレートの ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md) — テンプレートをこう分ける理由
|
|
153
198
|
- [`@o3co/auth-provider-core`](../packages/core) — コアアプリケーションファクトリ
|
package/README.md
CHANGED
|
@@ -1,35 +1,49 @@
|
|
|
1
1
|
# @o3co/create-auth-provider
|
|
2
2
|
|
|
3
|
-
Last updated: 2026-
|
|
3
|
+
Last updated: 2026-10-03
|
|
4
4
|
|
|
5
|
-
CLI scaffolder for auth.provider. Generates a new
|
|
5
|
+
CLI scaffolder for auth.provider. Generates a new server project from one of the built-in templates.
|
|
6
6
|
|
|
7
7
|
## Responsibility
|
|
8
8
|
|
|
9
|
-
**Role.** The `npx` entry point that turns the in-repo
|
|
10
|
-
[`templates
|
|
11
|
-
project. It runs once, on the operator's machine; nothing in the generated
|
|
9
|
+
**Role.** The `npx` entry point that turns one of the in-repo templates under
|
|
10
|
+
[`templates/`](../templates) — each a deployable composition root — into a new,
|
|
11
|
+
independent project. It runs once, on the operator's machine; nothing in the generated
|
|
12
12
|
project imports it, and it imports none of the `packages/*` libraries.
|
|
13
13
|
|
|
14
|
-
**Owns.** Project-name and
|
|
15
|
-
rewriting the generated `package.json` (name, `workspace:*`
|
|
16
|
-
versions), writing the project's `pnpm-workspace.yaml`, and the
|
|
17
|
-
`pnpm-lock.yaml` resolution.
|
|
14
|
+
**Owns.** Project-name, directory and template validation, copying the
|
|
15
|
+
chosen template, rewriting the generated `package.json` (name, `workspace:*`
|
|
16
|
+
→ published versions), writing the project's `pnpm-workspace.yaml`, and the
|
|
17
|
+
one-time `pnpm-lock.yaml` resolution.
|
|
18
18
|
|
|
19
19
|
**Does not own.** The content of the generated project — source, config,
|
|
20
|
-
Dockerfile, tests — which is the template's (edit `templates
|
|
21
|
-
this package)
|
|
22
|
-
|
|
20
|
+
Dockerfile, tests — which is the template's (edit `templates/<name>`, not
|
|
21
|
+
this package); and which templates there are, and what each is for — the
|
|
22
|
+
[composition templates ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md).
|
|
23
|
+
Runtime behaviour belongs to `@o3co/auth-provider-core` and the libraries the
|
|
24
|
+
template depends on.
|
|
23
25
|
|
|
24
26
|
**Why a separate package.** It is published on its own with a `bin`, so it can
|
|
25
27
|
be run with `npx` without installing the provider. The monorepo is not in the
|
|
26
|
-
published tarball, so the package carries its own copy of
|
|
27
|
-
the library versions
|
|
28
|
+
published tarball, so the package carries its own copy of every template and
|
|
29
|
+
of the library versions they pin ([How the templates are bundled](#how-the-templates-are-bundled)).
|
|
28
30
|
|
|
29
31
|
## Usage
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
|
-
npx @o3co/create-auth-provider <project-name> [--dir <dir-name>] [--no-lockfile]
|
|
34
|
+
npx @o3co/create-auth-provider <project-name> [--template <name>] [--dir <dir-name>] [--no-lockfile] [--no-mfa]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`--template` names the template to copy, `standalone` by default. The
|
|
38
|
+
templates are the directories under [`templates/`](../templates) that hold a
|
|
39
|
+
`package.json` (not a symbolic link, not dot-named), and the CLI refuses any
|
|
40
|
+
other name, listing the ones it has.
|
|
41
|
+
What each template is for is in its own README; how the set is drawn — a
|
|
42
|
+
template per composition shape, not per feature — is in the
|
|
43
|
+
[composition templates ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md).
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx @o3co/create-auth-provider my-auth-server --template standalone
|
|
33
47
|
```
|
|
34
48
|
|
|
35
49
|
`<project-name>` may be either a scoped npm name (`@scope/pkg`) or an unscoped name (`pkg`).
|
|
@@ -59,6 +73,20 @@ cd provider
|
|
|
59
73
|
|
|
60
74
|
`--no-lockfile` skips the lockfile step (step 7 below).
|
|
61
75
|
|
|
76
|
+
The scaffold requires a second factor at every password login: the
|
|
77
|
+
template's MFA switch, `mfaMode` (`MFA_MODE`), defaults to `required`. In
|
|
78
|
+
development that needs nothing more; outside it, the project's boot is
|
|
79
|
+
refused until it sets what MFA needs (its two stores on Redis, a key, an SMTP
|
|
80
|
+
relay) or turns MFA off with `MFA_MODE=off`. The MFA page defaults to `/mfa`,
|
|
81
|
+
which the project must serve, or every password login stops there. What the
|
|
82
|
+
switch installs and needs is in the template's README.
|
|
83
|
+
|
|
84
|
+
`--no-mfa` writes the switch off in the scaffold instead:
|
|
85
|
+
it appends `mfaMode = "off"` and then `mfaMode = ${?MFA_MODE}` to
|
|
86
|
+
`config/application.conf`, so the project stays off whatever default a later
|
|
87
|
+
template ships, and `MFA_MODE` still turns MFA on without re-scaffolding. The
|
|
88
|
+
MFA package stays a dependency; nothing else is removed or changed.
|
|
89
|
+
|
|
62
90
|
The generated project is a pnpm project: its `Dockerfile` installs with
|
|
63
91
|
`pnpm install --frozen-lockfile`, and its build allowlist lives in
|
|
64
92
|
`pnpm-workspace.yaml`.
|
|
@@ -67,8 +95,8 @@ The CLI's closing message suggests `pnpm run debug` next. On the scaffold's
|
|
|
67
95
|
defaults alone that does not boot: it reads no `.env` file (only the compose
|
|
68
96
|
files do), and needs from the shell's environment an issuer
|
|
69
97
|
(`OAUTH_JWT_ISSUER`), a signing key pair, a session secret, the two URLs of
|
|
70
|
-
your user service (`
|
|
71
|
-
`
|
|
98
|
+
your user service (`REPOSITORIES_USER_HTTP_AUTHENTICATE_URL`,
|
|
99
|
+
`REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL`) and a Redis on `localhost:6379`. The
|
|
72
100
|
template's README, which the project carries, gives the commands under
|
|
73
101
|
[Usage](../templates/standalone/README.md#usage).
|
|
74
102
|
|
|
@@ -76,8 +104,8 @@ template's README, which the project carries, gives the commands under
|
|
|
76
104
|
|
|
77
105
|
1. Validates `<project-name>` (see [Validation Rules](#validation-rules)).
|
|
78
106
|
2. Derives the target directory name: `--dir <value>` if given, else the unscoped part of a scoped name, else the name itself.
|
|
79
|
-
3.
|
|
80
|
-
4. Copies the
|
|
107
|
+
3. Checks that `--template` (default `standalone`) names a bundled template, and resolves the target directory as `<cwd>/<dir-name>`, erroring if it already exists.
|
|
108
|
+
4. Copies the named template to the target directory, excluding `node_modules/` and `dist/`, and restores its `.gitignore` (the tarball carries it as `gitignore`, because npm drops a file named `.gitignore` from a published package). With `--no-mfa`, appends the MFA switch lines to its `config/application.conf`.
|
|
81
109
|
5. Rewrites `package.json` in the generated directory:
|
|
82
110
|
- Sets `name` to `<project-name>` verbatim (scope-preserving).
|
|
83
111
|
- Keeps `"private": true` on purpose: a scaffolded identity provider should not be publishable by accident. Remove the field yourself if you really intend to publish.
|
|
@@ -96,16 +124,25 @@ it is resolved once, here, against the rewritten `package.json`. **Commit it**
|
|
|
96
124
|
it is what makes `docker build` reproducible. If step 7 failed or was skipped,
|
|
97
125
|
run `pnpm install` in the project once and commit the result.
|
|
98
126
|
|
|
99
|
-
## How the
|
|
127
|
+
## How the templates are bundled
|
|
100
128
|
|
|
101
129
|
The package's `prebuild` and `prepack` scripts run
|
|
102
130
|
[`scripts/copy-templates.mjs`](scripts/copy-templates.mjs), which copies
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
the
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
131
|
+
every template into `create-app/templates/<name>` (git-ignored; `node_modules/`
|
|
132
|
+
and `dist/` excluded; the destination is rebuilt whole, so a template removed
|
|
133
|
+
from the repository does not linger) and writes `create-app/templates/versions.json`, the current version
|
|
134
|
+
of every published `@o3co/auth-provider-*` package. The tarball ships both
|
|
135
|
+
(`files: ["dist", "templates"]`), and `scaffold()` reads them from there. A
|
|
136
|
+
scaffold is therefore the template as it was when this package was built,
|
|
137
|
+
pinned to the library versions of that same build.
|
|
138
|
+
What a template is — a directory under `templates/`, not a symbolic link and
|
|
139
|
+
not dot-named, holding a `package.json`, named in lowercase kebab-case — is
|
|
140
|
+
defined once, in [`scripts/templates.mjs`](scripts/templates.mjs), which the
|
|
141
|
+
copy and CI's build of every template both use; the scaffolder's
|
|
142
|
+
`availableTemplates()` reads the copy by the same rule.
|
|
143
|
+
[`published-package.test.mts`](src/__tests__/published-package.test.mts)
|
|
144
|
+
packs the package and holds the tarball to the repository: it must ship every
|
|
145
|
+
template, and each must scaffold from it.
|
|
109
146
|
|
|
110
147
|
CI runs [`scripts/check-versions-json.mjs`](scripts/check-versions-json.mjs),
|
|
111
148
|
which fails when a published package under `packages/` is missing from
|
|
@@ -124,14 +161,19 @@ Both forms must be non-empty, not `.` or `..`, and ≤ 214 characters.
|
|
|
124
161
|
|
|
125
162
|
`--dir <value>` must match the unscoped pattern above (same constraints).
|
|
126
163
|
|
|
164
|
+
`--template <name>` must be the name of a bundled template, exactly; a path is
|
|
165
|
+
never one. A template's name is lowercase kebab-case,
|
|
166
|
+
`^[a-z0-9]+(?:-[a-z0-9]+)*$` (lowercase letters and digits, in parts joined by
|
|
167
|
+
single hyphens); the build refuses a template named otherwise.
|
|
168
|
+
|
|
127
169
|
## Known Limitations
|
|
128
170
|
|
|
129
|
-
-
|
|
171
|
+
- Each bundled template's `README.md` / `README.ja.md` carry its upstream title, such as `@o3co/auth-provider-standalone`. When generating a scoped project, that title will not match your `package.json` name; edit it manually if it matters for your use case.
|
|
130
172
|
- The template's README links into this repository with relative paths (`../../docs/…`, `../../packages/…`). Those resolve in the monorepo and not in a scaffolded project, where there is no `docs/` or `packages/` beside it; read them on GitHub instead.
|
|
131
173
|
|
|
132
174
|
## Generated Structure
|
|
133
175
|
|
|
134
|
-
The generated project is a complete copy of
|
|
176
|
+
The generated project is a complete copy of the chosen template, such as
|
|
135
177
|
[`templates/standalone`](../templates/standalone) (without `node_modules/` and
|
|
136
178
|
`dist/`) plus `pnpm-workspace.yaml` (step 6) and, unless `--no-lockfile` was
|
|
137
179
|
given or the lockfile step failed, `pnpm-lock.yaml` (step 7). The template's README describes its layout — which file is
|
|
@@ -142,12 +184,15 @@ the composition, which is the host process, and what the scaffold owns.
|
|
|
142
184
|
The module exports the functions the CLI is built from; their signatures are
|
|
143
185
|
in [`src/index.mts`](src/index.mts).
|
|
144
186
|
|
|
145
|
-
- `scaffold(targetDir, projectName)` — steps 4–6. Throws
|
|
187
|
+
- `scaffold(targetDir, projectName, template?, options?)` — steps 4–6, from `template` (default `DEFAULT_TEMPLATE`, `"standalone"`); `options.noMfa` is `--no-mfa`. Throws, before writing anything, with `templateRefusal`'s message; and throws if a `workspace:*` dependency has no entry in `versions.json`.
|
|
188
|
+
- `availableTemplates(templatesRoot?)` — the bundled templates' names, sorted.
|
|
189
|
+
- `templateRefusal(template, templates)` — why `template` cannot be scaffolded (none bundled, or not one of them), or `undefined`.
|
|
146
190
|
- `generateLockfile(targetDir)` — step 7. Returns `{ ok: true, command }` or `{ ok: false, reason }` rather than throwing.
|
|
147
|
-
- `main()` — the CLI: reads `process.argv`, and exits non-zero on an invalid argument or an existing directory.
|
|
191
|
+
- `main()` — the CLI: reads `process.argv`, and exits non-zero on an invalid argument, an unknown template or an existing directory.
|
|
148
192
|
- `isValidProjectName(name)` / `isValidDirName(name)` — the [Validation Rules](#validation-rules).
|
|
149
193
|
|
|
150
194
|
## See Also
|
|
151
195
|
|
|
152
|
-
- [`@o3co/auth-provider-standalone`](../templates/standalone)
|
|
196
|
+
- [`templates/`](../templates) — The templates this tool generates from; [`@o3co/auth-provider-standalone`](../templates/standalone) is the default
|
|
197
|
+
- [Composition templates ADR](../packages/core/docs/adr/2026-09-29-composition-templates.md) — Why the templates are split as they are
|
|
153
198
|
- [`@o3co/auth-provider-core`](../packages/core) — Core application factory
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
|
+
/** The template a scaffold is made from when none is named. */
|
|
2
|
+
export declare const DEFAULT_TEMPLATE = "standalone";
|
|
3
|
+
/**
|
|
4
|
+
* The templates under `templatesRoot`: every directory — not a symbolic link,
|
|
5
|
+
* not dot-named — holding a `package.json`, sorted; none when the directory is
|
|
6
|
+
* missing. This is the rule `scripts/templates.mjs` copies templates by, read
|
|
7
|
+
* here from the copy, where `versions.json` sits beside them. A name is only
|
|
8
|
+
* ever looked up in this list, so nothing outside the templates directory can
|
|
9
|
+
* be named as a template.
|
|
10
|
+
*/
|
|
11
|
+
export declare const availableTemplates: (templatesRoot?: string) => string[];
|
|
12
|
+
/**
|
|
13
|
+
* Why `template` cannot be scaffolded from `templates`, or `undefined` when it
|
|
14
|
+
* can: none is bundled (a checkout that never ran the prebuild script), or it
|
|
15
|
+
* is not one of them.
|
|
16
|
+
*/
|
|
17
|
+
export declare const templateRefusal: (template: string, templates: readonly string[]) => string | undefined;
|
|
1
18
|
export declare const isValidProjectName: (name: string) => boolean;
|
|
2
19
|
export declare const isValidDirName: (name: string) => boolean;
|
|
3
|
-
|
|
20
|
+
/** What `scaffold()` changes in the copy beyond the name and the versions. */
|
|
21
|
+
export interface ScaffoldOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Write the template's MFA switch off (`MFA_OFF_LINES`), so the scaffold
|
|
24
|
+
* stays off whatever default a later template ships; `MFA_MODE` still
|
|
25
|
+
* turns MFA on.
|
|
26
|
+
*/
|
|
27
|
+
readonly noMfa?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const scaffold: (targetDir: string, projectName: string, template?: string, options?: ScaffoldOptions) => void;
|
|
4
30
|
/** Outcome of the scaffold-time lockfile generation. */
|
|
5
31
|
export type LockfileResult = {
|
|
6
32
|
readonly ok: true;
|
|
@@ -10,15 +36,12 @@ export type LockfileResult = {
|
|
|
10
36
|
readonly reason: string;
|
|
11
37
|
};
|
|
12
38
|
/**
|
|
13
|
-
* Resolve the scaffolded project's dependency graph into `pnpm-lock.yaml
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* resolved once, here, against the rewritten `package.json`. Best-effort by
|
|
20
|
-
* design — it needs a package manager and a reachable registry — so failure
|
|
21
|
-
* is a result, not a throw.
|
|
39
|
+
* Resolve the scaffolded project's dependency graph into `pnpm-lock.yaml`,
|
|
40
|
+
* which the template's `pnpm install --frozen-lockfile` build needs. The
|
|
41
|
+
* lockfile cannot ship with the template: the dependency set it pins exists
|
|
42
|
+
* only after `scaffold` has replaced every `workspace:*`. Best-effort (it needs
|
|
43
|
+
* a package manager and a reachable registry), so failure is a result, not a
|
|
44
|
+
* throw.
|
|
22
45
|
*/
|
|
23
46
|
export declare const generateLockfile: (targetDir: string) => LockfileResult;
|
|
24
47
|
export declare const main: () => void;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAgCA,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,gBAAe,MAAuB,KAAG,MAAM,EAWjF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC3B,UAAU,MAAM,EAChB,WAAW,SAAS,MAAM,EAAE,KAC1B,MAAM,GAAG,SAQX,CAAC;AAcF,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,OAIjD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAI7C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CACzB;AAeD,eAAO,MAAM,QAAQ,GACpB,WAAW,MAAM,EACjB,aAAa,MAAM,EACnB,WAAU,MAAyB,EACnC,UAAS,eAAoB,KAC3B,IAwEF,CAAC;AAEF,wDAAwD;AACxD,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBnD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,WAAW,MAAM,KAAG,cA6BpD,CAAC;AA4EF,eAAO,MAAM,IAAI,QAAO,IA6EvB,CAAC"}
|