@pikku/cli 0.12.66 → 0.12.68
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/cli.schema.json +1 -1
- package/console-app/assets/{index-94z1KYC_.js → index-CttM2Aiz.js} +141 -141
- package/console-app/index.html +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +8 -0
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +6 -6
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +1 -1
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +6 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/cli.wiring.js +8 -0
- package/dist/src/fabric/functions/validate.function.js +1 -1
- package/dist/src/functions/commands/audit.js +25 -8
- package/dist/src/functions/commands/console.js +1 -1
- package/dist/src/functions/commands/enable.js +4 -4
- package/dist/src/functions/validate/workspace-validate.js +1 -1
- package/dist/src/functions/wirings/console/pikku-command-console-functions.js +13 -0
- package/dist/src/functions/wirings/console/pikku-command-nodes-meta.js +5 -1
- package/dist/src/functions/wirings/console/serialize-console-functions.js +6 -11
- package/dist/src/functions/wirings/functions/pikku-command-functions.js +5 -3
- package/dist/src/functions/workflows/all.workflow.js +17 -0
- package/dist/src/utils/strip-verbose-meta.d.ts +3 -0
- package/dist/src/utils/strip-verbose-meta.js +8 -0
- package/dist/src/utils/tsc-check.d.ts +46 -0
- package/dist/src/utils/tsc-check.js +141 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/skills/pikku-better-auth/SKILL.md +4 -0
- package/skills/pikku-deps/SKILL.md +91 -0
- package/skills/pikku-i18n/SKILL.md +58 -185
- package/skills/pikku-kysely/SKILL.md +68 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../bin/pikku.ts","../src/cli.wiring.ts","../src/services.ts","../src/deploy/build-pipeline.ts","../src/deploy/provider-adapter.ts","../src/deploy/server-entry.ts","../src/deploy/analyzer/analyzer.ts","../src/deploy/analyzer/index.ts","../src/deploy/analyzer/manifest.ts","../src/deploy/bundler/bun-bundler.ts","../src/deploy/bundler/bundler.interface.ts","../src/deploy/bundler/bundler.ts","../src/deploy/bundler/dep-extractor.ts","../src/deploy/bundler/index.ts","../src/deploy/bundler/node-bundler.ts","../src/deploy/bundler/types.ts","../src/deploy/codegen/index.ts","../src/deploy/codegen/per-unit-codegen.ts","../src/deploy/plan/executor.ts","../src/deploy/plan/formatter.ts","../src/deploy/plan/index.ts","../src/deploy/plan/planner.ts","../src/deploy/plan/provider.ts","../src/deploy/plan/types.ts","../src/fabric/fabric-commands.ts","../src/fabric/functions/add.function.ts","../src/fabric/functions/addon-verify.function.ts","../src/fabric/functions/db-schema.function.ts","../src/fabric/functions/deploy-list.function.ts","../src/fabric/functions/deploy-units.function.ts","../src/fabric/functions/deploy.function.ts","../src/fabric/functions/domains-add.function.ts","../src/fabric/functions/domains-list.function.ts","../src/fabric/functions/domains-remove.function.ts","../src/fabric/functions/errors.function.ts","../src/fabric/functions/init.function.ts","../src/fabric/functions/link.function.ts","../src/fabric/functions/llm-key.function.ts","../src/fabric/functions/login.function.ts","../src/fabric/functions/logs.function.ts","../src/fabric/functions/metrics.function.ts","../src/fabric/functions/publish.function.ts","../src/fabric/functions/rollback.function.ts","../src/fabric/functions/secrets-list.function.ts","../src/fabric/functions/secrets-set.function.ts","../src/fabric/functions/smoke.function.ts","../src/fabric/functions/status.function.ts","../src/fabric/functions/trace.function.ts","../src/fabric/functions/validate.function.ts","../src/fabric/lib/config.ts","../src/fabric/lib/console-url.ts","../src/fabric/lib/git.ts","../src/fabric/lib/http.ts","../src/fabric/lib/not-implemented.ts","../src/fabric/lib/output.ts","../src/fabric/lib/prompt.ts","../src/fabric/lib/stage.ts","../src/fabric/sdk/http-map.gen.d.ts","../src/fabric/sdk/pikku-fetch.gen.ts","../src/fabric/sdk/pikku-rpc.gen.ts","../src/fabric/sdk/rpc-map.gen.d.ts","../src/functions/commands/all.ts","../src/functions/commands/audit.ts","../src/functions/commands/binary.ts","../src/functions/commands/bootstrap.ts","../src/functions/commands/console.ts","../src/functions/commands/db-audit.ts","../src/functions/commands/db-generate.ts","../src/functions/commands/db-migrate.ts","../src/functions/commands/db-reset.ts","../src/functions/commands/db-seed.ts","../src/functions/commands/db-shared.ts","../src/functions/commands/deploy-apply.ts","../src/functions/commands/deploy-info.ts","../src/functions/commands/deploy-plan.ts","../src/functions/commands/dev-ai-runner.ts","../src/functions/commands/dev.ts","../src/functions/commands/emails-init.ts","../src/functions/commands/enable.ts","../src/functions/commands/info.ts","../src/functions/commands/load-user-project.ts","../src/functions/commands/login.ts","../src/functions/commands/meta.ts","../src/functions/commands/new-addon.ts","../src/functions/commands/new-function.ts","../src/functions/commands/new-middleware.ts","../src/functions/commands/new-permission.ts","../src/functions/commands/new-wiring.ts","../src/functions/commands/pikku-command-bootstrap.ts","../src/functions/commands/pikku-command-summary.ts","../src/functions/commands/serve-console.ts","../src/functions/commands/serve.ts","../src/functions/commands/skills.ts","../src/functions/commands/tests-coverage.ts","../src/functions/commands/tests-init.ts","../src/functions/commands/user-flow.ts","../src/functions/commands/versions-check.ts","../src/functions/commands/versions-init.ts","../src/functions/commands/versions-update.ts","../src/functions/commands/watch.ts","../src/functions/commands/workspace-validate.ts","../src/functions/db/annotation-parser.ts","../src/functions/db/better-auth-schema.ts","../src/functions/db/coercion-plugin.ts","../src/functions/db/db-codegen.ts","../src/functions/db/db-introspector.ts","../src/functions/db/db-migrator.ts","../src/functions/db/local-db.ts","../src/functions/db/zod-codegen.ts","../src/functions/db/postgres/pglite-kysely.ts","../src/functions/db/postgres/postgres-introspector.ts","../src/functions/db/postgres/postgres-migrator.ts","../src/functions/db/sqlite/seed.ts","../src/functions/db/sqlite/sqlite-introspector.ts","../src/functions/db/sqlite/sqlite-kysely.ts","../src/functions/db/sqlite/sqlite-migrator.ts","../src/functions/db/sqlite/sqlite-runtime-bun.ts","../src/functions/db/sqlite/sqlite-runtime-node.ts","../src/functions/db/sqlite/sqlite-runtime.ts","../src/functions/runtimes/fetch/index.ts","../src/functions/runtimes/nextjs/pikku-command-nextjs.ts","../src/functions/runtimes/nextjs/serialize-nextjs-backend-worker-rpc-wrapper.ts","../src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts","../src/functions/runtimes/nextjs/serialize-nextjs-http-wrapper.ts","../src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.ts","../src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.ts","../src/functions/runtimes/websocket/pikku-command-websocket-typed.ts","../src/functions/runtimes/websocket/serialize-websocket-wrapper.ts","../src/functions/validate/workspace-validate.ts","../src/functions/wirings/ai-agent/pikku-command-ai-agent-types.ts","../src/functions/wirings/ai-agent/pikku-command-ai-agent.ts","../src/functions/wirings/ai-agent/pikku-command-public-agent.ts","../src/functions/wirings/ai-agent/serialize-agent-map.ts","../src/functions/wirings/ai-agent/serialize-ai-agent-types.ts","../src/functions/wirings/ai-agent/serialize-public-agent.ts","../src/functions/wirings/auth/pikku-command-auth.ts","../src/functions/wirings/auth/serialize-auth-gen.ts","../src/functions/wirings/auth/serialize-auth-meta.ts","../src/functions/wirings/auth/serialize-auth-types.ts","../src/functions/wirings/channels/pikku-channels.ts","../src/functions/wirings/channels/pikku-command-channel-types.ts","../src/functions/wirings/channels/pikku-command-channels-map.ts","../src/functions/wirings/channels/pikku-command-channels.ts","../src/functions/wirings/channels/serialize-channel-types.ts","../src/functions/wirings/channels/serialize-typed-channel-map.ts","../src/functions/wirings/cli/pikku-command-cli-entry.ts","../src/functions/wirings/cli/pikku-command-cli-types.ts","../src/functions/wirings/cli/pikku-command-cli.ts","../src/functions/wirings/cli/serialize-channel-cli-client.ts","../src/functions/wirings/cli/serialize-channel-cli.ts","../src/functions/wirings/cli/serialize-cli-types.ts","../src/functions/wirings/cli/serialize-local-cli-bootstrap.ts","../src/functions/wirings/console/pikku-command-console-functions.ts","../src/functions/wirings/console/pikku-command-node-types.ts","../src/functions/wirings/console/pikku-command-nodes-meta.ts","../src/functions/wirings/console/serialize-console-functions.ts","../src/functions/wirings/console/serialize-node-types.ts","../src/functions/wirings/credentials/pikku-command-credentials.ts","../src/functions/wirings/credentials/serialize-credentials-types.ts","../src/functions/wirings/emails/pikku-command-emails.ts","../src/functions/wirings/emails/serialize-emails.ts","../src/functions/wirings/functions/pikku-command-addon-types.ts","../src/functions/wirings/functions/pikku-command-function-types-split.ts","../src/functions/wirings/functions/pikku-command-function-types.ts","../src/functions/wirings/functions/pikku-command-functions.ts","../src/functions/wirings/functions/pikku-command-services.ts","../src/functions/wirings/functions/schemas.ts","../src/functions/wirings/functions/serialize-addon-refs.ts","../src/functions/wirings/functions/serialize-addon-types.ts","../src/functions/wirings/functions/serialize-function-imports.ts","../src/functions/wirings/functions/serialize-function-types.ts","../src/functions/wirings/functions/serialize-pikku-types-hub.ts","../src/functions/wirings/gateway/pikku-command-gateway.ts","../src/functions/wirings/gateway/serialize-gateway-meta.ts","../src/functions/wirings/http/pikku-command-http-map.ts","../src/functions/wirings/http/pikku-command-http-routes.ts","../src/functions/wirings/http/pikku-command-http-types.ts","../src/functions/wirings/http/pikku-command-openapi.ts","../src/functions/wirings/http/pikku-http-routes.ts","../src/functions/wirings/http/serialize-fetch-wrapper.ts","../src/functions/wirings/http/serialize-http-types.ts","../src/functions/wirings/http/serialize-typed-http-map.ts","../src/functions/wirings/mcp/pikku-command-mcp-json.ts","../src/functions/wirings/mcp/pikku-command-mcp-types.ts","../src/functions/wirings/mcp/pikku-command-mcp.ts","../src/functions/wirings/mcp/serialize-mcp-types.ts","../src/functions/wirings/middleware/pikku-command-middleware.ts","../src/functions/wirings/middleware/serialize-middleware-imports.ts","../src/functions/wirings/package/pikku-command-package-types.ts","../src/functions/wirings/package/pikku-command-package.ts","../src/functions/wirings/package/serialize-package-types.ts","../src/functions/wirings/package/serialize-package.ts","../src/functions/wirings/permissions/pikku-command-permissions.ts","../src/functions/wirings/permissions/serialize-permissions-imports.ts","../src/functions/wirings/queue/pikku-command-queue-map.ts","../src/functions/wirings/queue/pikku-command-queue-service.ts","../src/functions/wirings/queue/pikku-command-queue-types.ts","../src/functions/wirings/queue/pikku-command-queue.ts","../src/functions/wirings/queue/pikku-queue-map.ts","../src/functions/wirings/queue/pikku-queue.ts","../src/functions/wirings/queue/serialize-queue-map.ts","../src/functions/wirings/queue/serialize-queue-meta.ts","../src/functions/wirings/queue/serialize-queue-types.ts","../src/functions/wirings/queue/serialize-queue-wrapper.ts","../src/functions/wirings/realtime/pikku-command-events-scaffold.ts","../src/functions/wirings/realtime/pikku-command-realtime.ts","../src/functions/wirings/realtime/serialize-events-scaffold.ts","../src/functions/wirings/realtime/serialize-realtime-client.ts","../src/functions/wirings/rpc/pikku-command-public-rpc.ts","../src/functions/wirings/rpc/pikku-command-react-query.ts","../src/functions/wirings/rpc/pikku-command-remote-rpc.ts","../src/functions/wirings/rpc/pikku-command-rpc-client.ts","../src/functions/wirings/rpc/pikku-command-rpc-map.ts","../src/functions/wirings/rpc/pikku-command-rpc.ts","../src/functions/wirings/rpc/serialize-public-rpc.ts","../src/functions/wirings/rpc/serialize-react-query-hooks.ts","../src/functions/wirings/rpc/serialize-remote-rpc.ts","../src/functions/wirings/rpc/serialize-rpc-wrapper.ts","../src/functions/wirings/rpc/serialize-typed-rpc-map.ts","../src/functions/wirings/scheduler/pikku-command-scheduler-types.ts","../src/functions/wirings/scheduler/pikku-command-scheduler.ts","../src/functions/wirings/scheduler/serialize-scheduler-meta.ts","../src/functions/wirings/scheduler/serialize-scheduler-types.ts","../src/functions/wirings/secrets/pikku-command-secrets.ts","../src/functions/wirings/secrets/serialize-secrets-types.ts","../src/functions/wirings/triggers/pikku-command-trigger-types.ts","../src/functions/wirings/triggers/pikku-command-trigger.ts","../src/functions/wirings/triggers/serialize-trigger-meta.ts","../src/functions/wirings/triggers/serialize-trigger-types.ts","../src/functions/wirings/variables/pikku-command-variables.ts","../src/functions/wirings/variables/serialize-variables-types.ts","../src/functions/wirings/workflow/pikku-command-workflow-routes.ts","../src/functions/wirings/workflow/pikku-command-workflow.ts","../src/functions/wirings/workflow/serialize-user-flow-actors.ts","../src/functions/wirings/workflow/serialize-workflow-bootstrap-map.ts","../src/functions/wirings/workflow/serialize-workflow-map.ts","../src/functions/wirings/workflow/serialize-workflow-meta.ts","../src/functions/wirings/workflow/serialize-workflow-registration.ts","../src/functions/wirings/workflow/serialize-workflow-routes.ts","../src/functions/wirings/workflow/serialize-workflow-types.ts","../src/functions/workflows/all.workflow.ts","../src/middleware/log-command-info-and-time.ts","../src/scaffold/rpc-remote.gen.ts","../src/server/bun-server-runner.ts","../src/server/dev-server-runner.interface.ts","../src/server/node-server-runner.ts","../src/services/cli-logger-forwarder.service.ts","../src/services/cli-logger.service.ts","../src/utils/assert-single-core-version.ts","../src/utils/check-required-types.ts","../src/utils/cli-session.ts","../src/utils/command-summary.ts","../src/utils/contract-versions.ts","../src/utils/detect-better-auth.ts","../src/utils/device-auth.ts","../src/utils/file-import-path.ts","../src/utils/file-imports-serializer.ts","../src/utils/file-writer.ts","../src/utils/generate-bootstrap-file.ts","../src/utils/get-cli-version.ts","../src/utils/parse-cli-filters.ts","../src/utils/pikku-cli-config.ts","../src/utils/pikku-files-and-methods.ts","../src/utils/serialize-import-map.ts","../src/utils/serialize-meta-ts.ts","../src/utils/serialize-schemas.ts","../src/utils/strip-verbose-meta.ts","../.pikku/pikku-bootstrap.gen.ts","../.pikku/pikku-meta-service.gen.ts","../.pikku/pikku-services.gen.ts","../.pikku/pikku-types.gen.ts","../.pikku/agent/pikku-agent-map.gen.d.ts","../.pikku/agent/pikku-agent-types.gen.ts","../.pikku/channel/pikku-channel-types.gen.ts","../.pikku/cli/pikku-cli-channel.ts","../.pikku/cli/pikku-cli-client.gen.ts","../.pikku/cli/pikku-cli-contracts-meta.gen.ts","../.pikku/cli/pikku-cli-types.gen.ts","../.pikku/cli/pikku-cli-wirings-meta.gen.ts","../.pikku/cli/pikku-cli-wirings.gen.ts","../.pikku/cli/pikku-cli.gen.ts","../.pikku/console/pikku-node-types.gen.ts","../.pikku/function/pikku-function-types.gen.ts","../.pikku/function/pikku-functions-meta.gen.ts","../.pikku/function/pikku-functions.gen.ts","../.pikku/http/pikku-http-types.gen.ts","../.pikku/http/pikku-http-wirings-map.gen.d.ts","../.pikku/http/pikku-http-wirings-meta.gen.ts","../.pikku/http/pikku-http-wirings.gen.ts","../.pikku/mcp/pikku-mcp-types.gen.ts","../.pikku/node/pikku-node-types.gen.ts","../.pikku/queue/pikku-queue-types.gen.ts","../.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts","../.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts","../.pikku/queue/pikku-queue-workers-wirings.gen.ts","../.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts","../.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts","../.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts","../.pikku/scheduler/pikku-scheduler-types.gen.ts","../.pikku/schemas/register.gen.ts","../.pikku/secrets/pikku-secret-types.gen.ts","../.pikku/secrets/pikku-secrets.gen.ts","../.pikku/trigger/pikku-trigger-types.gen.ts","../.pikku/variables/pikku-variable-types.gen.ts","../.pikku/variables/pikku-variables.gen.ts","../.pikku/workflow/pikku-workflow-map.gen.d.ts","../.pikku/workflow/pikku-workflow-types.gen.ts","../.pikku/workflow/pikku-workflow-wirings-meta.gen.ts","../.pikku/workflow/pikku-workflow-wirings.gen.ts","../types/application-types.d.ts","../types/bun-sqlite.d.ts","../types/config.d.ts"],"version":"6.0.3"}
|
|
1
|
+
{"root":["../bin/pikku.ts","../src/cli.wiring.ts","../src/services.ts","../src/deploy/build-pipeline.ts","../src/deploy/provider-adapter.ts","../src/deploy/server-entry.ts","../src/deploy/analyzer/analyzer.ts","../src/deploy/analyzer/index.ts","../src/deploy/analyzer/manifest.ts","../src/deploy/bundler/bun-bundler.ts","../src/deploy/bundler/bundler.interface.ts","../src/deploy/bundler/bundler.ts","../src/deploy/bundler/dep-extractor.ts","../src/deploy/bundler/index.ts","../src/deploy/bundler/node-bundler.ts","../src/deploy/bundler/types.ts","../src/deploy/codegen/index.ts","../src/deploy/codegen/per-unit-codegen.ts","../src/deploy/plan/executor.ts","../src/deploy/plan/formatter.ts","../src/deploy/plan/index.ts","../src/deploy/plan/planner.ts","../src/deploy/plan/provider.ts","../src/deploy/plan/types.ts","../src/fabric/fabric-commands.ts","../src/fabric/functions/add.function.ts","../src/fabric/functions/addon-verify.function.ts","../src/fabric/functions/db-schema.function.ts","../src/fabric/functions/deploy-list.function.ts","../src/fabric/functions/deploy-units.function.ts","../src/fabric/functions/deploy.function.ts","../src/fabric/functions/domains-add.function.ts","../src/fabric/functions/domains-list.function.ts","../src/fabric/functions/domains-remove.function.ts","../src/fabric/functions/errors.function.ts","../src/fabric/functions/init.function.ts","../src/fabric/functions/link.function.ts","../src/fabric/functions/llm-key.function.ts","../src/fabric/functions/login.function.ts","../src/fabric/functions/logs.function.ts","../src/fabric/functions/metrics.function.ts","../src/fabric/functions/publish.function.ts","../src/fabric/functions/rollback.function.ts","../src/fabric/functions/secrets-list.function.ts","../src/fabric/functions/secrets-set.function.ts","../src/fabric/functions/smoke.function.ts","../src/fabric/functions/status.function.ts","../src/fabric/functions/trace.function.ts","../src/fabric/functions/validate.function.ts","../src/fabric/lib/config.ts","../src/fabric/lib/console-url.ts","../src/fabric/lib/git.ts","../src/fabric/lib/http.ts","../src/fabric/lib/not-implemented.ts","../src/fabric/lib/output.ts","../src/fabric/lib/prompt.ts","../src/fabric/lib/stage.ts","../src/fabric/sdk/http-map.gen.d.ts","../src/fabric/sdk/pikku-fetch.gen.ts","../src/fabric/sdk/pikku-rpc.gen.ts","../src/fabric/sdk/rpc-map.gen.d.ts","../src/functions/commands/all.ts","../src/functions/commands/audit.ts","../src/functions/commands/binary.ts","../src/functions/commands/bootstrap.ts","../src/functions/commands/console.ts","../src/functions/commands/db-audit.ts","../src/functions/commands/db-generate.ts","../src/functions/commands/db-migrate.ts","../src/functions/commands/db-reset.ts","../src/functions/commands/db-seed.ts","../src/functions/commands/db-shared.ts","../src/functions/commands/deploy-apply.ts","../src/functions/commands/deploy-info.ts","../src/functions/commands/deploy-plan.ts","../src/functions/commands/dev-ai-runner.ts","../src/functions/commands/dev.ts","../src/functions/commands/emails-init.ts","../src/functions/commands/enable.ts","../src/functions/commands/info.ts","../src/functions/commands/load-user-project.ts","../src/functions/commands/login.ts","../src/functions/commands/meta.ts","../src/functions/commands/new-addon.ts","../src/functions/commands/new-function.ts","../src/functions/commands/new-middleware.ts","../src/functions/commands/new-permission.ts","../src/functions/commands/new-wiring.ts","../src/functions/commands/pikku-command-bootstrap.ts","../src/functions/commands/pikku-command-summary.ts","../src/functions/commands/serve-console.ts","../src/functions/commands/serve.ts","../src/functions/commands/skills.ts","../src/functions/commands/tests-coverage.ts","../src/functions/commands/tests-init.ts","../src/functions/commands/user-flow.ts","../src/functions/commands/versions-check.ts","../src/functions/commands/versions-init.ts","../src/functions/commands/versions-update.ts","../src/functions/commands/watch.ts","../src/functions/commands/workspace-validate.ts","../src/functions/db/annotation-parser.ts","../src/functions/db/better-auth-schema.ts","../src/functions/db/coercion-plugin.ts","../src/functions/db/db-codegen.ts","../src/functions/db/db-introspector.ts","../src/functions/db/db-migrator.ts","../src/functions/db/local-db.ts","../src/functions/db/zod-codegen.ts","../src/functions/db/postgres/pglite-kysely.ts","../src/functions/db/postgres/postgres-introspector.ts","../src/functions/db/postgres/postgres-migrator.ts","../src/functions/db/sqlite/seed.ts","../src/functions/db/sqlite/sqlite-introspector.ts","../src/functions/db/sqlite/sqlite-kysely.ts","../src/functions/db/sqlite/sqlite-migrator.ts","../src/functions/db/sqlite/sqlite-runtime-bun.ts","../src/functions/db/sqlite/sqlite-runtime-node.ts","../src/functions/db/sqlite/sqlite-runtime.ts","../src/functions/runtimes/fetch/index.ts","../src/functions/runtimes/nextjs/pikku-command-nextjs.ts","../src/functions/runtimes/nextjs/serialize-nextjs-backend-worker-rpc-wrapper.ts","../src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts","../src/functions/runtimes/nextjs/serialize-nextjs-http-wrapper.ts","../src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.ts","../src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.ts","../src/functions/runtimes/websocket/pikku-command-websocket-typed.ts","../src/functions/runtimes/websocket/serialize-websocket-wrapper.ts","../src/functions/validate/workspace-validate.ts","../src/functions/wirings/ai-agent/pikku-command-ai-agent-types.ts","../src/functions/wirings/ai-agent/pikku-command-ai-agent.ts","../src/functions/wirings/ai-agent/pikku-command-public-agent.ts","../src/functions/wirings/ai-agent/serialize-agent-map.ts","../src/functions/wirings/ai-agent/serialize-ai-agent-types.ts","../src/functions/wirings/ai-agent/serialize-public-agent.ts","../src/functions/wirings/auth/pikku-command-auth.ts","../src/functions/wirings/auth/serialize-auth-gen.ts","../src/functions/wirings/auth/serialize-auth-meta.ts","../src/functions/wirings/auth/serialize-auth-types.ts","../src/functions/wirings/channels/pikku-channels.ts","../src/functions/wirings/channels/pikku-command-channel-types.ts","../src/functions/wirings/channels/pikku-command-channels-map.ts","../src/functions/wirings/channels/pikku-command-channels.ts","../src/functions/wirings/channels/serialize-channel-types.ts","../src/functions/wirings/channels/serialize-typed-channel-map.ts","../src/functions/wirings/cli/pikku-command-cli-entry.ts","../src/functions/wirings/cli/pikku-command-cli-types.ts","../src/functions/wirings/cli/pikku-command-cli.ts","../src/functions/wirings/cli/serialize-channel-cli-client.ts","../src/functions/wirings/cli/serialize-channel-cli.ts","../src/functions/wirings/cli/serialize-cli-types.ts","../src/functions/wirings/cli/serialize-local-cli-bootstrap.ts","../src/functions/wirings/console/pikku-command-console-functions.ts","../src/functions/wirings/console/pikku-command-node-types.ts","../src/functions/wirings/console/pikku-command-nodes-meta.ts","../src/functions/wirings/console/serialize-console-functions.ts","../src/functions/wirings/console/serialize-node-types.ts","../src/functions/wirings/credentials/pikku-command-credentials.ts","../src/functions/wirings/credentials/serialize-credentials-types.ts","../src/functions/wirings/emails/pikku-command-emails.ts","../src/functions/wirings/emails/serialize-emails.ts","../src/functions/wirings/functions/pikku-command-addon-types.ts","../src/functions/wirings/functions/pikku-command-function-types-split.ts","../src/functions/wirings/functions/pikku-command-function-types.ts","../src/functions/wirings/functions/pikku-command-functions.ts","../src/functions/wirings/functions/pikku-command-services.ts","../src/functions/wirings/functions/schemas.ts","../src/functions/wirings/functions/serialize-addon-refs.ts","../src/functions/wirings/functions/serialize-addon-types.ts","../src/functions/wirings/functions/serialize-function-imports.ts","../src/functions/wirings/functions/serialize-function-types.ts","../src/functions/wirings/functions/serialize-pikku-types-hub.ts","../src/functions/wirings/gateway/pikku-command-gateway.ts","../src/functions/wirings/gateway/serialize-gateway-meta.ts","../src/functions/wirings/http/pikku-command-http-map.ts","../src/functions/wirings/http/pikku-command-http-routes.ts","../src/functions/wirings/http/pikku-command-http-types.ts","../src/functions/wirings/http/pikku-command-openapi.ts","../src/functions/wirings/http/pikku-http-routes.ts","../src/functions/wirings/http/serialize-fetch-wrapper.ts","../src/functions/wirings/http/serialize-http-types.ts","../src/functions/wirings/http/serialize-typed-http-map.ts","../src/functions/wirings/mcp/pikku-command-mcp-json.ts","../src/functions/wirings/mcp/pikku-command-mcp-types.ts","../src/functions/wirings/mcp/pikku-command-mcp.ts","../src/functions/wirings/mcp/serialize-mcp-types.ts","../src/functions/wirings/middleware/pikku-command-middleware.ts","../src/functions/wirings/middleware/serialize-middleware-imports.ts","../src/functions/wirings/package/pikku-command-package-types.ts","../src/functions/wirings/package/pikku-command-package.ts","../src/functions/wirings/package/serialize-package-types.ts","../src/functions/wirings/package/serialize-package.ts","../src/functions/wirings/permissions/pikku-command-permissions.ts","../src/functions/wirings/permissions/serialize-permissions-imports.ts","../src/functions/wirings/queue/pikku-command-queue-map.ts","../src/functions/wirings/queue/pikku-command-queue-service.ts","../src/functions/wirings/queue/pikku-command-queue-types.ts","../src/functions/wirings/queue/pikku-command-queue.ts","../src/functions/wirings/queue/pikku-queue-map.ts","../src/functions/wirings/queue/pikku-queue.ts","../src/functions/wirings/queue/serialize-queue-map.ts","../src/functions/wirings/queue/serialize-queue-meta.ts","../src/functions/wirings/queue/serialize-queue-types.ts","../src/functions/wirings/queue/serialize-queue-wrapper.ts","../src/functions/wirings/realtime/pikku-command-events-scaffold.ts","../src/functions/wirings/realtime/pikku-command-realtime.ts","../src/functions/wirings/realtime/serialize-events-scaffold.ts","../src/functions/wirings/realtime/serialize-realtime-client.ts","../src/functions/wirings/rpc/pikku-command-public-rpc.ts","../src/functions/wirings/rpc/pikku-command-react-query.ts","../src/functions/wirings/rpc/pikku-command-remote-rpc.ts","../src/functions/wirings/rpc/pikku-command-rpc-client.ts","../src/functions/wirings/rpc/pikku-command-rpc-map.ts","../src/functions/wirings/rpc/pikku-command-rpc.ts","../src/functions/wirings/rpc/serialize-public-rpc.ts","../src/functions/wirings/rpc/serialize-react-query-hooks.ts","../src/functions/wirings/rpc/serialize-remote-rpc.ts","../src/functions/wirings/rpc/serialize-rpc-wrapper.ts","../src/functions/wirings/rpc/serialize-typed-rpc-map.ts","../src/functions/wirings/scheduler/pikku-command-scheduler-types.ts","../src/functions/wirings/scheduler/pikku-command-scheduler.ts","../src/functions/wirings/scheduler/serialize-scheduler-meta.ts","../src/functions/wirings/scheduler/serialize-scheduler-types.ts","../src/functions/wirings/secrets/pikku-command-secrets.ts","../src/functions/wirings/secrets/serialize-secrets-types.ts","../src/functions/wirings/triggers/pikku-command-trigger-types.ts","../src/functions/wirings/triggers/pikku-command-trigger.ts","../src/functions/wirings/triggers/serialize-trigger-meta.ts","../src/functions/wirings/triggers/serialize-trigger-types.ts","../src/functions/wirings/variables/pikku-command-variables.ts","../src/functions/wirings/variables/serialize-variables-types.ts","../src/functions/wirings/workflow/pikku-command-workflow-routes.ts","../src/functions/wirings/workflow/pikku-command-workflow.ts","../src/functions/wirings/workflow/serialize-user-flow-actors.ts","../src/functions/wirings/workflow/serialize-workflow-bootstrap-map.ts","../src/functions/wirings/workflow/serialize-workflow-map.ts","../src/functions/wirings/workflow/serialize-workflow-meta.ts","../src/functions/wirings/workflow/serialize-workflow-registration.ts","../src/functions/wirings/workflow/serialize-workflow-routes.ts","../src/functions/wirings/workflow/serialize-workflow-types.ts","../src/functions/workflows/all.workflow.ts","../src/middleware/log-command-info-and-time.ts","../src/scaffold/rpc-remote.gen.ts","../src/server/bun-server-runner.ts","../src/server/dev-server-runner.interface.ts","../src/server/node-server-runner.ts","../src/services/cli-logger-forwarder.service.ts","../src/services/cli-logger.service.ts","../src/utils/assert-single-core-version.ts","../src/utils/check-required-types.ts","../src/utils/cli-session.ts","../src/utils/command-summary.ts","../src/utils/contract-versions.ts","../src/utils/detect-better-auth.ts","../src/utils/device-auth.ts","../src/utils/file-import-path.ts","../src/utils/file-imports-serializer.ts","../src/utils/file-writer.ts","../src/utils/generate-bootstrap-file.ts","../src/utils/get-cli-version.ts","../src/utils/parse-cli-filters.ts","../src/utils/pikku-cli-config.ts","../src/utils/pikku-files-and-methods.ts","../src/utils/serialize-import-map.ts","../src/utils/serialize-meta-ts.ts","../src/utils/serialize-schemas.ts","../src/utils/strip-verbose-meta.ts","../src/utils/tsc-check.ts","../.pikku/pikku-bootstrap.gen.ts","../.pikku/pikku-meta-service.gen.ts","../.pikku/pikku-services.gen.ts","../.pikku/pikku-types.gen.ts","../.pikku/agent/pikku-agent-map.gen.d.ts","../.pikku/agent/pikku-agent-types.gen.ts","../.pikku/channel/pikku-channel-types.gen.ts","../.pikku/cli/pikku-cli-channel.ts","../.pikku/cli/pikku-cli-client.gen.ts","../.pikku/cli/pikku-cli-contracts-meta.gen.ts","../.pikku/cli/pikku-cli-types.gen.ts","../.pikku/cli/pikku-cli-wirings-meta.gen.ts","../.pikku/cli/pikku-cli-wirings.gen.ts","../.pikku/cli/pikku-cli.gen.ts","../.pikku/console/pikku-node-types.gen.ts","../.pikku/function/pikku-function-types.gen.ts","../.pikku/function/pikku-functions-meta.gen.ts","../.pikku/function/pikku-functions.gen.ts","../.pikku/http/pikku-http-types.gen.ts","../.pikku/http/pikku-http-wirings-map.gen.d.ts","../.pikku/http/pikku-http-wirings-meta.gen.ts","../.pikku/http/pikku-http-wirings.gen.ts","../.pikku/mcp/pikku-mcp-types.gen.ts","../.pikku/node/pikku-node-types.gen.ts","../.pikku/queue/pikku-queue-types.gen.ts","../.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts","../.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts","../.pikku/queue/pikku-queue-workers-wirings.gen.ts","../.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts","../.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts","../.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts","../.pikku/scheduler/pikku-scheduler-types.gen.ts","../.pikku/schemas/register.gen.ts","../.pikku/secrets/pikku-secret-types.gen.ts","../.pikku/secrets/pikku-secrets.gen.ts","../.pikku/trigger/pikku-trigger-types.gen.ts","../.pikku/variables/pikku-variable-types.gen.ts","../.pikku/variables/pikku-variables.gen.ts","../.pikku/workflow/pikku-workflow-map.gen.d.ts","../.pikku/workflow/pikku-workflow-types.gen.ts","../.pikku/workflow/pikku-workflow-wirings-meta.gen.ts","../.pikku/workflow/pikku-workflow-wirings.gen.ts","../types/application-types.d.ts","../types/bun-sqlite.d.ts","../types/config.d.ts"],"version":"6.0.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.68",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"imports": {
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"@openapi-contrib/json-schema-to-openapi-schema": "^4.3.1",
|
|
30
30
|
"@pikku/better-auth": "^0.12.14",
|
|
31
31
|
"@pikku/bun-server": "^0.12.2",
|
|
32
|
-
"@pikku/core": "^0.12.
|
|
32
|
+
"@pikku/core": "^0.12.51",
|
|
33
33
|
"@pikku/deploy-cloudflare": "^0.12.8",
|
|
34
34
|
"@pikku/fetch": "^0.12.6",
|
|
35
|
-
"@pikku/inspector": "^0.12.
|
|
35
|
+
"@pikku/inspector": "^0.12.35",
|
|
36
36
|
"@pikku/kysely": "^0.13.0",
|
|
37
37
|
"@pikku/kysely-node-sqlite": "^0.12.3",
|
|
38
38
|
"@pikku/node-http-server": "^0.12.4",
|
|
@@ -52,6 +52,10 @@ Better Auth owns its own HTTP surface, database tables, and session cookie. The
|
|
|
52
52
|
|
|
53
53
|
You do NOT hand-write routes, the session middleware, or the secret wiring — `pikkuBetterAuth` + the CLI generate all of it. Re-run `pikku auth` (or `pikku all`) to regenerate.
|
|
54
54
|
|
|
55
|
+
### The console requires Better Auth
|
|
56
|
+
|
|
57
|
+
The Pikku console (`@pikku/addon-console`, enabled via `scaffold.console` in `pikku.config.json`) is an admin surface: **every console RPC now requires an authenticated session** (the functions are `pikkuFunc`; unauthenticated calls return `403`). So `scaffold.console` alone is **no longer the minimum** — you also need an auth strategy, and Better Auth is the supported one. `pikku all` **throws** if `scaffold.console` is set but no `pikkuBetterAuth(...)` is found in the project. Baseline is "must be logged in"; finer policy (admin-only, org scoping) is layered host-side via tag/HTTP middleware. See `pikku-deps` for the console's Security screen.
|
|
58
|
+
|
|
55
59
|
---
|
|
56
60
|
|
|
57
61
|
## Standard Setup
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pikku-deps
|
|
3
|
+
description: 'Use for the Pikku dependency security audit: the `pikku audit` CLI command, the `.pikku/audit.json` artifact, the `SecurityAuditReport` type in @pikku/core, and the console Security screen (getSecurityAudit / runSecurityAudit / updateDependency + SecurityAuditView).
|
|
4
|
+
TRIGGER when: user asks about `pikku audit`, dependency vulnerabilities/advisories, outdated dependencies, the Security screen/page in the console, updating a vulnerable dependency, or reading/rendering audit.json.
|
|
5
|
+
DO NOT TRIGGER when: user asks about authentication/sessions/JWT (use pikku-security), permissions (use pikku-permissions), or secrets/env vars (use pikku-config).'
|
|
6
|
+
installGroups: [core]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Pikku Dependency Audit
|
|
10
|
+
|
|
11
|
+
## Agent Operating Procedure
|
|
12
|
+
|
|
13
|
+
1. The audit is a generated artifact, not live state. `pikku audit` writes the
|
|
14
|
+
normalised report to `.pikku/audit.json` (config `outDir`), so it rides the
|
|
15
|
+
same meta pipeline as every other codegen output — uploaded on deploy,
|
|
16
|
+
readable by the console addon and any tooling. Read it via
|
|
17
|
+
`metaService.readFile('audit.json')`, never by shelling out to the package
|
|
18
|
+
manager from a function.
|
|
19
|
+
2. One source of truth for the shape: `SecurityAuditReport` (and
|
|
20
|
+
`SecurityAuditIssue` / `SecurityAuditUpdate` / `SecurityAuditSummary` +
|
|
21
|
+
`SecuritySeverity` / `SecurityUpdateLevel`) are exported from **@pikku/core**.
|
|
22
|
+
The CLI writes it, the addon reads it, the UI renders it — never redeclare
|
|
23
|
+
the type at a call site.
|
|
24
|
+
3. Validate with `pikku tsc` after changes; the command never fails a build
|
|
25
|
+
(advisories are informational; a missing/failed audit yields an
|
|
26
|
+
empty-but-valid report).
|
|
27
|
+
|
|
28
|
+
## The `pikku audit` command
|
|
29
|
+
|
|
30
|
+
- `pikku audit` — reports **security advisories** only.
|
|
31
|
+
- `pikku audit --outdated` — also reports **available dependency updates**.
|
|
32
|
+
- Package-manager detection is by **lockfile** (walks up: `bun.lock`/`bun.lockb`,
|
|
33
|
+
then `yarn.lock`). Only **bun** runs a real audit (`bun audit --json` +
|
|
34
|
+
`bun outdated`, normalised into one `SecurityAuditReport` with per-severity /
|
|
35
|
+
per-update-level counts). Other PMs are detected but **stubbed** with a `note`
|
|
36
|
+
field until their shapes are normalised — issues/updates come back empty.
|
|
37
|
+
- `bun audit` exits non-zero when it *finds* advisories but still writes a valid
|
|
38
|
+
report — treat any non-zero exit as data, not failure.
|
|
39
|
+
|
|
40
|
+
## Console integration (@pikku/addon-console)
|
|
41
|
+
|
|
42
|
+
Three RPCs, all reading/writing the same artifact via the meta service. Shared
|
|
43
|
+
spawn/read helpers live in `lib/audit-exec.ts` (`readAuditReport`,
|
|
44
|
+
`runPikkuAudit`, `spawnProcess`, `findBin`) — reuse them, don't re-implement.
|
|
45
|
+
Like every console RPC these require an **authenticated session** (the console
|
|
46
|
+
is admin-only), so the host must have Better Auth wired — see `pikku-better-auth`.
|
|
47
|
+
|
|
48
|
+
- `getSecurityAudit` — reads `.pikku/audit.json`, returns the report (or `null`).
|
|
49
|
+
- `runSecurityAudit` — runs `pikku audit --outdated` server-side (regenerates the
|
|
50
|
+
artifact) then returns the fresh report. Same shape as the Run Tests action.
|
|
51
|
+
- `updateDependency({ package, version })` — bumps the package in `package.json`
|
|
52
|
+
(preserving the `^`/`~` range prefix), runs `bun install`, re-audits, and
|
|
53
|
+
returns the fresh report. Throws if the package is not a direct dependency.
|
|
54
|
+
NOTE: `bun install` must be scoped to a standalone project — do not run it
|
|
55
|
+
inside a yarn/bun monorepo member (it resolves the whole workspace).
|
|
56
|
+
|
|
57
|
+
## Console UI (@pikku/console)
|
|
58
|
+
|
|
59
|
+
- `SecurityPage` — the page: **Run audit** button (`lead`) + responsive
|
|
60
|
+
`ShellHeader` (structured `search` + `selection` for the Issues/Dependencies
|
|
61
|
+
lens; never cram raw controls into the non-collapsing `filters`/`view` escape
|
|
62
|
+
hatch). Empty state until an audit has run.
|
|
63
|
+
- `SecurityAuditView` — exported presentational component. Two lenses
|
|
64
|
+
(Issues grouped by severity; Dependencies table). Each finding row carries its
|
|
65
|
+
actions **right-aligned in the row header** (`Accordion.Control` sibling, so a
|
|
66
|
+
click acts instead of toggling): "View advisory" + a per-finding
|
|
67
|
+
**remediation slot**.
|
|
68
|
+
- `renderRemediation({ pkg, version, issue })` — the extension seam. OSS default
|
|
69
|
+
is `UpdateDependencyButton` (the free bump + `bun install`). Downstream
|
|
70
|
+
consoles (Fabric) pass their own sandbox-verified action here — replace the
|
|
71
|
+
action, keep the view.
|
|
72
|
+
- Hooks: `useSecurityAudit` (read), `useRunSecurityAudit` (run),
|
|
73
|
+
`useUpdateDependency` (bump). All are `useMutation`/`useQuery` — surface
|
|
74
|
+
`mutation.error`, never hand-roll loading/error state or swallow the error.
|
|
75
|
+
|
|
76
|
+
## Report shape (SecurityAuditReport)
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
{
|
|
80
|
+
tool: string // e.g. 'bun'
|
|
81
|
+
note?: string // set when the audit could NOT run (unsupported PM);
|
|
82
|
+
// render ONLY the note — never a reassuring "no vulnerabilities"
|
|
83
|
+
summary: { critical, high, moderate, low, info: number }
|
|
84
|
+
issues: SecurityAuditIssue[] // package, severity, title, advisoryId, cwe[], cvssScore?,
|
|
85
|
+
// url?, vulnerableVersions, recommendedVersion?
|
|
86
|
+
updates: SecurityAuditUpdate[] // package, current, latest, level (major|minor|patch|unknown)
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
When `note` is present the audit did not run — show only the note (an "Audit not
|
|
91
|
+
run" state), never the "no known vulnerabilities / up to date" copy.
|
|
@@ -1,217 +1,90 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pikku-i18n
|
|
3
|
-
description: 'Wire i18n into a Pikku frontend
|
|
3
|
+
description: 'Wire i18n into a Pikku frontend with Paraglide JS (inlang). English by default, every user-facing string is a typed message function (`m.some__key()`) compiled from `messages/<locale>.json`, and additional languages are served under `/fr` `/de` URL prefixes. TRIGGER when: scaffolding or editing a frontend and writing user-facing text, adding a second language, or asked to "make this translatable / use tokens / add i18n". DO NOT TRIGGER for backend functions, error messages thrown from functions, or log output.'
|
|
4
4
|
installGroups: [core]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Pikku i18n
|
|
7
|
+
# Pikku i18n (Paraglide JS)
|
|
8
8
|
|
|
9
9
|
## Agent Operating Procedure
|
|
10
10
|
|
|
11
11
|
Use this skill as an execution checklist, not reference material.
|
|
12
12
|
|
|
13
|
-
1. Every user-facing string in a frontend is a
|
|
14
|
-
2. One `
|
|
15
|
-
3.
|
|
16
|
-
4. Validate with the app's own `tsc` then its `build`.
|
|
13
|
+
1. Every user-facing string in a frontend is a message. Never hardcode display text — add a key to `messages/en.json` and render `m.the__key()`. This holds even when the app ships only English; the messages are the seam a second language slots into later.
|
|
14
|
+
2. One `messages/<locale>.json` per language at the app root (NOT under `src/`), declared in `project.inlang/settings.json`. English (`en`) is `baseLocale` and the only locale until someone adds another.
|
|
15
|
+
3. Messages compile to typed ESM functions in `src/paraglide/` (generated, self-gitignored — never edit or commit it). The Vite plugin compiles during `dev`/`build` with HMR on message edits; run the CLI compile only when you need `tsc` before Vite has ever run.
|
|
16
|
+
4. Validate with the app's own `tsc` then its `build`. The deploy pipeline compiles Paraglide and runs each frontend's `tsc` before building it — an i18n mistake blocks the deploy.
|
|
17
17
|
|
|
18
|
-
## The
|
|
18
|
+
## The moving parts (starter-template layout)
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Tokens are **typed**, not stringly-typed. Each config augments i18next's
|
|
28
|
-
`CustomTypeOptions` with `resources: { translation: typeof en }` (the block is in
|
|
29
|
-
every config shape below). i18next flattens `typeof en` into a union of dot-path
|
|
30
|
-
keys, so:
|
|
31
|
-
|
|
32
|
-
- `t('auth.login.titel')` (typo) or `t('auth.removed')` (deleted key) is a **TypeScript error**, not a silent runtime `auth.removed` string.
|
|
33
|
-
- An added locale registered as `de satisfies typeof en` fails to compile if `de.json` is missing keys or has drifted from `en.json`.
|
|
34
|
-
|
|
35
|
-
This is enforced at deploy: the build pipeline runs each frontend's `tsc`
|
|
36
|
-
(`yarn tsc` / `tsc --noEmit`) **before** building it, and a type error aborts the
|
|
37
|
-
deploy. `vite build` does not type-check on its own, so this gate is the only
|
|
38
|
-
thing standing between a broken/missing token and production. Keep a `"tsc":
|
|
39
|
-
"tsc --noEmit"` script in every frontend's `package.json` so the gate uses it.
|
|
40
|
-
|
|
41
|
-
The type gate catches _invalid_ tokens but not _inlined_ strings — a hardcoded
|
|
42
|
-
`<h1>Welcome</h1>` compiles fine. Catching those is best-effort (the builder
|
|
43
|
-
agent is told never to inline) plus the debug mode below.
|
|
44
|
-
|
|
45
|
-
## i18n debug mode (find inlined strings)
|
|
46
|
-
|
|
47
|
-
Each config registers an i18next `postProcessor` named `i18nDebug` that, when
|
|
48
|
-
enabled, masks every _translated_ string to block glyphs (`█`). The trick: with
|
|
49
|
-
it on, anything still readable on screen is text that **never went through a
|
|
50
|
-
token** — i.e. a hardcoded/inlined string. It's a visual leak detector for
|
|
51
|
-
missing i18n, not a runtime feature, so it ships **off by default**.
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
export function isI18nDebug(): boolean {
|
|
55
|
-
if (typeof process !== 'undefined' && process.env?.I18N_DEBUG === '1')
|
|
56
|
-
return true
|
|
57
|
-
if (typeof window === 'undefined') return false
|
|
58
|
-
const params = new URLSearchParams(window.location.search)
|
|
59
|
-
if (params.has('i18n-debug')) return params.get('i18n-debug') !== '0'
|
|
60
|
-
return window.localStorage?.getItem('i18n-debug') === '1'
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const i18nDebugPostProcessor = {
|
|
64
|
-
type: 'postProcessor' as const,
|
|
65
|
-
name: 'i18nDebug',
|
|
66
|
-
process: (value: string) =>
|
|
67
|
-
isI18nDebug() ? value.replace(/\S/g, '█') : value,
|
|
68
|
-
}
|
|
69
|
-
// register on the instance: `.use(i18nDebugPostProcessor)` and add
|
|
70
|
-
// `postProcess: ['i18nDebug']` to `.init({ ... })`.
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
- **Client (Vite SPA/SSR):** toggle with `?i18n-debug` in the URL or `localStorage['i18n-debug'] = '1'`.
|
|
74
|
-
- **Server (Next.js server components):** there is no per-request URL toggle — enable for a build with `I18N_DEBUG=1` (the helper only checks the env var server-side).
|
|
75
|
-
|
|
76
|
-
All the bundled templates already wire this; mirror it when hand-wiring i18n in a new app. (A future e2e check can flip the flag and assert no unmasked text renders.)
|
|
77
|
-
|
|
78
|
-
## Config shape (client / SPA)
|
|
79
|
-
|
|
80
|
-
`src/i18n/config.ts`:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import i18n from 'i18next'
|
|
84
|
-
import { initReactI18next } from 'react-i18next'
|
|
85
|
-
import en from './en.json'
|
|
86
|
-
|
|
87
|
-
// Typed tokens. i18next flattens this resource type into dot-path keys, so
|
|
88
|
-
// `t('auth.login.title')` is checked and a typo/removed key is a compile error.
|
|
89
|
-
declare module 'i18next' {
|
|
90
|
-
interface CustomTypeOptions {
|
|
91
|
-
defaultNS: 'translation'
|
|
92
|
-
resources: {
|
|
93
|
-
translation: typeof en
|
|
94
|
-
}
|
|
20
|
+
- `messages/en.json` — flat keys, `{param}` interpolation, inlang message-format:
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"$schema": "https://inlang.com/schema/inlang-message-format",
|
|
24
|
+
"auth__login__title": "Sign in",
|
|
25
|
+
"auth__login__description": "Welcome back to {name}."
|
|
95
26
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (supportedLocales.includes(segment as Locale)) return segment as Locale
|
|
105
|
-
if (typeof navigator !== 'undefined') {
|
|
106
|
-
const lang = navigator.language?.split('-')[0]
|
|
107
|
-
if (supportedLocales.includes(lang as Locale)) return lang as Locale
|
|
108
|
-
}
|
|
109
|
-
return defaultLocale
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
i18n.use(initReactI18next).init({
|
|
113
|
-
resources: { en: { translation: en } },
|
|
114
|
-
lng:
|
|
115
|
-
typeof window !== 'undefined'
|
|
116
|
-
? detectLocale(window.location.pathname)
|
|
117
|
-
: defaultLocale,
|
|
118
|
-
fallbackLng: defaultLocale,
|
|
119
|
-
interpolation: { escapeValue: false },
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
export default i18n
|
|
123
|
-
```
|
|
27
|
+
```
|
|
28
|
+
Key convention: lower snake_case, `__` (double underscore) between namespace segments, `_` within a segment — `auth__login__title`, `common__email_placeholder`.
|
|
29
|
+
- `project.inlang/settings.json` — `baseLocale`, `locales`, the `@inlang/plugin-message-format` module, `pathPattern: "./messages/{locale}.json"`.
|
|
30
|
+
- `vite.config.ts` — `paraglideVitePlugin({ project: './project.inlang', outdir: './src/paraglide' })` from `@inlang/paraglide-js` (devDependency), FIRST in the plugins array.
|
|
31
|
+
- `src/paraglide/` — compiled output (`messages.js`, `runtime.js`, per-locale `messages/*.js`). Generated; it writes its own `.gitignore`.
|
|
32
|
+
- `src/i18n/messages.ts` — re-exports the generated `m` wrapped so every message returns a branded `I18nString` (satisfies the `@pikku/mantine` `I18nNode` prop gate) and passes through `maskI18n` for debug mode. **Components import `m` from `@/i18n/messages`, never from `../paraglide/messages.js` directly** — a raw Paraglide call returns a plain `string` and fails the Mantine typing gate.
|
|
33
|
+
- `src/i18n/config.ts` — locale plumbing: `supportedLocales`/`defaultLocale` (re-exported from `../paraglide/runtime.js`), `detectLocale`, `localeDir` (RTL for ar/he/fa/ur), a reactive locale store (`overwriteGetLocale` bridged to `useSyncExternalStore`), `setActiveLocale`, `useLocale()`, and the i18n-debug helpers.
|
|
34
|
+
- `tsconfig.json` — `"allowJs": true, "checkJs": false` so `tsc` can consume Paraglide's JSDoc-typed JS output.
|
|
124
35
|
|
|
125
|
-
|
|
36
|
+
## Using messages in components
|
|
126
37
|
|
|
127
38
|
```tsx
|
|
128
|
-
import {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
39
|
+
import { m } from '@/i18n/messages'
|
|
40
|
+
import { useLocale } from '@/i18n/config'
|
|
41
|
+
|
|
42
|
+
function LoginPage() {
|
|
43
|
+
useLocale() // subscribe: re-render m.*() when the locale switches
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<Title>{m.auth__login__title()}</Title>
|
|
47
|
+
<Text>{m.auth__login__description({ name: m.app__name() })}</Text>
|
|
48
|
+
</>
|
|
49
|
+
)
|
|
132
50
|
}
|
|
133
51
|
```
|
|
134
52
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
export const prettyStatus = (s: string) => i18n.t(`status.${s}`)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Per-framework delivery
|
|
143
|
-
|
|
144
|
-
### Vite SPA
|
|
145
|
-
|
|
146
|
-
The config above is the whole story. `import './i18n/config'` in `main.tsx`; `useTranslation` everywhere.
|
|
147
|
-
|
|
148
|
-
### Vite SSR (`@cloudflare/vite-plugin` / Worker)
|
|
53
|
+
- Params: `{name}` in the JSON → `m.auth__login__description({ name })`. Params are typed per message.
|
|
54
|
+
- Any component that renders `m.*()` calls `useLocale()` (bare call is enough); it also returns `{ locale, dir, setLocale }` for switchers.
|
|
55
|
+
- Non-component helpers (formatters, status maps) call `m.some__key()` directly — the functions are plain ESM, no hook needed; the render-time subscription lives in the component that displays the result.
|
|
56
|
+
- Locale switching: the root route persists to localStorage, sets `<html lang dir>` (`localeDir`), and calls `setActiveLocale` — in-SPA re-render, no page reload. Mirror `routes/__root.tsx` in the starter template.
|
|
149
57
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
### Next.js app-router — server components
|
|
153
|
-
|
|
154
|
-
Server components **cannot** call `useTranslation`, and they **must not** import `initReactI18next`: it calls React's `createContext`, which throws during RSC page-data collection (`(0 , Y.createContext) is not a function` at build). Use a plain i18next instance and a fixed translator instead.
|
|
155
|
-
|
|
156
|
-
`app/i18n/config.ts`:
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
import { createInstance } from 'i18next'
|
|
160
|
-
import en from './en.json'
|
|
161
|
-
|
|
162
|
-
// Typed tokens — same augmentation as the SPA config; `getT()('key')` is
|
|
163
|
-
// checked against en.json's flattened dot-path keys.
|
|
164
|
-
declare module 'i18next' {
|
|
165
|
-
interface CustomTypeOptions {
|
|
166
|
-
defaultNS: 'translation'
|
|
167
|
-
resources: {
|
|
168
|
-
translation: typeof en
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export const supportedLocales = ['en'] as const
|
|
174
|
-
export type Locale = (typeof supportedLocales)[number]
|
|
175
|
-
export const defaultLocale: Locale = 'en'
|
|
176
|
-
|
|
177
|
-
const i18n = createInstance()
|
|
178
|
-
i18n.init({
|
|
179
|
-
resources: { en: { translation: en } },
|
|
180
|
-
lng: defaultLocale,
|
|
181
|
-
fallbackLng: defaultLocale,
|
|
182
|
-
interpolation: { escapeValue: false },
|
|
183
|
-
})
|
|
58
|
+
## Type safety — and why deploys block on i18n
|
|
184
59
|
|
|
185
|
-
|
|
186
|
-
return i18n.getFixedT(locale)
|
|
187
|
-
}
|
|
60
|
+
A message IS a function: a typo'd or deleted key (`m.auth__login__titel()`) is a missing export — a **TypeScript error**, not a silent runtime fallback string. Params are typed too. The deploy pipeline compiles Paraglide then runs each frontend's `tsc` (`"tsc": "tsc --noEmit"` script — keep it in every frontend's `package.json`) **before** building; a type error aborts the deploy. `vite build` does not type-check on its own, so this gate is the only thing standing between a broken message and production.
|
|
188
61
|
|
|
189
|
-
|
|
190
|
-
```
|
|
62
|
+
The gate catches _invalid_ messages but not _inlined_ strings — the `@pikku/mantine` `I18nNode` prop typing catches those on Mantine props (a raw string literal fails to compile), and i18n-debug covers the rest.
|
|
191
63
|
|
|
192
|
-
|
|
193
|
-
import { getT } from './i18n/config'
|
|
194
|
-
export default function Page() {
|
|
195
|
-
const t = getT()
|
|
196
|
-
return <h1>{t('page.title')}</h1>
|
|
197
|
-
}
|
|
198
|
-
```
|
|
64
|
+
## Compile step
|
|
199
65
|
|
|
200
|
-
|
|
66
|
+
- **Dev/build:** the Vite plugin compiles automatically; editing `messages/*.json` under a running dev server recompiles + HMRs.
|
|
67
|
+
- **Standalone `tsc` before Vite has run** (fresh clone, CI):
|
|
68
|
+
```sh
|
|
69
|
+
npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/paraglide
|
|
70
|
+
```
|
|
71
|
+
This is exactly what the deploy CI does before the per-app `tsc`.
|
|
201
72
|
|
|
202
|
-
|
|
73
|
+
## Adding a second language
|
|
203
74
|
|
|
204
|
-
|
|
75
|
+
1. `messages/fr.json` mirroring `en.json`'s keys (translate the values, keep `{param}` names identical).
|
|
76
|
+
2. Add `"fr"` to `locales` in `project.inlang/settings.json`.
|
|
77
|
+
3. Recompile (restart/`vite dev` or the CLI compile). A locale file missing keys falls back to the base locale per message.
|
|
78
|
+
4. Content is reachable via the `/<lang>` URL prefix (`detectLocale` already resolves it); the base locale needs no prefix. Expose the switcher via `useLocale().setLocale`.
|
|
205
79
|
|
|
206
|
-
##
|
|
80
|
+
## i18n debug mode (find inlined strings)
|
|
207
81
|
|
|
208
|
-
|
|
209
|
-
2. In the config: `import de from './de.json'`, add `'de'` to `supportedLocales`, and register it as `de: { translation: de satisfies typeof en }`. The `satisfies typeof en` makes an incomplete or drifted `de.json` a **compile error** — which is what blocks a deploy on missing i18n (see below).
|
|
210
|
-
3. `detectLocale` already resolves `/de/...`; wire the locale segment into routing so `/de` renders the German tree (the default locale stays prefix-free).
|
|
82
|
+
`src/i18n/messages.ts` wraps every message in `maskI18n`: when enabled, every _translated_ string renders as block glyphs (`█`), so anything still readable on screen never went through a message — a hardcoded string. Off by default. Toggle: `?i18n-debug` in the URL, `localStorage['i18n-debug'] = '1'`, or `I18N_DEBUG=1` for SSR. The starter template wires this; mirror it when hand-wiring a new app.
|
|
211
83
|
|
|
212
84
|
## What NOT to do
|
|
213
85
|
|
|
214
|
-
- Don't hardcode display strings "just for now" —
|
|
215
|
-
- Don't
|
|
216
|
-
- Don't
|
|
86
|
+
- Don't hardcode display strings "just for now" — the message is the work.
|
|
87
|
+
- Don't edit or commit anything under `src/paraglide/` — it's regenerated; change `messages/*.json` instead.
|
|
88
|
+
- Don't import `m` from `../paraglide/messages.js` in components — go through `@/i18n/messages` (branding + debug mask).
|
|
89
|
+
- Don't reach for i18next/react-i18next or a runtime-fetch translation loader — Paraglide's compiled functions are the whole delivery mechanism.
|
|
217
90
|
- Don't tokenize backend error messages or logs here — those are not frontend display strings.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pikku-kysely
|
|
3
|
-
description: 'Use when setting up SQL database services with Kysely
|
|
4
|
-
TRIGGER when: code uses
|
|
3
|
+
description: 'Use when WRITING KYSELY QUERIES (select/join/aggregate/insert/update/delete) inside a Pikku function body, or when setting up SQL database services with Kysely. Covers the query builder API (joins, aggregates + groupBy/having, returning, sql template, expression builder, $if, transactions, jsonArrayFrom relation helpers) AND @pikku/kysely service setup (channel stores, workflow services, secret services, AI storage, deployment services).
|
|
4
|
+
TRIGGER when: writing any non-trivial kysely query (a join, an aggregate/count/sum, groupBy, subquery, transaction, or conditional query), the injected `kysely` service is used in a function body, or code uses PikkuKysely, KyselyChannelStore, KyselyWorkflowService, KyselySecretService, or the user asks about SQL setup with Pikku.
|
|
5
5
|
DO NOT TRIGGER when: user asks about MongoDB (use pikku-mongodb) or Redis (use pikku-redis).'
|
|
6
6
|
installGroups: [core]
|
|
7
7
|
---
|
|
@@ -18,6 +18,72 @@ Use this skill as an execution checklist, not reference material.
|
|
|
18
18
|
4. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
19
19
|
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
20
20
|
|
|
21
|
+
## Writing Queries — the Kysely query builder
|
|
22
|
+
|
|
23
|
+
In a Pikku function body the injected `kysely` IS the `Kysely<DB>` instance — query it directly. Pikku wires the **CamelCasePlugin**, so you write **camelCase everywhere in TS** (columns, aliases) and raw **snake_case ONLY inside a `` sql`` `` literal**. Kysely is a query builder, NOT an ORM — there are no relations; shape nested data with the JSON helpers below. Never hand-roll SQL strings; never annotate the return type (in Pikku the output zod schema IS the type).
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { sql } from 'kysely'
|
|
27
|
+
// Relation helpers are ENGINE-SPECIFIC — import the matching path:
|
|
28
|
+
import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/sqlite' // SQLite / libSQL
|
|
29
|
+
// import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres' // Postgres
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// SELECT + where/orderBy/limit/offset. Terminals: .execute() | .executeTakeFirst()
|
|
34
|
+
// | .executeTakeFirstOrThrow(() => new NotFoundError()) — pass an error factory.
|
|
35
|
+
const rows = await kysely.selectFrom('item')
|
|
36
|
+
.select(['id', 'name', 'quantity'])
|
|
37
|
+
.where('warehouseId', '=', warehouseId)
|
|
38
|
+
.orderBy('name').limit(50).execute()
|
|
39
|
+
|
|
40
|
+
// JOINS + aliased selects (qualify columns once a join exists)
|
|
41
|
+
await kysely.selectFrom('stock')
|
|
42
|
+
.innerJoin('item', 'item.id', 'stock.itemId')
|
|
43
|
+
.leftJoin('bin as b', 'b.id', 'stock.binId')
|
|
44
|
+
.select(['stock.id', 'item.name as itemName', 'b.code as binCode'])
|
|
45
|
+
.execute()
|
|
46
|
+
|
|
47
|
+
// AGGREGATES via the fn helper + groupBy/having. eb.fn.count returns string|number —
|
|
48
|
+
// cast if you need a JS number (SQLite: CAST(... AS INTEGER)).
|
|
49
|
+
await kysely.selectFrom('stock')
|
|
50
|
+
.select((eb) => ['itemId', eb.fn.sum<number>('quantity').as('onHand')])
|
|
51
|
+
.groupBy('itemId')
|
|
52
|
+
.having((eb) => eb.fn.sum('quantity'), '<', 10) // low-stock
|
|
53
|
+
.execute()
|
|
54
|
+
|
|
55
|
+
// INSERT + RETURNING (one round-trip; works on SQLite & Postgres)
|
|
56
|
+
const created = await kysely.insertInto('item')
|
|
57
|
+
.values({ name: input.name, warehouseId })
|
|
58
|
+
.returning(['id', 'name']).executeTakeFirstOrThrow()
|
|
59
|
+
|
|
60
|
+
// UPDATE + RETURNING, DELETE
|
|
61
|
+
await kysely.updateTable('item').set({ quantity: input.quantity })
|
|
62
|
+
.where('id', '=', input.id).returning(['id', 'quantity']).executeTakeFirstOrThrow()
|
|
63
|
+
await kysely.deleteFrom('item').where('id', '=', input.id).execute()
|
|
64
|
+
|
|
65
|
+
// EXPRESSION BUILDER for and/or; $if for conditional building; sql for raw fragments
|
|
66
|
+
await kysely.selectFrom('item')
|
|
67
|
+
.selectAll()
|
|
68
|
+
.where((eb) => eb.or([eb('quantity', '=', 0), eb('discontinued', '=', true)]))
|
|
69
|
+
.$if(!!input.search, (qb) => qb.where('name', 'like', `%${input.search}%`))
|
|
70
|
+
.select(sql<number>`quantity * unit_cost`.as('value')) // snake_case ok inside sql``
|
|
71
|
+
.execute()
|
|
72
|
+
|
|
73
|
+
// NESTED DATA (no relations) — jsonObjectFrom (one) / jsonArrayFrom (many)
|
|
74
|
+
await kysely.selectFrom('warehouse')
|
|
75
|
+
.select((eb) => ['warehouse.id', 'warehouse.name',
|
|
76
|
+
jsonArrayFrom(eb.selectFrom('bin').select(['bin.id', 'bin.code'])
|
|
77
|
+
.whereRef('bin.warehouseId', '=', 'warehouse.id')).as('bins')])
|
|
78
|
+
.execute()
|
|
79
|
+
|
|
80
|
+
// TRANSACTION — multi-write atomicity. Use trx (not kysely) inside.
|
|
81
|
+
await kysely.transaction().execute(async (trx) => {
|
|
82
|
+
await trx.updateTable('stock').set({ quantity: 0 }).where('itemId', '=', id).execute()
|
|
83
|
+
await trx.insertInto('stockMove').values({ itemId: id, delta: -qty }).execute()
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
21
87
|
Pikku provides SQL database services through four packages:
|
|
22
88
|
|
|
23
89
|
- `@pikku/kysely` — Base service implementations (database-agnostic)
|