@pikku/cli 0.12.85 → 0.12.88

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 (138) hide show
  1. package/console-app/assets/{index-CEv-kj3J.js → index-C3FPwdl7.js} +161 -147
  2. package/console-app/index.html +1 -1
  3. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  4. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  5. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  6. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  7. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  8. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  10. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  11. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +4 -0
  12. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  15. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +4 -0
  16. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  17. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  18. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  19. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  20. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  21. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  22. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  23. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  24. package/dist/.pikku/function/pikku-functions-meta.gen.json +41 -17
  25. package/dist/.pikku/function/pikku-functions.gen.js +3 -1
  26. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  27. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  28. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  29. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  30. package/dist/.pikku/pikku-bootstrap.gen.d.ts +3 -1
  31. package/dist/.pikku/pikku-bootstrap.gen.js +3 -1
  32. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  33. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  34. package/dist/.pikku/pikku-services.gen.d.ts +2 -1
  35. package/dist/.pikku/pikku-services.gen.js +1 -0
  36. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  37. package/dist/.pikku/pikku-types.gen.js +1 -1
  38. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  39. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  40. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.d.ts +1 -0
  41. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +6 -0
  42. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.json +6 -0
  43. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +4 -0
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +5 -0
  45. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  46. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -0
  47. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  48. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  49. package/dist/.pikku/schemas/register.gen.js +3 -1
  50. package/dist/.pikku/schemas/schemas/FabricLoginInput.schema.json +1 -1
  51. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  52. package/dist/.pikku/schemas/schemas/PikkuUserAdminFunctionsOutput.schema.json +1 -0
  53. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  54. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  55. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  56. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  57. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  58. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  59. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  60. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  61. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  62. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  63. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  64. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  65. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  66. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +8 -2
  67. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  68. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  69. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  70. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  71. package/dist/bin/pikku-bin.mjs +2 -2
  72. package/dist/bin/pikku.js +22 -0
  73. package/dist/src/fabric/fabric-commands.d.ts +6 -3
  74. package/dist/src/fabric/fabric-commands.js +4 -0
  75. package/dist/src/fabric/functions/deploy.function.js +6 -0
  76. package/dist/src/fabric/functions/init.function.js +2 -2
  77. package/dist/src/fabric/functions/llm-key.function.d.ts +4 -4
  78. package/dist/src/fabric/functions/login.function.d.ts +4 -0
  79. package/dist/src/fabric/functions/login.function.js +45 -4
  80. package/dist/src/fabric/functions/validate.function.js +12 -2
  81. package/dist/src/fabric/lib/config.d.ts +8 -0
  82. package/dist/src/fabric/lib/config.js +15 -1
  83. package/dist/src/fabric/lib/git.js +2 -2
  84. package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.js +6 -2
  85. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.d.ts +5 -1
  86. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +81 -48
  87. package/dist/src/functions/wirings/auth/pikku-command-auth.js +4 -0
  88. package/dist/src/functions/wirings/console/pikku-command-console-functions.js +6 -2
  89. package/dist/src/functions/wirings/console/serialize-console-functions.d.ts +5 -1
  90. package/dist/src/functions/wirings/console/serialize-console-functions.js +55 -23
  91. package/dist/src/functions/wirings/functions/schemas.js +10 -1
  92. package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.js +2 -0
  93. package/dist/src/functions/wirings/queue/pikku-command-queue.js +10 -2
  94. package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.js +8 -2
  95. package/dist/src/functions/wirings/realtime/serialize-events-scaffold.d.ts +5 -4
  96. package/dist/src/functions/wirings/realtime/serialize-events-scaffold.js +17 -7
  97. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +6 -2
  98. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +6 -2
  99. package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +5 -1
  100. package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +16 -5
  101. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +5 -1
  102. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +16 -5
  103. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +8 -2
  104. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +5 -1
  105. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +22 -16
  106. package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.d.ts +1 -0
  107. package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +49 -0
  108. package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.d.ts +24 -0
  109. package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +283 -0
  110. package/dist/src/functions/wirings/webhook/pikku-command-webhook.js +6 -2
  111. package/dist/src/functions/wirings/webhook/serialize-webhook.d.ts +5 -8
  112. package/dist/src/functions/wirings/webhook/serialize-webhook.js +19 -12
  113. package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.js +8 -2
  114. package/dist/src/functions/wirings/workflow/serialize-workflow-routes.d.ts +5 -1
  115. package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +61 -31
  116. package/dist/src/functions/workflows/all.workflow.js +8 -0
  117. package/dist/src/utils/pikku-cli-config.js +40 -10
  118. package/dist/src/utils/remove-legacy-scaffold-file.d.ts +3 -0
  119. package/dist/src/utils/remove-legacy-scaffold-file.js +43 -0
  120. package/dist/src/utils/serialize-schemas.js +57 -2
  121. package/dist/tsconfig.tsbuildinfo +1 -1
  122. package/package.json +7 -7
  123. package/skills/pikku-addon/SKILL.md +1 -0
  124. package/skills/pikku-ai-agent/SKILL.md +2 -1
  125. package/skills/pikku-ai-vercel/SKILL.md +1 -0
  126. package/skills/pikku-better-auth/SKILL.md +57 -0
  127. package/skills/pikku-concepts/SKILL.md +17 -1
  128. package/skills/pikku-concepts/references/concept-mapping.md +11 -9
  129. package/skills/pikku-emails/SKILL.md +1 -0
  130. package/skills/pikku-fabric/SKILL.md +92 -19
  131. package/skills/pikku-fabric-debug/SKILL.md +112 -0
  132. package/skills/pikku-permissions/SKILL.md +28 -12
  133. package/skills/pikku-react/SKILL.md +32 -3
  134. package/skills/pikku-react-query/SKILL.md +38 -1
  135. package/skills/pikku-realtime/SKILL.md +1 -1
  136. package/skills/pikku-security/SKILL.md +3 -3
  137. package/skills/pikku-template-clone/SKILL.md +1 -0
  138. package/cli.schema.json +0 -1
