@tappify/cli 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -31
- package/dist/src/app.module.js +6 -2
- package/dist/src/app.module.js.map +1 -1
- package/dist/src/core/api/api.service.d.ts +28 -2
- package/dist/src/core/api/api.service.js +151 -27
- package/dist/src/core/api/api.service.js.map +1 -1
- package/dist/src/core/auth/auth.service.d.ts +2 -0
- package/dist/src/core/auth/auth.service.js +31 -3
- package/dist/src/core/auth/auth.service.js.map +1 -1
- package/dist/src/core/config/config.service.d.ts +11 -2
- package/dist/src/core/config/config.service.js +13 -3
- package/dist/src/core/config/config.service.js.map +1 -1
- package/dist/src/core/core.module.js +33 -2
- package/dist/src/core/core.module.js.map +1 -1
- package/dist/src/core/environment/environment.service.d.ts +24 -0
- package/dist/src/core/environment/environment.service.js +93 -0
- package/dist/src/core/environment/environment.service.js.map +1 -0
- package/dist/src/core/environment/index.d.ts +1 -0
- package/dist/src/core/environment/index.js +18 -0
- package/dist/src/core/environment/index.js.map +1 -0
- package/dist/src/core/image/image-size.d.ts +5 -0
- package/dist/src/core/image/image-size.js +37 -0
- package/dist/src/core/image/image-size.js.map +1 -0
- package/dist/src/core/image/index.d.ts +1 -0
- package/dist/src/{domains/init/runners → core/image}/index.js +1 -1
- package/dist/src/core/image/index.js.map +1 -0
- package/dist/src/core/index.d.ts +10 -0
- package/dist/src/core/index.js +10 -0
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/link/project-link.service.d.ts +13 -0
- package/dist/src/{domains/init/runners/init.runner.js → core/link/project-link.service.js} +54 -44
- package/dist/src/core/link/project-link.service.js.map +1 -0
- package/dist/src/core/manifest/index.d.ts +2 -0
- package/dist/src/core/manifest/index.js +19 -0
- package/dist/src/core/manifest/index.js.map +1 -0
- package/dist/src/core/manifest/manifest.service.d.ts +14 -0
- package/dist/src/core/manifest/manifest.service.js +141 -0
- package/dist/src/core/manifest/manifest.service.js.map +1 -0
- package/dist/src/core/manifest/scope-rules.d.ts +8 -0
- package/dist/src/core/manifest/scope-rules.js +95 -0
- package/dist/src/core/manifest/scope-rules.js.map +1 -0
- package/dist/src/core/output/colors.d.ts +6 -0
- package/dist/src/core/output/colors.js +27 -0
- package/dist/src/core/output/colors.js.map +1 -0
- package/dist/src/core/output/index.d.ts +2 -0
- package/dist/src/core/output/index.js +19 -0
- package/dist/src/core/output/index.js.map +1 -0
- package/dist/src/core/output/output.service.d.ts +37 -0
- package/dist/src/core/output/output.service.js +119 -0
- package/dist/src/core/output/output.service.js.map +1 -0
- package/dist/src/core/project/index.d.ts +1 -0
- package/dist/src/core/project/index.js +18 -0
- package/dist/src/core/project/index.js.map +1 -0
- package/dist/src/core/project/package-manager.d.ts +6 -0
- package/dist/src/core/project/package-manager.js +47 -0
- package/dist/src/core/project/package-manager.js.map +1 -0
- package/dist/src/core/prompt/prompt.service.d.ts +17 -0
- package/dist/src/core/prompt/prompt.service.js +299 -0
- package/dist/src/core/prompt/prompt.service.js.map +1 -0
- package/dist/src/core/registry/index.d.ts +1 -0
- package/dist/src/core/registry/index.js +18 -0
- package/dist/src/core/registry/index.js.map +1 -0
- package/dist/src/core/registry/registry.service.d.ts +55 -0
- package/dist/src/core/registry/registry.service.js +119 -0
- package/dist/src/core/registry/registry.service.js.map +1 -0
- package/dist/src/core/shell/shell.service.d.ts +10 -5
- package/dist/src/core/shell/shell.service.js +109 -15
- package/dist/src/core/shell/shell.service.js.map +1 -1
- package/dist/src/core/shutdown/teardown.d.ts +3 -0
- package/dist/src/core/shutdown/teardown.js +22 -0
- package/dist/src/core/shutdown/teardown.js.map +1 -0
- package/dist/src/core/templates/index.d.ts +1 -0
- package/dist/src/core/templates/index.js +18 -0
- package/dist/src/core/templates/index.js.map +1 -0
- package/dist/src/core/templates/template.service.d.ts +10 -0
- package/dist/src/core/templates/template.service.js +91 -0
- package/dist/src/core/templates/template.service.js.map +1 -0
- package/dist/src/core/update/update-notifier.d.ts +6 -0
- package/dist/src/core/update/update-notifier.js +90 -28
- package/dist/src/core/update/update-notifier.js.map +1 -1
- package/dist/src/core/version.d.ts +5 -0
- package/dist/src/core/version.js +21 -0
- package/dist/src/core/version.js.map +1 -0
- package/dist/src/domains/auth/runners/login.runner.js +5 -1
- package/dist/src/domains/auth/runners/login.runner.js.map +1 -1
- package/dist/src/domains/auth/runners/logout.runner.js +1 -1
- package/dist/src/domains/auth/runners/logout.runner.js.map +1 -1
- package/dist/src/domains/deployments/runners/configure.runner.d.ts +6 -1
- package/dist/src/domains/deployments/runners/configure.runner.js +231 -200
- package/dist/src/domains/deployments/runners/configure.runner.js.map +1 -1
- package/dist/src/domains/environment/environment.module.d.ts +2 -0
- package/dist/src/domains/environment/environment.module.js +25 -0
- package/dist/src/domains/environment/environment.module.js.map +1 -0
- package/dist/src/domains/environment/index.d.ts +2 -0
- package/dist/src/domains/{deploy → environment}/index.js +1 -1
- package/dist/src/domains/environment/index.js.map +1 -0
- package/dist/src/domains/environment/runners/environment-current.runner.d.ts +7 -0
- package/dist/src/domains/environment/runners/environment-current.runner.js +35 -0
- package/dist/src/domains/environment/runners/environment-current.runner.js.map +1 -0
- package/dist/src/domains/environment/runners/environment-switcher.service.d.ts +11 -0
- package/dist/src/domains/environment/runners/environment-switcher.service.js +74 -0
- package/dist/src/domains/environment/runners/environment-switcher.service.js.map +1 -0
- package/dist/src/domains/environment/runners/environment-use.runner.d.ts +11 -0
- package/dist/src/domains/environment/runners/environment-use.runner.js +46 -0
- package/dist/src/domains/environment/runners/environment-use.runner.js.map +1 -0
- package/dist/src/domains/environment/runners/environment.command.d.ts +12 -0
- package/dist/src/domains/environment/runners/environment.command.js +53 -0
- package/dist/src/domains/environment/runners/environment.command.js.map +1 -0
- package/dist/src/domains/environment/runners/index.d.ts +4 -0
- package/dist/src/domains/environment/runners/index.js +21 -0
- package/dist/src/domains/environment/runners/index.js.map +1 -0
- package/dist/src/domains/extension/containers.d.ts +13 -0
- package/dist/src/domains/extension/containers.js +239 -0
- package/dist/src/domains/extension/containers.js.map +1 -0
- package/dist/src/domains/extension/extension.module.d.ts +2 -0
- package/dist/src/domains/extension/extension.module.js +66 -0
- package/dist/src/domains/extension/extension.module.js.map +1 -0
- package/dist/src/domains/extension/index.d.ts +1 -0
- package/dist/src/domains/extension/index.js +18 -0
- package/dist/src/domains/extension/index.js.map +1 -0
- package/dist/src/domains/extension/kinds.assistant.d.ts +2 -0
- package/dist/src/domains/extension/kinds.assistant.js +296 -0
- package/dist/src/domains/extension/kinds.assistant.js.map +1 -0
- package/dist/src/domains/extension/kinds.d.ts +8 -0
- package/dist/src/domains/extension/kinds.js +42 -0
- package/dist/src/domains/extension/kinds.js.map +1 -0
- package/dist/src/domains/extension/kinds.server.d.ts +3 -0
- package/dist/src/domains/extension/kinds.server.js +221 -0
- package/dist/src/domains/extension/kinds.server.js.map +1 -0
- package/dist/src/domains/extension/kinds.types.d.ts +65 -0
- package/dist/src/domains/extension/kinds.types.js +98 -0
- package/dist/src/domains/extension/kinds.types.js.map +1 -0
- package/dist/src/domains/extension/kinds.ui.d.ts +4 -0
- package/dist/src/domains/extension/kinds.ui.js +309 -0
- package/dist/src/domains/extension/kinds.ui.js.map +1 -0
- package/dist/src/domains/extension/labels.d.ts +27 -0
- package/dist/src/domains/extension/labels.js +143 -0
- package/dist/src/domains/extension/labels.js.map +1 -0
- package/dist/src/domains/extension/runners/add.runner.d.ts +69 -0
- package/dist/src/domains/extension/runners/add.runner.js +453 -0
- package/dist/src/domains/extension/runners/add.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/dev.runner.d.ts +33 -0
- package/dist/src/domains/extension/runners/dev.runner.js +257 -0
- package/dist/src/domains/extension/runners/dev.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/doctor.runner.d.ts +18 -0
- package/dist/src/domains/extension/runners/doctor.runner.js +107 -0
- package/dist/src/domains/extension/runners/doctor.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/events-add.runner.d.ts +12 -0
- package/dist/src/domains/extension/runners/events-add.runner.js +97 -0
- package/dist/src/domains/extension/runners/events-add.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/events-remove.runner.d.ts +10 -0
- package/dist/src/domains/extension/runners/events-remove.runner.js +75 -0
- package/dist/src/domains/extension/runners/events-remove.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/events.runner.d.ts +6 -0
- package/dist/src/domains/extension/runners/events.runner.js +40 -0
- package/dist/src/domains/extension/runners/events.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/extension.command.d.ts +10 -0
- package/dist/src/domains/extension/runners/extension.command.js +71 -0
- package/dist/src/domains/extension/runners/extension.command.js.map +1 -0
- package/dist/src/domains/extension/runners/extension.runner.d.ts +17 -0
- package/dist/src/domains/extension/runners/extension.runner.js +53 -0
- package/dist/src/domains/extension/runners/extension.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/index.d.ts +20 -0
- package/dist/src/domains/extension/runners/index.js +37 -0
- package/dist/src/domains/extension/runners/index.js.map +1 -0
- package/dist/src/domains/extension/runners/init.runner.d.ts +31 -0
- package/dist/src/domains/extension/runners/init.runner.js +276 -0
- package/dist/src/domains/extension/runners/init.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/list.runner.d.ts +10 -0
- package/dist/src/domains/extension/runners/list.runner.js +79 -0
- package/dist/src/domains/extension/runners/list.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/publish.runner.d.ts +38 -0
- package/dist/src/domains/extension/runners/publish.runner.js +178 -0
- package/dist/src/domains/extension/runners/publish.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/remove.runner.d.ts +20 -0
- package/dist/src/domains/extension/runners/remove.runner.js +105 -0
- package/dist/src/domains/extension/runners/remove.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/retire.runner.d.ts +18 -0
- package/dist/src/domains/extension/runners/retire.runner.js +80 -0
- package/dist/src/domains/extension/runners/retire.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/scopes-add.runner.d.ts +16 -0
- package/dist/src/domains/extension/runners/scopes-add.runner.js +122 -0
- package/dist/src/domains/extension/runners/scopes-add.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/scopes-remove.runner.d.ts +12 -0
- package/dist/src/domains/extension/runners/scopes-remove.runner.js +73 -0
- package/dist/src/domains/extension/runners/scopes-remove.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/scopes.runner.d.ts +6 -0
- package/dist/src/domains/extension/runners/scopes.runner.js +40 -0
- package/dist/src/domains/extension/runners/scopes.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/set.runner.d.ts +17 -0
- package/dist/src/domains/extension/runners/set.runner.js +157 -0
- package/dist/src/domains/extension/runners/set.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/status.runner.d.ts +12 -0
- package/dist/src/domains/extension/runners/status.runner.js +88 -0
- package/dist/src/domains/extension/runners/status.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/types.runner.d.ts +10 -0
- package/dist/src/domains/extension/runners/types.runner.js +43 -0
- package/dist/src/domains/extension/runners/types.runner.js.map +1 -0
- package/dist/src/domains/extension/runners/whoami.runner.d.ts +10 -0
- package/dist/src/domains/extension/runners/whoami.runner.js +71 -0
- package/dist/src/domains/extension/runners/whoami.runner.js.map +1 -0
- package/dist/src/domains/extension/services/add.service.d.ts +26 -0
- package/dist/src/domains/extension/services/add.service.js +263 -0
- package/dist/src/domains/extension/services/add.service.js.map +1 -0
- package/dist/src/domains/extension/services/checks/a11y-check.d.ts +3 -0
- package/dist/src/domains/extension/services/checks/a11y-check.js +84 -0
- package/dist/src/domains/extension/services/checks/a11y-check.js.map +1 -0
- package/dist/src/domains/extension/services/checks/bundle-checks.d.ts +3 -0
- package/dist/src/domains/extension/services/checks/bundle-checks.js +234 -0
- package/dist/src/domains/extension/services/checks/bundle-checks.js.map +1 -0
- package/dist/src/domains/extension/services/checks/bundle-files.d.ts +14 -0
- package/dist/src/domains/extension/services/checks/bundle-files.js +139 -0
- package/dist/src/domains/extension/services/checks/bundle-files.js.map +1 -0
- package/dist/src/domains/extension/services/checks/file-checks.d.ts +6 -0
- package/dist/src/domains/extension/services/checks/file-checks.js +128 -0
- package/dist/src/domains/extension/services/checks/file-checks.js.map +1 -0
- package/dist/src/domains/extension/services/checks/index.d.ts +7 -0
- package/dist/src/domains/extension/services/checks/index.js +24 -0
- package/dist/src/domains/extension/services/checks/index.js.map +1 -0
- package/dist/src/domains/extension/services/checks/manifest-checks.d.ts +7 -0
- package/dist/src/domains/extension/services/checks/manifest-checks.js +95 -0
- package/dist/src/domains/extension/services/checks/manifest-checks.js.map +1 -0
- package/dist/src/domains/extension/services/checks/project-checks.d.ts +7 -0
- package/dist/src/domains/extension/services/checks/project-checks.js +86 -0
- package/dist/src/domains/extension/services/checks/project-checks.js.map +1 -0
- package/dist/src/domains/extension/services/checks/types.d.ts +23 -0
- package/dist/src/domains/extension/services/checks/types.js +50 -0
- package/dist/src/domains/extension/services/checks/types.js.map +1 -0
- package/dist/src/domains/extension/services/dev.service.d.ts +26 -0
- package/dist/src/domains/extension/services/dev.service.js +58 -0
- package/dist/src/domains/extension/services/dev.service.js.map +1 -0
- package/dist/src/domains/extension/services/doctor.service.d.ts +36 -0
- package/dist/src/domains/extension/services/doctor.service.js +213 -0
- package/dist/src/domains/extension/services/doctor.service.js.map +1 -0
- package/dist/src/domains/extension/services/failures.d.ts +8 -0
- package/dist/src/domains/extension/services/failures.js +112 -0
- package/dist/src/domains/extension/services/failures.js.map +1 -0
- package/dist/src/domains/extension/services/guided.service.d.ts +36 -0
- package/dist/src/domains/extension/services/guided.service.js +133 -0
- package/dist/src/domains/extension/services/guided.service.js.map +1 -0
- package/dist/src/domains/extension/services/publish.service.d.ts +14 -0
- package/dist/src/domains/extension/services/publish.service.js +93 -0
- package/dist/src/domains/extension/services/publish.service.js.map +1 -0
- package/dist/src/domains/extension/services/registration.service.d.ts +7 -0
- package/dist/src/domains/extension/services/registration.service.js +43 -0
- package/dist/src/domains/extension/services/registration.service.js.map +1 -0
- package/dist/src/domains/extension/services/remove.service.d.ts +22 -0
- package/dist/src/domains/extension/services/remove.service.js +137 -0
- package/dist/src/domains/extension/services/remove.service.js.map +1 -0
- package/dist/src/domains/extension/services/types.service.d.ts +21 -0
- package/dist/src/domains/extension/services/types.service.js +81 -0
- package/dist/src/domains/extension/services/types.service.js.map +1 -0
- package/dist/src/domains/index.d.ts +6 -2
- package/dist/src/domains/index.js +6 -2
- package/dist/src/domains/index.js.map +1 -1
- package/dist/src/domains/{init → link}/index.d.ts +1 -1
- package/dist/src/domains/{init → link}/index.js +1 -1
- package/dist/src/domains/link/index.js.map +1 -0
- package/dist/src/domains/link/link.module.d.ts +2 -0
- package/dist/src/domains/{init/init.module.js → link/link.module.js} +8 -8
- package/dist/src/domains/link/link.module.js.map +1 -0
- package/dist/src/domains/link/runners/index.d.ts +1 -0
- package/dist/src/domains/{deploy → link}/runners/index.js +1 -1
- package/dist/src/domains/link/runners/index.js.map +1 -0
- package/dist/src/domains/link/runners/link.runner.d.ts +20 -0
- package/dist/src/domains/link/runners/link.runner.js +129 -0
- package/dist/src/domains/link/runners/link.runner.js.map +1 -0
- package/dist/src/domains/mcp/index.d.ts +5 -0
- package/dist/src/domains/mcp/index.js +22 -0
- package/dist/src/domains/mcp/index.js.map +1 -0
- package/dist/src/domains/mcp/mcp.module.d.ts +2 -0
- package/dist/src/domains/mcp/mcp.module.js +25 -0
- package/dist/src/domains/mcp/mcp.module.js.map +1 -0
- package/dist/src/domains/mcp/runners/mcp.runner.d.ts +7 -0
- package/dist/src/domains/mcp/runners/mcp.runner.js +45 -0
- package/dist/src/domains/mcp/runners/mcp.runner.js.map +1 -0
- package/dist/src/domains/mcp/services/docs-search.service.d.ts +23 -0
- package/dist/src/domains/mcp/services/docs-search.service.js +164 -0
- package/dist/src/domains/mcp/services/docs-search.service.js.map +1 -0
- package/dist/src/domains/mcp/services/mcp-server.factory.d.ts +42 -0
- package/dist/src/domains/mcp/services/mcp-server.factory.js +438 -0
- package/dist/src/domains/mcp/services/mcp-server.factory.js.map +1 -0
- package/dist/src/domains/mcp/services/validate.service.d.ts +17 -0
- package/dist/src/domains/mcp/services/validate.service.js +57 -0
- package/dist/src/domains/mcp/services/validate.service.js.map +1 -0
- package/dist/src/domains/upgrade/index.d.ts +1 -0
- package/dist/src/domains/upgrade/index.js +18 -0
- package/dist/src/domains/upgrade/index.js.map +1 -0
- package/dist/src/domains/upgrade/runners/index.d.ts +1 -0
- package/dist/src/domains/upgrade/runners/index.js +18 -0
- package/dist/src/domains/upgrade/runners/index.js.map +1 -0
- package/dist/src/domains/upgrade/runners/upgrade.runner.d.ts +12 -0
- package/dist/src/domains/upgrade/runners/upgrade.runner.js +191 -0
- package/dist/src/domains/upgrade/runners/upgrade.runner.js.map +1 -0
- package/dist/src/domains/upgrade/upgrade.module.d.ts +2 -0
- package/dist/src/domains/{deploy/deploy.module.js → upgrade/upgrade.module.js} +8 -8
- package/dist/src/domains/upgrade/upgrade.module.js.map +1 -0
- package/dist/src/domains/vendor/index.d.ts +1 -0
- package/dist/src/domains/vendor/index.js +18 -0
- package/dist/src/domains/vendor/index.js.map +1 -0
- package/dist/src/domains/vendor/runners/index.d.ts +2 -0
- package/dist/src/domains/vendor/runners/index.js +19 -0
- package/dist/src/domains/vendor/runners/index.js.map +1 -0
- package/dist/src/domains/vendor/runners/vendor-create.runner.d.ts +20 -0
- package/dist/src/domains/vendor/runners/vendor-create.runner.js +121 -0
- package/dist/src/domains/vendor/runners/vendor-create.runner.js.map +1 -0
- package/dist/src/domains/vendor/runners/vendor.command.d.ts +10 -0
- package/dist/src/domains/vendor/runners/vendor.command.js +42 -0
- package/dist/src/domains/vendor/runners/vendor.command.js.map +1 -0
- package/dist/src/domains/vendor/vendor.module.d.ts +2 -0
- package/dist/src/domains/vendor/vendor.module.js +22 -0
- package/dist/src/domains/vendor/vendor.module.js.map +1 -0
- package/dist/src/main.js +16 -2
- package/dist/src/main.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +43 -7
- package/templates/contributions/action/schemas/__file__.input.json +14 -0
- package/templates/contributions/action/server/actions/__file__.ts +8 -0
- package/templates/contributions/connector/server/metrics.ts +19 -0
- package/templates/contributions/context/server/context/__file__.ts +10 -0
- package/templates/contributions/knowledge/knowledge/__file__.md +6 -0
- package/templates/contributions/mention/server/mentions/__file__.ts +10 -0
- package/templates/contributions/page/src/pages/__file__.tsx +21 -0
- package/templates/contributions/page/test/__file__.test.tsx +12 -0
- package/templates/contributions/procedure/schemas/__file__.input.json +13 -0
- package/templates/contributions/procedure/schemas/__file__.output.json +13 -0
- package/templates/contributions/procedure/server/procedures/__file__.ts +13 -0
- package/templates/contributions/prompt/schemas/__file__.input.json +14 -0
- package/templates/contributions/row-action/src/row-actions/__file__.tsx +20 -0
- package/templates/contributions/row-action/test/__file__.test.tsx +17 -0
- package/templates/contributions/settings/schemas/settings.json +14 -0
- package/templates/contributions/settings/src/settings.tsx +24 -0
- package/templates/contributions/settings/test/settings.test.tsx +12 -0
- package/templates/contributions/skill/skills/__file__.md +14 -0
- package/templates/contributions/storage/schemas/__file__.json +14 -0
- package/templates/contributions/tab/src/tabs/__file__.tsx +21 -0
- package/templates/contributions/tab/test/__file__.test.tsx +12 -0
- package/templates/contributions/tool/schemas/__file__.input.json +14 -0
- package/templates/contributions/tool/server/tools/__file__.ts +8 -0
- package/templates/contributions/webhook/schemas/__file__.payload.json +13 -0
- package/templates/contributions/widget/src/widgets/__file__.tsx +48 -0
- package/templates/contributions/widget/test/__file__.test.tsx +16 -0
- package/templates/contributions/work/server/work.ts +14 -0
- package/templates/starter/README.md +75 -0
- package/templates/starter/api/tappify/[...path].ts +6 -0
- package/templates/starter/gitignore +6 -0
- package/templates/starter/icon.svg +4 -0
- package/templates/starter/package.json +37 -0
- package/templates/starter/pnpm-workspace.yaml +3 -0
- package/templates/starter/schemas/get-summary.input.json +11 -0
- package/templates/starter/schemas/get-summary.output.json +12 -0
- package/templates/starter/schemas/preferences.json +18 -0
- package/templates/starter/schemas/settings.json +19 -0
- package/templates/starter/server/actions/index.ts +1 -0
- package/templates/starter/server/context/index.ts +1 -0
- package/templates/starter/server/handler.ts +25 -0
- package/templates/starter/server/mentions/index.ts +1 -0
- package/templates/starter/server/procedures/get-summary.ts +32 -0
- package/templates/starter/server/procedures/index.ts +5 -0
- package/templates/starter/server/tools/index.ts +1 -0
- package/templates/starter/server/worker.ts +5 -0
- package/templates/starter/src/settings.tsx +24 -0
- package/templates/starter/src/styles.css +16 -0
- package/templates/starter/src/tappify.d.ts +59 -0
- package/templates/starter/src/widgets/summary.tsx +122 -0
- package/templates/starter/tappify.extension.json +68 -0
- package/templates/starter/test/matchers.d.ts +2 -0
- package/templates/starter/test/server.test.ts +69 -0
- package/templates/starter/test/settings.test.tsx +46 -0
- package/templates/starter/test/summary.test.tsx +109 -0
- package/templates/starter/tsconfig.json +20 -0
- package/templates/starter/vite.config.ts +8 -0
- package/templates/starter/vitest.config.ts +29 -0
- package/templates/starter/wrangler.toml +7 -0
- package/dist/src/domains/deploy/deploy.module.d.ts +0 -2
- package/dist/src/domains/deploy/deploy.module.js.map +0 -1
- package/dist/src/domains/deploy/index.d.ts +0 -2
- package/dist/src/domains/deploy/index.js.map +0 -1
- package/dist/src/domains/deploy/runners/deploy.runner.d.ts +0 -10
- package/dist/src/domains/deploy/runners/deploy.runner.js +0 -132
- package/dist/src/domains/deploy/runners/deploy.runner.js.map +0 -1
- package/dist/src/domains/deploy/runners/index.d.ts +0 -1
- package/dist/src/domains/deploy/runners/index.js.map +0 -1
- package/dist/src/domains/init/index.js.map +0 -1
- package/dist/src/domains/init/init.module.d.ts +0 -2
- package/dist/src/domains/init/init.module.js.map +0 -1
- package/dist/src/domains/init/runners/index.d.ts +0 -1
- package/dist/src/domains/init/runners/index.js.map +0 -1
- package/dist/src/domains/init/runners/init.runner.d.ts +0 -4
- package/dist/src/domains/init/runners/init.runner.js.map +0 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__id__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "__description__",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "vite",
|
|
9
|
+
"build": "vite build",
|
|
10
|
+
"typecheck": "tsc --noEmit",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"types": "tappify extension types",
|
|
13
|
+
"dev:worker": "wrangler dev",
|
|
14
|
+
"deploy:worker": "wrangler deploy"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@tanstack/react-query": "^5.100.14",
|
|
18
|
+
"@tappify/extension-sdk": "^2.0.0",
|
|
19
|
+
"react": "^19.2.6",
|
|
20
|
+
"react-dom": "^19.2.6"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@module-federation/vite": "~1.16.0",
|
|
24
|
+
"@testing-library/jest-dom": "^7.0.0",
|
|
25
|
+
"@testing-library/react": "^16.1.0",
|
|
26
|
+
"@testing-library/user-event": "^14.5.2",
|
|
27
|
+
"@types/node": "^22.13.0",
|
|
28
|
+
"@types/react": "^19.2.15",
|
|
29
|
+
"@types/react-dom": "^19.2.3",
|
|
30
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
31
|
+
"happy-dom": "^17.0.0",
|
|
32
|
+
"typescript": "^5.7.0",
|
|
33
|
+
"vite": "^8.0.14",
|
|
34
|
+
"vitest": "^4.1.0",
|
|
35
|
+
"wrangler": "^4.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "GetSummaryInput",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"days": { "type": "number" },
|
|
7
|
+
"platform": { "type": "string", "enum": ["ios", "android", "all"] }
|
|
8
|
+
},
|
|
9
|
+
"required": ["days", "platform"],
|
|
10
|
+
"additionalProperties": false
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "GetSummaryOutput",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"installs": { "type": "number" },
|
|
7
|
+
"delta": { "type": "number" },
|
|
8
|
+
"topKeyword": { "type": "string" }
|
|
9
|
+
},
|
|
10
|
+
"required": ["installs", "delta"],
|
|
11
|
+
"additionalProperties": false
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Preferences",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"compact": {
|
|
7
|
+
"type": "boolean",
|
|
8
|
+
"description": "Render the summary on one line"
|
|
9
|
+
},
|
|
10
|
+
"metric": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": ["downloads", "impressions"],
|
|
13
|
+
"description": "Which series the summary reports"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": ["compact", "metric"],
|
|
17
|
+
"additionalProperties": false
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Settings",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"refreshMinutes": {
|
|
7
|
+
"type": "number",
|
|
8
|
+
"title": "Refresh minutes",
|
|
9
|
+
"description": "How often the summary asks the server for new numbers"
|
|
10
|
+
},
|
|
11
|
+
"showDelta": {
|
|
12
|
+
"type": "boolean",
|
|
13
|
+
"title": "Show change",
|
|
14
|
+
"description": "Show the change against the previous period"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["refreshMinutes"],
|
|
18
|
+
"additionalProperties": false
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const actions = {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const context = {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTappifyHandler,
|
|
3
|
+
type TappifyFetchHandler,
|
|
4
|
+
type TappifyHandlerOptions,
|
|
5
|
+
} from '@tappify/extension-sdk/server';
|
|
6
|
+
import { actions } from './actions';
|
|
7
|
+
import { context } from './context';
|
|
8
|
+
import { mentions } from './mentions';
|
|
9
|
+
import { procedures } from './procedures';
|
|
10
|
+
import { tools } from './tools';
|
|
11
|
+
|
|
12
|
+
export const handlerOptions: TappifyHandlerOptions = {
|
|
13
|
+
extensionId: '__id__',
|
|
14
|
+
|
|
15
|
+
health: () => ({ ok: true, version: '0.1.0' }),
|
|
16
|
+
|
|
17
|
+
procedures,
|
|
18
|
+
tools,
|
|
19
|
+
actions,
|
|
20
|
+
mentions,
|
|
21
|
+
context,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const handler: TappifyFetchHandler =
|
|
25
|
+
createTappifyHandler(handlerOptions);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const mentions = {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TapProcedureInput,
|
|
3
|
+
TapProcedureOutput,
|
|
4
|
+
} from '@tappify/extension-sdk';
|
|
5
|
+
import { TapServerError } from '@tappify/extension-sdk/server';
|
|
6
|
+
import type { TappifyRequest } from '@tappify/extension-sdk/server';
|
|
7
|
+
|
|
8
|
+
const BASELINE_INSTALLS_PER_DAY = 180;
|
|
9
|
+
|
|
10
|
+
export function getSummary(
|
|
11
|
+
request: TappifyRequest<TapProcedureInput<'getSummary'>>,
|
|
12
|
+
): TapProcedureOutput<'getSummary'> {
|
|
13
|
+
const { days, platform } = request.input;
|
|
14
|
+
|
|
15
|
+
if (days < 1) {
|
|
16
|
+
throw new TapServerError(
|
|
17
|
+
'RANGE_TOO_SHORT',
|
|
18
|
+
'getSummary needs a range of at least one day. Widen the date picker, then retry.',
|
|
19
|
+
400,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const multiplier = platform === 'all' ? 1 : 0.55;
|
|
24
|
+
const installs = Math.round(BASELINE_INSTALLS_PER_DAY * days * multiplier);
|
|
25
|
+
const previous = Math.round(installs * 0.92);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
installs,
|
|
29
|
+
delta: (installs - previous) / previous,
|
|
30
|
+
topKeyword: 'photo editor',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const tools = {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TapForm,
|
|
3
|
+
TapPageHeader,
|
|
4
|
+
type TapSettingsProps,
|
|
5
|
+
} from '@tappify/extension-sdk';
|
|
6
|
+
import '@tappify/extension-sdk/styles.css';
|
|
7
|
+
import schema from '../schemas/settings.json';
|
|
8
|
+
|
|
9
|
+
export default function Settings({ values, onChange }: TapSettingsProps) {
|
|
10
|
+
return (
|
|
11
|
+
<div className="tap-stack">
|
|
12
|
+
<TapPageHeader
|
|
13
|
+
title="__title__"
|
|
14
|
+
description="These values reach your server as documents.settings on every call."
|
|
15
|
+
/>
|
|
16
|
+
<TapForm
|
|
17
|
+
schema={schema}
|
|
18
|
+
value={values}
|
|
19
|
+
submitLabel="Save"
|
|
20
|
+
onSubmit={next => onChange(next)}
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.starter-summary {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.starter-summary--compact {
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
align-items: baseline;
|
|
10
|
+
gap: 8px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.starter-summary__footnote {
|
|
14
|
+
color: var(--fg-muted, rgba(18, 18, 18, 0.6));
|
|
15
|
+
font-size: 11px;
|
|
16
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Generated by `tappify extension types`. Do not edit by hand.
|
|
4
|
+
* Re-run the command after changing tappify.extension.json or any schema it points at.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface Preferences {
|
|
8
|
+
/**
|
|
9
|
+
* Render the summary on one line
|
|
10
|
+
*/
|
|
11
|
+
compact: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Which series the summary reports
|
|
14
|
+
*/
|
|
15
|
+
metric: 'downloads' | 'impressions';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface GetSummaryInput {
|
|
19
|
+
days: number;
|
|
20
|
+
platform: 'ios' | 'android' | 'all';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface GetSummaryOutput {
|
|
24
|
+
installs: number;
|
|
25
|
+
delta: number;
|
|
26
|
+
topKeyword?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* How often the summary asks the server for new numbers
|
|
31
|
+
*/
|
|
32
|
+
export type RefreshMinutes = number;
|
|
33
|
+
/**
|
|
34
|
+
* Show the change against the previous period
|
|
35
|
+
*/
|
|
36
|
+
export type ShowChange = boolean;
|
|
37
|
+
|
|
38
|
+
export interface Settings {
|
|
39
|
+
refreshMinutes: RefreshMinutes;
|
|
40
|
+
showDelta?: ShowChange;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare module '@tappify/extension-sdk' {
|
|
44
|
+
interface TapStorageMap {
|
|
45
|
+
'preferences': { kind: 'singleton'; scope: 'user'; document: Preferences };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface TapProcedureMap {
|
|
49
|
+
'getSummary': { input: GetSummaryInput; output: GetSummaryOutput };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface TapTelemetryEvents {
|
|
53
|
+
'summary_viewed': true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface TapSettings extends Settings {}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TapButton,
|
|
3
|
+
TapCard,
|
|
4
|
+
TapErrorState,
|
|
5
|
+
TapSkeleton,
|
|
6
|
+
TapStat,
|
|
7
|
+
cn,
|
|
8
|
+
useTap,
|
|
9
|
+
useTapFilters,
|
|
10
|
+
useTapQuery,
|
|
11
|
+
useTapServer,
|
|
12
|
+
useTapStorage,
|
|
13
|
+
type TapSeriesPoint,
|
|
14
|
+
type TapWidgetProps,
|
|
15
|
+
} from '@tappify/extension-sdk';
|
|
16
|
+
import '@tappify/extension-sdk/styles.css';
|
|
17
|
+
import { useEffect } from 'react';
|
|
18
|
+
import '../styles.css';
|
|
19
|
+
|
|
20
|
+
function daysBetween(from: string, to: string): number {
|
|
21
|
+
const start = new Date(from).getTime();
|
|
22
|
+
const end = new Date(to).getTime();
|
|
23
|
+
return Math.max(1, Math.round((end - start) / 86_400_000));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function bestDay(points: TapSeriesPoint[]): number {
|
|
27
|
+
return points.reduce((highest, point) => Math.max(highest, point.value), 0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function Summary(_props: TapWidgetProps) {
|
|
31
|
+
const tap = useTap();
|
|
32
|
+
const filters = useTapFilters();
|
|
33
|
+
const preferences = useTapStorage('preferences');
|
|
34
|
+
|
|
35
|
+
const downloads = useTapQuery({
|
|
36
|
+
kind: 'series',
|
|
37
|
+
metric: 'downloads',
|
|
38
|
+
range: filters.range,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const summary = useTapServer(
|
|
42
|
+
'getSummary',
|
|
43
|
+
{
|
|
44
|
+
days: daysBetween(filters.range.from, filters.range.to),
|
|
45
|
+
platform: filters.platform,
|
|
46
|
+
},
|
|
47
|
+
{ invalidateOn: ['settings.changed'] },
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const refetchSummary = summary.refetch;
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
return tap.data.subscribe('release.shipped', () => {
|
|
54
|
+
tap.ui.toast('A release shipped — refreshing the summary.', 'neutral');
|
|
55
|
+
refetchSummary();
|
|
56
|
+
});
|
|
57
|
+
}, [tap, refetchSummary]);
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
tap.telemetry.event('summary_viewed', { size: tap.ui.size });
|
|
61
|
+
}, [tap]);
|
|
62
|
+
|
|
63
|
+
const compact = preferences.data?.compact ?? false;
|
|
64
|
+
const failure = summary.error ?? downloads.error;
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<TapCard
|
|
68
|
+
title="Install summary"
|
|
69
|
+
action={
|
|
70
|
+
<TapButton
|
|
71
|
+
variant="ghost"
|
|
72
|
+
size="sm"
|
|
73
|
+
onClick={() => void preferences.patch({ compact: !compact })}
|
|
74
|
+
>
|
|
75
|
+
{compact ? 'Expand' : 'Compact'}
|
|
76
|
+
</TapButton>
|
|
77
|
+
}
|
|
78
|
+
footer={
|
|
79
|
+
<span className="starter-summary__footnote">
|
|
80
|
+
{tap.format.date(filters.range.from)} to{' '}
|
|
81
|
+
{tap.format.date(filters.range.to)}
|
|
82
|
+
</span>
|
|
83
|
+
}
|
|
84
|
+
>
|
|
85
|
+
{(summary.isLoading || downloads.isLoading) && <TapSkeleton lines={2} />}
|
|
86
|
+
|
|
87
|
+
{failure !== null && (
|
|
88
|
+
<TapErrorState
|
|
89
|
+
title="The summary did not load"
|
|
90
|
+
description={failure.message}
|
|
91
|
+
onRetry={() => {
|
|
92
|
+
summary.refetch();
|
|
93
|
+
downloads.refetch();
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
)}
|
|
97
|
+
|
|
98
|
+
{failure === null && summary.data !== undefined && (
|
|
99
|
+
<div
|
|
100
|
+
className={cn('starter-summary', compact && 'starter-summary--compact')}
|
|
101
|
+
>
|
|
102
|
+
<TapStat
|
|
103
|
+
label="Installs"
|
|
104
|
+
value={tap.format.number(summary.data.installs)}
|
|
105
|
+
delta={summary.data.delta}
|
|
106
|
+
/>
|
|
107
|
+
{downloads.data !== undefined && (
|
|
108
|
+
<span className="starter-summary__footnote">
|
|
109
|
+
Best day: {tap.format.number(bestDay(downloads.data.points))}{' '}
|
|
110
|
+
downloads
|
|
111
|
+
</span>
|
|
112
|
+
)}
|
|
113
|
+
{summary.data.topKeyword !== undefined && (
|
|
114
|
+
<span className="starter-summary__footnote">
|
|
115
|
+
Top keyword: {summary.data.topKeyword}
|
|
116
|
+
</span>
|
|
117
|
+
)}
|
|
118
|
+
</div>
|
|
119
|
+
)}
|
|
120
|
+
</TapCard>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schema.tappify.ai/extension/v2.json",
|
|
3
|
+
"id": "__id__",
|
|
4
|
+
"name": "__title__",
|
|
5
|
+
"description": "__description__",
|
|
6
|
+
"icon": "icon.svg",
|
|
7
|
+
"category": "product_analytics",
|
|
8
|
+
"sdk": "^2.0.0",
|
|
9
|
+
"visibility": "private",
|
|
10
|
+
"installScope": "project",
|
|
11
|
+
"scopes": [
|
|
12
|
+
{
|
|
13
|
+
"key": "ui:render"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"key": "analytics:read"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"key": "storage:write"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"telemetry": [
|
|
23
|
+
"summary_viewed"
|
|
24
|
+
],
|
|
25
|
+
"contributes": {
|
|
26
|
+
"widgets": [
|
|
27
|
+
{
|
|
28
|
+
"id": "summary",
|
|
29
|
+
"title": "Install summary",
|
|
30
|
+
"entry": "src/widgets/summary.tsx",
|
|
31
|
+
"page": "analytics",
|
|
32
|
+
"slot": "kpi-row",
|
|
33
|
+
"size": "1x1",
|
|
34
|
+
"expandable": true
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"settings": {
|
|
38
|
+
"entry": "src/settings.tsx",
|
|
39
|
+
"schema": {
|
|
40
|
+
"$ref": "./schemas/settings.json"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"storage": {
|
|
44
|
+
"preferences": {
|
|
45
|
+
"scope": "user",
|
|
46
|
+
"singleton": true,
|
|
47
|
+
"schema": {
|
|
48
|
+
"$ref": "./schemas/preferences.json"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"server": {
|
|
54
|
+
"baseUrl": "https://__id__.example.com",
|
|
55
|
+
"procedures": {
|
|
56
|
+
"getSummary": {
|
|
57
|
+
"input": {
|
|
58
|
+
"$ref": "./schemas/get-summary.input.json"
|
|
59
|
+
},
|
|
60
|
+
"output": {
|
|
61
|
+
"$ref": "./schemas/get-summary.output.json"
|
|
62
|
+
},
|
|
63
|
+
"cache": "5m",
|
|
64
|
+
"kind": "read"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createTestClient } from '@tappify/extension-sdk/testing';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { handlerOptions } from '../server/handler';
|
|
4
|
+
|
|
5
|
+
const client = createTestClient(handlerOptions);
|
|
6
|
+
const vercelClient = createTestClient({ ...handlerOptions, basePath: '/api' });
|
|
7
|
+
|
|
8
|
+
describe('the extension server', () => {
|
|
9
|
+
it('answers the publish health check', async () => {
|
|
10
|
+
await expect(client.health()).resolves.toEqual({
|
|
11
|
+
ok: true,
|
|
12
|
+
version: '0.1.0',
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('answers getSummary with the declared output shape', async () => {
|
|
17
|
+
const summary = await client.procedure('getSummary', {
|
|
18
|
+
days: 7,
|
|
19
|
+
platform: 'all',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(summary).toMatchObject({
|
|
23
|
+
installs: expect.any(Number),
|
|
24
|
+
delta: expect.any(Number),
|
|
25
|
+
topKeyword: 'photo editor',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('scales the answer with the platform filter', async () => {
|
|
30
|
+
const all = await client.procedure('getSummary', {
|
|
31
|
+
days: 7,
|
|
32
|
+
platform: 'all',
|
|
33
|
+
});
|
|
34
|
+
const ios = await client.procedure('getSummary', {
|
|
35
|
+
days: 7,
|
|
36
|
+
platform: 'ios',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(all).toMatchObject({ installs: 1260 });
|
|
40
|
+
expect(ios).toMatchObject({ installs: 693 });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('returns a coded error a widget can show', async () => {
|
|
44
|
+
await expect(
|
|
45
|
+
client.procedure('getSummary', { days: 0, platform: 'all' }),
|
|
46
|
+
).rejects.toMatchObject({
|
|
47
|
+
code: 'RANGE_TOO_SHORT',
|
|
48
|
+
status: 400,
|
|
49
|
+
message:
|
|
50
|
+
'getSummary needs a range of at least one day. Widen the date picker, then retry.',
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('404s a procedure the manifest does not declare', async () => {
|
|
55
|
+
const response = await client.raw('POST', '/tappify/procedures/ghost', {});
|
|
56
|
+
|
|
57
|
+
expect(response.status).toBe(404);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('answers under the /api prefix the Vercel function is mounted at', async () => {
|
|
61
|
+
await expect(vercelClient.health()).resolves.toEqual({
|
|
62
|
+
ok: true,
|
|
63
|
+
version: '0.1.0',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const response = await vercelClient.raw('GET', '/api/tappify/health');
|
|
67
|
+
expect(response.status).toBe(200);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { renderWithTap } from '@tappify/extension-sdk/testing';
|
|
2
|
+
import { screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import Settings from '../src/settings';
|
|
6
|
+
|
|
7
|
+
describe('the settings panel', () => {
|
|
8
|
+
it('renders one control per schema field', () => {
|
|
9
|
+
renderWithTap(
|
|
10
|
+
<Settings values={{ refreshMinutes: 15 }} onChange={vi.fn()} />,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect(screen.getByLabelText('Refresh minutes')).toHaveValue(15);
|
|
14
|
+
expect(screen.getByLabelText('Show change')).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('reports the new values on save', async () => {
|
|
18
|
+
const onChange = vi.fn();
|
|
19
|
+
renderWithTap(
|
|
20
|
+
<Settings values={{ refreshMinutes: 15 }} onChange={onChange} />,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
await userEvent.clear(screen.getByLabelText('Refresh minutes'));
|
|
24
|
+
await userEvent.type(screen.getByLabelText('Refresh minutes'), '30');
|
|
25
|
+
await userEvent.click(screen.getByLabelText('Show change'));
|
|
26
|
+
await userEvent.click(screen.getByRole('button', { name: 'Save' }));
|
|
27
|
+
|
|
28
|
+
expect(onChange).toHaveBeenCalledWith({
|
|
29
|
+
refreshMinutes: 30,
|
|
30
|
+
showDelta: true,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('refuses to save when a required value is missing', async () => {
|
|
35
|
+
const onChange = vi.fn();
|
|
36
|
+
renderWithTap(
|
|
37
|
+
<Settings values={{ refreshMinutes: 15 }} onChange={onChange} />,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
await userEvent.clear(screen.getByLabelText('Refresh minutes'));
|
|
41
|
+
await userEvent.click(screen.getByRole('button', { name: 'Save' }));
|
|
42
|
+
|
|
43
|
+
expect(screen.getByText('Refresh minutes is required.')).toBeInTheDocument();
|
|
44
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
});
|