@pikku/cli 0.12.124 → 0.12.126
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/CHANGELOG.md +245 -0
- package/console-app/assets/{abnfDiagram-N423BO3Z-BP7zxMq6.js → abnfDiagram-N423BO3Z-B2suyn6i.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-DmG0bXDT.js +1 -0
- package/console-app/assets/{architectureDiagram-T3A2C74G-mvqdkIfF.js → architectureDiagram-T3A2C74G-BQ5Dfvpo.js} +1 -1
- package/console-app/assets/{blockDiagram-VBNYF7ZC-daD8h3VT.js → blockDiagram-VBNYF7ZC-D4pVRDiF.js} +1 -1
- package/console-app/assets/{c4Diagram-5PPSVZJV-Bd0_wKJj.js → c4Diagram-5PPSVZJV-Da04jGpq.js} +1 -1
- package/console-app/assets/channel-BgCT5gon.js +1 -0
- package/console-app/assets/{chunk-2GRJ4B5K-BFRr_H2V.js → chunk-2GRJ4B5K-CwODIPP4.js} +1 -1
- package/console-app/assets/{chunk-4I5QYGJK-BXWo5Xyx.js → chunk-4I5QYGJK-Bep4akjR.js} +1 -1
- package/console-app/assets/{chunk-5RXB4S5H-BFnXfzzz.js → chunk-5RXB4S5H-CGyCRU9L.js} +1 -1
- package/console-app/assets/{chunk-6Q2QTUOP-Bswg4T3s.js → chunk-6Q2QTUOP-D0IK0SMT.js} +1 -1
- package/console-app/assets/{chunk-7Z6QIM7H-StNGH40U.js → chunk-7Z6QIM7H-D12vS1jX.js} +1 -1
- package/console-app/assets/{chunk-GF5L2VYU-QwXKtQxa.js → chunk-GF5L2VYU-kOLwTzIA.js} +1 -1
- package/console-app/assets/{chunk-I66GZJ75-DDQhhfA0.js → chunk-I66GZJ75-Cb2nDoa3.js} +1 -1
- package/console-app/assets/{chunk-JQJVKLGR-wFyF2bUv.js → chunk-JQJVKLGR-B3a_ctfQ.js} +1 -1
- package/console-app/assets/{chunk-KBJHAD2P-CQPQVDkD.js → chunk-KBJHAD2P-DeP2Lqwp.js} +1 -1
- package/console-app/assets/{chunk-NSK5VX7P-DZhjvnHm.js → chunk-NSK5VX7P-BO8vlGrO.js} +1 -1
- package/console-app/assets/{chunk-QR6OTTB3-D1-TbcCP.js → chunk-QR6OTTB3-sX5V0Lok.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-82OYF6U8.js → chunk-RYQCIY6F-DoCObEhk.js} +1 -1
- package/console-app/assets/{chunk-UBXNYLIW-D85x6Zh2.js → chunk-UBXNYLIW-BndMXU5r.js} +1 -1
- package/console-app/assets/{chunk-W5SLKNZC-B1Ps46_n.js → chunk-W5SLKNZC--VrZN8EC.js} +1 -1
- package/console-app/assets/{chunk-WRU74C26-Ct8XrToU.js → chunk-WRU74C26-DdS0mzXO.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-EP2C9tTO.js +1 -0
- package/console-app/assets/classDiagram-JCYQIIEL-D9wGqB4J.js +1 -0
- package/console-app/assets/classDiagram-v2-OCEON4UE-D9wGqB4J.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-DdevwV5Y.js → cose-bilkent-JH36ORCC-C5EnHkFn.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-Dj55csoo.js → cynefin-VYW2F7L2-9irdkTt4.js} +1 -1
- package/console-app/assets/{cynefinDiagram-MW4NZA55-XWSzdajo.js → cynefinDiagram-MW4NZA55-DY19660c.js} +1 -1
- package/console-app/assets/{dagre-VZM6K2ZE-BV2l3zSF.js → dagre-VZM6K2ZE-BYFZSaSb.js} +1 -1
- package/console-app/assets/{dagre-CLoXIMX5.js → dagre-nXgDYqvf.js} +1 -1
- package/console-app/assets/{diagram-7IWD3JNH-DC9NK-nv.js → diagram-7IWD3JNH-oDftiTp1.js} +1 -1
- package/console-app/assets/{diagram-B4RE2ZJO-Cirfb0aN.js → diagram-B4RE2ZJO-Cbj-pPbH.js} +1 -1
- package/console-app/assets/{diagram-LBJQPF4R-BuRRy5X5.js → diagram-LBJQPF4R-Ch53oSKw.js} +1 -1
- package/console-app/assets/{diagram-Q27KOJAE-CAOKQ2xs.js → diagram-Q27KOJAE-DA7K814v.js} +1 -1
- package/console-app/assets/{diagram-UB23O5K3-Bto5kBJo.js → diagram-UB23O5K3-B-_C-ctS.js} +1 -1
- package/console-app/assets/{ebnfDiagram-BXEA7PRR-C5OndYGC.js → ebnfDiagram-BXEA7PRR-DsOdsKXy.js} +1 -1
- package/console-app/assets/{erDiagram-JOGREHBK-DqU4xV4C.js → erDiagram-JOGREHBK-XB1mP5_A.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-NKFCZ8Fj.js +1 -0
- package/console-app/assets/flowDiagram-UKHOOZJN-BpdPkmum.js +1 -0
- package/console-app/assets/{ganttDiagram-PKOTCBZU-D5_DE9R0.js → ganttDiagram-PKOTCBZU-knk0XSHi.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-nuqfz7Fd.js → gitGraph-TEB2WS4Q-COJnK2tM.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-DS77QQ5N-BtJwp2Y3.js → gitGraphDiagram-DS77QQ5N-sF0v605q.js} +1 -1
- package/console-app/assets/{index-DXcH2K9z.css → index-C8MC-uMB.css} +1 -1
- package/console-app/assets/{index-DRfts2XF.js → index-DMnbsgzs.js} +3 -3
- package/console-app/assets/{info-DKCQHKI2-CIfPVqHr.js → info-DKCQHKI2-Cbatr0w6.js} +1 -1
- package/console-app/assets/{infoDiagram-6WML65LV-B-gTHQad.js → infoDiagram-6WML65LV-93TFPCu2.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-WSZJBQD7-CCwAWb1g.js → ishikawaDiagram-WSZJBQD7-BBR8_Qms.js} +1 -1
- package/console-app/assets/{journeyDiagram-NVQOT4AX-DhqNj_ci.js → journeyDiagram-NVQOT4AX-zG55yDoc.js} +1 -1
- package/console-app/assets/{kanban-definition-27J2QSJJ-DspZ1b3Y.js → kanban-definition-27J2QSJJ-DonGcEAY.js} +1 -1
- package/console-app/assets/{line-D7ZCpNkR.js → line-D1WdVm1S.js} +1 -1
- package/console-app/assets/{linear-B5jMy_q9.js → linear-D2GQL4Cm.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-CMBFGJ0U.js → mermaid-parser.core-b4yKyO56.js} +3 -3
- package/console-app/assets/{mermaid.core-DYoDrSEJ.js → mermaid.core-Cwfec1gr.js} +4 -4
- package/console-app/assets/{mindmap-definition-FAOFIHXS-DsHwd2K9.js → mindmap-definition-FAOFIHXS-D0G4yKgw.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-BSRRjf4H.js → packet-7NZHBO7P-DDa4HL2T.js} +1 -1
- package/console-app/assets/{pegDiagram-VL7TDLO6-Bi0OlzgS.js → pegDiagram-VL7TDLO6-fPdN5VZs.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-D-8tgqYW.js → pie-RZYD4A2V-DRHURUqo.js} +1 -1
- package/console-app/assets/{pieDiagram-7S7Q4E2Y-CsYbVqaR.js → pieDiagram-7S7Q4E2Y-DMYn8ga_.js} +1 -1
- package/console-app/assets/{quadrantDiagram-CIZ2JOQS-LkLWrWKK.js → quadrantDiagram-CIZ2JOQS-C190OamC.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-Bst62XZP.js → radar-I7S5WNFK-Djvqzz9A.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-zJswMQYF.js → railroad-3IZDKUUU-C9YvFeFq.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-B3CYVW4p.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DrZ2yF62.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-CWAmMyxd.js +1 -0
- package/console-app/assets/{railroadDiagram-AXF67PYL-C0QZkg7m.js → railroadDiagram-AXF67PYL-IRFg1VrU.js} +1 -1
- package/console-app/assets/{requirementDiagram-LRYGKXZP-BQg0AbLI.js → requirementDiagram-LRYGKXZP-L-7ubbcT.js} +1 -1
- package/console-app/assets/{sankeyDiagram-W5VNT64P-CQb0BMMi.js → sankeyDiagram-W5VNT64P-DBttV6Gt.js} +1 -1
- package/console-app/assets/{sequenceDiagram-SI44F4Z6-BzgBi0a5.js → sequenceDiagram-SI44F4Z6-Bg15oKAB.js} +1 -1
- package/console-app/assets/{src-Dg-KiSsV.js → src-DUC7tLWb.js} +1 -1
- package/console-app/assets/{stateDiagram-OKZ733FA-BiqXn68g.js → stateDiagram-OKZ733FA-PWl0XGs5.js} +1 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-Celbgz4u.js +1 -0
- package/console-app/assets/{swimlanes-SLNWSIFB-Dy7wDP1q.js → swimlanes-SLNWSIFB-CyXEtGBV.js} +1 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-zxpNaB4U.js +8 -0
- package/console-app/assets/{timeline-definition-Z64GVDOM-DSWXli8X.js → timeline-definition-Z64GVDOM-BLA-DhBt.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-CeWwcs9r.js → treeView-QDETBFTQ-Bfnmn2UY.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-BfrumiJh.js → treemap-6X3UGDF4-DTA0wveO.js} +1 -1
- package/console-app/assets/{vennDiagram-T6HMQDX7-BsuldZ1n.js → vennDiagram-T6HMQDX7-CLXYZln0.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-oZldxS8z.js → wardley-OPB4EBWU-zwxqisG0.js} +1 -1
- package/console-app/assets/{wardleyDiagram-T6FBY63Y-C5LXyHMj.js → wardleyDiagram-T6FBY63Y-hKtKvNlv.js} +1 -1
- package/console-app/assets/{xychartDiagram-ELKLHX3M-CwhqhNkO.js → xychartDiagram-ELKLHX3M-BGf8p4bo.js} +1 -1
- package/console-app/index.html +2 -2
- package/dist/.pikku/addon/index.d.ts +1 -1
- package/dist/.pikku/addon/index.js +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.js +1 -1
- package/dist/.pikku/agent/index.d.ts +1 -1
- package/dist/.pikku/agent/index.js +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
- package/dist/.pikku/auth/index.d.ts +1 -1
- package/dist/.pikku/auth/index.js +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.d.ts +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.js +1 -1
- package/dist/.pikku/channel/index.d.ts +1 -1
- package/dist/.pikku/channel/index.js +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/index.d.ts +1 -1
- package/dist/.pikku/cli/index.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +11 -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-contracts-meta.gen.json +7 -0
- 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 +27 -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/error/index.d.ts +1 -1
- package/dist/.pikku/error/index.js +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.d.ts +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.js +1 -1
- package/dist/.pikku/function/index.d.ts +1 -1
- package/dist/.pikku/function/index.js +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 +59 -23
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/gateway/index.d.ts +1 -1
- package/dist/.pikku/gateway/index.js +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.d.ts +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.js +1 -1
- package/dist/.pikku/http/index.d.ts +1 -1
- package/dist/.pikku/http/index.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/mcp/index.d.ts +1 -1
- package/dist/.pikku/mcp/index.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/middleware/index.d.ts +1 -1
- package/dist/.pikku/middleware/index.js +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.d.ts +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.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-services.gen.d.ts +1 -1
- package/dist/.pikku/queue/index.d.ts +1 -1
- package/dist/.pikku/queue/index.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/rpc/pikku-rpc-wirings-meta.internal.gen.json +2 -0
- package/dist/.pikku/scenarios/index.d.ts +1 -1
- package/dist/.pikku/scenarios/index.js +1 -1
- package/dist/.pikku/scenarios/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/scheduler/index.d.ts +1 -1
- package/dist/.pikku/scheduler/index.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 +7 -1
- package/dist/.pikku/schemas/schemas/DeployApplyInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricProjectsListInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricProjectsListOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricSecretsListInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsSetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricVariablesGetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricVariablesSetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PersonaSecretInput.schema.json +1 -0
- package/dist/.pikku/scopes/index.d.ts +1 -1
- package/dist/.pikku/scopes/index.js +1 -1
- package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- package/dist/.pikku/secrets/index.d.ts +1 -1
- package/dist/.pikku/secrets/index.js +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/services/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/services/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/setup/index.d.ts +1 -1
- package/dist/.pikku/setup/index.js +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.d.ts +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.js +1 -1
- package/dist/.pikku/trigger/index.d.ts +1 -1
- package/dist/.pikku/trigger/index.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/index.d.ts +1 -1
- package/dist/.pikku/variables/index.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/index.d.ts +1 -1
- package/dist/.pikku/workflow/index.js +1 -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 +13 -1
- package/dist/src/deploy/build-pipeline.d.ts +10 -0
- package/dist/src/deploy/build-pipeline.js +16 -1
- package/dist/src/deploy/bundler/bun-bundler.js +12 -5
- package/dist/src/deploy/frontend-assets.d.ts +50 -0
- package/dist/src/deploy/frontend-assets.js +82 -0
- package/dist/src/fabric/fabric-commands.d.ts +55 -15
- package/dist/src/fabric/fabric-commands.js +6 -0
- package/dist/src/fabric/functions/deploy.function.js +12 -2
- package/dist/src/fabric/functions/projects-list.function.d.ts +72 -0
- package/dist/src/fabric/functions/projects-list.function.js +63 -0
- package/dist/src/fabric/functions/secrets-list.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-list.function.js +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.js +8 -5
- package/dist/src/fabric/functions/secrets-set.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-set.function.js +4 -4
- package/dist/src/fabric/functions/validate.function.js +49 -24
- package/dist/src/fabric/functions/variables-get.function.d.ts +4 -4
- package/dist/src/fabric/functions/variables-get.function.js +4 -4
- package/dist/src/fabric/functions/variables-set.function.d.ts +4 -4
- package/dist/src/fabric/functions/variables-set.function.js +4 -4
- package/dist/src/fabric/lib/blank-comments.d.ts +21 -0
- package/dist/src/fabric/lib/blank-comments.js +71 -0
- package/dist/src/fabric/lib/blank-scenario-meta.d.ts +1 -0
- package/dist/src/fabric/lib/blank-scenario-meta.js +110 -0
- package/dist/src/fabric/lib/deployment.d.ts +26 -0
- package/dist/src/fabric/lib/deployment.js +35 -0
- package/dist/src/fabric/lib/stage.d.ts +19 -3
- package/dist/src/fabric/lib/stage.js +29 -6
- package/dist/src/functions/commands/db-reset.js +6 -2
- package/dist/src/functions/commands/deploy-apply.d.ts +10 -0
- package/dist/src/functions/commands/deploy-apply.js +8 -0
- package/dist/src/functions/commands/deploy-plan.js +1 -0
- package/dist/src/functions/commands/dev.js +18 -3
- package/dist/src/functions/commands/environment.d.ts +10 -0
- package/dist/src/functions/commands/environment.js +24 -0
- package/dist/src/functions/commands/persona.d.ts +18 -0
- package/dist/src/functions/commands/persona.js +41 -2
- package/dist/src/functions/commands/scenario-browser.d.ts +13 -5
- package/dist/src/functions/commands/serve-frontend.d.ts +11 -0
- package/dist/src/functions/commands/serve-frontend.js +17 -0
- package/dist/src/functions/commands/serve.js +16 -3
- package/dist/src/functions/db/annotation-parser.d.ts +8 -0
- package/dist/src/functions/db/annotation-parser.js +2 -0
- package/dist/src/functions/db/check-enums.d.ts +38 -0
- package/dist/src/functions/db/check-enums.js +103 -0
- package/dist/src/functions/db/db-codegen.js +35 -1
- package/dist/src/functions/db/postgres/postgres-introspector.d.ts +14 -0
- package/dist/src/functions/db/postgres/postgres-introspector.js +48 -0
- package/dist/src/functions/db/sqlite/sqlite-introspector.d.ts +3 -4
- package/dist/src/functions/db/sqlite/sqlite-introspector.js +5 -17
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.d.ts +9 -6
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +57 -30
- package/dist/src/server/actor-sign-in.d.ts +24 -1
- package/dist/src/server/actor-sign-in.js +45 -2
- package/dist/src/server/dev-server-runner.interface.d.ts +9 -0
- package/dist/src/server/node-server-runner.js +3 -0
- package/dist/src/server/server-ready.d.ts +6 -9
- package/dist/src/server/server-ready.js +6 -9
- package/dist/src/utils/frontend.d.ts +9 -0
- package/dist/src/utils/frontend.js +18 -0
- package/dist/src/utils/persona-credentials.d.ts +23 -2
- package/dist/src/utils/persona-credentials.js +55 -2
- package/dist/src/utils/pikku-cli-config.d.ts +14 -5
- package/dist/src/utils/pikku-cli-config.js +57 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/snippets.json +2 -2
- package/surface.json +101 -51
- package/console-app/assets/architecture-TIHT7OUA-D4Hj6824.js +0 -1
- package/console-app/assets/channel-09aKDzM0.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-C1KaR4pt.js +0 -1
- package/console-app/assets/classDiagram-JCYQIIEL-23nagJMi.js +0 -1
- package/console-app/assets/classDiagram-v2-OCEON4UE-23nagJMi.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-RyG54ZHy.js +0 -1
- package/console-app/assets/flowDiagram-UKHOOZJN-DNdfrnRg.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-DX4FqVY6.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DdyOtX1l.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-CclC1sXF.js +0 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-I34jrzP0.js +0 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-C1PrPB0G.js +0 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { readFile, readdir } from 'node:fs/promises';
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
4
|
+
import { dirname, join, relative } from 'node:path';
|
|
5
5
|
import { createRequire } from 'node:module';
|
|
6
6
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
7
7
|
import { added, changed, removed, dim } from '../lib/output.js';
|
|
@@ -10,6 +10,8 @@ import { readJsonSafe, readTextSafe, runSharedProjectChecks, } from '../../funct
|
|
|
10
10
|
import { runTypeIdentityChecks } from '../../functions/validate/type-identity-checks.js';
|
|
11
11
|
import { migrationCreatesTable } from '../../functions/validate/shared-checks.js';
|
|
12
12
|
import { isGitRepo, isTracked } from '../lib/git.js';
|
|
13
|
+
import { blankComments, lineOfOffset } from '../lib/blank-comments.js';
|
|
14
|
+
import { blankScenarioMeta } from '../lib/blank-scenario-meta.js';
|
|
13
15
|
const FindingSchema = z.object({
|
|
14
16
|
id: z.string(),
|
|
15
17
|
severity: z.enum(['error', 'warn', 'info']),
|
|
@@ -66,15 +68,6 @@ async function listSourceFiles(dir) {
|
|
|
66
68
|
return [];
|
|
67
69
|
}
|
|
68
70
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Blanks comment bodies so a raw-text scan cannot read prose as code. Prose in a
|
|
71
|
-
* scenario description ("Converted from the Gherkin scenario...") otherwise
|
|
72
|
-
* matches the import scanner's `from "..."` and reports a package that is really
|
|
73
|
-
* a sentence.
|
|
74
|
-
*/
|
|
75
|
-
const stripCommentText = (text) => text
|
|
76
|
-
.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '))
|
|
77
|
-
.replace(/(^|[^:'"`\\])\/\/[^\n]*/g, (_m, p1) => p1);
|
|
78
71
|
// Heavy/generated dirs pruned during a source walk.
|
|
79
72
|
const SKIP_WALK_DIRS = new Set([
|
|
80
73
|
'node_modules',
|
|
@@ -489,17 +482,20 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
|
|
|
489
482
|
// tsconfig `paths` keys (e.g. "@/*") are internal aliases, not packages.
|
|
490
483
|
const tsconfig = await readJsonSafe(join(dir, 'tsconfig.json'));
|
|
491
484
|
const aliasPrefixes = Object.keys(tsconfig?.compilerOptions?.paths ?? {}).map((k) => k.replace(/\*$/, ''));
|
|
485
|
+
// name → "<relative file>:<line>" of the first import that used it.
|
|
492
486
|
const used = new Map();
|
|
493
487
|
for (const file of await listSourceFiles(join(dir, 'src'))) {
|
|
494
488
|
if (/\.gen\.(ts|tsx)$/.test(file))
|
|
495
489
|
continue;
|
|
496
|
-
const
|
|
497
|
-
if (!
|
|
490
|
+
const raw = await readTextSafe(file);
|
|
491
|
+
if (!raw)
|
|
498
492
|
continue;
|
|
499
|
-
|
|
493
|
+
// Comments first, or prose becomes a dependency: `from "is fine"` in a
|
|
494
|
+
// sentence is indistinguishable from an import to this regex.
|
|
495
|
+
const txt = blankComments(raw);
|
|
500
496
|
const re = /(?:from|import|require)\s*\(?\s*['"]([^'".#][^'"]*)['"]/g;
|
|
501
497
|
let m;
|
|
502
|
-
while ((m = re.exec(
|
|
498
|
+
while ((m = re.exec(txt))) {
|
|
503
499
|
const spec = m[1];
|
|
504
500
|
if (/\s/.test(spec) ||
|
|
505
501
|
spec.startsWith('node:') ||
|
|
@@ -516,13 +512,15 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
|
|
|
516
512
|
const name = pkgNameOf(spec);
|
|
517
513
|
if (NODE_BUILTINS.has(name) || name === pkg.name || wsNames.has(name))
|
|
518
514
|
continue;
|
|
519
|
-
if (!used.has(name))
|
|
520
|
-
|
|
515
|
+
if (!used.has(name)) {
|
|
516
|
+
const where = `${relative(root, file).replace(/\\/g, '/')}:${lineOfOffset(raw, m.index)}`;
|
|
517
|
+
used.set(name, where);
|
|
518
|
+
}
|
|
521
519
|
}
|
|
522
520
|
}
|
|
523
521
|
const missing = [...used.keys()].filter((n) => !declared.has(n)).sort();
|
|
524
522
|
if (missing.length) {
|
|
525
|
-
e(`undeclared-deps-${(pkg.name ?? dir).replace(/[@/]/g, '-')}`, `${pkg.name ?? dir} imports undeclared package(s): ${missing.join(', ')} — the deploy bundle cannot resolve them`, join(dir, 'package.json'), lines(`Add the missing package(s) to ${pkg.name ?? 'this package'}'s dependencies, e.g.:`, ...missing.map((n) => ` "${n}": "<version>"`), 'then reinstall. They import-resolve locally via tsconfig paths / root', 'hoisting, but esbuild/Bun.build resolves each package independently.'));
|
|
523
|
+
e(`undeclared-deps-${(pkg.name ?? dir).replace(/[@/]/g, '-')}`, `${pkg.name ?? dir} imports undeclared package(s): ${missing.join(', ')} — the deploy bundle cannot resolve them`, join(dir, 'package.json'), lines(`Add the missing package(s) to ${pkg.name ?? 'this package'}'s dependencies, e.g.:`, ...missing.map((n) => ` "${n}": "<version>" (first used at ${used.get(n)})`), 'then reinstall. They import-resolve locally via tsconfig paths / root', 'hoisting, but esbuild/Bun.build resolves each package independently.'));
|
|
526
524
|
}
|
|
527
525
|
// @pikku/browser pins `puppeteer-core` to the exact version that
|
|
528
526
|
// @cloudflare/puppeteer forks, so headless rendering behaves identically
|
|
@@ -762,13 +760,37 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
|
|
|
762
760
|
// readdir failure — skip
|
|
763
761
|
}
|
|
764
762
|
}
|
|
763
|
+
// ── the coercion map has to reach a Kysely instance ──────────────────
|
|
764
|
+
// `pikku db migrate` generates a CoercionMap from the `kind` entries in
|
|
765
|
+
// db/annotations.ts, and nothing wires it up on the project's behalf. An
|
|
766
|
+
// unwired map is invisible locally and fatal deployed: the dev sqlite
|
|
767
|
+
// driver hydrates a TEXT date into a Date by itself, libsql on a stage
|
|
768
|
+
// returns the raw string, and the generated schema types the column
|
|
769
|
+
// `Date` either way — so tsc flags nothing and there is no failing local
|
|
770
|
+
// test to write. It surfaces as `TypeError: e.getFullYear is not a
|
|
771
|
+
// function` on the first deployed request. Booleans diverge more quietly
|
|
772
|
+
// still: `1` from a stage where local gives `true`.
|
|
773
|
+
const outDirRel = typeof pikkuConfig?.outDir === 'string' ? pikkuConfig.outDir : '.pikku';
|
|
774
|
+
const coercionPath = join(root, outDirRel, 'db', 'coercion.gen.ts');
|
|
775
|
+
const coercionText = await readTextSafe(coercionPath);
|
|
776
|
+
// `{}` means no column declared a `kind`, so there is nothing to wire.
|
|
777
|
+
if (coercionText && /:\s*"(date|boolean|json)"/.test(coercionText)) {
|
|
778
|
+
const wired = (await Promise.all((await walkSourceFiles(root)).map((f) => readTextSafe(f)))).some((text) => text?.includes('createCoercionPlugin'));
|
|
779
|
+
if (!wired) {
|
|
780
|
+
e('coercion-map-not-wired', `${join(outDirRel, 'db', 'coercion.gen.ts')} declares coercions that no Kysely instance applies`, coercionPath, lines('Attach the plugin where the kysely singleton is created, in', 'createSingletonServices:', '', " import { createCoercionPlugin } from '@pikku/kysely'", " import { coercionMap } from '#pikku/db/coercion.gen.js'", '', ' kysely: existingServices.kysely.withPlugin(', ' createCoercionPlugin({ map: coercionMap }),', ' )', '', 'Without it a deployed stage returns raw strings and integers where', 'the generated schema promises Date and boolean. The dev driver', 'hydrates them for you, so this cannot fail locally.'));
|
|
781
|
+
}
|
|
782
|
+
}
|
|
765
783
|
const devSeedPath = join(root, 'db', dbEngine === 'postgres' ? 'postgres-dev-seed.sql' : 'sqlite-dev-seed.sql');
|
|
784
|
+
// Info, not an error. The dev seed is replayed by `pikku db reset` and
|
|
785
|
+
// never by a deploy, so a project whose data has correctly moved into a
|
|
786
|
+
// migration — where anything a deployed stage needs has to live — no
|
|
787
|
+
// longer needs this file, and was being failed for not carrying it.
|
|
766
788
|
if (!existsSync(devSeedPath)) {
|
|
767
|
-
|
|
768
|
-
? 'db/postgres-dev-seed.sql
|
|
769
|
-
: 'db/sqlite-dev-seed.sql
|
|
770
|
-
|
|
771
|
-
|
|
789
|
+
const seedFile = dbEngine === 'postgres'
|
|
790
|
+
? 'db/postgres-dev-seed.sql'
|
|
791
|
+
: 'db/sqlite-dev-seed.sql';
|
|
792
|
+
const migrationsRel = dbEngine === 'postgres' ? 'db/postgres/' : 'db/sqlite/';
|
|
793
|
+
info('dev-seed-sql-missing', `${seedFile} not found — no dev seed will be applied by \`pikku db reset\``, devSeedPath, lines(`Optional. Add \`${seedFile}\` for rows you want locally and nowhere else;`, 'it is replayed by `pikku db reset` against a freshly wiped database and', 'is never applied to a deployed stage.', `Data a deployed stage needs is migration data — put it in ${migrationsRel}`, 'rather than here, whatever it looks like.'));
|
|
772
794
|
}
|
|
773
795
|
// audit table — info if not present (optional feature)
|
|
774
796
|
if (existsSync(migrationsDir)) {
|
|
@@ -1038,7 +1060,7 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
|
|
|
1038
1060
|
}
|
|
1039
1061
|
}
|
|
1040
1062
|
if (loginFiles.length > 0 && !hasQuickLogin) {
|
|
1041
|
-
e(`app-missing-actor-quick-login-${name}`, `apps/${name} has a login screen (${loginFiles[0]}) but no one-click actor sign-in — nobody can view the app as a scenario persona without a password`, join(appPath, loginFiles[0]), lines('Render the dev-only "Sign in as …" switcher from the login screen.', `In ${loginFiles[0]}:`, " import { DevActorSwitcher } from '@pikku/mantine/dev'", ' <DevActorSwitcher', ' actors={import.meta.env.DEV ? import.meta.env.VITE_DEV_ACTORS : undefined}', '
|
|
1063
|
+
e(`app-missing-actor-quick-login-${name}`, `apps/${name} has a login screen (${loginFiles[0]}) but no one-click actor sign-in — nobody can view the app as a scenario persona without a password`, join(appPath, loginFiles[0]), lines('Render the dev-only "Sign in as …" switcher from the login screen.', `In ${loginFiles[0]}:`, " import { DevActorSwitcher } from '@pikku/mantine/dev'", ' <DevActorSwitcher', ' actors={import.meta.env.DEV ? import.meta.env.VITE_DEV_ACTORS : undefined}', ' secrets={import.meta.env.DEV ? import.meta.env.VITE_DEV_ACTOR_SECRETS : undefined}', ' apiUrl={apiUrl()}', " onSignedIn={() => navigate({ to: '/' })}", ' />', 'The sandbox dev server bakes both env vars from your declared personas;', 'neither is set in production, so the control renders null there.', 'VITE_DEV_ACTOR_SECRETS is one credential per persona, each accepted for', 'that persona only. Gate the reads on import.meta.env.DEV as above so no', 'credential reaches a production bundle. Next.js reads the NEXT_PUBLIC_* pair.', 'For custom UI, build on useDevActors() from @pikku/react instead.'));
|
|
1042
1064
|
}
|
|
1043
1065
|
}
|
|
1044
1066
|
}
|
|
@@ -1241,7 +1263,10 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
|
|
|
1241
1263
|
const text = await readTextSafe(file);
|
|
1242
1264
|
if (!text)
|
|
1243
1265
|
continue;
|
|
1244
|
-
|
|
1266
|
+
// Comments carry the copy they explain; a feature's own name and
|
|
1267
|
+
// description are Console meta authored in the project's locale, not
|
|
1268
|
+
// app copy. Neither reaches the DOM, so neither is a selector.
|
|
1269
|
+
const code = blankScenarioMeta(blankComments(text));
|
|
1245
1270
|
const hits = [];
|
|
1246
1271
|
for (const match of code.matchAll(STRING_LITERAL)) {
|
|
1247
1272
|
const literal = match[2];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const FabricVariablesGetInput: z.ZodObject<{
|
|
3
3
|
name: z.ZodString;
|
|
4
|
-
branch: z.ZodString
|
|
4
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
5
5
|
json: z.ZodOptional<z.ZodBoolean>;
|
|
6
6
|
}, z.core.$strip>;
|
|
7
7
|
export declare const FabricVariablesGetOutput: z.ZodObject<{
|
|
@@ -11,7 +11,7 @@ export declare const FabricVariablesGetOutput: z.ZodObject<{
|
|
|
11
11
|
}, z.core.$strip>;
|
|
12
12
|
export declare const FabricVariablesGet: import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionConfig<{
|
|
13
13
|
name: string;
|
|
14
|
-
branch
|
|
14
|
+
branch?: string | undefined;
|
|
15
15
|
json?: boolean | undefined;
|
|
16
16
|
}, {
|
|
17
17
|
name: string;
|
|
@@ -19,7 +19,7 @@ export declare const FabricVariablesGet: import("../../../.pikku/function/pikku-
|
|
|
19
19
|
value: unknown;
|
|
20
20
|
}, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionSessionless<{
|
|
21
21
|
name: string;
|
|
22
|
-
branch
|
|
22
|
+
branch?: string | undefined;
|
|
23
23
|
json?: boolean | undefined;
|
|
24
24
|
}, {
|
|
25
25
|
name: string;
|
|
@@ -27,7 +27,7 @@ export declare const FabricVariablesGet: import("../../../.pikku/function/pikku-
|
|
|
27
27
|
value: unknown;
|
|
28
28
|
}, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").WiredServices, unknown> | import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunction<{
|
|
29
29
|
name: string;
|
|
30
|
-
branch
|
|
30
|
+
branch?: string | undefined;
|
|
31
31
|
json?: boolean | undefined;
|
|
32
32
|
}, {
|
|
33
33
|
name: string;
|
|
@@ -2,10 +2,10 @@ import { z } from 'zod';
|
|
|
2
2
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveStage } from '../lib/stage.js';
|
|
6
6
|
export const FabricVariablesGetInput = z.object({
|
|
7
7
|
name: z.string(),
|
|
8
|
-
branch: z.string(),
|
|
8
|
+
branch: z.string().optional(),
|
|
9
9
|
json: z.boolean().optional(),
|
|
10
10
|
});
|
|
11
11
|
export const FabricVariablesGetOutput = z.object({
|
|
@@ -17,14 +17,14 @@ export const FabricVariablesGet = pikkuSessionlessFunc({
|
|
|
17
17
|
description: 'Read a stage-scoped variable back, so you can see the shape it was stored in rather than the shape you meant.',
|
|
18
18
|
input: FabricVariablesGetInput,
|
|
19
19
|
output: FabricVariablesGetOutput,
|
|
20
|
-
func: async (_services, { name, branch, json }) => {
|
|
20
|
+
func: async (_services, { name, branch: requested, json }) => {
|
|
21
21
|
const ctx = await resolveApiContext();
|
|
22
22
|
if (!ctx.token)
|
|
23
23
|
throw new Error('Not logged in. Run `pikku fabric login` first.');
|
|
24
24
|
if (!ctx.projectId)
|
|
25
25
|
throw new Error('No fabric project linked. Run `pikku fabric link` first.');
|
|
26
26
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
27
|
-
const stageId = await
|
|
27
|
+
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
28
28
|
const { exists, value } = await rpc.invoke('getStageConsoleVariable', {
|
|
29
29
|
stageId,
|
|
30
30
|
variableId: name,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const FabricVariablesSetInput: z.ZodObject<{
|
|
3
3
|
name: z.ZodString;
|
|
4
|
-
branch: z.ZodString
|
|
4
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
5
5
|
value: z.ZodString;
|
|
6
6
|
}, z.core.$strip>;
|
|
7
7
|
export declare const FabricVariablesSetOutput: z.ZodObject<{
|
|
@@ -10,22 +10,22 @@ export declare const FabricVariablesSetOutput: z.ZodObject<{
|
|
|
10
10
|
}, z.core.$strip>;
|
|
11
11
|
export declare const FabricVariablesSet: import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionConfig<{
|
|
12
12
|
name: string;
|
|
13
|
-
branch: string;
|
|
14
13
|
value: string;
|
|
14
|
+
branch?: string | undefined;
|
|
15
15
|
}, {
|
|
16
16
|
name: string;
|
|
17
17
|
success: boolean;
|
|
18
18
|
}, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionSessionless<{
|
|
19
19
|
name: string;
|
|
20
|
-
branch: string;
|
|
21
20
|
value: string;
|
|
21
|
+
branch?: string | undefined;
|
|
22
22
|
}, {
|
|
23
23
|
name: string;
|
|
24
24
|
success: boolean;
|
|
25
25
|
}, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").WiredServices, unknown> | import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunction<{
|
|
26
26
|
name: string;
|
|
27
|
-
branch: string;
|
|
28
27
|
value: string;
|
|
28
|
+
branch?: string | undefined;
|
|
29
29
|
}, {
|
|
30
30
|
name: string;
|
|
31
31
|
success: boolean;
|
|
@@ -2,11 +2,11 @@ import { z } from 'zod';
|
|
|
2
2
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveStage } from '../lib/stage.js';
|
|
6
6
|
import { parseVariableValue } from '../lib/variable-value.js';
|
|
7
7
|
export const FabricVariablesSetInput = z.object({
|
|
8
8
|
name: z.string(),
|
|
9
|
-
branch: z.string(),
|
|
9
|
+
branch: z.string().optional(),
|
|
10
10
|
value: z.string(),
|
|
11
11
|
});
|
|
12
12
|
export const FabricVariablesSetOutput = z.object({
|
|
@@ -17,14 +17,14 @@ export const FabricVariablesSet = pikkuSessionlessFunc({
|
|
|
17
17
|
description: 'Set a stage-scoped variable — the deployed counterpart of a line in .env. Not a secret: the value is stored in plain form and is readable back.',
|
|
18
18
|
input: FabricVariablesSetInput,
|
|
19
19
|
output: FabricVariablesSetOutput,
|
|
20
|
-
func: async (_services, { name, branch, value }) => {
|
|
20
|
+
func: async (_services, { name, branch: requested, value }) => {
|
|
21
21
|
const ctx = await resolveApiContext();
|
|
22
22
|
if (!ctx.token)
|
|
23
23
|
throw new Error('Not logged in. Run `pikku fabric login` first.');
|
|
24
24
|
if (!ctx.projectId)
|
|
25
25
|
throw new Error('No fabric project linked. Run `pikku fabric link` first.');
|
|
26
26
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
27
|
-
const stageId = await
|
|
27
|
+
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
28
28
|
// Deliberately not sealed, and deliberately not prompted for. A variable is
|
|
29
29
|
// configuration — a port, a URL, a feature switch — and treating it like a
|
|
30
30
|
// secret would mean it could not be read back, which is most of the value of
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace every comment in a TypeScript/JavaScript source with spaces, keeping
|
|
3
|
+
* the string exactly as long and every newline where it was, so offsets and
|
|
4
|
+
* line numbers computed against the result still point at the real file.
|
|
5
|
+
*
|
|
6
|
+
* The checks that scan source text with a regex have to run over this first.
|
|
7
|
+
* Scanning raw text made prose executable: a sentence reading
|
|
8
|
+
*
|
|
9
|
+
* // what separates "needs you" from "is fine" at a glance
|
|
10
|
+
*
|
|
11
|
+
* matched an import-specifier pattern and reported `is fine` as an undeclared
|
|
12
|
+
* dependency. Quotes are tracked rather than blanked, because the specifier a
|
|
13
|
+
* caller is looking for lives inside them.
|
|
14
|
+
*
|
|
15
|
+
* A regex literal holding `//` or an unpaired quote is not modelled — telling
|
|
16
|
+
* `/` as division from `/` as a regex needs the parser this deliberately is
|
|
17
|
+
* not. The failure mode is a blanked region, never a comment left readable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function blankComments(source: string): string;
|
|
20
|
+
/** 1-based line number of a character offset. */
|
|
21
|
+
export declare function lineOfOffset(source: string, offset: number): number;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace every comment in a TypeScript/JavaScript source with spaces, keeping
|
|
3
|
+
* the string exactly as long and every newline where it was, so offsets and
|
|
4
|
+
* line numbers computed against the result still point at the real file.
|
|
5
|
+
*
|
|
6
|
+
* The checks that scan source text with a regex have to run over this first.
|
|
7
|
+
* Scanning raw text made prose executable: a sentence reading
|
|
8
|
+
*
|
|
9
|
+
* // what separates "needs you" from "is fine" at a glance
|
|
10
|
+
*
|
|
11
|
+
* matched an import-specifier pattern and reported `is fine` as an undeclared
|
|
12
|
+
* dependency. Quotes are tracked rather than blanked, because the specifier a
|
|
13
|
+
* caller is looking for lives inside them.
|
|
14
|
+
*
|
|
15
|
+
* A regex literal holding `//` or an unpaired quote is not modelled — telling
|
|
16
|
+
* `/` as division from `/` as a regex needs the parser this deliberately is
|
|
17
|
+
* not. The failure mode is a blanked region, never a comment left readable.
|
|
18
|
+
*/
|
|
19
|
+
export function blankComments(source) {
|
|
20
|
+
const out = source.split('');
|
|
21
|
+
const blank = (start, end) => {
|
|
22
|
+
for (let i = start; i < end && i < out.length; i++) {
|
|
23
|
+
if (out[i] !== '\n' && out[i] !== '\r')
|
|
24
|
+
out[i] = ' ';
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
let i = 0;
|
|
28
|
+
while (i < source.length) {
|
|
29
|
+
const ch = source[i];
|
|
30
|
+
const next = source[i + 1];
|
|
31
|
+
if (ch === '/' && next === '/') {
|
|
32
|
+
const end = source.indexOf('\n', i);
|
|
33
|
+
blank(i, end === -1 ? source.length : end);
|
|
34
|
+
i = end === -1 ? source.length : end;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (ch === '/' && next === '*') {
|
|
38
|
+
const close = source.indexOf('*/', i + 2);
|
|
39
|
+
const end = close === -1 ? source.length : close + 2;
|
|
40
|
+
blank(i, end);
|
|
41
|
+
i = end;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (ch === "'" || ch === '"' || ch === '`') {
|
|
45
|
+
i++;
|
|
46
|
+
while (i < source.length) {
|
|
47
|
+
if (source[i] === '\\') {
|
|
48
|
+
i += 2;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (source[i] === ch) {
|
|
52
|
+
i++;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
i++;
|
|
60
|
+
}
|
|
61
|
+
return out.join('');
|
|
62
|
+
}
|
|
63
|
+
/** 1-based line number of a character offset. */
|
|
64
|
+
export function lineOfOffset(source, offset) {
|
|
65
|
+
let line = 1;
|
|
66
|
+
for (let i = 0; i < offset && i < source.length; i++) {
|
|
67
|
+
if (source[i] === '\n')
|
|
68
|
+
line++;
|
|
69
|
+
}
|
|
70
|
+
return line;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function blankScenarioMeta(source: string): string;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blank the `name`, `description` and `template` values declared directly on a
|
|
3
|
+
* `pikkuFeature` / `pikkuScenario` / `pikkuScenarioStep` object, keeping the
|
|
4
|
+
* source the same length so a later scan still reports real positions.
|
|
5
|
+
*
|
|
6
|
+
* Those three fields are Console meta — authored in the project's `locale`,
|
|
7
|
+
* describing the test to whoever reads the run — and are deliberately not the
|
|
8
|
+
* app's UI copy. The hardcoded-copy check flagged them anyway whenever a
|
|
9
|
+
* feature happened to be named after the screen it covers:
|
|
10
|
+
*
|
|
11
|
+
* export const downloadsFeature = pikkuFeature({
|
|
12
|
+
* name: 'Downloads', → ✗ "Downloads" → nav__downloads | downloads__title
|
|
13
|
+
*
|
|
14
|
+
* and its advice — read the string from the app catalogue — would tie the
|
|
15
|
+
* Console's language to the product's, which is the opposite of what should
|
|
16
|
+
* happen. Complying with the rule that puts features in `*.scenario.ts` was
|
|
17
|
+
* what surfaced them, so the two rules disagreed: satisfying one created
|
|
18
|
+
* violations of the other.
|
|
19
|
+
*
|
|
20
|
+
* Only the top level of the object is blanked. `getByRole('button', { name:
|
|
21
|
+
* 'Speichern' })` nested inside a step is a selector built out of UI copy —
|
|
22
|
+
* exactly what the check exists to catch — and stays visible.
|
|
23
|
+
*/
|
|
24
|
+
const DECLARATIONS = [
|
|
25
|
+
'pikkuFeature',
|
|
26
|
+
'pikkuScenario',
|
|
27
|
+
'pikkuScenarioStep',
|
|
28
|
+
'pikkuPlatformScenarioStep',
|
|
29
|
+
'pikkuAddonScenarioStep',
|
|
30
|
+
];
|
|
31
|
+
const META_FIELDS = /^(name|description|template)$/;
|
|
32
|
+
const QUOTES = new Set(["'", '"', '`']);
|
|
33
|
+
/** Index just past the string literal opening at `start`, or -1. */
|
|
34
|
+
function endOfString(src, start) {
|
|
35
|
+
const quote = src[start];
|
|
36
|
+
let i = start + 1;
|
|
37
|
+
while (i < src.length) {
|
|
38
|
+
if (src[i] === '\\') {
|
|
39
|
+
i += 2;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (src[i] === quote)
|
|
43
|
+
return i + 1;
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
export function blankScenarioMeta(source) {
|
|
49
|
+
const out = source.split('');
|
|
50
|
+
for (const decl of DECLARATIONS) {
|
|
51
|
+
const call = new RegExp(`\\b${decl}\\s*\\(`, 'g');
|
|
52
|
+
let m;
|
|
53
|
+
while ((m = call.exec(source))) {
|
|
54
|
+
let i = m.index + m[0].length;
|
|
55
|
+
while (i < source.length && /\s/.test(source[i]))
|
|
56
|
+
i++;
|
|
57
|
+
if (source[i] !== '{')
|
|
58
|
+
continue;
|
|
59
|
+
let depth = 0;
|
|
60
|
+
while (i < source.length) {
|
|
61
|
+
const ch = source[i];
|
|
62
|
+
if (QUOTES.has(ch)) {
|
|
63
|
+
const end = endOfString(source, i);
|
|
64
|
+
if (end === -1)
|
|
65
|
+
break;
|
|
66
|
+
i = end;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ch === '{') {
|
|
70
|
+
depth++;
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (ch === '}') {
|
|
75
|
+
depth--;
|
|
76
|
+
if (depth === 0)
|
|
77
|
+
break;
|
|
78
|
+
i++;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (depth === 1 && /[A-Za-z_$]/.test(ch)) {
|
|
82
|
+
const key = /^[A-Za-z0-9_$]+/.exec(source.slice(i))[0];
|
|
83
|
+
let j = i + key.length;
|
|
84
|
+
while (j < source.length && /\s/.test(source[j]))
|
|
85
|
+
j++;
|
|
86
|
+
if (source[j] === ':' && META_FIELDS.test(key)) {
|
|
87
|
+
j++;
|
|
88
|
+
while (j < source.length && /\s/.test(source[j]))
|
|
89
|
+
j++;
|
|
90
|
+
if (QUOTES.has(source[j])) {
|
|
91
|
+
const end = endOfString(source, j);
|
|
92
|
+
if (end !== -1) {
|
|
93
|
+
for (let k = j + 1; k < end - 1; k++) {
|
|
94
|
+
if (out[k] !== '\n' && out[k] !== '\r')
|
|
95
|
+
out[k] = ' ';
|
|
96
|
+
}
|
|
97
|
+
i = end;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
i += key.length;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
i++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return out.join('');
|
|
110
|
+
}
|
|
@@ -118,4 +118,30 @@ export interface WaitOptions {
|
|
|
118
118
|
now?: () => number;
|
|
119
119
|
}
|
|
120
120
|
export declare function waitForDeployment({ rpc, deploymentId, timeoutMs, approve, onEvent, sleep, now, }: WaitOptions): Promise<WaitResult>;
|
|
121
|
+
/**
|
|
122
|
+
* The sha a deployment actually holds, or an error naming the disagreement.
|
|
123
|
+
*
|
|
124
|
+
* `deployByStageKind` does not always cut a new deployment: with one already
|
|
125
|
+
* parked at `suspended` for the branch, it attaches to that plan — pinned to
|
|
126
|
+
* whatever commit it was created at — and returns its id. The CLI then
|
|
127
|
+
* reported the sha it had been *asked* for, so `apply` printed
|
|
128
|
+
*
|
|
129
|
+
* status: suspended sha: 599439e6
|
|
130
|
+
*
|
|
131
|
+
* for a deployment `deploy list` showed pinned to `5bfe84c`, five commits
|
|
132
|
+
* above it. Passing `--ref` explicitly changed nothing; the argument was
|
|
133
|
+
* echoed back. Nothing shipped only because that plan timed out.
|
|
134
|
+
*
|
|
135
|
+
* The blast radius is bounded — a second command still publishes, and only a
|
|
136
|
+
* commit already on the branch can go out — but the failure mode is a rollback
|
|
137
|
+
* that silently does not roll back, and a rollback is reached for precisely
|
|
138
|
+
* when production is already wrong. So whatever `apply` reports as the ref is
|
|
139
|
+
* read from the deployment, and a disagreement is an error rather than a line
|
|
140
|
+
* of output nobody can tell from the truth.
|
|
141
|
+
*/
|
|
142
|
+
export declare function reconcileDeployedRef({ requested, actual, deploymentId, }: {
|
|
143
|
+
requested: string;
|
|
144
|
+
actual: string | null;
|
|
145
|
+
deploymentId: string;
|
|
146
|
+
}): string;
|
|
121
147
|
export {};
|
|
@@ -286,3 +286,38 @@ export async function waitForDeployment({ rpc, deploymentId, timeoutMs, approve,
|
|
|
286
286
|
latest = await readDeploymentStatus(rpc, deploymentId);
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* The sha a deployment actually holds, or an error naming the disagreement.
|
|
291
|
+
*
|
|
292
|
+
* `deployByStageKind` does not always cut a new deployment: with one already
|
|
293
|
+
* parked at `suspended` for the branch, it attaches to that plan — pinned to
|
|
294
|
+
* whatever commit it was created at — and returns its id. The CLI then
|
|
295
|
+
* reported the sha it had been *asked* for, so `apply` printed
|
|
296
|
+
*
|
|
297
|
+
* status: suspended sha: 599439e6
|
|
298
|
+
*
|
|
299
|
+
* for a deployment `deploy list` showed pinned to `5bfe84c`, five commits
|
|
300
|
+
* above it. Passing `--ref` explicitly changed nothing; the argument was
|
|
301
|
+
* echoed back. Nothing shipped only because that plan timed out.
|
|
302
|
+
*
|
|
303
|
+
* The blast radius is bounded — a second command still publishes, and only a
|
|
304
|
+
* commit already on the branch can go out — but the failure mode is a rollback
|
|
305
|
+
* that silently does not roll back, and a rollback is reached for precisely
|
|
306
|
+
* when production is already wrong. So whatever `apply` reports as the ref is
|
|
307
|
+
* read from the deployment, and a disagreement is an error rather than a line
|
|
308
|
+
* of output nobody can tell from the truth.
|
|
309
|
+
*/
|
|
310
|
+
export function reconcileDeployedRef({ requested, actual, deploymentId, }) {
|
|
311
|
+
if (!actual)
|
|
312
|
+
return requested;
|
|
313
|
+
if (actual === requested)
|
|
314
|
+
return actual;
|
|
315
|
+
const short = (sha) => sha.slice(0, 8);
|
|
316
|
+
throw new Error([
|
|
317
|
+
`Refusing to continue: deployment ${deploymentId} is pinned to ${short(actual)}, not the ${short(requested)} you asked for.`,
|
|
318
|
+
'A deployment already parked for this branch was attached to rather than a new one being cut,',
|
|
319
|
+
'so continuing would deploy a different commit than the one named.',
|
|
320
|
+
`Inspect it with \`pikku fabric deploy list --json\`, then either publish it deliberately with`,
|
|
321
|
+
`\`pikku fabric deploy apply --deployment-id ${deploymentId} --sync\` or dismiss it and re-run.`,
|
|
322
|
+
].join('\n'));
|
|
323
|
+
}
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
import type { PikkuRPC } from '../sdk/pikku-rpc.gen.js';
|
|
2
|
+
export interface ResolvedStage {
|
|
3
|
+
stageId: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
|
-
* Resolve a stage
|
|
4
|
-
*
|
|
7
|
+
* Resolve a stage from (projectId, branch) via the `listStages` RPC. The
|
|
8
|
+
* stageId-based read RPCs (listDeployments, listDeploymentWorkers,
|
|
5
9
|
* getStageDatabaseSchema) need a UUID, but the CLI only knows the branch.
|
|
10
|
+
*
|
|
11
|
+
* `branch` is optional because it is optional in practice: nothing upstream
|
|
12
|
+
* guarantees the flag was passed, and interpolating what arrived produced
|
|
13
|
+
* `No stage for branch "undefined"` — an error naming the missing argument's
|
|
14
|
+
* value rather than saying the argument is missing, directly above a line
|
|
15
|
+
* listing the one stage it could have used. With exactly one stage there is
|
|
16
|
+
* nothing to disambiguate, so that stage is the answer.
|
|
17
|
+
*
|
|
18
|
+
* The branch comes back with the id so callers can name the stage they acted
|
|
19
|
+
* on rather than echoing the argument, which is `undefined` in exactly the
|
|
20
|
+
* case this function exists to handle.
|
|
6
21
|
*/
|
|
7
|
-
export declare function
|
|
22
|
+
export declare function resolveStage(rpc: PikkuRPC, projectId: string, branch: string | undefined): Promise<ResolvedStage>;
|
|
23
|
+
export declare function resolveStageId(rpc: PikkuRPC, projectId: string, branch: string | undefined): Promise<string>;
|
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve a stage
|
|
3
|
-
*
|
|
2
|
+
* Resolve a stage from (projectId, branch) via the `listStages` RPC. The
|
|
3
|
+
* stageId-based read RPCs (listDeployments, listDeploymentWorkers,
|
|
4
4
|
* getStageDatabaseSchema) need a UUID, but the CLI only knows the branch.
|
|
5
|
+
*
|
|
6
|
+
* `branch` is optional because it is optional in practice: nothing upstream
|
|
7
|
+
* guarantees the flag was passed, and interpolating what arrived produced
|
|
8
|
+
* `No stage for branch "undefined"` — an error naming the missing argument's
|
|
9
|
+
* value rather than saying the argument is missing, directly above a line
|
|
10
|
+
* listing the one stage it could have used. With exactly one stage there is
|
|
11
|
+
* nothing to disambiguate, so that stage is the answer.
|
|
12
|
+
*
|
|
13
|
+
* The branch comes back with the id so callers can name the stage they acted
|
|
14
|
+
* on rather than echoing the argument, which is `undefined` in exactly the
|
|
15
|
+
* case this function exists to handle.
|
|
5
16
|
*/
|
|
6
|
-
export async function
|
|
17
|
+
export async function resolveStage(rpc, projectId, branch) {
|
|
7
18
|
const { stages } = await rpc.invoke('listStages', { projectId });
|
|
19
|
+
const known = stages.map((s) => s.branch);
|
|
20
|
+
if (!branch) {
|
|
21
|
+
const only = stages[0];
|
|
22
|
+
if (stages.length === 1 && only) {
|
|
23
|
+
return { stageId: only.stageId, branch: only.branch };
|
|
24
|
+
}
|
|
25
|
+
throw new Error(stages.length === 0
|
|
26
|
+
? 'No stages deployed for this project yet — run `pikku fabric deploy apply --branch <branch>` first.'
|
|
27
|
+
: `--branch is required — this project has ${stages.length} stages: ${known.join(', ')}`);
|
|
28
|
+
}
|
|
8
29
|
const stage = stages.find((s) => s.branch === branch);
|
|
9
30
|
if (!stage) {
|
|
10
|
-
|
|
11
|
-
throw new Error(`No stage for branch "${branch}".${known ? ` Existing: ${known}` : ''}`);
|
|
31
|
+
throw new Error(`No stage for branch "${branch}".${known.length ? ` Existing: ${known.join(', ')}` : ''}`);
|
|
12
32
|
}
|
|
13
|
-
return stage.stageId;
|
|
33
|
+
return { stageId: stage.stageId, branch: stage.branch };
|
|
34
|
+
}
|
|
35
|
+
export async function resolveStageId(rpc, projectId, branch) {
|
|
36
|
+
return (await resolveStage(rpc, projectId, branch)).stageId;
|
|
14
37
|
}
|