@@ -2,10 +2,13 @@ import { pikkuSessionlessFunc } from '#pikku';
2
2
  import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
3
3
  import { writeFileInDir } from '../../../utils/file-writer.js';
4
4
  import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
5
+ import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
5
6
  import { serializeEventsScaffold } from './serialize-events-scaffold.js';
6
7
  export const pikkuEventsScaffold = pikkuSessionlessFunc({
7
8
  func: async ({ logger, config }) => {
8
- if (!config.scaffold?.events || !config.eventsChannelFile) {
9
+ if (!config.scaffold?.events ||
10
+ !config.eventsChannelFile ||
11
+ !config.eventsSchemasFile) {
9
12
  logger.debug({
10
13
  message: 'Skipping events scaffold (set scaffold.events in pikku.config.json to enable).',
11
14
  type: 'skip',
@@ -14,7 +17,10 @@ export const pikkuEventsScaffold = pikkuSessionlessFunc({
14
17
  }
15
18
  const authRequired = config.scaffold.events === 'auth';
16
19
  const pikkuTypesImportPath = getFileImportRelativePath(config.eventsChannelFile, config.typesDeclarationFile, config.packageMappings);
17
- await writeFileInDir(logger, config.eventsChannelFile, serializeEventsScaffold(authRequired, pikkuTypesImportPath));
20
+ const { schemas, functions } = serializeEventsScaffold(authRequired, pikkuTypesImportPath);
21
+ await writeFileInDir(logger, config.eventsSchemasFile, schemas);
22
+ await writeFileInDir(logger, config.eventsChannelFile, functions);
23
+ await removeLegacyScaffoldFile(config.eventsChannelFile);
18
24
  return true;
19
25
  },
20
26
  middleware: [
@@ -1,3 +1,7 @@
1
+ export interface EventsGenOutput {
2
+ schemas: string;
3
+ functions: string;
4
+ }
1
5
  /**
2
6
  * Generates the server-side `events.gen.ts` scaffold.
3
7
  *
@@ -16,8 +20,5 @@
16
20
  * Both routes call `eventHub.subscribe`/`unsubscribe` with the channel id;
17
21
  * publish-side ergonomics (envelope shape) are documented in the
18
22
  * pikku-realtime skill.
19
- *
20
- * Uses TypeScript generics (not named Zod schema constants) so schemas and
21
- * wiring calls can safely coexist in a single generated file.
22
23
  */
23
- export declare const serializeEventsScaffold: (authRequired: boolean, pikkuTypesImportPath: string) => string;
24
+ export declare const serializeEventsScaffold: (authRequired: boolean, pikkuTypesImportPath: string) => EventsGenOutput;
@@ -16,19 +16,25 @@
16
16
  * Both routes call `eventHub.subscribe`/`unsubscribe` with the channel id;
17
17
  * publish-side ergonomics (envelope shape) are documented in the
18
18
  * pikku-realtime skill.
19
- *
20
- * Uses TypeScript generics (not named Zod schema constants) so schemas and
21
- * wiring calls can safely coexist in a single generated file.
22
19
  */
23
20
  export const serializeEventsScaffold = (authRequired, pikkuTypesImportPath) => {
24
21
  const auth = authRequired ? 'true' : 'false';
25
- return `import {
22
+ const schemas = `/**
23
+ * Auto-generated realtime event schemas
24
+ * Do not edit manually - regenerate with 'npx pikku'
25
+ */
26
+ import { z } from 'zod'
27
+
28
+ export const TopicRef = z.object({ topic: z.string() })
29
+ `;
30
+ const functions = `import {
26
31
  pikkuChannelFunc,
27
32
  pikkuSessionlessFunc,
28
33
  wireChannel,
29
34
  wireHTTP,
30
35
  defineChannelRoutes,
31
36
  } from '${pikkuTypesImportPath}'
37
+ import { TopicRef } from './events.schemas.gen.js'
32
38
 
33
39
  /**
34
40
  * Topic envelope clients receive: \`{ topic, data }\`. Functions that publish
@@ -40,13 +46,15 @@ export const serializeEventsScaffold = (authRequired, pikkuTypesImportPath) => {
40
46
  * the duplication; pick whichever style your project prefers.
41
47
  */
42
48
 
43
- export const realtimeSubscribe = pikkuChannelFunc<{ topic: string }>({
49
+ export const realtimeSubscribe = pikkuChannelFunc({
50
+ input: TopicRef,
44
51
  func: async ({ eventHub }, { topic }, { channel }) => {
45
52
  await eventHub?.subscribe(topic, channel.channelId)
46
53
  },
47
54
  })
48
55
 
49
- export const realtimeUnsubscribe = pikkuChannelFunc<{ topic: string }>({
56
+ export const realtimeUnsubscribe = pikkuChannelFunc({
57
+ input: TopicRef,
50
58
  func: async ({ eventHub }, { topic }, { channel }) => {
51
59
  await eventHub?.unsubscribe(topic, channel.channelId)
52
60
  },
@@ -74,7 +82,8 @@ wireChannel({
74
82
  * SSE per-topic stream. One connection = one subscription. The eventHub
75
83
  * cleans up automatically when the channel closes (onChannelClosed).
76
84
  */
77
- export const realtimeEventStream = pikkuSessionlessFunc<{ topic: string }, void>({
85
+ export const realtimeEventStream = pikkuSessionlessFunc({
86
+ input: TopicRef,
78
87
  description: 'Auto-generated SSE stream for a single event-hub topic',
79
88
  func: async ({ eventHub }, { topic }, { channel }) => {
80
89
  if (!channel) {
@@ -95,4 +104,5 @@ wireHTTP({
95
104
  tags: ['pikku:realtime', 'sse'],
96
105
  })
97
106
  `;
107
+ return { schemas, functions };
98
108
  };
@@ -2,6 +2,7 @@ import { pikkuSessionlessFunc } from '#pikku';
2
2
  import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
3
3
  import { writeFileInDir } from '../../../utils/file-writer.js';
4
4
  import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
5
+ import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
5
6
  import { serializePublicRPC } from './serialize-public-rpc.js';
6
7
  export const pikkuPublicRPC = pikkuSessionlessFunc({
7
8
  func: async ({ logger, config, variables }) => {
@@ -9,9 +10,12 @@ export const pikkuPublicRPC = pikkuSessionlessFunc({
9
10
  if (deployCodegenFlag === '1') {
10
11
  return false;
11
12
  }
12
- if (config.scaffold?.rpc) {
13
+ if (config.scaffold?.rpc && config.publicRpcSchemasFile) {
13
14
  const pathToPikkuTypes = getFileImportRelativePath(config.publicRpcFile, config.typesDeclarationFile, config.packageMappings);
14
- await writeFileInDir(logger, config.publicRpcFile, serializePublicRPC(pathToPikkuTypes, config.scaffold.rpc === 'auth', config.globalHTTPPrefix || ''));
15
+ const { schemas, functions } = serializePublicRPC(pathToPikkuTypes, config.scaffold.rpc === 'auth', config.globalHTTPPrefix || '');
16
+ await writeFileInDir(logger, config.publicRpcSchemasFile, schemas);
17
+ await writeFileInDir(logger, config.publicRpcFile, functions);
18
+ await removeLegacyScaffoldFile(config.publicRpcFile);
15
19
  return true;
16
20
  }
17
21
  return false;
@@ -2,6 +2,7 @@ import { pikkuSessionlessFunc } from '#pikku';
2
2
  import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
3
3
  import { writeFileInDir } from '../../../utils/file-writer.js';
4
4
  import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
5
+ import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
5
6
  import { serializeRemoteRPC } from './serialize-remote-rpc.js';
6
7
  export const pikkuRemoteRPC = pikkuSessionlessFunc({
7
8
  func: async ({ logger, config, variables }) => {
@@ -9,9 +10,12 @@ export const pikkuRemoteRPC = pikkuSessionlessFunc({
9
10
  if (deployCodegenFlag === '1') {
10
11
  return false;
11
12
  }
12
- if (config.remoteRpcWorkersFile) {
13
+ if (config.remoteRpcWorkersFile && config.remoteRpcSchemasFile) {
13
14
  const pathToPikkuTypes = getFileImportRelativePath(config.remoteRpcWorkersFile, config.typesDeclarationFile, config.packageMappings);
14
- await writeFileInDir(logger, config.remoteRpcWorkersFile, serializeRemoteRPC(pathToPikkuTypes));
15
+ const { schemas, functions } = serializeRemoteRPC(pathToPikkuTypes);
16
+ await writeFileInDir(logger, config.remoteRpcSchemasFile, schemas);
17
+ await writeFileInDir(logger, config.remoteRpcWorkersFile, functions);
18
+ await removeLegacyScaffoldFile(config.remoteRpcWorkersFile);
15
19
  return true;
16
20
  }
17
21
  return false;
@@ -1,4 +1,8 @@
1
+ export interface PublicRPCGenOutput {
2
+ schemas: string;
3
+ functions: string;
4
+ }
1
5
  /**
2
6
  * Generate public RPC HTTP endpoint
3
7
  */
4
- export declare const serializePublicRPC: (pathToPikkuTypes: string, requireAuth?: boolean, globalHTTPPrefix?: string) => string;
8
+ export declare const serializePublicRPC: (pathToPikkuTypes: string, requireAuth?: boolean, globalHTTPPrefix?: string) => PublicRPCGenOutput;
@@ -3,18 +3,28 @@
3
3
  */
4
4
  export const serializePublicRPC = (pathToPikkuTypes, requireAuth = true, globalHTTPPrefix = '') => {
5
5
  const authFlag = requireAuth ? 'true' : 'false';
6
- return `/**
6
+ const schemas = `/**
7
+ * Auto-generated public RPC endpoint schemas
8
+ * Do not edit manually - regenerate with 'npx pikku'
9
+ */
10
+ import { z } from 'zod'
11
+
12
+ export const RPCCall = z.object({
13
+ rpcName: z.string(),
14
+ data: z.unknown().optional(),
15
+ })
16
+ `;
17
+ const functions = `/**
7
18
  * Auto-generated public RPC HTTP endpoint
8
19
  * Do not edit manually - regenerate with 'npx pikku'
9
20
  */
10
21
  import { pikkuSessionlessFunc, wireHTTP } from '${pathToPikkuTypes}'
22
+ import { RPCCall } from './rpc-public.schemas.gen.js'
11
23
 
12
- export const rpcCaller = pikkuSessionlessFunc<
13
- { rpcName: string; data?: unknown },
14
- unknown
15
- >({
24
+ export const rpcCaller = pikkuSessionlessFunc({
16
25
  tags: ['pikku'],
17
26
  auth: ${authFlag},
27
+ input: RPCCall,
18
28
  func: async (_services, { rpcName, data }, { rpc }) => {
19
29
  return await rpc.exposed(rpcName, data)
20
30
  },
@@ -28,4 +38,5 @@ wireHTTP({
28
38
  func: rpcCaller,
29
39
  })
30
40
  `;
41
+ return { schemas, functions };
31
42
  };
@@ -1,4 +1,8 @@
1
+ export interface RemoteRPCGenOutput {
2
+ schemas: string;
3
+ functions: string;
4
+ }
1
5
  /**
2
6
  * Generate remote internal RPC queue worker and HTTP endpoint
3
7
  */
4
- export declare const serializeRemoteRPC: (pathToPikkuTypes: string) => string;
8
+ export declare const serializeRemoteRPC: (pathToPikkuTypes: string) => RemoteRPCGenOutput;
@@ -2,18 +2,28 @@
2
2
  * Generate remote internal RPC queue worker and HTTP endpoint
3
3
  */
4
4
  export const serializeRemoteRPC = (pathToPikkuTypes) => {
5
- return `/**
5
+ const schemas = `/**
6
+ * Auto-generated remote internal RPC schemas
7
+ * Do not edit manually - regenerate with 'npx pikku'
8
+ */
9
+ import { z } from 'zod'
10
+
11
+ export const RemoteRPCCall = z.object({
12
+ rpcName: z.string(),
13
+ data: z.unknown().optional(),
14
+ })
15
+ `;
16
+ const functions = `/**
6
17
  * Auto-generated remote internal RPC queue worker and HTTP endpoint
7
18
  * Do not edit manually - regenerate with 'npx pikku'
8
19
  */
9
20
  import { pikkuSessionlessFunc, wireHTTP, wireQueueWorker } from '${pathToPikkuTypes}'
10
21
  import { pikkuRemoteAuthMiddleware } from '@pikku/core/middleware'
22
+ import { RemoteRPCCall } from './rpc-remote.schemas.gen.js'
11
23
 
12
- export const remoteRPCHandler = pikkuSessionlessFunc<
13
- { rpcName: string, data?: unknown },
14
- unknown
15
- >({
24
+ export const remoteRPCHandler = pikkuSessionlessFunc({
16
25
  tags: ['pikku'],
26
+ input: RemoteRPCCall,
17
27
  func: async (_services, { rpcName, data }, { rpc }) => {
18
28
  return await (rpc.invoke as any)(rpcName, data)
19
29
  },
@@ -35,4 +45,5 @@ wireHTTP({
35
45
  func: remoteRPCHandler,
36
46
  })
37
47
  `;
48
+ return { schemas, functions };
38
49
  };
@@ -2,6 +2,7 @@ import { pikkuSessionlessFunc } from '#pikku';
2
2
  import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
3
3
  import { writeFileInDir } from '../../../utils/file-writer.js';
4
4
  import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
5
+ import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
5
6
  import { serializeScenarioFunctions } from './serialize-scenario-functions.js';
6
7
  export const pikkuScenarioFunctions = pikkuSessionlessFunc({
7
8
  func: async ({ logger, config, variables }) => {
@@ -9,9 +10,14 @@ export const pikkuScenarioFunctions = pikkuSessionlessFunc({
9
10
  if (deployCodegenFlag === '1') {
10
11
  return false;
11
12
  }
12
- if (config.scaffold?.scenarios && config.scenariosFunctionsFile) {
13
+ if (config.scaffold?.scenarios &&
14
+ config.scenariosFunctionsFile &&
15
+ config.scenariosSchemasFile) {
13
16
  const pathToPikkuTypes = getFileImportRelativePath(config.scenariosFunctionsFile, config.typesDeclarationFile, config.packageMappings);
14
- await writeFileInDir(logger, config.scenariosFunctionsFile, serializeScenarioFunctions(pathToPikkuTypes, config.scaffold.scenarios === 'auth'));
17
+ const { schemas, functions } = serializeScenarioFunctions(pathToPikkuTypes, config.scaffold.scenarios === 'auth');
18
+ await writeFileInDir(logger, config.scenariosSchemasFile, schemas);
19
+ await writeFileInDir(logger, config.scenariosFunctionsFile, functions);
20
+ await removeLegacyScaffoldFile(config.scenariosFunctionsFile);
15
21
  return true;
16
22
  }
17
23
  return false;
@@ -1,6 +1,10 @@
1
+ export interface ScenarioGenOutput {
2
+ schemas: string;
3
+ functions: string;
4
+ }
1
5
  /**
2
6
  * Generate the scenario instrumentation functions (`pikku scenario` coverage
3
7
  * snapshots and stub-call inspection) into the project scaffold, so scenario
4
8
  * runs work against any server without requiring the console addon.
5
9
  */
6
- export declare const serializeScenarioFunctions: (pathToPikkuTypes: string, requireAuth?: boolean) => string;
10
+ export declare const serializeScenarioFunctions: (pathToPikkuTypes: string, requireAuth?: boolean) => ScenarioGenOutput;
@@ -5,7 +5,19 @@
5
5
  */
6
6
  export const serializeScenarioFunctions = (pathToPikkuTypes, requireAuth = true) => {
7
7
  const authFlag = requireAuth ? 'true' : 'false';
8
- return `/**
8
+ const schemas = `/**
9
+ * Auto-generated scenario instrumentation schemas
10
+ * Do not edit manually - regenerate with 'npx pikku'
11
+ */
12
+ import { z } from 'zod'
13
+
14
+ export const StubCallsQuery = z.object({
15
+ service: z.string().optional(),
16
+ })
17
+
18
+ export const Enabled = z.object({ enabled: z.boolean() })
19
+ `;
20
+ const functions = `/**
9
21
  * Auto-generated scenario instrumentation functions
10
22
  * Do not edit manually - regenerate with 'npx pikku'
11
23
  */
@@ -16,14 +28,10 @@ import {
16
28
  getStubTracker,
17
29
  isTestRun,
18
30
  type CoverageFunctionMeta,
19
- type FunctionCoverageReport,
20
- type StubCall,
21
31
  } from '@pikku/core/services'
32
+ import { StubCallsQuery, Enabled } from './scenarios.schemas.gen.js'
22
33
 
23
- export const pikkuScenarioTakeLiveCoverage = pikkuFunc<
24
- null,
25
- FunctionCoverageReport | null
26
- >({
34
+ export const pikkuScenarioTakeLiveCoverage = pikkuFunc({
27
35
  tags: ['pikku'],
28
36
  title: 'Take Live Coverage',
29
37
  description:
@@ -50,16 +58,14 @@ export const pikkuScenarioTakeLiveCoverage = pikkuFunc<
50
58
  },
51
59
  })
52
60
 
53
- export const pikkuScenarioResetLiveCoverage = pikkuFunc<
54
- null,
55
- { enabled: boolean }
56
- >({
61
+ export const pikkuScenarioResetLiveCoverage = pikkuFunc({
57
62
  tags: ['pikku'],
58
63
  title: 'Reset Live Coverage',
59
64
  description:
60
65
  'Clears V8 precise-coverage call counts so the next takeLiveCoverage snapshot is attributable to a single scenario run. Reports enabled: false when the server was not started with coverage enabled.',
61
66
  expose: true,
62
67
  auth: ${authFlag},
68
+ output: Enabled,
63
69
  func: async ({ coverageService }) => {
64
70
  if (!coverageService) return { enabled: false }
65
71
  await coverageService.reset()
@@ -67,32 +73,32 @@ export const pikkuScenarioResetLiveCoverage = pikkuFunc<
67
73
  },
68
74
  })
69
75
 
70
- export const pikkuScenarioResetStubs = pikkuFunc<null, { enabled: boolean }>({
76
+ export const pikkuScenarioResetStubs = pikkuFunc({
71
77
  tags: ['pikku'],
72
78
  title: 'Reset Stubs',
73
79
  description:
74
80
  'Clears recorded stub calls so the next getStubCalls result is attributable to a single scenario run. Reports enabled: false when the server was not started in test mode.',
75
81
  expose: true,
76
82
  auth: ${authFlag},
83
+ output: Enabled,
77
84
  func: async () => {
78
85
  getStubTracker().reset()
79
86
  return { enabled: isTestRun() }
80
87
  },
81
88
  })
82
89
 
83
- export const pikkuScenarioGetStubCalls = pikkuFunc<
84
- { service?: string },
85
- StubCall[]
86
- >({
90
+ export const pikkuScenarioGetStubCalls = pikkuFunc({
87
91
  tags: ['pikku'],
88
92
  title: 'Get Stub Calls',
89
93
  description:
90
94
  'Returns calls recorded against stubbed/spied services (via the stub()/spy() core utils). Empty unless the server records service calls (pikku dev --test).',
91
95
  expose: true,
92
96
  auth: ${authFlag},
97
+ input: StubCallsQuery,
93
98
  func: async (_services, data) => {
94
99
  return getStubTracker().getCalls(data?.service ?? undefined)
95
100
  },
96
101
  })
97
102
  `;
103
+ return { schemas, functions };
98
104
  };
@@ -0,0 +1 @@
1
+ export declare const pikkuUserAdminFunctions: import("#pikku").PikkuFunctionConfig<void, boolean, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, boolean, "rpc" | "session", import("#pikku").WiredServices> | import("#pikku").PikkuFunction<void, boolean, "rpc" | "session", import("#pikku").WiredServices>, undefined, undefined>;
@@ -0,0 +1,49 @@
1
+ import { pikkuSessionlessFunc } from '#pikku';
2
+ import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
3
+ import { writeFileInDir } from '../../../utils/file-writer.js';
4
+ import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
5
+ import { serializeUserAdminFunctions } from './serialize-user-admin-functions.js';
6
+ export const pikkuUserAdminFunctions = pikkuSessionlessFunc({
7
+ func: async ({ logger, config, getInspectorState }) => {
8
+ if (!config.scaffold?.userAdmin ||
9
+ !config.userAdminFunctionsFile ||
10
+ !config.userAdminSchemasFile) {
11
+ logger.debug({
12
+ message: 'Skipping user admin scaffold (set scaffold.userAdmin in pikku.config.json to enable).',
13
+ type: 'skip',
14
+ });
15
+ return false;
16
+ }
17
+ const { definition } = (await getInspectorState()).auth;
18
+ // These functions are thin wrappers over better-auth's admin() endpoints.
19
+ // Without that plugin the endpoints do not exist, so the scaffold would
20
+ // generate four RPCs that throw on every call and four scopes that grant
21
+ // nothing. Fail the codegen instead of shipping that.
22
+ if (!definition) {
23
+ throw new Error(`"scaffold.userAdmin" is enabled but no pikkuBetterAuth(...) was found in the project.\n` +
24
+ `User management wraps better-auth's admin() endpoints, so there is nothing to wrap.\n` +
25
+ `Fix: set up Better Auth before scaffolding user management, or remove ` +
26
+ `"scaffold.userAdmin" from pikku.config.json.`);
27
+ }
28
+ if (!definition.plugins.includes('admin')) {
29
+ throw new Error(`"scaffold.userAdmin" is enabled but better-auth is configured without the admin() plugin.\n` +
30
+ `Ban, delete, session-revocation and set-password are implemented by that plugin — without it ` +
31
+ `the generated functions would fail on every call.\n` +
32
+ `Fix: add admin() to the plugins array in ${definition.sourceFile}:\n` +
33
+ ` import { admin } from 'better-auth/plugins'\n` +
34
+ ` betterAuth({ plugins: [admin()] })\n` +
35
+ `Then re-run codegen. Or remove "scaffold.userAdmin" from pikku.config.json.`);
36
+ }
37
+ const pathToPikkuTypes = getFileImportRelativePath(config.userAdminFunctionsFile, config.typesDeclarationFile, config.packageMappings);
38
+ const { schemas, functions } = serializeUserAdminFunctions(pathToPikkuTypes, config.scaffold.userAdmin === 'auth');
39
+ await writeFileInDir(logger, config.userAdminSchemasFile, schemas);
40
+ await writeFileInDir(logger, config.userAdminFunctionsFile, functions);
41
+ return true;
42
+ },
43
+ middleware: [
44
+ logCommandInfoAndTime({
45
+ commandStart: 'Generating user management functions',
46
+ commandEnd: 'Generated user management functions',
47
+ }),
48
+ ],
49
+ });
@@ -0,0 +1,24 @@
1
+ export interface UserAdminGenOutput {
2
+ schemas: string;
3
+ functions: string;
4
+ }
5
+ /**
6
+ * Generate the user-management functions into the project scaffold: the
7
+ * directory read plus the writes that wrap better-auth's `admin()` endpoints.
8
+ *
9
+ * Scaffolded rather than shipped in an addon because managing users is ordinary
10
+ * application behaviour: an app should not have to install the console — which
11
+ * exists to be served alongside a running dev server — just to list or ban its
12
+ * own users. The console UI calls these same functions when it is present.
13
+ *
14
+ * Each function is gated on its own `admin:users:*` scope. The writes are only
15
+ * meaningful where `admin()` is wired, which is why this file is generated only
16
+ * in that case.
17
+ *
18
+ * Emitted as two files. The schemas are zod, and the inspector reads a zod
19
+ * schema by importing the module that declares it — which it cannot do for the
20
+ * functions file, whose relative pikku-types import per-unit deploy codegen
21
+ * rewrites. Keeping the schemas in a sibling module that imports nothing but
22
+ * zod sidesteps that entirely.
23
+ */
24
+ export declare const serializeUserAdminFunctions: (pathToPikkuTypes: string, requireAuth?: boolean) => UserAdminGenOutput;