@pikku/cli 0.12.38 → 0.12.40

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 (81) hide show
  1. package/console-app/assets/{index-Dxl3JsMK.js → index-D9Z9rySK.js} +2 -2
  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-types.gen.d.ts +1 -1
  8. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  10. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  14. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  15. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  16. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  17. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  18. package/dist/.pikku/function/pikku-functions-meta.gen.json +135 -135
  19. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  20. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  21. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  22. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  23. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  24. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  25. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  26. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  27. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  28. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  29. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  30. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  31. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  32. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  33. package/dist/.pikku/pikku-types.gen.js +1 -1
  34. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  35. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  36. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  37. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  38. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  39. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  40. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +3 -3
  41. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  42. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  43. package/dist/.pikku/schemas/register.gen.js +5 -5
  44. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  45. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  46. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  47. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  48. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  49. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  50. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  51. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  52. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  53. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  54. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  55. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  56. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  57. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  58. package/dist/bin/pikku-bin.mjs +2 -2
  59. package/dist/src/deploy/build-pipeline.d.ts +1 -0
  60. package/dist/src/deploy/build-pipeline.js +1 -1
  61. package/dist/src/fabric/functions/validate-core.js +2 -7
  62. package/dist/src/fabric/functions/validate.function.js +16 -14
  63. package/dist/src/functions/commands/db-generate.js +0 -3
  64. package/dist/src/functions/commands/db-reset.js +11 -7
  65. package/dist/src/functions/commands/db-seed.js +4 -7
  66. package/dist/src/functions/commands/db-shared.js +2 -4
  67. package/dist/src/functions/commands/deploy-apply.js +1 -0
  68. package/dist/src/functions/commands/deploy-plan.js +1 -0
  69. package/dist/src/functions/commands/dev.js +1 -1
  70. package/dist/src/functions/db/local-db.d.ts +9 -5
  71. package/dist/src/functions/db/local-db.js +287 -108
  72. package/dist/src/functions/db/postgres/pglite-kysely.d.ts +8 -0
  73. package/dist/src/functions/db/postgres/pglite-kysely.js +79 -0
  74. package/dist/src/functions/db/postgres/postgres-introspector.d.ts +1 -0
  75. package/dist/src/functions/db/postgres/postgres-introspector.js +6 -1
  76. package/dist/src/functions/db/postgres/postgres-migrator.d.ts +7 -2
  77. package/dist/src/functions/db/postgres/postgres-migrator.js +6 -1
  78. package/dist/src/functions/validate/workspace-validate.js +4 -4
  79. package/dist/src/scaffold/rpc-remote.gen.js +1 -1
  80. package/dist/tsconfig.tsbuildinfo +1 -1
  81. package/package.json +3 -2
@@ -119,6 +119,7 @@
119
119
  "pikkuMCPJSON": "pikkuMCPJSON",
120
120
  "pikkuMCPTypes": "pikkuMCPTypes",
121
121
  "pikkuMCP": "pikkuMCP",
122
+ "pikkuMiddleware": "pikkuMiddleware",
122
123
  "pikkuSecretDefinitionTypes": "pikkuSecretDefinitionTypes",
123
124
  "pikkuVariableDefinitionTypes": "pikkuVariableDefinitionTypes",
124
125
  "pikkuPackage": "pikkuPackage",
@@ -128,15 +129,14 @@
128
129
  "pikkuCommandQueue": "pikkuCommandQueue",
129
130
  "pikkuQueueMap": "pikkuQueueMap",
130
131
  "pikkuQueue": "pikkuQueue",
131
- "pikkuMiddleware": "pikkuMiddleware",
132
132
  "pikkuEventsScaffold": "pikkuEventsScaffold",
133
+ "pikkuSchedulerTypes": "pikkuSchedulerTypes",
134
+ "pikkuScheduler": "pikkuScheduler",
133
135
  "pikkuPublicRPC": "pikkuPublicRPC",
134
136
  "pikkuRemoteRPC": "pikkuRemoteRPC",
135
137
  "pikkuRPCInternalMap": "pikkuRPCInternalMap",
136
138
  "pikkuRPCExposedMap": "pikkuRPCExposedMap",
137
139
  "pikkuRPC": "pikkuRPC",
