@tappify/cli 1.5.2 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/bin/tappify +1 -12
  2. package/dist/src/core/registry/registry.service.d.ts +1 -0
  3. package/dist/src/core/registry/registry.service.js +2 -0
  4. package/dist/src/core/registry/registry.service.js.map +1 -1
  5. package/dist/src/core/shell/shell.service.d.ts +7 -1
  6. package/dist/src/core/shell/shell.service.js +74 -4
  7. package/dist/src/core/shell/shell.service.js.map +1 -1
  8. package/dist/src/core/shutdown/teardown.d.ts +1 -0
  9. package/dist/src/core/shutdown/teardown.js +15 -2
  10. package/dist/src/core/shutdown/teardown.js.map +1 -1
  11. package/dist/src/domains/extension/kinds.ui.js +1 -1
  12. package/dist/src/domains/extension/kinds.ui.js.map +1 -1
  13. package/dist/src/domains/extension/runners/dev.runner.d.ts +6 -1
  14. package/dist/src/domains/extension/runners/dev.runner.js +215 -68
  15. package/dist/src/domains/extension/runners/dev.runner.js.map +1 -1
  16. package/dist/src/domains/extension/runners/init.runner.js +1 -1
  17. package/dist/src/domains/extension/runners/init.runner.js.map +1 -1
  18. package/dist/src/domains/extension/services/dev.service.d.ts +15 -2
  19. package/dist/src/domains/extension/services/dev.service.js +55 -13
  20. package/dist/src/domains/extension/services/dev.service.js.map +1 -1
  21. package/dist/src/domains/extension/services/types.service.d.ts +5 -2
  22. package/dist/src/domains/extension/services/types.service.js +4 -4
  23. package/dist/src/domains/extension/services/types.service.js.map +1 -1
  24. package/dist/src/main.js +5 -1
  25. package/dist/src/main.js.map +1 -1
  26. package/dist/tsconfig.build.tsbuildinfo +1 -1
  27. package/package.json +1 -1
  28. package/templates/contributions/procedure/test/__file__.test.ts +13 -0
  29. package/templates/starter/README.md +1 -1
  30. package/templates/starter/api/tappify/actions/[id].ts +6 -0
  31. package/templates/starter/api/tappify/context/[id].ts +6 -0
  32. package/templates/starter/api/tappify/mentions/[id].ts +6 -0
  33. package/templates/starter/api/tappify/procedures/[id].ts +6 -0
  34. package/templates/starter/api/tappify/tools/[id].ts +6 -0
  35. package/templates/starter/api/tappify/work/[id].ts +6 -0
  36. package/templates/starter/test/get-summary.test.ts +45 -0
  37. package/templates/starter/test/server.test.ts +0 -38
  38. /package/templates/starter/api/tappify/{[...path].ts → [route].ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tappify/cli",
3
- "version": "1.5.2",
3
+ "version": "1.6.1",
4
4
  "description": "Tappify CLI - Command line interface for managing deployments and more",
5
5
  "author": "Tappify Team",
6
6
  "private": false,
@@ -0,0 +1,13 @@
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
+
7
+ describe('the __name__ procedure', () => {
8
+ it('answers with the declared output shape', async () => {
9
+ await expect(client.procedure('__name__', { days: 7 })).resolves.toEqual({
10
+ value: 7,
11
+ });
12
+ });
13
+ });
@@ -45,7 +45,7 @@ pnpm deploy:worker
45
45
 
46
46
  deploys `server/worker.ts` to Cloudflare Workers using `wrangler.toml`. The Worker serves the routes at the root, so set `server.baseUrl` in `tappify.extension.json` to `https://__id__-server.<your-subdomain>.workers.dev` — the origin, with no path.
47
47
 
48
- `api/tappify/[...path].ts` is a Vercel function over the same handler. Vercel invokes it at `/api/tappify/…`, so the function passes `basePath: "/api"`; deploy the repository to Vercel and set `server.baseUrl` to `https://<your-app>.vercel.app/api` — the origin **and** the `/api` prefix.
48
+ `api/tappify/[route].ts` and the `[id].ts` files in the explicit `actions`, `context`, `mentions`, `procedures`, `tools`, and `work` directories are Vercel functions over the same handler. The first serves one-level routes such as health, metrics, and events; the named directories serve their corresponding two-level routes. Every entrypoint passes `basePath: "/api"`. Deploy the repository to Vercel and set `server.baseUrl` to `https://<your-app>.vercel.app/api` — the origin **and** the `/api` prefix.
49
49
 
50
50
  Whichever you pick, Tappify calls `GET <baseUrl>/tappify/health` at publish and every 15 minutes, and `POST <baseUrl>/tappify/procedures/getSummary` whenever the widget asks.
51
51
 
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,6 @@
1
+ import { createTappifyHandler } from '@tappify/extension-sdk/server';
2
+ import { handlerOptions } from '../../../server/handler';
3
+
4
+ export const config = { runtime: 'edge' };
5
+
6
+ export default createTappifyHandler({ ...handlerOptions, basePath: '/api' });
@@ -0,0 +1,45 @@
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
+
7
+ describe('the getSummary procedure', () => {
8
+ it('answers with the declared output shape', async () => {
9
+ const summary = await client.procedure('getSummary', {
10
+ days: 7,
11
+ platform: 'all',
12
+ });
13
+
14
+ expect(summary).toMatchObject({
15
+ installs: expect.any(Number),
16
+ delta: expect.any(Number),
17
+ topKeyword: 'photo editor',
18
+ });
19
+ });
20
+
21
+ it('scales the answer with the platform filter', async () => {
22
+ const all = await client.procedure('getSummary', {
23
+ days: 7,
24
+ platform: 'all',
25
+ });
26
+ const ios = await client.procedure('getSummary', {
27
+ days: 7,
28
+ platform: 'ios',
29
+ });
30
+
31
+ expect(all).toMatchObject({ installs: 1260 });
32
+ expect(ios).toMatchObject({ installs: 693 });
33
+ });
34
+
35
+ it('returns a coded error a widget can show', async () => {
36
+ await expect(
37
+ client.procedure('getSummary', { days: 0, platform: 'all' }),
38
+ ).rejects.toMatchObject({
39
+ code: 'RANGE_TOO_SHORT',
40
+ status: 400,
41
+ message:
42
+ 'getSummary needs a range of at least one day. Widen the date picker, then retry.',
43
+ });
44
+ });
45
+ });
@@ -13,44 +13,6 @@ describe('the extension server', () => {
13
13
  });
14
14
  });
15
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
16
  it('404s a procedure the manifest does not declare', async () => {
55
17
  const response = await client.raw('POST', '/tappify/procedures/ghost', {});
56
18