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. diff --git a/README.md b/README.md index c4401ca..3a5b8ad 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # TEMPLATES -![license: MIT](././docs/badges/license.svg) ![npm: v2.0.0](././docs/badges/npm.svg) ![runtime: bun](././docs/badges/runtime.svg) ![typescript: strict](././docs/badges/typescript.svg) ![eslint: checked](././docs/badges/eslint.svg) ![prettier: checked](././docs/badges/prettier.svg) ![build: checked](././docs/badges/build.svg) ![tests: checked](././docs/badges/tests.svg) ![docs: paradox](././docs/badges/docs.svg) +![license: MIT](././docs/badges/license.svg) ![npm: v2.1.0](././docs/badges/npm.svg) ![runtime: bun](././docs/badges/runtime.svg) ![typescript: strict](././docs/badges/typescript.svg) ![eslint: checked](././docs/badges/eslint.svg) ![prettier: checked](././docs/badges/prettier.svg) ![build: checked](././docs/badges/build.svg) ![tests: checked](././docs/badges/tests.svg) ![docs: paradox](././docs/badges/docs.svg) 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/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=="], 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 @@ - -npm: v2.0.0 + +npm: v2.1.0 npm -v2.0.0 +v2.1.0 diff --git a/docs/diagrams/architecture-overview.mmd b/docs/diagrams/architecture-overview.mmd index 45c4ef4..51424f1 100644 --- a/docs/diagrams/architecture-overview.mmd +++ b/docs/diagrams/architecture-overview.mmd @@ -30,13 +30,17 @@ graph TD 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"] diff --git a/docs/diagrams/export-graph.mmd b/docs/diagrams/export-graph.mmd index e8ad83b..ad3d07b 100644 --- a/docs/diagrams/export-graph.mmd +++ b/docs/diagrams/export-graph.mmd @@ -5,6 +5,7 @@ graph LR 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"] @@ -188,10 +189,18 @@ graph LR 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 @@ -201,6 +210,17 @@ graph LR 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 diff --git a/docs/diagrams/module-relationships.mmd b/docs/diagrams/module-relationships.mmd index 062e048..b216e14 100644 --- a/docs/diagrams/module-relationships.mmd +++ b/docs/diagrams/module-relationships.mmd @@ -5,6 +5,7 @@ graph LR 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"] @@ -190,11 +191,13 @@ graph LR 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 diff --git a/docs/diagrams/sequences/create-category-app-manifest.mmd b/docs/diagrams/sequences/create-category-app-manifest.mmd new file mode 100644 index 0000000..1b71107 --- /dev/null +++ b/docs/diagrams/sequences/create-category-app-manifest.mmd @@ -0,0 +1,19 @@ +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 diff --git a/docs/diagrams/sequences/create-oauth-fixture-manifest.mmd b/docs/diagrams/sequences/create-oauth-fixture-manifest.mmd new file mode 100644 index 0000000..40b427c --- /dev/null +++ b/docs/diagrams/sequences/create-oauth-fixture-manifest.mmd @@ -0,0 +1,27 @@ +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 diff --git a/docs/exports.json b/docs/exports.json index 80971e3..15af272 100644 --- a/docs/exports.json +++ b/docs/exports.json @@ -177,7 +177,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"], @@ -212,6 +212,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, @@ -250,6 +282,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, @@ -339,6 +396,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, diff --git a/docs/exports.md b/docs/exports.md index f6b7018..099233e 100644 --- a/docs/exports.md +++ b/docs/exports.md @@ -55,7 +55,7 @@ Source: `src/templates/starter/starter.types.ts:48:1` Kind: `function` Module: `src/generators/create-category-app.ts` -Source: `src/generators/create-category-app.ts:141:1` +Source: `src/generators/create-category-app.ts:67:1` ### Signatures @@ -65,6 +65,18 @@ Source: `src/generators/create-category-app.ts:141:1` - template: `"starter"` (optional) - returns: `AppManifest` +## createOAuthFixtureManifest + +Kind: `function` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:87:1` + +### Signatures + +- `(args: { category: AppCategory; fixture: OAuthFixtureId; template?: TemplateKind; overrides?: AppManifestOverrides; }) => AppManifest` + - args: `{ category: AppCategory; fixture: OAuthFixtureId; template?: TemplateKind; overrides?: AppManifestOverrides; }` + - returns: `AppManifest` + ## createStarterTemplate Kind: `function` @@ -78,6 +90,17 @@ Source: `src/templates/starter/starter.template.ts:36:1` - seed: `TemplateSeed` - returns: `AppManifest` +## listOAuthFixtures + +Kind: `function` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:79:1` + +### Signatures + +- `() => OAuthFixtureDefinition[]` + - returns: `OAuthFixtureDefinition[]` + ## listStarterTemplates Kind: `function` @@ -113,6 +136,51 @@ Source: `src/templates/starter/starter.registry.ts:124:1` - `() => readonly StarterTemplateSummary[]` - returns: `readonly StarterTemplateSummary[]` +## OAUTH_CALLBACK_ROUTE + +Kind: `value` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:8:14` + +## OAUTH_FIXTURE_IDS + +Kind: `value` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:9:14` + +## OAuthFixtureDefinition + +Kind: `type` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:16:1` + +### Members + +| Name | 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 + +Kind: `unknown` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:11:1` + +## resolveOAuthFixture + +Kind: `function` +Module: `src/fixtures/oauth.ts` +Source: `src/fixtures/oauth.ts:83:1` + +### Signatures + +- `(id: "google" | "apple" | "google-apple") => OAuthFixtureDefinition` + - id: `"google" | "apple" | "google-apple"` + - returns: `OAuthFixtureDefinition` + ## resolveStarterTemplate Kind: `function` diff --git a/docs/index.html b/docs/index.html index 7ebb3fb..b463b55 100644 --- a/docs/index.html +++ b/docs/index.html @@ -225,6 +225,12 @@

TEMPLATES

19 functions +
  • + +
  • @@ -1249,9 +1255,9 @@

    TEMPLATES

    Package overview

    -
    21public exports
    +
    28public exports
    0components
    -
    175modules
    +
    176modules
    1entrypoints

    Entrypoints

    @@ -1348,7 +1354,25 @@

    src/commands.ts

    +

    src/fixtures/oauth.ts

    +

    Referenced module

    +

    + 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 +

    +
    +

    src/generators/create-category-app.ts

    Referenced module

    @@ -1356,15 +1380,13 @@

    src/generators/create-category-app.ts

    Dependencies: 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

    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
    + + + + + + + + + + + + + + + + + +
    ParameterTypeRequiredDescription
    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
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MemberKindTypeRequiredDescription
    descriptionpropertystringyes
    idproperty + "google" | "apple" | "google-apple" + yes
    labelpropertystringyes
    oauthproperty + 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
    + + + + + + + + + + + + + + + + + +
    ParameterTypeRequiredDescription
    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/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/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. 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", 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": { diff --git a/src/fixtures/oauth.ts b/src/fixtures/oauth.ts new file mode 100644 index 0000000..7e42567 --- /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; +} + +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', + 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]), + }, +}; + +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, + }, + }, + }); +} 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); } 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 { diff --git a/test/oauth-auth-templates.test.ts b/test/oauth-auth-templates.test.ts index 9d6c967..f3105de 100644 --- a/test/oauth-auth-templates.test.ts +++ b/test/oauth-auth-templates.test.ts @@ -1,108 +1,117 @@ -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.startsWith('/')).toBe(false); + 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'); + 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); }); }); 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',