138
- "pikkuSchedulerTypes": "pikkuSchedulerTypes",
139
- "pikkuScheduler": "pikkuScheduler",
140
140
  "pikkuSecrets": "pikkuSecrets",
141
141
  "pikkuTriggerTypes": "pikkuTriggerTypes",
142
142
  "pikkuTrigger": "pikkuTrigger",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  /**
5
5
  * Scheduler-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  /**
5
5
  * Scheduler-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { addSchema } from '@pikku/core/schema';
5
5
  import * as PikkuSchemasOutput from './schemas/PikkuSchemasOutput.schema.json' with { type: 'json' };
@@ -190,6 +190,10 @@ import * as PikkuCLIEntryOutput from './schemas/PikkuCLIEntryOutput.schema.json'
190
190
  addSchema('PikkuCLIEntryOutput', PikkuCLIEntryOutput);
191
191
  import * as PikkuCLIOutput from './schemas/PikkuCLIOutput.schema.json' with { type: 'json' };
192
192
  addSchema('PikkuCLIOutput', PikkuCLIOutput);
193
+ import * as PikkuConsoleFunctionsOutput from './schemas/PikkuConsoleFunctionsOutput.schema.json' with { type: 'json' };
194
+ addSchema('PikkuConsoleFunctionsOutput', PikkuConsoleFunctionsOutput);
195
+ import * as PikkuNodesMetaOutput from './schemas/PikkuNodesMetaOutput.schema.json' with { type: 'json' };
196
+ addSchema('PikkuNodesMetaOutput', PikkuNodesMetaOutput);
193
197
  import * as PikkuFunctionTypesSplitInput from './schemas/PikkuFunctionTypesSplitInput.schema.json' with { type: 'json' };
194
198
  addSchema('PikkuFunctionTypesSplitInput', PikkuFunctionTypesSplitInput);
195
199
  import * as PikkuFunctionTypesInput from './schemas/PikkuFunctionTypesInput.schema.json' with { type: 'json' };
@@ -230,9 +234,5 @@ import * as PikkuTriggerOutput from './schemas/PikkuTriggerOutput.schema.json' w
230
234
  addSchema('PikkuTriggerOutput', PikkuTriggerOutput);
231
235
  import * as PikkuWorkflowRoutesOutput from './schemas/PikkuWorkflowRoutesOutput.schema.json' with { type: 'json' };
232
236
  addSchema('PikkuWorkflowRoutesOutput', PikkuWorkflowRoutesOutput);
233
- import * as PikkuConsoleFunctionsOutput from './schemas/PikkuConsoleFunctionsOutput.schema.json' with { type: 'json' };
234
- addSchema('PikkuConsoleFunctionsOutput', PikkuConsoleFunctionsOutput);
235
- import * as PikkuNodesMetaOutput from './schemas/PikkuNodesMetaOutput.schema.json' with { type: 'json' };
236
- addSchema('PikkuNodesMetaOutput', PikkuNodesMetaOutput);
237
237
  import * as PikkuCLIConfig from './schemas/PikkuCLIConfig.schema.json' with { type: 'json' };
238
238
  addSchema('PikkuCLIConfig', PikkuCLIConfig);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  export { wireSecret } from '@pikku/core/secret';
5
5
  export type { CoreSecret, SecretDefinitionMeta, SecretDefinitionsMeta } from '@pikku/core/secret';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  export { wireSecret } from '@pikku/core/secret';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  import type { SecretService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  const CREDENTIALS_META = {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  export { wireVariable } from '@pikku/core/variable';
5
5
  export type { CoreVariable, VariableDefinitionMeta, VariableDefinitionsMeta } from '@pikku/core/variable';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  export { wireVariable } from '@pikku/core/variable';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  import type { VariablesService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  const VARIABLES_META = {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { pikkuState } from '@pikku/core/internal';
5
5
  import allWorkflowMeta from './meta/allWorkflow.gen.json' with { type: 'json' };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.38
2
+ * This file was generated by @pikku/cli@0.12.40
3
3
  */
4
4
  import { addWorkflow } from '@pikku/core/workflow';
5
5
  import './pikku-workflow-wirings-meta.gen.js';
@@ -11,8 +11,8 @@ async function checkForUpdate() {
11
11
  })
12
12
  if (!res.ok) return
13
13
  const { version: latest } = await res.json()
