From dc85a1f9baf4a4cdd2e43198305acf1452587627 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:47:26 +0200
Subject: [PATCH 01/32] refactor: leave OAuth auth UI to Studio
---
src/generators/create-category-app.ts | 78 +--------------------------
1 file changed, 2 insertions(+), 76 deletions(-)
diff --git a/src/generators/create-category-app.ts b/src/generators/create-category-app.ts
index 2a110f9..7a13bf9 100644
--- a/src/generators/create-category-app.ts
+++ b/src/generators/create-category-app.ts
@@ -1,26 +1,10 @@
-import {
- type AppCategory,
- type AppManifest,
- resolveAuthFlow,
- type ScreenSpec,
- type ThemeConfig,
-} from '@ankhorage/contracts';
+import type { AppCategory, AppManifest, ThemeConfig } from '@ankhorage/contracts';
import { mergeAppManifest } from '../internal/merge';
import type { AppManifestOverrides } from '../internal/overrides';
import { CATEGORY_PRESETS } from '../presets/category-presets';
-import { createScreen } from '../templates/shared/screen';
-import {
- createScreenRoot,
- createSection,
- createZoraNode,
-} from '../templates/shared/zora-node-helpers';
import { createStarterTemplate, type TemplateKind } from '../templates/starter';
-type ProviderConfig = NonNullable<
- NonNullable['oauth']
->['providers'][number];
-
function resolveThemeModeValue(
overrides: AppManifestOverrides | undefined,
selector: (theme: ThemeConfig) => TValue,
@@ -80,69 +64,11 @@ function createManifestFromTemplate(
return TEMPLATE_FACTORIES[template](category, overrides);
}
-function addProviderEntryScreen(manifest: AppManifest): AppManifest {
- const providers = manifest.infra.auth?.oauth?.providers.filter(
- (provider) => provider.enabled !== false,
- );
-
- if (
- manifest.infra.auth?.oauth?.enabled !== true ||
- providers === undefined ||
- providers.length === 0
- ) {
- return manifest;
- }
-
- const screenId = resolveAuthFlow(manifest.infra.auth.flow).signInRoute;
-
- if (manifest.screens[screenId] !== undefined) {
- return manifest;
- }
-
- return {
- ...manifest,
- screens: {
- ...manifest.screens,
- [screenId]: createProviderEntryScreen(screenId, providers),
- },
- };
-}
-
-function createProviderEntryScreen(
- screenId: string,
- providers: readonly ProviderConfig[],
-): ScreenSpec {
- return createScreen({
- id: screenId,
- name: 'Provider entry',
- title: 'Provider entry',
- description: 'Choose a provider.',
- root: createScreenRoot('provider-entry-screen', { width: 'default' }, [
- createZoraNode('provider-entry-header', 'SectionHeader', {
- eyebrow: 'Account',
- title: 'Continue',
- description: 'Choose a configured provider.',
- }),
- createSection('provider-entry-section', { title: 'Providers' }, [
- createZoraNode('provider-entry-list', 'OAuthProviderList', {
- providers: providers.map((provider) => ({
- id: provider.id,
- ...(provider.label ? { label: provider.label } : {}),
- ...(provider.icon ? { icon: provider.icon } : {}),
- })),
- layout: 'stack',
- fullWidth: true,
- }),
- ]),
- ]),
- });
-}
-
export function createCategoryAppManifest(
category: AppCategory,
template: TemplateKind = 'starter',
overrides?: AppManifestOverrides,
): AppManifest {
const manifest = createManifestFromTemplate(category, template, overrides);
- return addProviderEntryScreen(mergeAppManifest(manifest, overrides));
+ return mergeAppManifest(manifest, overrides);
}
From 22c38ed85892c79bcce61ca81fb11e9ed185bcd8 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:47:44 +0200
Subject: [PATCH 02/32] feat: add canonical OAuth manifest fixtures
---
src/fixtures/oauth.ts | 107 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 src/fixtures/oauth.ts
diff --git a/src/fixtures/oauth.ts b/src/fixtures/oauth.ts
new file mode 100644
index 0000000..e36e2cf
--- /dev/null
+++ b/src/fixtures/oauth.ts
@@ -0,0 +1,107 @@
+import type { AppCategory, AppManifest } from '@ankhorage/contracts';
+
+import { createCategoryAppManifest } from '../generators/create-category-app';
+import { mergeAppManifest } from '../internal/merge';
+import type { AppManifestOverrides } from '../internal/overrides';
+import type { TemplateKind } from '../templates/starter';
+
+export const OAUTH_CALLBACK_ROUTE = 'auth/callback';
+export const OAUTH_FIXTURE_IDS = ['google', 'apple', 'google-apple'] as const;
+
+export type OAuthFixtureId = (typeof OAUTH_FIXTURE_IDS)[number];
+
+type OAuthConfig = NonNullable['oauth']>;
+type OAuthProviderConfig = OAuthConfig['providers'][number];
+
+export interface OAuthFixtureDefinition {
+ readonly id: OAuthFixtureId;
+ readonly label: string;
+ readonly description: string;
+ readonly oauth: OAuthConfig;
+}
+
+const GOOGLE_PROVIDER: OAuthProviderConfig = {
+ id: 'google',
+ label: 'Continue with Google',
+ enabled: true,
+ credentialsRef: 'auth/oauth/google',
+ scopes: ['openid', 'email', 'profile'],
+ queryParams: {
+ prompt: 'select_account',
+ },
+ icon: {
+ provider: 'FontAwesome',
+ name: 'google',
+ },
+};
+
+const APPLE_PROVIDER: OAuthProviderConfig = {
+ id: 'apple',
+ label: 'Continue with Apple',
+ enabled: true,
+ credentialsRef: 'auth/oauth/apple',
+ scopes: ['name', 'email'],
+ icon: {
+ provider: 'FontAwesome',
+ name: 'apple',
+ },
+};
+
+const FIXTURES: Record = {
+ google: {
+ id: 'google',
+ label: 'Google OAuth',
+ description: 'Canonical Google authorization-code-with-PKCE fixture.',
+ oauth: createOAuthConfig([GOOGLE_PROVIDER]),
+ },
+ apple: {
+ id: 'apple',
+ label: 'Apple OAuth',
+ description: 'Canonical Apple authorization-code-with-PKCE fixture.',
+ oauth: createOAuthConfig([APPLE_PROVIDER]),
+ },
+ 'google-apple': {
+ id: 'google-apple',
+ label: 'Google and Apple OAuth',
+ description: 'Canonical combined Google and Apple authorization-code-with-PKCE fixture.',
+ oauth: createOAuthConfig([GOOGLE_PROVIDER, APPLE_PROVIDER]),
+ },
+};
+
+function createOAuthConfig(providers: readonly OAuthProviderConfig[]): OAuthConfig {
+ return {
+ enabled: true,
+ callbackRoute: OAUTH_CALLBACK_ROUTE,
+ providers: structuredClone(providers),
+ };
+}
+
+export function listOAuthFixtures(): OAuthFixtureDefinition[] {
+ return OAUTH_FIXTURE_IDS.map((id) => structuredClone(FIXTURES[id]));
+}
+
+export function resolveOAuthFixture(id: OAuthFixtureId): OAuthFixtureDefinition {
+ return structuredClone(FIXTURES[id]);
+}
+
+export function createOAuthFixtureManifest(args: {
+ category: AppCategory;
+ fixture: OAuthFixtureId;
+ template?: TemplateKind;
+ overrides?: AppManifestOverrides;
+}): AppManifest {
+ const manifest = createCategoryAppManifest(
+ args.category,
+ args.template ?? 'starter',
+ args.overrides,
+ );
+ const fixture = resolveOAuthFixture(args.fixture);
+
+ return mergeAppManifest(manifest, {
+ infra: {
+ auth: {
+ oauth: fixture.oauth,
+ },
+ },
+ });
+}
From b7d99f79746de37e3a79c2d14e718e7011ddca1b Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:48:02 +0200
Subject: [PATCH 03/32] feat: export OAuth fixture API
---
src/index.ts | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/index.ts b/src/index.ts
index 2268c0c..ada16e1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,12 @@
+export {
+ createOAuthFixtureManifest,
+ listOAuthFixtures,
+ OAUTH_CALLBACK_ROUTE,
+ OAUTH_FIXTURE_IDS,
+ type OAuthFixtureDefinition,
+ type OAuthFixtureId,
+ resolveOAuthFixture,
+} from './fixtures/oauth';
export { createCategoryAppManifest } from './generators/create-category-app';
export { CATEGORY_PRESETS, type CategoryPreset } from './presets/category-presets';
export {
From 064d9a76ddf8078c5b0e4c37b7ea201bcd5de375 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:48:29 +0200
Subject: [PATCH 04/32] test: cover canonical OAuth fixtures
---
test/oauth-auth-templates.test.ts | 177 +++++++++++++++---------------
1 file changed, 90 insertions(+), 87 deletions(-)
diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts
index 9d6c967..08320c3 100644
--- a/test/oauth-auth-templates.test.ts
+++ b/test/oauth-auth-templates.test.ts
@@ -1,108 +1,111 @@
-import type { AppManifest, UiNode } from '@ankhorage/contracts';
-import { resolveAuthFlow } from '@ankhorage/contracts/auth';
+import { APP_CATEGORIES, resolveAuthFlow } from '@ankhorage/contracts';
import { describe, expect, test } from 'bun:test';
-import { createCategoryAppManifest } from '../src/index';
+import {
+ createCategoryAppManifest,
+ createOAuthFixtureManifest,
+ listOAuthFixtures,
+ OAUTH_CALLBACK_ROUTE,
+ OAUTH_FIXTURE_IDS,
+ resolveOAuthFixture,
+} from '../src/index';
-function collectNodes(node: UiNode): UiNode[] {
- return [node, ...(node.children?.flatMap(collectNodes) ?? [])];
-}
+const SECRET_SENTINEL = 'sentinel-phase3-template-secret-do-not-leak';
-function createOauthManifest() {
- return createCategoryAppManifest('developer_tools', 'starter', {
- infra: {
- auth: {
- oauth: {
- enabled: true,
- callbackRoute: '/auth/callback',
- providers: [
- {
- id: 'google',
- label: 'Google',
- enabled: true,
- icon: { provider: 'FontAwesome', name: 'google' },
- },
- {
- id: 'github',
- label: 'GitHub',
- enabled: false,
- icon: { provider: 'FontAwesome', name: 'github' },
- },
- {
- id: 'custom-sso',
- label: 'Custom SSO',
- enabled: true,
- },
- ],
- },
- },
- },
- });
+function serialize(value: unknown): string {
+ return JSON.stringify(value);
}
-describe('OAuth auth template generation', () => {
- test('adds an OAuth provider entry screen outside navigation when enabled', () => {
- const manifest = createOauthManifest();
- const { signInRoute } = resolveAuthFlow(manifest.infra.auth?.flow);
- const screen = manifest.screens[signInRoute];
-
- expect(screen).toBeDefined();
- expect(manifest.navigator.routes.map((route) => route.name)).not.toContain(signInRoute);
-
- const nodes = screen ? collectNodes(screen.root) : [];
- const providerList = nodes.find((node) => node.type === 'OAuthProviderList');
-
- expect(providerList?.props).toEqual({
- providers: [
- {
- id: 'google',
- label: 'Google',
- icon: { provider: 'FontAwesome', name: 'google' },
- },
- {
- id: 'custom-sso',
- label: 'Custom SSO',
- },
- ],
- layout: 'stack',
- fullWidth: true,
- });
- });
-
- test('does not add an OAuth provider entry screen when OAuth is disabled', () => {
+describe('canonical OAuth template fixtures', () => {
+ test('does not create template-owned OAuth auth screens', () => {
const manifest = createCategoryAppManifest('developer_tools', 'starter', {
- infra: {
- auth: {
- oauth: {
- enabled: false,
- callbackRoute: '/auth/callback',
- providers: [{ id: 'google', label: 'Google' }],
- },
- },
- },
- });
-
- const { signInRoute } = resolveAuthFlow(manifest.infra.auth?.flow);
- expect(manifest.screens[signInRoute]).toBeUndefined();
- });
-
- test('does not add an OAuth provider entry screen when all providers are disabled', () => {
- const manifest: AppManifest = createCategoryAppManifest('developer_tools', 'starter', {
infra: {
auth: {
oauth: {
enabled: true,
- callbackRoute: '/auth/callback',
+ callbackRoute: OAUTH_CALLBACK_ROUTE,
providers: [
- { id: 'google', label: 'Google', enabled: false },
- { id: 'github', label: 'GitHub', enabled: false },
+ {
+ id: 'google',
+ enabled: true,
+ credentialsRef: 'auth/oauth/google',
+ },
],
},
},
},
});
-
const { signInRoute } = resolveAuthFlow(manifest.infra.auth?.flow);
+
expect(manifest.screens[signInRoute]).toBeUndefined();
+ expect(manifest.navigator.routes.map((route) => route.name)).not.toContain(signInRoute);
+ expect(serialize(manifest)).not.toContain('OAuthProviderList');
+ });
+
+ test('publishes deterministic Google, Apple, and combined fixtures', () => {
+ expect(OAUTH_FIXTURE_IDS).toEqual(['google', 'apple', 'google-apple']);
+ expect(listOAuthFixtures().map((fixture) => fixture.id)).toEqual(OAUTH_FIXTURE_IDS);
+ expect(resolveOAuthFixture('google').oauth.providers.map((provider) => provider.id)).toEqual([
+ 'google',
+ ]);
+ expect(resolveOAuthFixture('apple').oauth.providers.map((provider) => provider.id)).toEqual([
+ 'apple',
+ ]);
+ expect(
+ resolveOAuthFixture('google-apple').oauth.providers.map((provider) => provider.id),
+ ).toEqual(['google', 'apple']);
+ });
+
+ test('uses one canonical callback and logical credential references only', () => {
+ for (const fixture of listOAuthFixtures()) {
+ expect(fixture.oauth.enabled).toBe(true);
+ expect(fixture.oauth.callbackRoute).toBe('auth/callback');
+ expect(fixture.oauth.callbackRoute).not.toStartWith('/');
+ expect(fixture.oauth.providers.length).toBeGreaterThan(0);
+
+ for (const provider of fixture.oauth.providers) {
+ expect(['google', 'apple']).toContain(provider.id);
+ expect(provider.enabled).toBe(true);
+ expect(provider.credentialsRef).toBe(`auth/oauth/${provider.id}`);
+ expect(provider.label).toBe(`Continue with ${provider.id === 'google' ? 'Google' : 'Apple'}`);
+ }
+
+ const serialized = serialize(fixture);
+ expect(serialized).not.toContain(SECRET_SENTINEL);
+ expect(serialized).not.toContain('clientSecret');
+ expect(serialized).not.toContain('privateKey');
+ expect(serialized).not.toContain('serviceRoleKey');
+ expect(serialized).not.toContain('accessToken');
+ expect(serialized).not.toContain('refreshToken');
+ }
+ });
+
+ test('creates OAuth fixture manifests without changing canonical auth flow', () => {
+ for (const category of APP_CATEGORIES) {
+ const manifest = createOAuthFixtureManifest({
+ category,
+ fixture: 'google-apple',
+ });
+ const flow = resolveAuthFlow(manifest.infra.auth?.flow);
+
+ expect(flow.signInRoute).toBe('sign-in');
+ expect(flow.signUpRoute).toBe('sign-up');
+ expect(flow.signOutRoute).toBe('sign-out');
+ expect(flow.postSignInRoute).toBe('/');
+ expect(manifest.infra.auth?.oauth?.callbackRoute).toBe(OAUTH_CALLBACK_ROUTE);
+ expect(manifest.infra.auth?.oauth?.providers.map((provider) => provider.id)).toEqual([
+ 'google',
+ 'apple',
+ ]);
+ expect(serialize(manifest)).not.toContain('OAuthProviderList');
+ }
+ });
+
+ test('returns isolated fixture definitions', () => {
+ const fixture = resolveOAuthFixture('google');
+ fixture.oauth.providers[0]!.label = SECRET_SENTINEL;
+
+ expect(resolveOAuthFixture('google').oauth.providers[0]?.label).toBe('Continue with Google');
+ expect(serialize(listOAuthFixtures())).not.toContain(SECRET_SENTINEL);
});
});
From af1d8de96cd41a1bc575f4271b3ac8aa520d26e9 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:48:49 +0200
Subject: [PATCH 05/32] test: use canonical OAuth callback route
---
test/secret-store-default.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/secret-store-default.test.ts b/test/secret-store-default.test.ts
index 45087af..99c6e69 100644
--- a/test/secret-store-default.test.ts
+++ b/test/secret-store-default.test.ts
@@ -22,7 +22,7 @@ describe('canonical secret-store template default', () => {
auth: {
oauth: {
enabled: true,
- callbackRoute: '/auth/callback',
+ callbackRoute: 'auth/callback',
providers: [
{
id: 'google',
From f7f750215789e5e774cfad87e09fcee343ca9100 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:49:14 +0200
Subject: [PATCH 06/32] chore: consume Contracts 3
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 4d2a39a..02b49b0 100644
--- a/package.json
+++ b/package.json
@@ -74,7 +74,7 @@
"version-packages": "changeset version"
},
"dependencies": {
- "@ankhorage/contracts": "^2.1.0",
+ "@ankhorage/contracts": "^3.0.0",
"@ankhorage/zora": "^2.8.0"
},
"devDependencies": {
From df27b77e46220696f10ba9477fcf1d15dc78183d Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:52:13 +0200
Subject: [PATCH 07/32] chore: add OAuth fixtures changeset
---
.changeset/canonical-oauth-fixtures.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .changeset/canonical-oauth-fixtures.md
diff --git a/.changeset/canonical-oauth-fixtures.md b/.changeset/canonical-oauth-fixtures.md
new file mode 100644
index 0000000..8382bee
--- /dev/null
+++ b/.changeset/canonical-oauth-fixtures.md
@@ -0,0 +1,5 @@
+---
+'@ankhorage/templates': minor
+---
+
+Add canonical Google, Apple, and combined OAuth manifest fixtures, and remove template-owned OAuth provider screen generation so Studio remains the single auth UI/runtime owner.
From fe93cfff8ec7895e454e034b9277d2890aa401c0 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:55:37 +0200
Subject: [PATCH 08/32] chore: refresh Phase 3 lockfile
---
.github/workflows/refresh-phase3-lock.yml | 42 +++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 .github/workflows/refresh-phase3-lock.yml
diff --git a/.github/workflows/refresh-phase3-lock.yml b/.github/workflows/refresh-phase3-lock.yml
new file mode 100644
index 0000000..5bde762
--- /dev/null
+++ b/.github/workflows/refresh-phase3-lock.yml
@@ -0,0 +1,42 @@
+name: Refresh Phase 3 lockfile
+
+on:
+ push:
+ branches:
+ - phase3/canonical-oauth-fixtures
+
+permissions:
+ contents: write
+
+jobs:
+ refresh-lockfile:
+ if: github.actor != 'github-actions[bot]'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v4
+ with:
+ ref: phase3/canonical-oauth-fixtures
+ fetch-depth: 0
+
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: '1.3.13'
+
+ - name: Refresh lockfile
+ run: bun install
+
+ - name: Commit lockfile
+ run: |
+ if git diff --quiet -- bun.lock; then
+ echo "Lockfile is already current."
+ exit 0
+ fi
+
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add bun.lock
+ git commit -m "chore: refresh lockfile"
+ git push
From 2f0a1de48ea04b30ae2d95c117ff9808380fa013 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 12 Jul 2026 08:55:50 +0000
Subject: [PATCH 09/32] chore: refresh lockfile
---
bun.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bun.lock b/bun.lock
index 38eab25..02a3a7b 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,7 +5,7 @@
"": {
"name": "@ankhorage/templates",
"dependencies": {
- "@ankhorage/contracts": "^2.1.0",
+ "@ankhorage/contracts": "^3.0.0",
"@ankhorage/zora": "^2.8.0",
},
"devDependencies": {
@@ -25,7 +25,7 @@
"@ankhorage/color-theory": ["@ankhorage/color-theory@0.0.7", "", { "dependencies": { "culori": "^4.0.2" } }, "sha512-fcdJZMmhfbvc9Yhz5vjTolmWYAaCsUaUOq4/P6YDZLHhXer8Mv8y0LaOhWgaXcwq48nrxILGUMOxOl48tRhTmA=="],
- "@ankhorage/contracts": ["@ankhorage/contracts@2.1.0", "", { "dependencies": { "@ankhorage/color-theory": "^0.0.7" } }, "sha512-QGG0atpGDe9+BUWzWvV83Kj309TBOK76yBRbWOoQli8g0LY8QLb7Z4UquD+qVhtWJTp3Y1jHUTEttQ0WjdhY/Q=="],
+ "@ankhorage/contracts": ["@ankhorage/contracts@3.0.0", "", { "dependencies": { "@ankhorage/color-theory": "^0.0.7" } }, "sha512-IXBdPehcgJpDjl/0QXHunl7AsgkTAXoC89jBiQWE+tanp8SBdgVFxWMm9A1MtbU3Rr1UU6U81GjhASM2OhGVUw=="],
"@ankhorage/devtools": ["@ankhorage/devtools@1.0.6", "", { "dependencies": { "@eslint/js": "^10.0.1", "eslint": "^10.2.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-unused-imports": "^4.4.1", "knip": "^6.12.2", "prettier": "^3.8.1", "typescript-eslint": "^8.24.0" }, "bin": { "ankhorage-eslint": "dist/eslint-cli.js", "ankhorage-knip": "dist/knip-cli.js", "ankhorage-prettier": "dist/prettier-cli.js" } }, "sha512-QXvpJ3uvr3xcl/smjv0yMimtGRCt/dPs0lVdHYMAXg06u1HsZmoKhRyxdFX8OXcCv9RnfPNheUkjAbOrs0eeaQ=="],
From 337d93c2ddce29322e5414c6fc54feab2ca5cb54 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 10:56:41 +0200
Subject: [PATCH 10/32] chore: remove lockfile refresh workflow
---
.github/workflows/refresh-phase3-lock.yml | 42 -----------------------
1 file changed, 42 deletions(-)
delete mode 100644 .github/workflows/refresh-phase3-lock.yml
diff --git a/.github/workflows/refresh-phase3-lock.yml b/.github/workflows/refresh-phase3-lock.yml
deleted file mode 100644
index 5bde762..0000000
--- a/.github/workflows/refresh-phase3-lock.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: Refresh Phase 3 lockfile
-
-on:
- push:
- branches:
- - phase3/canonical-oauth-fixtures
-
-permissions:
- contents: write
-
-jobs:
- refresh-lockfile:
- if: github.actor != 'github-actions[bot]'
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout branch
- uses: actions/checkout@v4
- with:
- ref: phase3/canonical-oauth-fixtures
- fetch-depth: 0
-
- - name: Setup Bun
- uses: oven-sh/setup-bun@v2
- with:
- bun-version: '1.3.13'
-
- - name: Refresh lockfile
- run: bun install
-
- - name: Commit lockfile
- run: |
- if git diff --quiet -- bun.lock; then
- echo "Lockfile is already current."
- exit 0
- fi
-
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add bun.lock
- git commit -m "chore: refresh lockfile"
- git push
From 3d088b79732f86a0531c5b49d40460f5d2a5f541 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:00:22 +0200
Subject: [PATCH 11/32] fix: materialize mutable OAuth provider arrays
---
src/fixtures/oauth.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fixtures/oauth.ts b/src/fixtures/oauth.ts
index e36e2cf..0bad1b0 100644
--- a/src/fixtures/oauth.ts
+++ b/src/fixtures/oauth.ts
@@ -72,7 +72,7 @@ function createOAuthConfig(providers: readonly OAuthProviderConfig[]): OAuthConf
return {
enabled: true,
callbackRoute: OAUTH_CALLBACK_ROUTE,
- providers: structuredClone(providers),
+ providers: providers.map((provider) => structuredClone(provider)),
};
}
From 7d109b14cbbab1d1778b79ee18958b20a51b58dc Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:01:17 +0200
Subject: [PATCH 12/32] chore: apply repository formatting
---
.github/workflows/format-phase3-fixtures.yml | 48 ++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 .github/workflows/format-phase3-fixtures.yml
diff --git a/.github/workflows/format-phase3-fixtures.yml b/.github/workflows/format-phase3-fixtures.yml
new file mode 100644
index 0000000..959fa10
--- /dev/null
+++ b/.github/workflows/format-phase3-fixtures.yml
@@ -0,0 +1,48 @@
+name: Format Phase 3 OAuth fixtures
+
+on:
+ push:
+ branches:
+ - phase3/canonical-oauth-fixtures
+
+permissions:
+ contents: write
+
+jobs:
+ format:
+ if: github.actor != 'github-actions[bot]'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v4
+ with:
+ ref: phase3/canonical-oauth-fixtures
+ fetch-depth: 0
+
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: '1.3.13'
+
+ - name: Install dependencies
+ run: bun install --frozen-lockfile
+
+ - name: Apply lint fixes
+ run: bun run lint:fix
+
+ - name: Apply formatting
+ run: bun run format
+
+ - name: Commit formatting
+ run: |
+ if git diff --quiet; then
+ echo "Repository formatting is already current."
+ exit 0
+ fi
+
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add src test package.json .changeset
+ git commit -m "style: format OAuth fixtures"
+ git push
From 77d22426fd357ea7dec94d45cdf08adbc0da859a Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:04:13 +0200
Subject: [PATCH 13/32] chore: continue after lint auto-fixes
---
.github/workflows/format-phase3-fixtures.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/format-phase3-fixtures.yml b/.github/workflows/format-phase3-fixtures.yml
index 959fa10..865965e 100644
--- a/.github/workflows/format-phase3-fixtures.yml
+++ b/.github/workflows/format-phase3-fixtures.yml
@@ -29,7 +29,7 @@ jobs:
run: bun install --frozen-lockfile
- name: Apply lint fixes
- run: bun run lint:fix
+ run: bun run lint:fix || true
- name: Apply formatting
run: bun run format
From fa89f771554173a9f362592e37184b98b309b9bc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 12 Jul 2026 09:04:33 +0000
Subject: [PATCH 14/32] style: format OAuth fixtures
---
test/oauth-auth-templates.test.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts
index 08320c3..4403c49 100644
--- a/test/oauth-auth-templates.test.ts
+++ b/test/oauth-auth-templates.test.ts
@@ -67,7 +67,9 @@ describe('canonical OAuth template fixtures', () => {
expect(['google', 'apple']).toContain(provider.id);
expect(provider.enabled).toBe(true);
expect(provider.credentialsRef).toBe(`auth/oauth/${provider.id}`);
- expect(provider.label).toBe(`Continue with ${provider.id === 'google' ? 'Google' : 'Apple'}`);
+ expect(provider.label).toBe(
+ `Continue with ${provider.id === 'google' ? 'Google' : 'Apple'}`,
+ );
}
const serialized = serialize(fixture);
From abe3439f33494802c428a0100907f0239686de77 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:05:37 +0200
Subject: [PATCH 15/32] chore: capture OAuth fixture lint diagnostics
---
.github/workflows/format-phase3-fixtures.yml | 22 +++++++-------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/format-phase3-fixtures.yml b/.github/workflows/format-phase3-fixtures.yml
index 865965e..3e97755 100644
--- a/.github/workflows/format-phase3-fixtures.yml
+++ b/.github/workflows/format-phase3-fixtures.yml
@@ -1,4 +1,4 @@
-name: Format Phase 3 OAuth fixtures
+name: Capture Phase 3 lint diagnostics
on:
push:
@@ -9,7 +9,7 @@ permissions:
contents: write
jobs:
- format:
+ diagnose:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
@@ -28,21 +28,13 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile
- - name: Apply lint fixes
- run: bun run lint:fix || true
+ - name: Capture lint output
+ run: bun run lint > lint-phase3.txt 2>&1 || true
- - name: Apply formatting
- run: bun run format
-
- - name: Commit formatting
+ - name: Commit diagnostics
run: |
- if git diff --quiet; then
- echo "Repository formatting is already current."
- exit 0
- fi
-
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add src test package.json .changeset
- git commit -m "style: format OAuth fixtures"
+ git add lint-phase3.txt
+ git commit -m "chore: capture lint diagnostics"
git push
From 7fda23a6613164886625ef119c1d1db85a7d4813 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 12 Jul 2026 09:05:54 +0000
Subject: [PATCH 16/32] chore: capture lint diagnostics
---
lint-phase3.txt | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 lint-phase3.txt
diff --git a/lint-phase3.txt b/lint-phase3.txt
new file mode 100644
index 0000000..9a795f6
--- /dev/null
+++ b/lint-phase3.txt
@@ -0,0 +1,8 @@
+$ ankhorage-eslint . --max-warnings=0
+
+/home/runner/work/templates/templates/test/oauth-auth-templates.test.ts
+ 108:5 error Forbidden non-null assertion @typescript-eslint/no-non-null-assertion
+
+✖ 1 problem (1 error, 0 warnings)
+
+error: script "lint" exited with code 1
From 5d5c0d061ef5eca4841a2f2ca1c84477c5bd4c33 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:06:48 +0200
Subject: [PATCH 17/32] fix: avoid non-null OAuth fixture assertions
---
test/oauth-auth-templates.test.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts
index 4403c49..fcf87f0 100644
--- a/test/oauth-auth-templates.test.ts
+++ b/test/oauth-auth-templates.test.ts
@@ -105,7 +105,11 @@ describe('canonical OAuth template fixtures', () => {
test('returns isolated fixture definitions', () => {
const fixture = resolveOAuthFixture('google');
- fixture.oauth.providers[0]!.label = SECRET_SENTINEL;
+ const [provider] = fixture.oauth.providers;
+ if (!provider) {
+ throw new Error('Expected the Google OAuth fixture to contain one provider.');
+ }
+ provider.label = SECRET_SENTINEL;
expect(resolveOAuthFixture('google').oauth.providers[0]?.label).toBe('Continue with Google');
expect(serialize(listOAuthFixtures())).not.toContain(SECRET_SENTINEL);
From 44e11bf4106fdc11f74faa51d6aae23653b90f43 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 12 Jul 2026 09:07:04 +0000
Subject: [PATCH 18/32] chore: capture lint diagnostics
---
lint-phase3.txt | 7 -------
1 file changed, 7 deletions(-)
diff --git a/lint-phase3.txt b/lint-phase3.txt
index 9a795f6..a4b4342 100644
--- a/lint-phase3.txt
+++ b/lint-phase3.txt
@@ -1,8 +1 @@
$ ankhorage-eslint . --max-warnings=0
-
-/home/runner/work/templates/templates/test/oauth-auth-templates.test.ts
- 108:5 error Forbidden non-null assertion @typescript-eslint/no-non-null-assertion
-
-✖ 1 problem (1 error, 0 warnings)
-
-error: script "lint" exited with code 1
From 9524d560e938d8a4635be73cec67ab17d8d7b46b Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:07:24 +0200
Subject: [PATCH 19/32] fix: declare OAuth fixture factory before use
---
src/fixtures/oauth.ts | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/fixtures/oauth.ts b/src/fixtures/oauth.ts
index 0bad1b0..7e42567 100644
--- a/src/fixtures/oauth.ts
+++ b/src/fixtures/oauth.ts
@@ -20,6 +20,14 @@ export interface OAuthFixtureDefinition {
readonly oauth: OAuthConfig;
}
+function createOAuthConfig(providers: readonly OAuthProviderConfig[]): OAuthConfig {
+ return {
+ enabled: true,
+ callbackRoute: OAUTH_CALLBACK_ROUTE,
+ providers: providers.map((provider) => structuredClone(provider)),
+ };
+}
+
const GOOGLE_PROVIDER: OAuthProviderConfig = {
id: 'google',
label: 'Continue with Google',
@@ -68,14 +76,6 @@ const FIXTURES: Record = {
},
};
-function createOAuthConfig(providers: readonly OAuthProviderConfig[]): OAuthConfig {
- return {
- enabled: true,
- callbackRoute: OAUTH_CALLBACK_ROUTE,
- providers: providers.map((provider) => structuredClone(provider)),
- };
-}
-
export function listOAuthFixtures(): OAuthFixtureDefinition[] {
return OAUTH_FIXTURE_IDS.map((id) => structuredClone(FIXTURES[id]));
}
From 47552c4fe8dfda7ed0da32bc5f98b5a39951534a Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:07:44 +0200
Subject: [PATCH 20/32] chore: remove temporary lint workflow
---
.github/workflows/format-phase3-fixtures.yml | 40 --------------------
1 file changed, 40 deletions(-)
delete mode 100644 .github/workflows/format-phase3-fixtures.yml
diff --git a/.github/workflows/format-phase3-fixtures.yml b/.github/workflows/format-phase3-fixtures.yml
deleted file mode 100644
index 3e97755..0000000
--- a/.github/workflows/format-phase3-fixtures.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: Capture Phase 3 lint diagnostics
-
-on:
- push:
- branches:
- - phase3/canonical-oauth-fixtures
-
-permissions:
- contents: write
-
-jobs:
- diagnose:
- if: github.actor != 'github-actions[bot]'
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout branch
- uses: actions/checkout@v4
- with:
- ref: phase3/canonical-oauth-fixtures
- fetch-depth: 0
-
- - name: Setup Bun
- uses: oven-sh/setup-bun@v2
- with:
- bun-version: '1.3.13'
-
- - name: Install dependencies
- run: bun install --frozen-lockfile
-
- - name: Capture lint output
- run: bun run lint > lint-phase3.txt 2>&1 || true
-
- - name: Commit diagnostics
- run: |
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add lint-phase3.txt
- git commit -m "chore: capture lint diagnostics"
- git push
From ebec0e4f8fcc8d0345ca6010abb876d392653d3d Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:09:10 +0200
Subject: [PATCH 21/32] fix: use typed callback path assertion
---
test/oauth-auth-templates.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts
index fcf87f0..bb2f4e4 100644
--- a/test/oauth-auth-templates.test.ts
+++ b/test/oauth-auth-templates.test.ts
@@ -60,7 +60,7 @@ describe('canonical OAuth template fixtures', () => {
for (const fixture of listOAuthFixtures()) {
expect(fixture.oauth.enabled).toBe(true);
expect(fixture.oauth.callbackRoute).toBe('auth/callback');
- expect(fixture.oauth.callbackRoute).not.toStartWith('/');
+ expect(fixture.oauth.callbackRoute.startsWith('/')).toBe(false);
expect(fixture.oauth.providers.length).toBeGreaterThan(0);
for (const provider of fixture.oauth.providers) {
From 1fea41fc72c9b49a042feb0ab2180185ce08dfa1 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:10:31 +0200
Subject: [PATCH 22/32] chore: capture Phase 3 typecheck diagnostics
---
.github/workflows/ci.yml | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fbdee6c..366dd42 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -70,11 +70,23 @@ jobs:
- name: Run typecheck
run: |
if node -e "const p=require('./package.json'); process.exit(p.scripts?.typecheck ? 0 : 1)"; then
- bun run typecheck
+ set +e
+ bun run typecheck > typecheck-phase3.txt 2>&1
+ status=$?
+ cat typecheck-phase3.txt
+ exit $status
else
- echo "No typecheck script found; skipping."
+ echo "No typecheck script found; skipping." | tee typecheck-phase3.txt
fi
+ - name: Upload typecheck diagnostics
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: phase3-typecheck-diagnostics
+ path: typecheck-phase3.txt
+ if-no-files-found: error
+
- name: Check changesets
if: github.event_name == 'pull_request'
run: |
From c2ff6c6f6954464d746294b8f9bf0d05a286b544 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:12:08 +0200
Subject: [PATCH 23/32] fix: compare OAuth fixture ids as mutable array
---
test/oauth-auth-templates.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts
index bb2f4e4..f3105de 100644
--- a/test/oauth-auth-templates.test.ts
+++ b/test/oauth-auth-templates.test.ts
@@ -44,7 +44,7 @@ describe('canonical OAuth template fixtures', () => {
test('publishes deterministic Google, Apple, and combined fixtures', () => {
expect(OAUTH_FIXTURE_IDS).toEqual(['google', 'apple', 'google-apple']);
- expect(listOAuthFixtures().map((fixture) => fixture.id)).toEqual(OAUTH_FIXTURE_IDS);
+ expect(listOAuthFixtures().map((fixture) => fixture.id)).toEqual([...OAUTH_FIXTURE_IDS]);
expect(resolveOAuthFixture('google').oauth.providers.map((provider) => provider.id)).toEqual([
'google',
]);
From c92a6d57564b576c6e1709b762090af3850e763c Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:12:31 +0200
Subject: [PATCH 24/32] chore: restore standard CI workflow
---
.github/workflows/ci.yml | 16 ++--------------
1 file changed, 2 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 366dd42..fbdee6c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -70,23 +70,11 @@ jobs:
- name: Run typecheck
run: |
if node -e "const p=require('./package.json'); process.exit(p.scripts?.typecheck ? 0 : 1)"; then
- set +e
- bun run typecheck > typecheck-phase3.txt 2>&1
- status=$?
- cat typecheck-phase3.txt
- exit $status
+ bun run typecheck
else
- echo "No typecheck script found; skipping." | tee typecheck-phase3.txt
+ echo "No typecheck script found; skipping."
fi
- - name: Upload typecheck diagnostics
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: phase3-typecheck-diagnostics
- path: typecheck-phase3.txt
- if-no-files-found: error
-
- name: Check changesets
if: github.event_name == 'pull_request'
run: |
From 82bfbad002726676669e01a2556d21734544b878 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:13:34 +0200
Subject: [PATCH 25/32] docs: regenerate OAuth fixture API
---
.github/workflows/generate-phase3-docs.yml | 45 ++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 .github/workflows/generate-phase3-docs.yml
diff --git a/.github/workflows/generate-phase3-docs.yml b/.github/workflows/generate-phase3-docs.yml
new file mode 100644
index 0000000..d3069a2
--- /dev/null
+++ b/.github/workflows/generate-phase3-docs.yml
@@ -0,0 +1,45 @@
+name: Generate Phase 3 OAuth docs
+
+on:
+ push:
+ branches:
+ - phase3/canonical-oauth-fixtures
+
+permissions:
+ contents: write
+
+jobs:
+ generate-docs:
+ if: github.actor != 'github-actions[bot]'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v4
+ with:
+ ref: phase3/canonical-oauth-fixtures
+ fetch-depth: 0
+
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: '1.3.13'
+
+ - name: Install dependencies
+ run: bun install --frozen-lockfile
+
+ - name: Generate documentation
+ run: bun run docs
+
+ - name: Commit generated documentation
+ run: |
+ if git diff --quiet -- README.md docs; then
+ echo "Generated documentation is already current."
+ exit 0
+ fi
+
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add README.md docs
+ git commit -m "docs: update OAuth fixture API"
+ git push
From 627201f4f4a8513174bee9ed2d7725b46ec45cb4 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 12 Jul 2026 09:13:49 +0000
Subject: [PATCH 26/32] docs: update OAuth fixture API
---
README.md | 4 +-
docs/badges/npm.svg | 6 +-
docs/diagrams/architecture-overview.mmd | 8 +-
docs/diagrams/export-graph.mmd | 20 +
docs/diagrams/module-relationships.mmd | 7 +-
.../create-category-app-manifest.mmd | 19 +
.../create-oauth-fixture-manifest.mmd | 27 +
docs/exports.json | 192 ++++++-
docs/exports.md | 70 ++-
docs/index.html | 535 ++++++++++++++++--
docs/paradox.json | 433 +++++++++++---
11 files changed, 1188 insertions(+), 133 deletions(-)
create mode 100644 docs/diagrams/sequences/create-category-app-manifest.mmd
create mode 100644 docs/diagrams/sequences/create-oauth-fixture-manifest.mmd
diff --git a/README.md b/README.md
index c4401ca..3a5b8ad 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
# TEMPLATES
-        
+        
Reusable Ankhorage app templates, presets, and manifest generators.
@@ -22,6 +22,8 @@ bunx @ankhorage/templates
- [Module relationships](././docs/diagrams/module-relationships.mmd)
- [Export graph](././docs/diagrams/export-graph.mmd)
- [ankhorage-templates sequence](././docs/diagrams/sequences/ankhorage-templates.mmd)
+- [createCategoryAppManifest sequence](././docs/diagrams/sequences/create-category-app-manifest.mmd)
+- [createOAuthFixtureManifest sequence](././docs/diagrams/sequences/create-oauth-fixture-manifest.mmd)
- [createStarterTemplate sequence](././docs/diagrams/sequences/create-starter-template.mmd)
- [listStarterTemplatesByCategory sequence](././docs/diagrams/sequences/list-starter-templates-by-category.mmd)
- [resolveStarterTemplate sequence](././docs/diagrams/sequences/resolve-starter-template.mmd)
diff --git a/docs/badges/npm.svg b/docs/badges/npm.svg
index 1562b37..1dbf9ac 100644
--- a/docs/badges/npm.svg
+++ b/docs/badges/npm.svg
@@ -1,7 +1,7 @@
-
Exports: createCategoryAppManifest
src/index.ts
Configured entrypoint
@@ -1373,14 +1395,17 @@ src/index.ts
Exports: APP_CATEGORIES, AppCategory,
CATEGORY_PRESETS, CategoryPreset,
CategoryStarterTemplateDefinition,
- createCategoryAppManifest, createStarterTemplate,
+ createCategoryAppManifest, createOAuthFixtureManifest,
+ createStarterTemplate, listOAuthFixtures,
listStarterTemplates, listStarterTemplatesByCategory,
- listStarterTemplateSummaries, resolveStarterTemplate,
- SplashScreenResizeMode, SplashScreenSpec,
- StarterTemplateFactory, StarterTemplateId,
- StarterTemplateOptions, StarterTemplateSelection,
- StarterTemplateSummary, TEMPLATE_KINDS,
- TemplateKind, TemplateSeed
+ listStarterTemplateSummaries, OAUTH_CALLBACK_ROUTE,
+ OAUTH_FIXTURE_IDS, OAuthFixtureDefinition,
+ OAuthFixtureId, resolveOAuthFixture,
+ resolveStarterTemplate, SplashScreenResizeMode,
+ SplashScreenSpec, StarterTemplateFactory,
+ StarterTemplateId, StarterTemplateOptions,
+ StarterTemplateSelection, StarterTemplateSummary,
+ TEMPLATE_KINDS, TemplateKind, TemplateSeed
SplashScreenSpec
+
+ src/fixtures/oauth.ts
+
+ createOAuthFixtureManifest
+ function • src/fixtures/oauth.ts:87:1
+
+ Export paths: src/index.ts
+
+
Related symbols:
+
+ - AppCategory
+ - OAuthFixtureId
+ - TemplateKind
+
+
+
+
Signature
+
+(args: { category: AppCategory; fixture: OAuthFixtureId; template?: TemplateKind; overrides?: AppManifestOverrides; }) => AppManifest
+
+
+
+ | Parameter |
+ Type |
+ Required |
+ Description |
+
+
+
+
+ args |
+
+ { category: AppCategory; fixture: OAuthFixtureId; template?:
+ TemplateKind; overrides?: AppManifestOverrides; }
+ |
+ yes |
+ |
+
+
+
+
Returns: AppManifest
+
+
+
+ listOAuthFixtures
+ function • src/fixtures/oauth.ts:79:1
+
+ Export paths: src/index.ts
+
+
Related symbols:
+
+ - OAuthFixtureDefinition
+
+
+
+
Signature
+
() => OAuthFixtureDefinition[]
+
+
Returns: OAuthFixtureDefinition[]
+
+
+
+ OAUTH_CALLBACK_ROUTE
+ value • src/fixtures/oauth.ts:8:14
+
+ Export paths: src/index.ts
+ Related symbols: None
+
+
+ OAUTH_FIXTURE_IDS
+ value • src/fixtures/oauth.ts:9:14
+
+ Export paths: src/index.ts
+ Related symbols: None
+
+
+ OAuthFixtureDefinition
+ type • src/fixtures/oauth.ts:16:1
+
+ Export paths: src/index.ts
+ Related symbols: None
+
+
+
+
+ | Member |
+ Kind |
+ Type |
+ Required |
+ Description |
+
+
+
+
+ description |
+ property |
+ string |
+ yes |
+ |
+
+
+ id |
+ property |
+
+ "google" | "apple" | "google-apple"
+ |
+ yes |
+ |
+
+
+ label |
+ property |
+ string |
+ yes |
+ |
+
+
+ oauth |
+ property |
+
+ import("/home/runner/work/templates/templates/node_modules/@ankhorage/contracts/dist/auth").AuthOAuthConfig
+ |
+ yes |
+ |
+
+
+
+
+
+ OAuthFixtureId
+ unknown • src/fixtures/oauth.ts:11:1
+
+ Export paths: src/index.ts
+ Related symbols: None
+
+
+ resolveOAuthFixture
+ function • src/fixtures/oauth.ts:83:1
+
+ Export paths: src/index.ts
+
+
Related symbols:
+
+ - OAuthFixtureDefinition
+
+
+
+
Signature
+
+(id: "google" | "apple" | "google-apple") => OAuthFixtureDefinition
+
+
+
+ | Parameter |
+ Type |
+ Required |
+ Description |
+
+
+
+
+ id |
+
+ "google" | "apple" | "google-apple"
+ |
+ yes |
+ |
+
+
+
+
Returns: OAuthFixtureDefinition
+
+
+
src/generators/create-category-app.ts
src/generators/create-category-app.ts
>
createCategoryAppManifest
- function • src/generators/create-category-app.ts:141:1
+ function • src/generators/create-category-app.ts:67:1
Export paths: src/index.ts
@@ -6006,17 +6243,20 @@ Architecture overview
module_src_projectSeed_ts module_src_commands_ts -->
module_src_templates_starter_index_ts module_src_commands_ts -->
module_src_templateSelector_ts
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
+ package__ankhorage_templates -.-> module_src_fixtures_oauth_ts
+ module_src_fixtures_oauth_ts --> module_src_generators_create_category_app_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_merge_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_overrides_ts
+ module_src_fixtures_oauth_ts --> module_src_templates_starter_index_ts
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
package__ankhorage_templates -.-> module_src_generators_create_category_app_ts
module_src_generators_create_category_app_ts --> module_src_internal_merge_ts
module_src_generators_create_category_app_ts --> module_src_internal_overrides_ts
module_src_generators_create_category_app_ts -->
module_src_presets_category_presets_ts module_src_generators_create_category_app_ts
- --> module_src_templates_shared_screen_ts
- module_src_generators_create_category_app_ts -->
- module_src_templates_shared_zora_node_helpers_ts
- module_src_generators_create_category_app_ts -->
- module_src_templates_starter_index_ts module_src_index_ts["src/index.ts"]
+ --> module_src_templates_starter_index_ts
+ module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
package__ankhorage_templates -.-> module_src_internal_defaults_ts
module_src_internal_merge_ts["src/internal/merge.ts"]
@@ -7306,13 +7546,17 @@ Architecture overview
module_src_commands_ts --> module_src_projectSeed_ts
module_src_commands_ts --> module_src_templates_starter_index_ts
module_src_commands_ts --> module_src_templateSelector_ts
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
+ package__ankhorage_templates -.-> module_src_fixtures_oauth_ts
+ module_src_fixtures_oauth_ts --> module_src_generators_create_category_app_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_merge_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_overrides_ts
+ module_src_fixtures_oauth_ts --> module_src_templates_starter_index_ts
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
package__ankhorage_templates -.-> module_src_generators_create_category_app_ts
module_src_generators_create_category_app_ts --> module_src_internal_merge_ts
module_src_generators_create_category_app_ts --> module_src_internal_overrides_ts
module_src_generators_create_category_app_ts --> module_src_presets_category_presets_ts
- module_src_generators_create_category_app_ts --> module_src_templates_shared_screen_ts
- module_src_generators_create_category_app_ts --> module_src_templates_shared_zora_node_helpers_ts
module_src_generators_create_category_app_ts --> module_src_templates_starter_index_ts
module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
@@ -8048,6 +8292,7 @@ Module relationships
module_src_cli_standalone_ts["src/cli/standalone.ts"]
module_src_commandContext_ts["src/commandContext.ts"]
module_src_commands_ts["src/commands.ts"]
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
@@ -8233,13 +8478,14 @@ Module relationships
module_src_packageMetadata_ts module_src_commands_ts -->
module_src_projectSeed_ts module_src_commands_ts -->
module_src_templates_starter_index_ts module_src_commands_ts -->
- module_src_templateSelector_ts module_src_generators_create_category_app_ts -->
- module_src_internal_merge_ts module_src_generators_create_category_app_ts -->
- module_src_internal_overrides_ts module_src_generators_create_category_app_ts -->
- module_src_presets_category_presets_ts module_src_generators_create_category_app_ts
- --> module_src_templates_shared_screen_ts
- module_src_generators_create_category_app_ts -->
- module_src_templates_shared_zora_node_helpers_ts
+ module_src_templateSelector_ts module_src_fixtures_oauth_ts -->
+ module_src_generators_create_category_app_ts module_src_fixtures_oauth_ts -->
+ module_src_internal_merge_ts module_src_fixtures_oauth_ts -->
+ module_src_internal_overrides_ts module_src_fixtures_oauth_ts -->
+ module_src_templates_starter_index_ts module_src_generators_create_category_app_ts
+ --> module_src_internal_merge_ts module_src_generators_create_category_app_ts
+ --> module_src_internal_overrides_ts module_src_generators_create_category_app_ts
+ --> module_src_presets_category_presets_ts
module_src_generators_create_category_app_ts -->
module_src_templates_starter_index_ts module_src_internal_merge_ts -->
module_src_internal_overrides_ts module_src_packageMetadata_ts -->
@@ -9021,6 +9267,7 @@ Module relationships
module_src_cli_standalone_ts["src/cli/standalone.ts"]
module_src_commandContext_ts["src/commandContext.ts"]
module_src_commands_ts["src/commands.ts"]
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
@@ -9206,11 +9453,13 @@ Module relationships
module_src_commands_ts --> module_src_projectSeed_ts
module_src_commands_ts --> module_src_templates_starter_index_ts
module_src_commands_ts --> module_src_templateSelector_ts
+ module_src_fixtures_oauth_ts --> module_src_generators_create_category_app_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_merge_ts
+ module_src_fixtures_oauth_ts --> module_src_internal_overrides_ts
+ module_src_fixtures_oauth_ts --> module_src_templates_starter_index_ts
module_src_generators_create_category_app_ts --> module_src_internal_merge_ts
module_src_generators_create_category_app_ts --> module_src_internal_overrides_ts
module_src_generators_create_category_app_ts --> module_src_presets_category_presets_ts
- module_src_generators_create_category_app_ts --> module_src_templates_shared_screen_ts
- module_src_generators_create_category_app_ts --> module_src_templates_shared_zora_node_helpers_ts
module_src_generators_create_category_app_ts --> module_src_templates_starter_index_ts
module_src_internal_merge_ts --> module_src_internal_overrides_ts
module_src_packageMetadata_ts --> module_package_json
@@ -9608,6 +9857,7 @@ Export graph
module_src_cli_standalone_ts["src/cli/standalone.ts"]
module_src_commandContext_ts["src/commandContext.ts"]
module_src_commands_ts["src/commands.ts"]
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
@@ -9792,10 +10042,18 @@ Export graph
export_createCategoryAppManifest["createCategoryAppManifest"]
module_src_generators_create_category_app_ts --> export_createCategoryAppManifest
export_createCategoryAppManifest -.-> export_SplashScreenResizeMode
+ export_createOAuthFixtureManifest["createOAuthFixtureManifest"]
+ module_src_fixtures_oauth_ts --> export_createOAuthFixtureManifest
+ export_createOAuthFixtureManifest -.-> export_AppCategory
+ export_createOAuthFixtureManifest -.-> export_OAuthFixtureId
+ export_createOAuthFixtureManifest -.-> export_TemplateKind
export_createStarterTemplate["createStarterTemplate"]
module_src_templates_starter_starter_template_ts --> export_createStarterTemplate
export_createStarterTemplate -.-> export_StarterTemplateOptions
export_createStarterTemplate -.-> export_TemplateSeed
+ export_listOAuthFixtures["listOAuthFixtures"] module_src_fixtures_oauth_ts
+ --> export_listOAuthFixtures export_listOAuthFixtures -.->
+ export_OAuthFixtureDefinition
export_listStarterTemplates["listStarterTemplates"]
module_src_templates_starter_starter_registry_ts --> export_listStarterTemplates
export_listStarterTemplates -.-> export_CategoryStarterTemplateDefinition
@@ -9807,6 +10065,17 @@ Export graph
module_src_templates_starter_starter_registry_ts -->
export_listStarterTemplateSummaries export_listStarterTemplateSummaries -.->
export_StarterTemplateSummary
+ export_OAUTH_CALLBACK_ROUTE["OAUTH_CALLBACK_ROUTE"]
+ module_src_fixtures_oauth_ts --> export_OAUTH_CALLBACK_ROUTE
+ export_OAUTH_FIXTURE_IDS["OAUTH_FIXTURE_IDS"] module_src_fixtures_oauth_ts
+ --> export_OAUTH_FIXTURE_IDS
+ export_OAuthFixtureDefinition["OAuthFixtureDefinition"]
+ module_src_fixtures_oauth_ts --> export_OAuthFixtureDefinition
+ export_OAuthFixtureId["OAuthFixtureId"] module_src_fixtures_oauth_ts
+ --> export_OAuthFixtureId
+ export_resolveOAuthFixture["resolveOAuthFixture"]
+ module_src_fixtures_oauth_ts --> export_resolveOAuthFixture
+ export_resolveOAuthFixture -.-> export_OAuthFixtureDefinition
export_resolveStarterTemplate["resolveStarterTemplate"]
module_src_templates_starter_starter_registry_ts -->
export_resolveStarterTemplate export_resolveStarterTemplate -.->
@@ -9845,6 +10114,7 @@ Export graph
module_src_cli_standalone_ts["src/cli/standalone.ts"]
module_src_commandContext_ts["src/commandContext.ts"]
module_src_commands_ts["src/commands.ts"]
+ module_src_fixtures_oauth_ts["src/fixtures/oauth.ts"]
module_src_generators_create_category_app_ts["src/generators/create-category-app.ts"]
module_src_index_ts["src/index.ts"]
module_src_internal_defaults_ts["src/internal/defaults.ts"]
@@ -10028,10 +10298,18 @@ Export graph
export_createCategoryAppManifest["createCategoryAppManifest"]
module_src_generators_create_category_app_ts --> export_createCategoryAppManifest
export_createCategoryAppManifest -.-> export_SplashScreenResizeMode
+ export_createOAuthFixtureManifest["createOAuthFixtureManifest"]
+ module_src_fixtures_oauth_ts --> export_createOAuthFixtureManifest
+ export_createOAuthFixtureManifest -.-> export_AppCategory
+ export_createOAuthFixtureManifest -.-> export_OAuthFixtureId
+ export_createOAuthFixtureManifest -.-> export_TemplateKind
export_createStarterTemplate["createStarterTemplate"]
module_src_templates_starter_starter_template_ts --> export_createStarterTemplate
export_createStarterTemplate -.-> export_StarterTemplateOptions
export_createStarterTemplate -.-> export_TemplateSeed
+ export_listOAuthFixtures["listOAuthFixtures"]
+ module_src_fixtures_oauth_ts --> export_listOAuthFixtures
+ export_listOAuthFixtures -.-> export_OAuthFixtureDefinition
export_listStarterTemplates["listStarterTemplates"]
module_src_templates_starter_starter_registry_ts --> export_listStarterTemplates
export_listStarterTemplates -.-> export_CategoryStarterTemplateDefinition
@@ -10041,6 +10319,17 @@ Export graph
export_listStarterTemplateSummaries["listStarterTemplateSummaries"]
module_src_templates_starter_starter_registry_ts --> export_listStarterTemplateSummaries
export_listStarterTemplateSummaries -.-> export_StarterTemplateSummary
+ export_OAUTH_CALLBACK_ROUTE["OAUTH_CALLBACK_ROUTE"]
+ module_src_fixtures_oauth_ts --> export_OAUTH_CALLBACK_ROUTE
+ export_OAUTH_FIXTURE_IDS["OAUTH_FIXTURE_IDS"]
+ module_src_fixtures_oauth_ts --> export_OAUTH_FIXTURE_IDS
+ export_OAuthFixtureDefinition["OAuthFixtureDefinition"]
+ module_src_fixtures_oauth_ts --> export_OAuthFixtureDefinition
+ export_OAuthFixtureId["OAuthFixtureId"]
+ module_src_fixtures_oauth_ts --> export_OAuthFixtureId
+ export_resolveOAuthFixture["resolveOAuthFixture"]
+ module_src_fixtures_oauth_ts --> export_resolveOAuthFixture
+ export_resolveOAuthFixture -.-> export_OAuthFixtureDefinition
export_resolveStarterTemplate["resolveStarterTemplate"]
module_src_templates_starter_starter_registry_ts --> export_resolveStarterTemplate
export_resolveStarterTemplate -.-> export_CategoryStarterTemplateDefinition
@@ -10140,6 +10429,132 @@ ankhorage-templates sequence
participant_renderUnknownCommand-->>participant_runCli: return
participant_runCli->>participant_runCommand: runCommand()
participant_runCommand-->>participant_runCli: return
+
+
+
+
+ createCategoryAppManifest sequence
+ diagrams/sequences/create-category-app-manifest.mmd
+
+ sequenceDiagram participant participant___type as __type participant
+ participant_createCategoryAppManifest as createCategoryAppManifest participant
+ participant_createManifestFromTemplate as createManifestFromTemplate participant
+ participant_isPlainObject as isPlainObject participant participant_mergeAppManifest
+ as mergeAppManifest participant participant_mergeValue as mergeValue
+ participant_createCategoryAppManifest->>participant_createManifestFromTemplate:
+ createManifestFromTemplate()
+ participant_createManifestFromTemplate->>participant___type:
+ TEMPLATE_FACTORIES[template]()
+ participant___type-->>participant_createManifestFromTemplate: return
+ participant_createManifestFromTemplate-->>participant_createCategoryAppManifest:
+ return participant_createCategoryAppManifest->>participant_mergeAppManifest:
+ mergeAppManifest() participant_mergeAppManifest->>participant_mergeValue:
+ mergeValue() participant_mergeValue->>participant_isPlainObject:
+ isPlainObject() participant_isPlainObject-->>participant_mergeValue: return
+ participant_mergeValue->>participant_mergeValue: mergeValue()
+ participant_mergeValue-->>participant_mergeValue: return
+ participant_mergeValue-->>participant_mergeAppManifest: return
+ participant_mergeAppManifest-->>participant_createCategoryAppManifest: return
+
+
+ View Mermaid source
+
+sequenceDiagram
+ participant participant___type as __type
+ participant participant_createCategoryAppManifest as createCategoryAppManifest
+ participant participant_createManifestFromTemplate as createManifestFromTemplate
+ participant participant_isPlainObject as isPlainObject
+ participant participant_mergeAppManifest as mergeAppManifest
+ participant participant_mergeValue as mergeValue
+ participant_createCategoryAppManifest->>participant_createManifestFromTemplate: createManifestFromTemplate()
+ participant_createManifestFromTemplate->>participant___type: TEMPLATE_FACTORIES[template]()
+ participant___type-->>participant_createManifestFromTemplate: return
+ participant_createManifestFromTemplate-->>participant_createCategoryAppManifest: return
+ participant_createCategoryAppManifest->>participant_mergeAppManifest: mergeAppManifest()
+ participant_mergeAppManifest->>participant_mergeValue: mergeValue()
+ participant_mergeValue->>participant_isPlainObject: isPlainObject()
+ participant_isPlainObject-->>participant_mergeValue: return
+ participant_mergeValue->>participant_mergeValue: mergeValue()
+ participant_mergeValue-->>participant_mergeValue: return
+ participant_mergeValue-->>participant_mergeAppManifest: return
+ participant_mergeAppManifest-->>participant_createCategoryAppManifest: return
+
+
+
+
+ createOAuthFixtureManifest sequence
+ diagrams/sequences/create-oauth-fixture-manifest.mmd
+
+ sequenceDiagram participant participant___type as __type participant
+ participant_createCategoryAppManifest as createCategoryAppManifest participant
+ participant_createManifestFromTemplate as createManifestFromTemplate participant
+ participant_createOAuthFixtureManifest as createOAuthFixtureManifest participant
+ participant_isPlainObject as isPlainObject participant participant_mergeAppManifest
+ as mergeAppManifest participant participant_mergeValue as mergeValue participant
+ participant_resolveOAuthFixture as resolveOAuthFixture
+ participant_createOAuthFixtureManifest->>participant_createCategoryAppManifest:
+ createCategoryAppManifest()
+ participant_createCategoryAppManifest->>participant_createManifestFromTemplate:
+ createManifestFromTemplate()
+ participant_createManifestFromTemplate->>participant___type:
+ TEMPLATE_FACTORIES[template]()
+ participant___type-->>participant_createManifestFromTemplate: return
+ participant_createManifestFromTemplate-->>participant_createCategoryAppManifest:
+ return participant_createCategoryAppManifest->>participant_mergeAppManifest:
+ mergeAppManifest() participant_mergeAppManifest->>participant_mergeValue:
+ mergeValue() participant_mergeValue->>participant_isPlainObject:
+ isPlainObject() participant_isPlainObject-->>participant_mergeValue: return
+ participant_mergeValue->>participant_mergeValue: mergeValue()
+ participant_mergeValue-->>participant_mergeValue: return
+ participant_mergeValue-->>participant_mergeAppManifest: return
+ participant_mergeAppManifest-->>participant_createCategoryAppManifest: return
+ participant_createCategoryAppManifest-->>participant_createOAuthFixtureManifest:
+ return
+ participant_createOAuthFixtureManifest->>participant_resolveOAuthFixture:
+ resolveOAuthFixture()
+ participant_resolveOAuthFixture-->>participant_createOAuthFixtureManifest:
+ return participant_createOAuthFixtureManifest->>participant_mergeAppManifest:
+ mergeAppManifest()
+ participant_mergeAppManifest-->>participant_createOAuthFixtureManifest: return
+
+
+ View Mermaid source
+
+sequenceDiagram
+ participant participant___type as __type
+ participant participant_createCategoryAppManifest as createCategoryAppManifest
+ participant participant_createManifestFromTemplate as createManifestFromTemplate
+ participant participant_createOAuthFixtureManifest as createOAuthFixtureManifest
+ participant participant_isPlainObject as isPlainObject
+ participant participant_mergeAppManifest as mergeAppManifest
+ participant participant_mergeValue as mergeValue
+ participant participant_resolveOAuthFixture as resolveOAuthFixture
+ participant_createOAuthFixtureManifest->>participant_createCategoryAppManifest: createCategoryAppManifest()
+ participant_createCategoryAppManifest->>participant_createManifestFromTemplate: createManifestFromTemplate()
+ participant_createManifestFromTemplate->>participant___type: TEMPLATE_FACTORIES[template]()
+ participant___type-->>participant_createManifestFromTemplate: return
+ participant_createManifestFromTemplate-->>participant_createCategoryAppManifest: return
+ participant_createCategoryAppManifest->>participant_mergeAppManifest: mergeAppManifest()
+ participant_mergeAppManifest->>participant_mergeValue: mergeValue()
+ participant_mergeValue->>participant_isPlainObject: isPlainObject()
+ participant_isPlainObject-->>participant_mergeValue: return
+ participant_mergeValue->>participant_mergeValue: mergeValue()
+ participant_mergeValue-->>participant_mergeValue: return
+ participant_mergeValue-->>participant_mergeAppManifest: return
+ participant_mergeAppManifest-->>participant_createCategoryAppManifest: return
+ participant_createCategoryAppManifest-->>participant_createOAuthFixtureManifest: return
+ participant_createOAuthFixtureManifest->>participant_resolveOAuthFixture: resolveOAuthFixture()
+ participant_resolveOAuthFixture-->>participant_createOAuthFixtureManifest: return
+ participant_createOAuthFixtureManifest->>participant_mergeAppManifest: mergeAppManifest()
+ participant_mergeAppManifest-->>participant_createOAuthFixtureManifest: return
@@ -10430,6 +10845,36 @@ isHelpToken
+
+
+ src/fixtures/oauth.ts
+
+ createOAuthConfig
+ src/fixtures/oauth.ts:23:1
+ No description available.
+
+
+ listOAuthFixtures
+ src/fixtures/oauth.ts:79:1
+ No description available.
+
+
+ resolveOAuthFixture
+ src/fixtures/oauth.ts:83:1
+ No description available.
+
+
+ createOAuthFixtureManifest
+ src/fixtures/oauth.ts:87:1
+ No description available.
+
+
+
src/generators/create-category-app.ts
data-search="resolveThemeModeValue src/generators/create-category-app.ts "
>
resolveThemeModeValue
- src/generators/create-category-app.ts:24:1
+ src/generators/create-category-app.ts:8:1
No description available.
resolveThemeModeValue
data-search="resolveSeedName src/generators/create-category-app.ts "
>
resolveSeedName
- src/generators/create-category-app.ts:33:1
+ src/generators/create-category-app.ts:17:1
No description available.
resolveSeedName
data-search="resolveSeedSlug src/generators/create-category-app.ts "
>
resolveSeedSlug
- src/generators/create-category-app.ts:37:1
+ src/generators/create-category-app.ts:21:1
No description available.
resolveSeedSlug
data-search="resolveSeedThemeId src/generators/create-category-app.ts "
>
resolveSeedThemeId
- src/generators/create-category-app.ts:41:1
+ src/generators/create-category-app.ts:25:1
No description available.
resolveSeedThemeId
data-search="createManifestFromTemplate src/generators/create-category-app.ts "
>
createManifestFromTemplate
- src/generators/create-category-app.ts:75:1
- No description available.
-
-
- addProviderEntryScreen
- src/generators/create-category-app.ts:83:1
- No description available.
-
-
- createProviderEntryScreen
- src/generators/create-category-app.ts:111:1
+ src/generators/create-category-app.ts:59:1
No description available.
createProviderEntryScreen
data-search="createCategoryAppManifest src/generators/create-category-app.ts "
>
createCategoryAppManifest
- src/generators/create-category-app.ts:141:1
+ src/generators/create-category-app.ts:67:1
No description available.
diff --git a/docs/paradox.json b/docs/paradox.json
index 9a356b6..0ec60e6 100644
--- a/docs/paradox.json
+++ b/docs/paradox.json
@@ -12,7 +12,7 @@
{
"id": "npm",
"label": "npm",
- "value": "v2.0.0",
+ "value": "v2.1.0",
"color": "cb3837"
},
{
@@ -144,6 +144,25 @@
"TemplatesCommandInvocation"
]
},
+ {
+ "path": "src/fixtures/oauth.ts",
+ "isEntrypoint": false,
+ "dependencies": [
+ "src/generators/create-category-app.ts",
+ "src/internal/merge.ts",
+ "src/internal/overrides.ts",
+ "src/templates/starter/index.ts"
+ ],
+ "exports": [
+ "createOAuthFixtureManifest",
+ "listOAuthFixtures",
+ "OAUTH_CALLBACK_ROUTE",
+ "OAUTH_FIXTURE_IDS",
+ "OAuthFixtureDefinition",
+ "OAuthFixtureId",
+ "resolveOAuthFixture"
+ ]
+ },
{
"path": "src/generators/create-category-app.ts",
"isEntrypoint": false,
@@ -151,8 +170,6 @@
"src/internal/merge.ts",
"src/internal/overrides.ts",
"src/presets/category-presets.ts",
- "src/templates/shared/screen.ts",
- "src/templates/shared/zora-node-helpers.ts",
"src/templates/starter/index.ts"
],
"exports": ["createCategoryAppManifest"]
@@ -168,10 +185,17 @@
"CategoryPreset",
"CategoryStarterTemplateDefinition",
"createCategoryAppManifest",
+ "createOAuthFixtureManifest",
"createStarterTemplate",
+ "listOAuthFixtures",
"listStarterTemplates",
"listStarterTemplatesByCategory",
"listStarterTemplateSummaries",
+ "OAUTH_CALLBACK_ROUTE",
+ "OAUTH_FIXTURE_IDS",
+ "OAuthFixtureDefinition",
+ "OAuthFixtureId",
+ "resolveOAuthFixture",
"resolveStarterTemplate",
"SplashScreenResizeMode",
"SplashScreenSpec",
@@ -1957,7 +1981,7 @@
"modulePath": "src/generators/create-category-app.ts",
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 141,
+ "line": 67,
"column": 1
},
"exportPaths": ["src/index.ts"],
@@ -1992,6 +2016,38 @@
"members": [],
"structuredRows": []
},
+ {
+ "name": "createOAuthFixtureManifest",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "function",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 87,
+ "column": 1
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": ["AppCategory", "OAuthFixtureId", "TemplateKind"],
+ "signatures": [
+ {
+ "label": "(args: { category: AppCategory; fixture: OAuthFixtureId; template?: TemplateKind; overrides?: AppManifestOverrides; }) => AppManifest",
+ "parameters": [
+ {
+ "name": "args",
+ "type": "{ category: AppCategory; fixture: OAuthFixtureId; template?: TemplateKind; overrides?: AppManifestOverrides; }",
+ "required": true,
+ "description": null
+ }
+ ],
+ "returnType": "AppManifest",
+ "returnDescription": null
+ }
+ ],
+ "members": [],
+ "structuredRows": []
+ },
{
"name": "createStarterTemplate",
"description": null,
@@ -2030,6 +2086,31 @@
"members": [],
"structuredRows": []
},
+ {
+ "name": "listOAuthFixtures",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "function",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 79,
+ "column": 1
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": ["OAuthFixtureDefinition"],
+ "signatures": [
+ {
+ "label": "() => OAuthFixtureDefinition[]",
+ "parameters": [],
+ "returnType": "OAuthFixtureDefinition[]",
+ "returnDescription": null
+ }
+ ],
+ "members": [],
+ "structuredRows": []
+ },
{
"name": "listStarterTemplates",
"description": null,
@@ -2119,6 +2200,139 @@
"members": [],
"structuredRows": []
},
+ {
+ "name": "OAUTH_CALLBACK_ROUTE",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "value",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 8,
+ "column": 14
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": [],
+ "signatures": [],
+ "members": [],
+ "structuredRows": []
+ },
+ {
+ "name": "OAUTH_FIXTURE_IDS",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "value",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 9,
+ "column": 14
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": [],
+ "signatures": [],
+ "members": [],
+ "structuredRows": []
+ },
+ {
+ "name": "OAuthFixtureDefinition",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "type",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 16,
+ "column": 1
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": [],
+ "signatures": [],
+ "members": [
+ {
+ "name": "description",
+ "kind": "property",
+ "type": "string",
+ "required": true,
+ "description": null
+ },
+ {
+ "name": "id",
+ "kind": "property",
+ "type": "\"google\" | \"apple\" | \"google-apple\"",
+ "required": true,
+ "description": null
+ },
+ {
+ "name": "label",
+ "kind": "property",
+ "type": "string",
+ "required": true,
+ "description": null
+ },
+ {
+ "name": "oauth",
+ "kind": "property",
+ "type": "import(\"/home/runner/work/templates/templates/node_modules/@ankhorage/contracts/dist/auth\").AuthOAuthConfig",
+ "required": true,
+ "description": null
+ }
+ ],
+ "structuredRows": []
+ },
+ {
+ "name": "OAuthFixtureId",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "unknown",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 11,
+ "column": 1
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": [],
+ "signatures": [],
+ "members": [],
+ "structuredRows": []
+ },
+ {
+ "name": "resolveOAuthFixture",
+ "description": null,
+ "isReadme": false,
+ "examples": [],
+ "kind": "function",
+ "modulePath": "src/fixtures/oauth.ts",
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 83,
+ "column": 1
+ },
+ "exportPaths": ["src/index.ts"],
+ "relatedSymbols": ["OAuthFixtureDefinition"],
+ "signatures": [
+ {
+ "label": "(id: \"google\" | \"apple\" | \"google-apple\") => OAuthFixtureDefinition",
+ "parameters": [
+ {
+ "name": "id",
+ "type": "\"google\" | \"apple\" | \"google-apple\"",
+ "required": true,
+ "description": null
+ }
+ ],
+ "returnType": "OAuthFixtureDefinition",
+ "returnDescription": null
+ }
+ ],
+ "members": [],
+ "structuredRows": []
+ },
{
"name": "resolveStarterTemplate",
"description": null,
@@ -2777,65 +2991,83 @@
}
},
{
- "name": "resolveThemeModeValue",
+ "name": "createOAuthConfig",
"description": null,
"sourceLocation": {
- "filePath": "src/generators/create-category-app.ts",
- "line": 24,
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 23,
"column": 1
}
},
{
- "name": "resolveSeedName",
+ "name": "listOAuthFixtures",
"description": null,
"sourceLocation": {
- "filePath": "src/generators/create-category-app.ts",
- "line": 33,
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 79,
"column": 1
}
},
{
- "name": "resolveSeedSlug",
+ "name": "resolveOAuthFixture",
+ "description": null,
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 83,
+ "column": 1
+ }
+ },
+ {
+ "name": "createOAuthFixtureManifest",
+ "description": null,
+ "sourceLocation": {
+ "filePath": "src/fixtures/oauth.ts",
+ "line": 87,
+ "column": 1
+ }
+ },
+ {
+ "name": "resolveThemeModeValue",
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 37,
+ "line": 8,
"column": 1
}
},
{
- "name": "resolveSeedThemeId",
+ "name": "resolveSeedName",
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 41,
+ "line": 17,
"column": 1
}
},
{
- "name": "createManifestFromTemplate",
+ "name": "resolveSeedSlug",
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 75,
+ "line": 21,
"column": 1
}
},
{
- "name": "addProviderEntryScreen",
+ "name": "resolveSeedThemeId",
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 83,
+ "line": 25,
"column": 1
}
},
{
- "name": "createProviderEntryScreen",
+ "name": "createManifestFromTemplate",
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 111,
+ "line": 59,
"column": 1
}
},
@@ -2844,7 +3076,7 @@
"description": null,
"sourceLocation": {
"filePath": "src/generators/create-category-app.ts",
- "line": 141,
+ "line": 67,
"column": 1
}
},
@@ -4432,6 +4664,14 @@
"description": null,
"isReadme": false
},
+ {
+ "kind": "export",
+ "name": "createOAuthFixtureManifest",
+ "sourcePath": "src/fixtures/oauth.ts",
+ "symbolName": "createOAuthFixtureManifest",
+ "description": null,
+ "isReadme": false
+ },
{
"kind": "export",
"name": "createStarterTemplate",
@@ -4440,6 +4680,14 @@
"description": null,
"isReadme": false
},
+ {
+ "kind": "export",
+ "name": "listOAuthFixtures",
+ "sourcePath": "src/fixtures/oauth.ts",
+ "symbolName": "listOAuthFixtures",
+ "description": null,
+ "isReadme": false
+ },
{
"kind": "export",
"name": "listStarterTemplates",
@@ -4464,6 +4712,14 @@
"description": null,
"isReadme": false
},
+ {
+ "kind": "export",
+ "name": "resolveOAuthFixture",
+ "sourcePath": "src/fixtures/oauth.ts",
+ "symbolName": "resolveOAuthFixture",
+ "description": null,
+ "isReadme": false
+ },
{
"kind": "export",
"name": "resolveStarterTemplate",
@@ -4535,6 +4791,11 @@
"toPath": "src/templateSelector.ts",
"sourcePath": "src/commands.ts"
},
+ {
+ "fromPath": "src/index.ts",
+ "toPath": "src/fixtures/oauth.ts",
+ "sourcePath": "src/index.ts"
+ },
{
"fromPath": "src/index.ts",
"toPath": "src/generators/create-category-app.ts",
@@ -4586,28 +4847,38 @@
"sourcePath": "src/cli/standalone.ts"
},
{
- "fromPath": "src/generators/create-category-app.ts",
+ "fromPath": "src/fixtures/oauth.ts",
+ "toPath": "src/generators/create-category-app.ts",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromPath": "src/fixtures/oauth.ts",
"toPath": "src/internal/merge.ts",
- "sourcePath": "src/generators/create-category-app.ts"
+ "sourcePath": "src/fixtures/oauth.ts"
},
{
- "fromPath": "src/generators/create-category-app.ts",
+ "fromPath": "src/fixtures/oauth.ts",
"toPath": "src/internal/overrides.ts",
- "sourcePath": "src/generators/create-category-app.ts"
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromPath": "src/fixtures/oauth.ts",
+ "toPath": "src/templates/starter/index.ts",
+ "sourcePath": "src/fixtures/oauth.ts"
},
{
"fromPath": "src/generators/create-category-app.ts",
- "toPath": "src/presets/category-presets.ts",
+ "toPath": "src/internal/merge.ts",
"sourcePath": "src/generators/create-category-app.ts"
},
{
"fromPath": "src/generators/create-category-app.ts",
- "toPath": "src/templates/shared/screen.ts",
+ "toPath": "src/internal/overrides.ts",
"sourcePath": "src/generators/create-category-app.ts"
},
{
"fromPath": "src/generators/create-category-app.ts",
- "toPath": "src/templates/shared/zora-node-helpers.ts",
+ "toPath": "src/presets/category-presets.ts",
"sourcePath": "src/generators/create-category-app.ts"
},
{
@@ -6920,6 +7191,30 @@
"callExpression": "runCli",
"sourcePath": "src/cli/standalone.ts"
},
+ {
+ "fromSymbol": "src/fixtures/oauth.ts",
+ "toSymbol": "createOAuthConfig",
+ "callExpression": "createOAuthConfig",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toSymbol": "createCategoryAppManifest",
+ "callExpression": "createCategoryAppManifest",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toSymbol": "resolveOAuthFixture",
+ "callExpression": "resolveOAuthFixture",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toSymbol": "mergeAppManifest",
+ "callExpression": "mergeAppManifest",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
{
"fromSymbol": "resolveThemeModeValue",
"toSymbol": "selector",
@@ -6962,54 +7257,12 @@
"callExpression": "TEMPLATE_FACTORIES[template]",
"sourcePath": "src/generators/create-category-app.ts"
},
- {
- "fromSymbol": "addProviderEntryScreen",
- "toSymbol": "resolveAuthFlow",
- "callExpression": "resolveAuthFlow",
- "sourcePath": "src/generators/create-category-app.ts"
- },
- {
- "fromSymbol": "addProviderEntryScreen",
- "toSymbol": "createProviderEntryScreen",
- "callExpression": "createProviderEntryScreen",
- "sourcePath": "src/generators/create-category-app.ts"
- },
- {
- "fromSymbol": "createProviderEntryScreen",
- "toSymbol": "createScreen",
- "callExpression": "createScreen",
- "sourcePath": "src/generators/create-category-app.ts"
- },
- {
- "fromSymbol": "createProviderEntryScreen",
- "toSymbol": "createScreenRoot",
- "callExpression": "createScreenRoot",
- "sourcePath": "src/generators/create-category-app.ts"
- },
- {
- "fromSymbol": "createProviderEntryScreen",
- "toSymbol": "createZoraNode",
- "callExpression": "createZoraNode",
- "sourcePath": "src/generators/create-category-app.ts"
- },
- {
- "fromSymbol": "createProviderEntryScreen",
- "toSymbol": "createSection",
- "callExpression": "createSection",
- "sourcePath": "src/generators/create-category-app.ts"
- },
{
"fromSymbol": "createCategoryAppManifest",
"toSymbol": "createManifestFromTemplate",
"callExpression": "createManifestFromTemplate",
"sourcePath": "src/generators/create-category-app.ts"
},
- {
- "fromSymbol": "createCategoryAppManifest",
- "toSymbol": "addProviderEntryScreen",
- "callExpression": "addProviderEntryScreen",
- "sourcePath": "src/generators/create-category-app.ts"
- },
{
"fromSymbol": "createCategoryAppManifest",
"toSymbol": "mergeAppManifest",
@@ -9112,6 +9365,46 @@
}
],
"typeReferences": [
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toType": "AppCategory",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toType": "AppManifest",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toType": "AppManifestOverrides",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toType": "OAuthFixtureId",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "createOAuthFixtureManifest",
+ "toType": "TemplateKind",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "listOAuthFixtures",
+ "toType": "OAuthFixtureDefinition",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "OAuthFixtureDefinition",
+ "toType": "AuthOAuthConfig",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
+ {
+ "fromSymbol": "resolveOAuthFixture",
+ "toType": "OAuthFixtureDefinition",
+ "sourcePath": "src/fixtures/oauth.ts"
+ },
{
"fromSymbol": "createCategoryAppManifest",
"toType": "AdapterId",
From 106c9962a494c231725bf23cb9fc532de50bf615 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:15:04 +0200
Subject: [PATCH 27/32] chore: remove temporary docs workflow
---
.github/workflows/generate-phase3-docs.yml | 45 ----------------------
1 file changed, 45 deletions(-)
delete mode 100644 .github/workflows/generate-phase3-docs.yml
diff --git a/.github/workflows/generate-phase3-docs.yml b/.github/workflows/generate-phase3-docs.yml
deleted file mode 100644
index d3069a2..0000000
--- a/.github/workflows/generate-phase3-docs.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-name: Generate Phase 3 OAuth docs
-
-on:
- push:
- branches:
- - phase3/canonical-oauth-fixtures
-
-permissions:
- contents: write
-
-jobs:
- generate-docs:
- if: github.actor != 'github-actions[bot]'
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout branch
- uses: actions/checkout@v4
- with:
- ref: phase3/canonical-oauth-fixtures
- fetch-depth: 0
-
- - name: Setup Bun
- uses: oven-sh/setup-bun@v2
- with:
- bun-version: '1.3.13'
-
- - name: Install dependencies
- run: bun install --frozen-lockfile
-
- - name: Generate documentation
- run: bun run docs
-
- - name: Commit generated documentation
- run: |
- if git diff --quiet -- README.md docs; then
- echo "Generated documentation is already current."
- exit 0
- fi
-
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add README.md docs
- git commit -m "docs: update OAuth fixture API"
- git push
From 2cca6526690f87ad0299a2bbab95ff097b46fb35 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:15:40 +0200
Subject: [PATCH 28/32] docs: capture generated OAuth fixture documentation
---
.github/workflows/ci.yml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fbdee6c..3fcbe55 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -75,6 +75,18 @@ jobs:
echo "No typecheck script found; skipping."
fi
+ - name: Generate documentation
+ run: bun run docs
+
+ - name: Upload generated documentation
+ uses: actions/upload-artifact@v4
+ with:
+ name: phase3-generated-docs
+ path: |
+ README.md
+ docs
+ if-no-files-found: error
+
- name: Check changesets
if: github.event_name == 'pull_request'
run: |
From 549d92585b9c0ca18515761a99e5fa25b3031bd1 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:17:47 +0200
Subject: [PATCH 29/32] docs: commit generated OAuth fixture documentation
---
.github/workflows/ci.yml | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3fcbe55..013c8dc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,7 +7,7 @@ on:
- main
permissions:
- contents: read
+ contents: write
jobs:
validate:
@@ -17,6 +17,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
+ ref: phase3/canonical-oauth-fixtures
fetch-depth: 0
- name: Setup Bun
@@ -78,15 +79,6 @@ jobs:
- name: Generate documentation
run: bun run docs
- - name: Upload generated documentation
- uses: actions/upload-artifact@v4
- with:
- name: phase3-generated-docs
- path: |
- README.md
- docs
- if-no-files-found: error
-
- name: Check changesets
if: github.event_name == 'pull_request'
run: |
@@ -95,3 +87,17 @@ jobs:
else
echo "No changeset status script found; skipping."
fi
+
+ - name: Commit generated documentation
+ if: github.actor != 'github-actions[bot]'
+ run: |
+ if git diff --quiet -- README.md docs; then
+ echo "Generated documentation is already current."
+ exit 0
+ fi
+
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add README.md docs
+ git commit -m "docs: update OAuth fixture API"
+ git push
From 7ad80a15925a30fe695413da9fd04a01ecdef07c Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:20:16 +0200
Subject: [PATCH 30/32] chore: restore read-only CI workflow
---
.github/workflows/ci.yml | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 013c8dc..fbdee6c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,7 +7,7 @@ on:
- main
permissions:
- contents: write
+ contents: read
jobs:
validate:
@@ -17,7 +17,6 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
- ref: phase3/canonical-oauth-fixtures
fetch-depth: 0
- name: Setup Bun
@@ -76,9 +75,6 @@ jobs:
echo "No typecheck script found; skipping."
fi
- - name: Generate documentation
- run: bun run docs
-
- name: Check changesets
if: github.event_name == 'pull_request'
run: |
@@ -87,17 +83,3 @@ jobs:
else
echo "No changeset status script found; skipping."
fi
-
- - name: Commit generated documentation
- if: github.actor != 'github-actions[bot]'
- run: |
- if git diff --quiet -- README.md docs; then
- echo "Generated documentation is already current."
- exit 0
- fi
-
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add README.md docs
- git commit -m "docs: update OAuth fixture API"
- git push
From 53cfac0e9fbbddda2f7a9321b799da9065537471 Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:22:04 +0200
Subject: [PATCH 31/32] chore: remove lint diagnostics
---
lint-phase3.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 lint-phase3.txt
diff --git a/lint-phase3.txt b/lint-phase3.txt
deleted file mode 100644
index a4b4342..0000000
--- a/lint-phase3.txt
+++ /dev/null
@@ -1 +0,0 @@
-$ ankhorage-eslint . --max-warnings=0
From 39c229088daa946e1d3cbbe4774976b0ae181dba Mon Sep 17 00:00:00 2001
From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com>
Date: Sun, 12 Jul 2026 11:24:16 +0200
Subject: [PATCH 32/32] docs: explain OAuth fixture redirect setup
---
docs/oauth-fixtures.md | 69 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 docs/oauth-fixtures.md
diff --git a/docs/oauth-fixtures.md b/docs/oauth-fixtures.md
new file mode 100644
index 0000000..bf788b1
--- /dev/null
+++ b/docs/oauth-fixtures.md
@@ -0,0 +1,69 @@
+# OAuth fixture setup
+
+The first-party OAuth fixtures configure the logical application callback route
+`auth/callback`. They never contain provider credentials or a complete deployment URL.
+Studio resolves that route into the platform-specific redirect URI when it generates the app.
+
+## Keep the two redirect layers separate
+
+OAuth through Supabase uses two different redirect layers:
+
+1. The provider redirects to Supabase Auth.
+2. Supabase Auth redirects back to the generated application.
+
+Do not register the application callback directly as the Google or Apple provider callback.
+
+## Google provider console
+
+Configure a Web application OAuth client in Google Auth Platform.
+
+- Authorized JavaScript origin: the application origin, such as `https://app.example.com`.
+- Authorized redirect URI: the callback shown on the Google provider page in the Supabase
+ Dashboard.
+- Hosted-project example: `https://.supabase.co/auth/v1/callback`.
+- Local Supabase example: `http://127.0.0.1:54321/auth/v1/callback`.
+
+When the Supabase project uses a custom Auth domain, use that domain's callback instead of the
+`supabase.co` example.
+
+Official reference:
+[Supabase Login with Google](https://supabase.com/docs/guides/auth/social-login/auth-google)
+
+## Apple developer console
+
+Configure Sign in with Apple for the App ID and Services ID used by the application.
+
+For the Services ID Website URLs:
+
+- Domain: the domain hosting Supabase Auth, commonly `.supabase.co`.
+- Return URL: `https://.supabase.co/auth/v1/callback`.
+
+Use the actual callback shown by the Supabase Apple provider configuration when a custom Auth
+hostname is configured.
+
+Official reference:
+[Supabase Login with Apple](https://supabase.com/docs/guides/auth/social-login/auth-apple)
+
+## Supabase redirect allow list
+
+The application-facing redirect URI must be added to the Supabase Auth Redirect URLs list.
+The fixture route resolves to values such as:
+
+- Web: `https://app.example.com/auth/callback`.
+- Local web: `http://localhost:/auth/callback`.
+- Native development or production build: `://auth/callback`.
+
+Use the exact generated scheme from the app configuration. Prefer exact production redirect URLs;
+reserve wildcard patterns for controlled local or preview environments.
+
+Official references:
+
+- [Supabase Redirect URLs](https://supabase.com/docs/guides/auth/redirect-urls)
+- [Supabase Native Mobile Deep Linking](https://supabase.com/docs/guides/auth/native-mobile-deep-linking)
+
+## What the fixtures prove
+
+The fixtures and their tests prove deterministic manifest generation, supported provider IDs,
+logical credential references, canonical callback routing, and absence of secret-shaped fields.
+They do not prove that an external Google or Apple tenant has been configured correctly, and they
+do not perform live provider authentication.