14
- if (latest !== '0.12.38') {
15
- process.stderr.write(`\n Update available 0.12.38 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.40') {
15
+ process.stderr.write(`\n Update available 0.12.40 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
@@ -37,5 +37,6 @@ export declare function runBuildPipeline(options: {
37
37
  serverlessIncompatible?: string[];
38
38
  getEntryContext: (unitDir: string, pikkuDir: string, unit: DeploymentManifest['units'][0], state: InspectorState) => unknown;
39
39
  deployDir?: string;
40
+ outDir?: string;
40
41
  logger: BuildLogger;
41
42
  }): Promise<BuildPipelineResult>;
@@ -71,7 +71,7 @@ export async function runBuildPipeline(options) {
71
71
  };
72
72
  manifest.units = [singleUnit];
73
73
  const unitDir = join(providerDir, unitName);
74
- const pikkuDir = join(projectDir, '.pikku');
74
+ const pikkuDir = options.outDir ?? join(projectDir, '.pikku');
75
75
  await mkdir(unitDir, { recursive: true });
76
76
  const ctx = getEntryContext(unitDir, pikkuDir, singleUnit, inspectorState);
77
77
  const source = provider.generateEntrySource(ctx);
@@ -93,13 +93,8 @@ export async function runFabricValidate(startDir = process.cwd()) {
93
93
  const rootPkgPath = join(root, 'package.json');
94
94
  const rootPkg = await readJsonSafe(rootPkgPath);
95
95
  if (rootPkg) {
96
- const allDeps = {
97
- ...rootPkg.dependencies,
98
- ...rootPkg.devDependencies,
99
- };
100
- if (!allDeps['@pikku/fabric-cli']) {
101
- info('missing-fabric-cli', '@pikku/fabric-cli not in devDependencies — fabric CLI commands (validate, deploy) will not be available', rootPkgPath, 'Add "@pikku/fabric-cli" to devDependencies: use "file:./vendor/pikku-fabric-cli.tgz" (bundled release) or "portal:/path/to/pikku/packages/fabric-cli" (local dev)');
102
- }
96
+ // Intentionally only validating presence/shape here; dependency-specific
97
+ // checks live in the main fabric validator.
103
98
  }
104
99
  const fnDir = join(root, 'packages', 'functions');
105
100
  const functionsSdkPkgName = (await readJsonSafe(join(root, 'packages', 'functions-sdk', 'package.json')))?.name;
@@ -84,25 +84,26 @@ export async function runValidate(startDir = process.cwd()) {
84
84
  const info = (id, message, path, fixHint) => {
85
85
  findings.push({ id, severity: 'info', message, path, fixHint });
86
86
  };
87
+ const lines = (...parts) => parts.join('\n');
87
88
  // ── pikkufabric.config.json ────────────────────────────────────────────
88
89
  // Not required to run validate — downgraded to info so any pikku project
89
90
  // can be checked for compatibility before it is linked to a fabric account.
90
91
  const fabricConfigPath = join(root, 'pikkufabric.config.json');
91
92
  const fabricConfig = await readJsonSafe(fabricConfigPath);
92
93
  if (!fabricConfig) {
93
- info('fabric-config-missing', 'pikkufabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, 'Run `pikku fabric link` to create it, or create manually: {"projectId": "__PROJECT_ID__"}');
94
+ info('fabric-config-missing', 'pikkufabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, lines('Recommended fix:', '1. Run `pikku fabric link` if you already have a Fabric project.', '2. If you only want to scaffold the file, create:', '{', ' "projectId": "__PROJECT_ID__"', '}', '3. Replace `__PROJECT_ID__` later with the real Fabric project id.'));
94
95
  }
95
96
  else if (!fabricConfig.projectId) {
96
- info('fabric-config-no-project-id', 'pikkufabric.config.json is missing "projectId"', fabricConfigPath, 'Add "projectId": "<your-project-id>" to pikkufabric.config.json, or run `pikku fabric link`');
97
+ info('fabric-config-no-project-id', 'pikkufabric.config.json is missing "projectId"', fabricConfigPath, lines('Edit `pikkufabric.config.json` and add:', '{', ' "projectId": "<your-project-id>"', '}', 'If you do not know the id yet, run `pikku fabric link`.'));
97
98
  }
98
99
  else if (fabricConfig.projectId === '__PROJECT_ID__') {
99
- info('fabric-config-placeholder-project-id', 'pikkufabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, 'Run `pikku fabric link` to replace the placeholder with a real project ID');
100
+ info('fabric-config-placeholder-project-id', 'pikkufabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, lines('The file exists but still contains the placeholder project id.', 'Run `pikku fabric link` to replace it automatically, or edit the file and set:', '"projectId": "<real-project-id>"'));
100
101
  }
101
102
  // ── root pikku.config.json ─────────────────────────────────────────────
102
103
  const pikkuConfigPath = join(root, 'pikku.config.json');
103
104
  const pikkuConfig = await readJsonSafe(pikkuConfigPath);
104
105
  if (!pikkuConfig) {
105
- e('pikku-config-missing', 'pikku.config.json not found at project root', pikkuConfigPath, 'Create pikku.config.json with srcDirectories pointing to packages/functions/src, outDir, and clientFiles');
106
+ e('pikku-config-missing', 'pikku.config.json not found at project root', pikkuConfigPath, lines('Create `pikku.config.json` at the repo root.', 'Minimum useful shape:', '{', ' "srcDirectories": ["packages/functions/src"],', ' "outDir": "packages/functions/.pikku",', ' "clientFiles": {', ' "rpcMapDeclarationFile": "packages/functions-sdk/src/pikku/rpc-map.gen.d.ts",', ' "reactQueryFile": "packages/functions-sdk/src/pikku/api.gen.ts"', ' }', '}'));
106
107
  }
107
108
  else {
108
109
  if (!pikkuConfig.srcDirectories) {
@@ -112,7 +113,7 @@ export async function runValidate(startDir = process.cwd()) {
112
113
  e('pikku-config-no-out-dir', 'pikku.config.json missing "outDir"', pikkuConfigPath, 'Add "outDir": "packages/functions/.pikku" to pikku.config.json');
113
114
  }
114
115
  if (!pikkuConfig.clientFiles) {
115
- info('pikku-config-no-client-files', 'pikku.config.json missing "clientFiles" — no generated SDK or React Query hooks', pikkuConfigPath, 'Add clientFiles.rpcMapDeclarationFile and clientFiles.reactQueryFile pointing to packages/functions-sdk/src/pikku/');
116
+ info('pikku-config-no-client-files', 'pikku.config.json missing "clientFiles" — generated RPC client files and React Query hooks will not be written', pikkuConfigPath, lines('Add a `clientFiles` block to `pikku.config.json`.', 'Recommended values:', '"clientFiles": {', ' "rpcMapDeclarationFile": "packages/functions-sdk/src/pikku/rpc-map.gen.d.ts",', ' "reactQueryFile": "packages/functions-sdk/src/pikku/api.gen.ts"', '}', 'Those files should live in `packages/functions-sdk/src/pikku/` and are generated by Pikku.'));
116
117
  }
117
118
  }
118
119
  const dbEngine = pikkuConfig?.db?.engine ?? 'sqlite';
@@ -129,9 +130,6 @@ export async function runValidate(startDir = process.cwd()) {
129
130
  ...rootPkg.dependencies,
130
131
  ...rootPkg.devDependencies,
131
132
  };
132
- if (!allDeps['@pikku/fabric-cli']) {
133
- info('missing-fabric-cli', '@pikku/fabric-cli not in devDependencies — fabric CLI commands (validate, deploy) will not be available', rootPkgPath, 'Add "@pikku/fabric-cli" to devDependencies: use "file:./vendor/pikku-fabric-cli.tgz" (bundled release) or "portal:/path/to/pikku/packages/fabric-cli" (local dev)');
134
- }
135
133
  if (!allDeps['@pikku/core']) {
136
134
  e('missing-core', '@pikku/core not in dependencies', rootPkgPath, 'Add "@pikku/core": "file:./vendor/pikku-core.tgz" to dependencies');
137
135
  }
@@ -248,8 +246,8 @@ export async function runValidate(startDir = process.cwd()) {
248
246
  e('seed-sql-missing', dbEngine === 'postgres'
249
247
  ? 'db/postgres-seed.sql not found'
250
248
  : 'db/sqlite-seed.sql not found', seedPath, dbEngine === 'postgres'
251
- ? 'Create db/postgres-seed.sql with idempotent seed data for local/test data'
252
- : 'Create db/sqlite-seed.sql with idempotent INSERT OR IGNORE statements for demo/test data');
249
+ ? lines('Create `db/postgres-seed.sql`.', 'Use idempotent INSERT statements suitable for local/dev/test setup.', 'Keep it safe to re-run.')
250
+ : lines('Create `db/sqlite-seed.sql`.', 'Use idempotent `INSERT OR IGNORE` statements for local/dev/test data.', 'Keep it safe to re-run.'));
253
251
  }
254
252
  // audit table — info if not present (optional feature)
255
253
  if (existsSync(migrationsDir)) {
@@ -258,7 +256,7 @@ export async function runValidate(startDir = process.cwd()) {
258
256
  const hasAuditTable = (await Promise.all(migFiles.map((f) => readTextSafe(join(migrationsDir, f))))).some((sql) => sql &&
259
257
  /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?audit\b/i.test(sql));
260
258
  if (!hasAuditTable) {
261
- info('audit-table-missing', 'No migration creates the audit table — Fabric audit events will be dropped', migrationsDir, 'Add a migration with CREATE TABLE IF NOT EXISTS audit (...) see the starter-template for a reference schema');
259
+ info('audit-table-missing', 'No migration creates the audit table — Fabric audit events will be dropped', migrationsDir, lines('Add a new migration in this directory that creates an `audit` table.', 'Use the starter-template audit migration as the reference shape.', 'Expected columns come from `AuditEvent`:', '- eventId', '- type', '- source', '- outcome', '- occurredAt', '- functionId', '- wireType', '- wireId', '- traceId', '- transactionId', '- queryId', '- actor', '- input', '- metadata', 'At minimum, create the table so Fabric audit writes are not silently dropped.'));
262
260
  }
263
261
  }
264
262
  catch {
@@ -345,12 +343,12 @@ export async function runValidate(startDir = process.cwd()) {
345
343
  // ── packages/functions/tests/ ─────────────────────────────────────────
346
344
  const testsDir = join(fnDir, 'tests');
347
345
  if (!existsSync(testsDir)) {
348
- info('tests-missing', 'packages/functions/tests/ not found — no function test harness', testsDir, 'Run `pikku tests init` to scaffold the Cucumber test harness under packages/functions/tests/');
346
+ info('tests-missing', 'packages/functions/tests/ not found — no function test harness', testsDir, lines('Run `pikku tests init` from the repo root.', 'That should scaffold `packages/functions/tests/` with the generated function test harness.', 'Expected contents include feature files, step definitions, and support files.', 'Commit the scaffolded files after generation.'));
349
347
  }
350
348
  // ── packages/functions-sdk/ ───────────────────────────────────────────
351
349
  const sdkDir = join(root, 'packages', 'functions-sdk');
352
350
  if (!existsSync(sdkDir)) {
353
- info('functions-sdk-missing', 'packages/functions-sdk/ not found — generated RPC client and React Query hooks will not be available', sdkDir, 'Create packages/functions-sdk/ as a workspace with src/pikku/ subdirectory; configure clientFiles in root pikku.config.json to point to packages/functions-sdk/src/pikku/');
351
+ info('functions-sdk-missing', 'packages/functions-sdk/ not found — generated RPC client and React Query hooks will not be available', sdkDir, lines('Create a workspace at `packages/functions-sdk/`.', 'Minimum structure:', '- packages/functions-sdk/package.json', '- packages/functions-sdk/src/pikku/', 'Point `pikku.config.json` clientFiles to:', '- packages/functions-sdk/src/pikku/rpc-map.gen.d.ts', '- packages/functions-sdk/src/pikku/api.gen.ts', 'This package is the home for generated client artifacts, not handwritten server code.'));
354
352
  }
355
353
  const ok = !findings.some((f) => f.severity === 'error');
356
354
  return { ok, root, findings };
@@ -378,9 +376,13 @@ export const renderValidate = (_s, { ok, root, findings }) => {
378
376
  : f.severity === 'warn'
379
377
  ? changed('⚠')
380
378
  : dim('ℹ');
379
+ const fixLines = f.fixHint.split('\n');
381
380
  console.log(`${icon} ${f.message}`);
382
381
  console.log(` ${dim('path:')} ${relPath(f.path)}`);
383
- console.log(` ${dim('fix:')} ${f.fixHint}`);
382
+ console.log(` ${dim('fix:')}`);
383
+ for (const line of fixLines) {
384
+ console.log(` ${line}`);
385
+ }
384
386
  console.log();
385
387
  }
386
388
  const counts = [];
@@ -20,9 +20,6 @@ export const dbGenerate = pikkuSessionlessFunc({
20
20
  case 'up-to-date':
21
21
  logger.info('db generate: Better Auth schema already covered by existing migrations — nothing to generate');
22
22
  return;
23
- case 'unsupported-dialect':
24
- logger.warn('db generate: automatic Better Auth migration generation is currently SQLite-only. Run Better Auth schema generation manually for postgres.');
25
- return;
26
23
  case 'incremental-unsupported': {
27
24
  const cols = (result.missingColumns ?? [])
28
25
  .map((m) => `${m.table}(${m.columns.join(', ')})`)
@@ -4,20 +4,24 @@ import { loadUserConfigForDb } from './db-shared.js';
4
4
  export const dbReset = pikkuSessionlessFunc({
5
5
  remote: true,
6
6
  func: async ({ logger, config }) => {
7
+ if (process.env.NODE_ENV === 'production') {
8
+ logger.error('pikku db reset refused: NODE_ENV=production. This command only runs in dev.');
9
+ throw new Error('pikku db reset refused: NODE_ENV=production');
10
+ }
7
11
  const userConfig = await loadUserConfigForDb({ config, logger });
8
12
  if (!userConfig)
9
13
  return;
10
14
  const resolved = resolveDb(userConfig, config.rootDir, config.outDir, config.runtimeDir);
11
15
  if (!resolved) {
12
- logger.error('pikku db reset: no database configured — set sqliteDb in your createConfig.');
16
+ logger.error('pikku db reset: no database configured — set sqliteDb or postgresUrl in your createConfig.');
13
17
  throw new Error('no database configured');
14
18
  }
15
- if (resolved.dialect !== 'sqlite') {
16
- logger.error('pikku db reset: reset is only supported for SQLite databases.');
17
- throw new Error('reset not supported for postgres');
18
- }
19
- reset(resolved, config.rootDir);
20
- logger.info(`db reset: removed ${resolved.dbFile}`);
19
+ await reset(resolved, config.rootDir);
20
+ logger.info(resolved.dialect === 'sqlite'
21
+ ? `db reset: removed ${resolved.dbFile}`
22
+ : resolved.mode === 'pglite'
23
+ ? `db reset: removed ${resolved.pgliteDir}`
24
+ : 'db reset: cleared non-system Postgres schemas');
21
25
  const { migrate, codegen, zod } = await migrateAndCodegen(resolved);
22
26
  for (const name of migrate.applied) {
23
27
  logger.info(`db reset: applied ${name}`);
@@ -9,19 +9,16 @@ export const dbSeed = pikkuSessionlessFunc({
9
9
  return;
10
10
  const resolved = resolveDb(userConfig, config.rootDir, config.outDir, config.runtimeDir);
11
11
  if (!resolved) {
12
- logger.error('pikku db seed: no database configured — set sqliteDb in your createConfig.');
12
+ logger.error('pikku db seed: no database configured — set sqliteDb or postgresUrl in your createConfig.');
13
13
  throw new Error('no database configured');
14
14
  }
15
- if (resolved.dialect !== 'sqlite') {
16
- logger.error('pikku db seed: seed is only supported for SQLite databases.');
17
- throw new Error('seed not supported for postgres');
18
- }
19
15
  const result = await seed(resolved);
16
+ const seedFile = resolved.seedFile;
20
17
  if (!result.applied) {
21
- logger.info(`db seed: no ${resolved.seedFile} found, nothing to do`);
18
+ logger.info(`db seed: no ${seedFile} found, nothing to do`);
22
19
  }
23
20
  else {
24
- logger.info(`db seed: applied ${resolved.seedFile} (${result.bytes} bytes)`);
21
+ logger.info(`db seed: applied ${seedFile} (${result.bytes} bytes)`);
25
22
  }
26
23
  },
27
24
  });
@@ -24,10 +24,8 @@ export async function loadUserConfigForDb(options) {
24
24
  const getFallbackConfig = () => {
25
25
  if (hasSqliteDbAssets)
26
26
  return { sqliteDb: '.pikku-runtime/dev.db' };
27
- if (hasPostgresDbAssets) {
28
- logger.error('Postgres assets detected but postgresUrl is not configured in createConfig.');
29
- return null;
30
- }
27
+ if (hasPostgresDbAssets)
28
+ return {};
31
29
  return null;
32
30
  };
33
31
  const configFactoryFile = findUserConfigFactoryFile(config.rootDir, config.srcDirectories);
@@ -179,6 +179,7 @@ export const deployApply = pikkuSessionlessFunc({
179
179
  inspectorState,
180
180
  serverlessIncompatible: config.deploy?.serverlessIncompatible,
181
181
  getEntryContext,
182
+ outDir: config.outDir,
182
183
  logger,
183
184
  });
184
185
  if (buildResult.manifest.units.length === 0) {
@@ -55,6 +55,7 @@ export const deployPlan = pikkuSessionlessFunc({
55
55
  inspectorState,
56
56
  serverlessIncompatible: config.deploy?.serverlessIncompatible,
57
57
  getEntryContext,
58
+ outDir: config.outDir,
58
59
  logger,
59
60
  });
60
61
  if (result.manifest.units.length === 0) {
@@ -113,7 +113,7 @@ export const dev = pikkuSessionlessFunc({
113
113
  ? parseDatabaseUrl(envDatabaseUrl)
114
114
  : userConfig;
115
115
  const resolvedDb = resolveDb(effectiveDbConfig, config.rootDir, config.outDir, config.runtimeDir);
116
- const resolvedLocalDb = resolvedDb?.dialect === 'sqlite' ? resolvedDb : undefined;
116
+ const resolvedLocalDb = resolvedDb ?? undefined;
117
117
  const kysely = resolvedLocalDb
118
118
  ? await createKysely(resolvedLocalDb)
119
119
  : undefined;
@@ -25,7 +25,11 @@ export interface ResolvedSqliteDb extends ResolvedDbBase {
25
25
  }
26
26
  export interface ResolvedPostgresDb extends ResolvedDbBase {
27
27
  dialect: 'postgres';
28
- connectionString: string;
28
+ mode: 'url' | 'pglite';
29
+ connectionString?: string;
30
+ pgliteDir?: string;
31
+ runtimeDir: string;
32
+ seedFile: string;
29
33
  }
30
34
  export type ResolvedDb = ResolvedSqliteDb | ResolvedPostgresDb;
31
35
  /**
@@ -50,9 +54,9 @@ export interface MigrateAndCodegenOutcome {
50
54
  classificationsJsonWritten: boolean;
51
55
  }
52
56
  export declare function migrateAndCodegen(resolved: ResolvedDb): Promise<MigrateAndCodegenOutcome>;
53
- export declare function seed(resolved: ResolvedSqliteDb): Promise<SeedResult>;
54
- export declare function reset(resolved: ResolvedSqliteDb, rootDir: string): void;
55
- export declare function createKysely<DB>(resolved: ResolvedSqliteDb): Promise<Kysely<DB>>;
57
+ export declare function seed(resolved: ResolvedDb): Promise<SeedResult>;
58
+ export declare function reset(resolved: ResolvedDb, rootDir: string): Promise<void>;
59
+ export declare function createKysely<DB>(resolved: ResolvedDb): Promise<Kysely<DB>>;
56
60
  type SchemaMap = Map<string, Set<string>>;
57
61
  export interface DesiredAuthSchema {
58
62
  tables: SchemaMap;
@@ -75,7 +79,7 @@ export declare function computeAuthDrift(resolved: ResolvedDb, rootDir: string,
75
79
  error: (msg: string) => void;
76
80
  }): Promise<AuthDriftResult>;
77
81
  export interface GenerateAuthResult {
78
- status: 'no-auth' | 'up-to-date' | 'written' | 'incremental-unsupported' | 'unsupported-dialect';
82
+ status: 'no-auth' | 'up-to-date' | 'written' | 'incremental-unsupported';
79
83
  file?: string;
80
84
  missingTables?: string[];
81
85
  missingColumns?: {