@pikku/cli 0.12.115 → 0.12.116
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 +260 -0
- package/console-app/assets/{abnfDiagram-N423BO3Z-Bltf5dmS.js → abnfDiagram-N423BO3Z-WNIAg_Oa.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-CIT-Nug2.js +1 -0
- package/console-app/assets/{architectureDiagram-T3A2C74G-BTtx6R7-.js → architectureDiagram-T3A2C74G-DM698mgf.js} +1 -1
- package/console-app/assets/{blockDiagram-VBNYF7ZC-DgeTIOaM.js → blockDiagram-VBNYF7ZC-DPfy9K5S.js} +1 -1
- package/console-app/assets/{c4Diagram-5PPSVZJV-CaswnNob.js → c4Diagram-5PPSVZJV-DhLbbBbX.js} +1 -1
- package/console-app/assets/channel-DQC6cL1c.js +1 -0
- package/console-app/assets/{chunk-2GRJ4B5K-OnpnkpQT.js → chunk-2GRJ4B5K-C1RQ1gvs.js} +1 -1
- package/console-app/assets/{chunk-4I5QYGJK-CWmfNXFr.js → chunk-4I5QYGJK-BkzSdNc_.js} +1 -1
- package/console-app/assets/{chunk-5RXB4S5H-M8QmKeuk.js → chunk-5RXB4S5H-DZpBpdcU.js} +1 -1
- package/console-app/assets/{chunk-6Q2QTUOP-C_h5lS68.js → chunk-6Q2QTUOP-mZObxdld.js} +1 -1
- package/console-app/assets/{chunk-7Z6QIM7H-DSnVb09k.js → chunk-7Z6QIM7H-C0HbxZEa.js} +1 -1
- package/console-app/assets/{chunk-GF5L2VYU-BkX038sq.js → chunk-GF5L2VYU-DXPVwWqW.js} +1 -1
- package/console-app/assets/{chunk-I66GZJ75-b3yMIljX.js → chunk-I66GZJ75-pVpq9ckD.js} +1 -1
- package/console-app/assets/{chunk-JQJVKLGR-Bihcz4nv.js → chunk-JQJVKLGR-DJQ8K4wK.js} +1 -1
- package/console-app/assets/{chunk-KBJHAD2P-CS7eflbk.js → chunk-KBJHAD2P-B8XuxRCO.js} +1 -1
- package/console-app/assets/{chunk-NSK5VX7P-CfigFGDQ.js → chunk-NSK5VX7P-cYzQU4bD.js} +1 -1
- package/console-app/assets/{chunk-QR6OTTB3-BBy8NfTW.js → chunk-QR6OTTB3-CNoTFsqn.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-BCfZVQef.js → chunk-RYQCIY6F-DoKRUO_N.js} +1 -1
- package/console-app/assets/{chunk-UBXNYLIW-DkMKDHW4.js → chunk-UBXNYLIW-BqcIoUpU.js} +1 -1
- package/console-app/assets/{chunk-W5SLKNZC-BSLytTSJ.js → chunk-W5SLKNZC-p0Qalbjj.js} +1 -1
- package/console-app/assets/{chunk-WRU74C26-Dic7ZP8H.js → chunk-WRU74C26-DUMn96Dr.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-Dgz5VbWO.js +1 -0
- package/console-app/assets/classDiagram-JCYQIIEL-1ASFocNV.js +1 -0
- package/console-app/assets/classDiagram-v2-OCEON4UE-1ASFocNV.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-CEpWcE3M.js → cose-bilkent-JH36ORCC-BCh3BlPI.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-irPiPhgz.js → cynefin-VYW2F7L2-ZfghUZsD.js} +1 -1
- package/console-app/assets/{cynefinDiagram-MW4NZA55-CIkqQ912.js → cynefinDiagram-MW4NZA55-DcV3QXCe.js} +1 -1
- package/console-app/assets/{dagre-FZyyw3H3.js → dagre-BPFWXLBN.js} +1 -1
- package/console-app/assets/{dagre-VZM6K2ZE-Dxnnu7Rh.js → dagre-VZM6K2ZE-DETshBO-.js} +1 -1
- package/console-app/assets/{diagram-7IWD3JNH-DaT47sVs.js → diagram-7IWD3JNH-CsLX3P2o.js} +1 -1
- package/console-app/assets/{diagram-B4RE2ZJO-Dmht03tx.js → diagram-B4RE2ZJO-o2zcxm5S.js} +1 -1
- package/console-app/assets/{diagram-LBJQPF4R-B--jwILh.js → diagram-LBJQPF4R-BD2zKU21.js} +1 -1
- package/console-app/assets/{diagram-Q27KOJAE-D9H0euUr.js → diagram-Q27KOJAE-DHaacyna.js} +1 -1
- package/console-app/assets/{diagram-UB23O5K3-DloUQ8tO.js → diagram-UB23O5K3-pSLCMUyV.js} +1 -1
- package/console-app/assets/{ebnfDiagram-BXEA7PRR-gaOXzNBU.js → ebnfDiagram-BXEA7PRR-BDzawX3O.js} +1 -1
- package/console-app/assets/{erDiagram-JOGREHBK-3X9eTLsh.js → erDiagram-JOGREHBK-CyYnPmbN.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-BYJ0A5k-.js +1 -0
- package/console-app/assets/flowDiagram-UKHOOZJN-CVn87uiP.js +1 -0
- package/console-app/assets/{ganttDiagram-PKOTCBZU-khAFwSBy.js → ganttDiagram-PKOTCBZU-3fhCBbPA.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-Bb7uENmk.js → gitGraph-TEB2WS4Q-CdLRkVux.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-DS77QQ5N-OkSBM0h0.js → gitGraphDiagram-DS77QQ5N-CC1epdKw.js} +1 -1
- package/console-app/assets/{index-Bn1BoT3w.js → index-BRmokG9t.js} +184 -184
- package/console-app/assets/{index-suVNAhyL.css → index-GruDnAhJ.css} +1 -1
- package/console-app/assets/{info-DKCQHKI2-BH5dbX2B.js → info-DKCQHKI2-BJs8WkzC.js} +1 -1
- package/console-app/assets/{infoDiagram-6WML65LV-IbUl8J2C.js → infoDiagram-6WML65LV-uoOwoIeI.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-WSZJBQD7-CX0gA3de.js → ishikawaDiagram-WSZJBQD7-vCUJhwTi.js} +1 -1
- package/console-app/assets/{journeyDiagram-NVQOT4AX--k2etXu8.js → journeyDiagram-NVQOT4AX-D2QcIlLG.js} +1 -1
- package/console-app/assets/{kanban-definition-27J2QSJJ-D1FvtPpN.js → kanban-definition-27J2QSJJ-JwwKowmR.js} +1 -1
- package/console-app/assets/{line-JLMY_DDK.js → line-h2oRreYF.js} +1 -1
- package/console-app/assets/{linear-CSvLB3cd.js → linear-Dz002X_a.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-CwwjcAjz.js → mermaid-parser.core-DTgmT0AA.js} +3 -3
- package/console-app/assets/{mermaid.core-hmS_M4K5.js → mermaid.core-1jSEDr-j.js} +4 -4
- package/console-app/assets/{mindmap-definition-FAOFIHXS-rTDa_CTp.js → mindmap-definition-FAOFIHXS-C3Txxhj4.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-DBUJcYfI.js → packet-7NZHBO7P-BGG7zIK2.js} +1 -1
- package/console-app/assets/{pegDiagram-VL7TDLO6-D42PxXnS.js → pegDiagram-VL7TDLO6--g1r_rov.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-dM0uFAE4.js → pie-RZYD4A2V-C5OepMH7.js} +1 -1
- package/console-app/assets/{pieDiagram-7S7Q4E2Y-wCln1ucl.js → pieDiagram-7S7Q4E2Y-DGD_LzGm.js} +1 -1
- package/console-app/assets/{quadrantDiagram-CIZ2JOQS-DrRwS1g5.js → quadrantDiagram-CIZ2JOQS-CyBQQlD2.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-BW0V-EGR.js → radar-I7S5WNFK-CaBOAO95.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-FiTHaDbb.js → railroad-3IZDKUUU-2aTWN4Pw.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-TU7k5gB_.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DbArPBkM.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-TzB93z4K.js +1 -0
- package/console-app/assets/{railroadDiagram-AXF67PYL-9ef7j5U7.js → railroadDiagram-AXF67PYL-3Nr0rlTp.js} +1 -1
- package/console-app/assets/{requirementDiagram-LRYGKXZP-Cu90DbEZ.js → requirementDiagram-LRYGKXZP-BN7sEwSa.js} +1 -1
- package/console-app/assets/{sankeyDiagram-W5VNT64P-Bhxmyxaw.js → sankeyDiagram-W5VNT64P-CXZR46wO.js} +1 -1
- package/console-app/assets/{sequenceDiagram-SI44F4Z6-CBsbRTz8.js → sequenceDiagram-SI44F4Z6-DNtmdJ4U.js} +1 -1
- package/console-app/assets/{src-BR8qR3lM.js → src-x1E3pJJ-.js} +1 -1
- package/console-app/assets/{stateDiagram-OKZ733FA-Dr0frETZ.js → stateDiagram-OKZ733FA-B_GyYdl_.js} +1 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-D7V_HITc.js +1 -0
- package/console-app/assets/{swimlanes-SLNWSIFB-CXMjvd_a.js → swimlanes-SLNWSIFB-D4N7VdF7.js} +1 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-C4XcIHKT.js +8 -0
- package/console-app/assets/{timeline-definition-Z64GVDOM-DpmEZPV0.js → timeline-definition-Z64GVDOM-DU5rsOWQ.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-CjmuinMk.js → treeView-QDETBFTQ-DaKM_9sB.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-BP_fU6Cn.js → treemap-6X3UGDF4-BabsKtZY.js} +1 -1
- package/console-app/assets/{vennDiagram-T6HMQDX7-DgZS7iuW.js → vennDiagram-T6HMQDX7-Dniftpq0.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-CgMPoouN.js → wardley-OPB4EBWU-BWffQNys.js} +1 -1
- package/console-app/assets/{wardleyDiagram-T6FBY63Y-6y-xxP1R.js → wardleyDiagram-T6FBY63Y-CQ74fVdn.js} +1 -1
- package/console-app/assets/{xychartDiagram-ELKLHX3M-DOeIQjYI.js → xychartDiagram-ELKLHX3M-D-XxbGIL.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 +42 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.js +41 -0
- 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 +2 -19
- package/dist/.pikku/auth/pikku-auth-types.gen.js +2 -19
- 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 +10 -18
- package/dist/.pikku/channel/pikku-channel-types.gen.js +9 -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 +6 -6
- 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 +24 -23
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +8 -7
- package/dist/.pikku/cli/pikku-cli-types.gen.js +8 -7
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +51 -23
- 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 +36 -37
- package/dist/.pikku/function/pikku-function-types.gen.js +21 -9
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +34 -34
- 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 +7 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +5 -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 +11 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +5 -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 +33 -24
- package/dist/.pikku/middleware/pikku-middleware-types.gen.js +29 -24
- 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 +3 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +3 -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 +1 -1
- package/dist/.pikku/scenarios/index.d.ts +1 -1
- package/dist/.pikku/scenarios/index.js +1 -1
- package/dist/.pikku/scenarios/pikku-personas.gen.d.ts +4 -0
- 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 +13 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.js +4 -0
- 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 +3 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +3 -1
- package/dist/.pikku/schemas/register.gen.js +5 -5
- package/dist/.pikku/schemas/schemas/DocInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/DocOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricDeployApplyInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricDeployApplyOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuSkillsInstallInput.schema.json +1 -1
- 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 +9 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +5 -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 +7 -19
- package/dist/.pikku/setup/pikku-setup-types.gen.js +11 -19
- 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 +5 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +5 -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 +9 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +5 -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 +29 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +8 -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 +21 -0
- package/dist/src/deploy/analyzer/analyzer.d.ts +1 -0
- package/dist/src/deploy/analyzer/analyzer.js +8 -6
- package/dist/src/deploy/build-pipeline.d.ts +1 -0
- package/dist/src/deploy/build-pipeline.js +1 -0
- package/dist/src/fabric/fabric-commands.d.ts +170 -54
- package/dist/src/fabric/fabric-commands.js +25 -20
- package/dist/src/fabric/functions/deploy.function.d.ts +246 -67
- package/dist/src/fabric/functions/deploy.function.js +316 -69
- package/dist/src/fabric/functions/init.function.js +1 -0
- package/dist/src/fabric/functions/link.function.js +4 -1
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.js +2 -2
- package/dist/src/fabric/functions/validate.function.js +123 -0
- package/dist/src/fabric/lib/deployment.d.ts +107 -0
- package/dist/src/fabric/lib/deployment.js +264 -0
- package/dist/src/fabric/sdk/pikku-fetch.gen.d.ts +1 -1
- package/dist/src/fabric/sdk/pikku-fetch.gen.js +1 -1
- package/dist/src/fabric/sdk/pikku-rpc.gen.d.ts +4 -1
- package/dist/src/fabric/sdk/pikku-rpc.gen.js +4 -1
- package/dist/src/functions/commands/deploy-apply.js +1 -0
- package/dist/src/functions/commands/deploy-plan.js +1 -0
- package/dist/src/functions/commands/doc.d.ts +22 -0
- package/dist/src/functions/commands/doc.js +25 -0
- package/dist/src/functions/commands/skills.d.ts +3 -0
- package/dist/src/functions/commands/skills.js +4 -2
- package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.d.ts +3 -2
- package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.js +33 -10
- package/dist/src/functions/surface/build-surface-doc.d.ts +8 -1
- package/dist/src/functions/surface/build-surface-doc.js +21 -8
- package/dist/src/functions/surface/collect-snippets.d.ts +13 -0
- package/dist/src/functions/surface/collect-snippets.js +83 -0
- package/dist/src/functions/surface/collect-surface.d.ts +27 -1
- package/dist/src/functions/surface/collect-surface.js +323 -13
- package/dist/src/functions/surface/generate-surface-doc.js +40 -5
- package/dist/src/functions/surface/render-surface-doc.d.ts +12 -0
- package/dist/src/functions/surface/render-surface-doc.js +209 -0
- package/dist/src/functions/surface/surface-doc.types.d.ts +15 -2
- package/dist/src/functions/surface/surface-editorial.d.ts +6 -0
- package/dist/src/functions/surface/surface-editorial.js +22 -1
- package/dist/src/functions/wirings/agent/serialize-agent-types.js +41 -0
- package/dist/src/functions/wirings/agent/serialize-public-agent.js +1 -1
- package/dist/src/functions/wirings/auth/serialize-auth-guards.js +1 -18
- package/dist/src/functions/wirings/auth/serialize-auth-types.js +7 -0
- package/dist/src/functions/wirings/channels/serialize-channel-types.js +9 -17
- package/dist/src/functions/wirings/cli/serialize-cli-types.js +7 -6
- package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
- package/dist/src/functions/wirings/functions/serialize-addon-refs.js +12 -0
- package/dist/src/functions/wirings/functions/serialize-function-types.js +23 -36
- package/dist/src/functions/wirings/http/serialize-http-types.js +6 -0
- package/dist/src/functions/wirings/mcp/serialize-mcp-types.js +10 -0
- package/dist/src/functions/wirings/middleware/serialize-middleware-types.js +32 -23
- package/dist/src/functions/wirings/queue/serialize-queue-types.js +2 -0
- package/dist/src/functions/wirings/scheduler/serialize-scheduler-types.js +2 -0
- package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +8 -0
- package/dist/src/functions/wirings/setup/serialize-setup-types.d.ts +1 -1
- package/dist/src/functions/wirings/setup/serialize-setup-types.js +19 -19
- package/dist/src/functions/wirings/triggers/serialize-trigger-types.js +4 -0
- package/dist/src/functions/wirings/variables/serialize-variables-types.js +8 -0
- package/dist/src/functions/wirings/workflow/serialize-personas.js +4 -0
- package/dist/src/functions/wirings/workflow/serialize-scenario-types.js +12 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +28 -0
- package/dist/src/services.js +8 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -7
- package/snippets-meta.json +131 -0
- package/snippets.json +131 -0
- package/surface.json +7393 -458
- package/console-app/assets/architecture-TIHT7OUA-DgRqRaqo.js +0 -1
- package/console-app/assets/channel-37lNznWk.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-B1prMCvW.js +0 -1
- package/console-app/assets/classDiagram-JCYQIIEL-BDCX9ZLm.js +0 -1
- package/console-app/assets/classDiagram-v2-OCEON4UE-BDCX9ZLm.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-BarrKD55.js +0 -1
- package/console-app/assets/flowDiagram-UKHOOZJN-B6RiRjcD.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-lmUjOixE.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-ZjdA7OHp.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-VHSlvwI8.js +0 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-BSXWhCvf.js +0 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-BUdsPDKC.js +0 -8
- package/dist/.pikku/schemas/schemas/FabricDeployPlanInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/FabricDeployPlanOutput.schema.json +0 -1
|
@@ -96,6 +96,10 @@ const toDocSymbols = (entrypoint, generatedRoot) => [...entrypoint.symbols]
|
|
|
96
96
|
...(symbol.deprecated
|
|
97
97
|
? { deprecated: symbol.deprecatedReason ?? 'Deprecated' }
|
|
98
98
|
: {}),
|
|
99
|
+
...(symbol.signature ? { signature: symbol.signature } : {}),
|
|
100
|
+
...(symbol.members?.length ? { members: symbol.members } : {}),
|
|
101
|
+
...(symbol.examples?.length ? { examples: symbol.examples } : {}),
|
|
102
|
+
...(symbol.status !== undefined ? { status: symbol.status } : {}),
|
|
99
103
|
}));
|
|
100
104
|
const byStepThenName = (a, b) => STEP_ORDER.indexOf(a.step) - STEP_ORDER.indexOf(b.step) ||
|
|
101
105
|
a.name.localeCompare(b.name);
|
|
@@ -121,6 +125,7 @@ const toLeaves = (entryPoint, entrypoints, editorial, generatedRoot) => {
|
|
|
121
125
|
name,
|
|
122
126
|
step: copy.step,
|
|
123
127
|
summary: copy.summary,
|
|
128
|
+
skill: copy.skill,
|
|
124
129
|
symbols: toDocSymbols(entrypoint, generatedRoot),
|
|
125
130
|
});
|
|
126
131
|
}
|
|
@@ -129,11 +134,12 @@ const toLeaves = (entryPoint, entrypoints, editorial, generatedRoot) => {
|
|
|
129
134
|
}
|
|
130
135
|
return leaves.sort(byStepThenName);
|
|
131
136
|
};
|
|
132
|
-
const projectEntryPoint = async (id, project) => {
|
|
137
|
+
const projectEntryPoint = async (id, project, snippets) => {
|
|
133
138
|
const projectDir = resolve(project.projectDir);
|
|
134
139
|
const generatedRoot = resolve(project.outDir ?? join(projectDir, '.pikku'));
|
|
135
140
|
const entrypoints = await collectSurface(projectDir, {
|
|
136
141
|
importsSubpath: PIKKU_IMPORTS_SUBPATH,
|
|
142
|
+
snippets,
|
|
137
143
|
});
|
|
138
144
|
return {
|
|
139
145
|
id,
|
|
@@ -142,10 +148,17 @@ const projectEntryPoint = async (id, project) => {
|
|
|
142
148
|
leaves: toLeaves(id, entrypoints, (subpath) => LEAF_EDITORIAL[leafNameOf(subpath)], generatedRoot),
|
|
143
149
|
};
|
|
144
150
|
};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
/**
|
|
152
|
+
* An example names a snippet rather than restating it, and both entrypoints
|
|
153
|
+
* resolve against the same map — the regions come from one running application
|
|
154
|
+
* (`examples/online-shop`), not from whichever template happened to hold them.
|
|
155
|
+
*/
|
|
156
|
+
export const buildSurfaceDoc = async ({ version, app, addon, snippets, }) => {
|
|
157
|
+
return {
|
|
158
|
+
version,
|
|
159
|
+
entryPoints: [
|
|
160
|
+
await projectEntryPoint('app', app, snippets),
|
|
161
|
+
await projectEntryPoint('addon', addon, snippets),
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class UnclosedSnippetError extends Error {
|
|
2
|
+
constructor(name: string, file: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class DuplicateSnippetError extends Error {
|
|
5
|
+
constructor(name: string, file: string, other: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The `// @snippet start <name>` regions in a project's source, so an example
|
|
9
|
+
* in a doc comment can name one instead of restating it. The same mechanism the
|
|
10
|
+
* website uses to pull its code blocks out of the shop template: the code that
|
|
11
|
+
* reaches the reader is the code that compiles, and it cannot drift.
|
|
12
|
+
*/
|
|
13
|
+
export declare const collectSnippets: (projectDir: string, into?: Map<string, string>, origins?: Map<string, string>) => Promise<Map<string, string>>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
const START = /^\s*(?:\/\/|--)\s*@snippet start (\S+)\s*$/;
|
|
4
|
+
const END = /^\s*(?:\/\/|--)\s*@snippet end (\S+)\s*$/;
|
|
5
|
+
const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.sql'];
|
|
6
|
+
const SKIPPED_DIRECTORIES = new Set(['node_modules', '.pikku', 'dist', '.git']);
|
|
7
|
+
export class UnclosedSnippetError extends Error {
|
|
8
|
+
constructor(name, file) {
|
|
9
|
+
super(`The snippet "${name}" opens in ${file} and never closes. Add "// @snippet end ${name}".`);
|
|
10
|
+
this.name = 'UnclosedSnippetError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class DuplicateSnippetError extends Error {
|
|
14
|
+
constructor(name, file, other) {
|
|
15
|
+
super(`The snippet "${name}" is defined twice, in ${other} and ${file}. Snippet names are the reference an example uses, so they have to be unique.`);
|
|
16
|
+
this.name = 'DuplicateSnippetError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const dedent = (lines) => {
|
|
20
|
+
const indents = lines
|
|
21
|
+
.filter((line) => line.trim().length > 0)
|
|
22
|
+
.map((line) => line.length - line.trimStart().length);
|
|
23
|
+
const shortest = indents.length > 0 ? Math.min(...indents) : 0;
|
|
24
|
+
return lines
|
|
25
|
+
.map((line) => line.slice(shortest))
|
|
26
|
+
.join('\n')
|
|
27
|
+
.trim();
|
|
28
|
+
};
|
|
29
|
+
const sourceFilesIn = async (directory, found = []) => {
|
|
30
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
31
|
+
const full = join(directory, entry.name);
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
if (SKIPPED_DIRECTORIES.has(entry.name) || entry.name.startsWith('.')) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
await sourceFilesIn(full, found);
|
|
37
|
+
}
|
|
38
|
+
else if (SOURCE_EXTENSIONS.some((ext) => entry.name.endsWith(ext))) {
|
|
39
|
+
found.push(full);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return found;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The `// @snippet start <name>` regions in a project's source, so an example
|
|
46
|
+
* in a doc comment can name one instead of restating it. The same mechanism the
|
|
47
|
+
* website uses to pull its code blocks out of the shop template: the code that
|
|
48
|
+
* reaches the reader is the code that compiles, and it cannot drift.
|
|
49
|
+
*/
|
|
50
|
+
export const collectSnippets = async (projectDir, into = new Map(), origins = new Map()) => {
|
|
51
|
+
for (const file of await sourceFilesIn(projectDir)) {
|
|
52
|
+
const where = relative(projectDir, file);
|
|
53
|
+
const lines = (await readFile(file, 'utf8')).split('\n');
|
|
54
|
+
const open = new Map();
|
|
55
|
+
for (const line of lines) {
|
|
56
|
+
const end = line.match(END);
|
|
57
|
+
if (end?.[1] && open.has(end[1])) {
|
|
58
|
+
const name = end[1];
|
|
59
|
+
const existing = origins.get(name);
|
|
60
|
+
if (existing)
|
|
61
|
+
throw new DuplicateSnippetError(name, where, existing);
|
|
62
|
+
into.set(name, dedent(open.get(name)));
|
|
63
|
+
origins.set(name, where);
|
|
64
|
+
open.delete(name);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const start = line.match(START);
|
|
68
|
+
if (start?.[1]) {
|
|
69
|
+
if (!open.has(start[1]))
|
|
70
|
+
open.set(start[1], []);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (end)
|
|
74
|
+
continue;
|
|
75
|
+
for (const body of open.values())
|
|
76
|
+
body.push(line);
|
|
77
|
+
}
|
|
78
|
+
const [unclosed] = open.keys();
|
|
79
|
+
if (unclosed)
|
|
80
|
+
throw new UnclosedSnippetError(unclosed, where);
|
|
81
|
+
}
|
|
82
|
+
return into;
|
|
83
|
+
};
|
|
@@ -12,6 +12,18 @@ export type SurfaceSymbol = {
|
|
|
12
12
|
summary?: string;
|
|
13
13
|
/** The symbol's JSDoc in full, paragraphs and examples included. */
|
|
14
14
|
docs?: string;
|
|
15
|
+
/** The type as the checker prints it, so a caller knows how to call it. */
|
|
16
|
+
signature?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The shape written at the call site, one `name?: type` per entry — the
|
|
19
|
+
* properties of the object a function takes, or of the type itself. The
|
|
20
|
+
* signature names that shape; this says what is in it.
|
|
21
|
+
*/
|
|
22
|
+
members?: SurfaceMember[];
|
|
23
|
+
/** The `@example` blocks, which the documentation comment leaves out. */
|
|
24
|
+
examples?: string[];
|
|
25
|
+
/** The HTTP status an error class is registered with. */
|
|
26
|
+
status?: number;
|
|
15
27
|
};
|
|
16
28
|
export type SurfaceEntrypoint = {
|
|
17
29
|
subpath: string;
|
|
@@ -28,5 +40,19 @@ export type CollectSurfaceOptions = {
|
|
|
28
40
|
importsSubpath?: string;
|
|
29
41
|
/** Restrict collection to these subpaths, so the program stays small. */
|
|
30
42
|
subpaths?: string[];
|
|
43
|
+
/** The snippet regions an `@example snippet: name` resolves against. */
|
|
44
|
+
snippets?: Map<string, string>;
|
|
45
|
+
};
|
|
46
|
+
export declare class UnknownSnippetError extends Error {
|
|
47
|
+
constructor(name: string, symbol: string, known: string[]);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* One key of an options object: how it is written, and — where the declaring
|
|
51
|
+
* type says so — what it means. `schedule: string` is a shape; "a cron
|
|
52
|
+
* expression" is what a caller actually needs, and only the JSDoc has it.
|
|
53
|
+
*/
|
|
54
|
+
export type SurfaceMember = {
|
|
55
|
+
line: string;
|
|
56
|
+
doc?: string;
|
|
31
57
|
};
|
|
32
|
-
export declare const collectSurface: (packageDir: string, { importsSubpath, subpaths }?: CollectSurfaceOptions) => Promise<SurfaceEntrypoint[]>;
|
|
58
|
+
export declare const collectSurface: (packageDir: string, { importsSubpath, subpaths, snippets }?: CollectSurfaceOptions) => Promise<SurfaceEntrypoint[]>;
|
|
@@ -150,10 +150,15 @@ const KIND_BY_FLAG = [
|
|
|
150
150
|
[ts.SymbolFlags.TypeAlias, 'type'],
|
|
151
151
|
[ts.SymbolFlags.Namespace, 'namespace'],
|
|
152
152
|
];
|
|
153
|
+
/**
|
|
154
|
+
* A leaf re-exports through `export *`, so the symbol reached here is an alias
|
|
155
|
+
* that carries no kind, no documentation, no tags and no type of its own.
|
|
156
|
+
*/
|
|
157
|
+
const aliasTargetOf = (symbol, checker) => symbol.flags & ts.SymbolFlags.Alias
|
|
158
|
+
? checker.getAliasedSymbol(symbol)
|
|
159
|
+
: symbol;
|
|
153
160
|
const kindOf = (symbol, checker) => {
|
|
154
|
-
const target = symbol
|
|
155
|
-
? checker.getAliasedSymbol(symbol)
|
|
156
|
-
: symbol;
|
|
161
|
+
const target = aliasTargetOf(symbol, checker);
|
|
157
162
|
for (const [flag, kind] of KIND_BY_FLAG) {
|
|
158
163
|
if (target.flags & flag)
|
|
159
164
|
return kind;
|
|
@@ -169,14 +174,49 @@ const kindOf = (symbol, checker) => {
|
|
|
169
174
|
}
|
|
170
175
|
return 'const';
|
|
171
176
|
};
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
|
|
177
|
+
const jsDocTagsOf = (symbol, checker) => {
|
|
178
|
+
const own = symbol.getJsDocTags(checker);
|
|
179
|
+
if (own.length > 0)
|
|
180
|
+
return own;
|
|
181
|
+
return aliasTargetOf(symbol, checker).getJsDocTags(checker);
|
|
182
|
+
};
|
|
183
|
+
const isDeprecated = (tags) => tags.some((tag) => tag.name === 'deprecated');
|
|
184
|
+
const deprecationReason = (tags) => {
|
|
185
|
+
const tag = tags.find((each) => each.name === 'deprecated');
|
|
175
186
|
if (!tag)
|
|
176
187
|
return undefined;
|
|
177
188
|
const text = ts.displayPartsToString(tag.text).trim();
|
|
178
189
|
return text.length > 0 ? text : undefined;
|
|
179
190
|
};
|
|
191
|
+
export class UnknownSnippetError extends Error {
|
|
192
|
+
constructor(name, symbol, known) {
|
|
193
|
+
super(`The example on ${symbol} names the snippet "${name}", which no template declares. Wrap the code you want shown in "// @snippet start ${name}" / "// @snippet end ${name}". Declared: ${known.join(', ')}.`);
|
|
194
|
+
this.name = 'UnknownSnippetError';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const SNIPPET_REFERENCE = /^snippet:\s*(\S+)$/;
|
|
198
|
+
/**
|
|
199
|
+
* The `@example` blocks. `getDocumentationComment` returns the description only,
|
|
200
|
+
* so an example an author wrote is dropped unless the tags are read separately.
|
|
201
|
+
* An `@example snippet: name` names a region of real template source instead of
|
|
202
|
+
* restating it, and is resolved here so the shipped doc holds code that compiles.
|
|
203
|
+
*/
|
|
204
|
+
const examplesOf = (tags, symbolName, snippets) => tags
|
|
205
|
+
.filter((tag) => tag.name === 'example')
|
|
206
|
+
.map((tag) => ts.displayPartsToString(tag.text).trim())
|
|
207
|
+
.filter((text) => text.length > 0)
|
|
208
|
+
.map((text) => {
|
|
209
|
+
const reference = text.match(SNIPPET_REFERENCE);
|
|
210
|
+
if (!reference?.[1] || !snippets)
|
|
211
|
+
return text;
|
|
212
|
+
const snippet = snippets.get(reference[1]);
|
|
213
|
+
if (snippet === undefined) {
|
|
214
|
+
throw new UnknownSnippetError(reference[1], symbolName, [
|
|
215
|
+
...snippets.keys(),
|
|
216
|
+
]);
|
|
217
|
+
}
|
|
218
|
+
return snippet;
|
|
219
|
+
});
|
|
180
220
|
/**
|
|
181
221
|
* The doc comment as written. A leaf re-exports through `export *`, so the
|
|
182
222
|
* symbol reached here is an alias carrying no documentation of its own, and an
|
|
@@ -195,6 +235,25 @@ const documentationOf = (symbol, checker) => {
|
|
|
195
235
|
if (documentation.length > 0)
|
|
196
236
|
return documentation;
|
|
197
237
|
}
|
|
238
|
+
return exportDeclarationDocumentationOf(symbol);
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* A re-export the generator documents (`export type { Services }`) carries its
|
|
242
|
+
* JSDoc on the export statement, which TypeScript attaches to no symbol at all
|
|
243
|
+
* — so it is read off the node.
|
|
244
|
+
*/
|
|
245
|
+
const exportDeclarationDocumentationOf = (symbol) => {
|
|
246
|
+
for (const declaration of symbol.declarations ?? []) {
|
|
247
|
+
if (!ts.isExportSpecifier(declaration))
|
|
248
|
+
continue;
|
|
249
|
+
const statement = declaration.parent.parent;
|
|
250
|
+
const [comment] = ts.getJSDocCommentsAndTags(statement);
|
|
251
|
+
if (!comment || !ts.isJSDoc(comment))
|
|
252
|
+
continue;
|
|
253
|
+
const documentation = ts.getTextOfJSDocComment(comment.comment)?.trim();
|
|
254
|
+
if (documentation && documentation.length > 0)
|
|
255
|
+
return documentation;
|
|
256
|
+
}
|
|
198
257
|
return undefined;
|
|
199
258
|
};
|
|
200
259
|
/**
|
|
@@ -210,13 +269,250 @@ const summaryOf = (documentation) => {
|
|
|
210
269
|
.trim();
|
|
211
270
|
};
|
|
212
271
|
const declarationFileOf = (symbol, checker) => {
|
|
213
|
-
const target = symbol
|
|
214
|
-
? checker.getAliasedSymbol(symbol)
|
|
215
|
-
: symbol;
|
|
272
|
+
const target = aliasTargetOf(symbol, checker);
|
|
216
273
|
const declaration = target.declarations?.[0] ?? symbol.declarations?.[0];
|
|
217
274
|
return declaration?.getSourceFile().fileName ?? null;
|
|
218
275
|
};
|
|
219
|
-
|
|
276
|
+
/**
|
|
277
|
+
* `NoTruncation` is the load-bearing one: the default cuts a type off at ~160
|
|
278
|
+
* characters, which lands in the middle of the generics of every wiring helper.
|
|
279
|
+
* `UseAliasDefinedOutsideCurrentScope` keeps a named alias named instead of
|
|
280
|
+
* inlining its definition, which is what keeps the result readable.
|
|
281
|
+
*/
|
|
282
|
+
const SIGNATURE_FLAGS = ts.TypeFormatFlags.NoTruncation |
|
|
283
|
+
ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope |
|
|
284
|
+
ts.TypeFormatFlags.WriteTypeArgumentsOfSignature;
|
|
285
|
+
const DECLARED_TYPE_KINDS = new Set(['interface', 'type']);
|
|
286
|
+
const typeOfSymbol = (symbol, kind, checker) => {
|
|
287
|
+
if (DECLARED_TYPE_KINDS.has(kind))
|
|
288
|
+
return checker.getDeclaredTypeOfSymbol(symbol);
|
|
289
|
+
const declaration = symbol.declarations?.[0];
|
|
290
|
+
return declaration
|
|
291
|
+
? checker.getTypeOfSymbolAtLocation(symbol, declaration)
|
|
292
|
+
: undefined;
|
|
293
|
+
};
|
|
294
|
+
const printType = (type, location, checker) => checker.typeToString(type, location, SIGNATURE_FLAGS).replace(/\s+/g, ' ');
|
|
295
|
+
/**
|
|
296
|
+
* The widest an expanded type may print before its name is the better answer.
|
|
297
|
+
* A method verb or a content type says everything inline; a wiring object does
|
|
298
|
+
* not, and expanding it buries the keys that matter in the ones that do not.
|
|
299
|
+
*/
|
|
300
|
+
const INLINE_LIMIT = 72;
|
|
301
|
+
const EXPANDED_FLAGS = SIGNATURE_FLAGS & ~ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
302
|
+
const NOT_TERMINAL = /[{}]|=>/;
|
|
303
|
+
const collapse = (constituents) => {
|
|
304
|
+
const collapsed = constituents.includes('true') && constituents.includes('false')
|
|
305
|
+
? [
|
|
306
|
+
'boolean',
|
|
307
|
+
...constituents.filter((c) => c !== 'true' && c !== 'false'),
|
|
308
|
+
]
|
|
309
|
+
: constituents;
|
|
310
|
+
const isAbsent = (c) => c === 'undefined' || c === 'null';
|
|
311
|
+
return [
|
|
312
|
+
...collapsed.filter((c) => !isAbsent(c)),
|
|
313
|
+
...collapsed.filter(isAbsent),
|
|
314
|
+
];
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* A named type whose definition is a short union or an index signature costs a
|
|
318
|
+
* reader a second lookup to learn something that fits on the line they are
|
|
319
|
+
* already reading, so it is printed as its values rather than its name.
|
|
320
|
+
*/
|
|
321
|
+
const printResolved = (type, location, checker, optional = false) => {
|
|
322
|
+
const constraint = type.flags & ts.TypeFlags.TypeParameter
|
|
323
|
+
? checker.getBaseConstraintOfType(type)
|
|
324
|
+
: undefined;
|
|
325
|
+
if (constraint) {
|
|
326
|
+
return printResolved(constraint, location, checker, optional);
|
|
327
|
+
}
|
|
328
|
+
const named = printType(type, location, checker);
|
|
329
|
+
const expanded = type.isUnion()
|
|
330
|
+
? collapse(type.types.map((constituent) => checker.typeToString(constituent, location, EXPANDED_FLAGS))).join(' | ')
|
|
331
|
+
: checker.typeToString(type, location, EXPANDED_FLAGS).replace(/\s+/g, ' ');
|
|
332
|
+
const shed = optional ? / \| undefined$/ : /(?!)/;
|
|
333
|
+
if (expanded === named || expanded.length > INLINE_LIMIT) {
|
|
334
|
+
return named.replace(shed, '');
|
|
335
|
+
}
|
|
336
|
+
return (NOT_TERMINAL.test(expanded) ? named : expanded).replace(shed, '');
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* A class prints as `typeof Foo`, which says nothing. Its construct signatures
|
|
340
|
+
* are what a caller needs, so they stand in for it.
|
|
341
|
+
*/
|
|
342
|
+
const constructorSignature = (name, type, checker) => {
|
|
343
|
+
const signatures = type.getConstructSignatures();
|
|
344
|
+
if (signatures.length === 0)
|
|
345
|
+
return undefined;
|
|
346
|
+
return signatures
|
|
347
|
+
.map((signature) => `new ${name}(${signature
|
|
348
|
+
.getParameters()
|
|
349
|
+
.map((parameter) => {
|
|
350
|
+
const declaration = parameter.valueDeclaration;
|
|
351
|
+
const parameterType = declaration
|
|
352
|
+
? checker.getTypeOfSymbolAtLocation(parameter, declaration)
|
|
353
|
+
: checker.getTypeOfSymbol(parameter);
|
|
354
|
+
const optional = declaration &&
|
|
355
|
+
ts.isParameter(declaration) &&
|
|
356
|
+
declaration.questionToken
|
|
357
|
+
? '?'
|
|
358
|
+
: '';
|
|
359
|
+
return `${parameter.getName()}${optional}: ${printResolved(parameterType, declaration, checker, optional === '?')}`;
|
|
360
|
+
})
|
|
361
|
+
.join(', ')})`)
|
|
362
|
+
.join(' | ');
|
|
363
|
+
};
|
|
364
|
+
const signatureOf = (name, type, kind, location, checker) => {
|
|
365
|
+
const printed = kind === 'class'
|
|
366
|
+
? constructorSignature(name, type, checker)
|
|
367
|
+
: printType(type, location, checker);
|
|
368
|
+
if (!printed || printed === 'any' || printed === 'error' || printed === name)
|
|
369
|
+
return undefined;
|
|
370
|
+
return collapseRuns(printed);
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* A union parameterised by the project — every function name, every route —
|
|
374
|
+
* is unbounded and belongs to `pikku meta`, not to a framework doc that is the
|
|
375
|
+
* same for every project. Printed in full it buried one export under 4,000
|
|
376
|
+
* tokens of another project's identifiers.
|
|
377
|
+
*/
|
|
378
|
+
const LITERAL_RUN = /("[^"]*"(?: \| "[^"]*"){7,})/g;
|
|
379
|
+
const collapseRuns = (line) => line.replace(LITERAL_RUN, (run) => `${run.split(' | ').length} names (pikku meta)`);
|
|
380
|
+
/**
|
|
381
|
+
* A key declared by the project rather than by the framework — the services in
|
|
382
|
+
* its own `SingletonServices`, a type it wrote — is not part of the surface
|
|
383
|
+
* every project shares. Left in, the doc built from the sample project told
|
|
384
|
+
* every reader their singleton services hold a `todoStore`.
|
|
385
|
+
*/
|
|
386
|
+
const isProjectOwned = (declaration, root) => {
|
|
387
|
+
const file = declaration.getSourceFile().fileName;
|
|
388
|
+
return file.startsWith(root) && !file.includes('node_modules');
|
|
389
|
+
};
|
|
390
|
+
const memberLine = (property, checker, program, root) => {
|
|
391
|
+
if (property.getName().startsWith('__'))
|
|
392
|
+
return undefined;
|
|
393
|
+
const declaration = property.valueDeclaration ?? property.declarations?.[0];
|
|
394
|
+
if (declaration &&
|
|
395
|
+
(program.isSourceFileDefaultLibrary(declaration.getSourceFile()) ||
|
|
396
|
+
isProjectOwned(declaration, root))) {
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
const type = declaration
|
|
400
|
+
? checker.getTypeOfSymbolAtLocation(property, declaration)
|
|
401
|
+
: checker.getTypeOfSymbol(property);
|
|
402
|
+
const optional = property.flags & ts.SymbolFlags.Optional ? '?' : '';
|
|
403
|
+
const doc = ts
|
|
404
|
+
.displayPartsToString(property.getDocumentationComment(checker))
|
|
405
|
+
.replace(/\s+/g, ' ')
|
|
406
|
+
.trim();
|
|
407
|
+
return {
|
|
408
|
+
line: collapseRuns(`${property.getName()}${optional}: ${printResolved(type, declaration, checker, optional === '?')}`),
|
|
409
|
+
...(doc ? { doc } : {}),
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* Every wiring and function helper takes one options object, so its signature
|
|
414
|
+
* can only name that object's type and the keys someone has to write sit one
|
|
415
|
+
* level below it. Anything else describes itself.
|
|
416
|
+
*/
|
|
417
|
+
const shapeOf = (type, kind, checker) => {
|
|
418
|
+
if (kind === 'class') {
|
|
419
|
+
return type.getConstructSignatures()[0]?.getReturnType();
|
|
420
|
+
}
|
|
421
|
+
if (kind !== 'function' && kind !== 'const')
|
|
422
|
+
return type;
|
|
423
|
+
const signature = type.getCallSignatures()[0];
|
|
424
|
+
if (!signature)
|
|
425
|
+
return type;
|
|
426
|
+
for (const parameter of signature.getParameters()) {
|
|
427
|
+
const declaration = parameter.valueDeclaration;
|
|
428
|
+
const parameterType = declaration
|
|
429
|
+
? checker.getTypeOfSymbolAtLocation(parameter, declaration)
|
|
430
|
+
: checker.getTypeOfSymbol(parameter);
|
|
431
|
+
if (checker.getPropertiesOfType(parameterType).length > 0)
|
|
432
|
+
return parameterType;
|
|
433
|
+
}
|
|
434
|
+
return undefined;
|
|
435
|
+
};
|
|
436
|
+
const membersOf = (type, kind, checker, program, root) => {
|
|
437
|
+
const shape = shapeOf(type, kind, checker);
|
|
438
|
+
if (!shape)
|
|
439
|
+
return [];
|
|
440
|
+
return checker
|
|
441
|
+
.getPropertiesOfType(shape)
|
|
442
|
+
.map((property) => memberLine(property, checker, program, root))
|
|
443
|
+
.filter((member) => member !== undefined)
|
|
444
|
+
.sort((a, b) => a.line.localeCompare(b.line));
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* `addError(SomeError, { status })` is a runtime registration, so nothing about
|
|
448
|
+
* a class says what it maps to. The calls are top-level statements next to the
|
|
449
|
+
* classes they register, which makes the mapping readable by parsing rather
|
|
450
|
+
* than by importing and booting the runtime.
|
|
451
|
+
*
|
|
452
|
+
* A surveyed project consumes pikku as `.d.ts`, and a declaration file carries
|
|
453
|
+
* no statements — the registrations survive only in the `.js` beside it, which
|
|
454
|
+
* is why the emitted sibling is parsed too.
|
|
455
|
+
*/
|
|
456
|
+
const collectErrorStatuses = (program) => {
|
|
457
|
+
const statuses = new Map();
|
|
458
|
+
const record = (name, details) => {
|
|
459
|
+
if (!ts.isIdentifier(name) || !ts.isObjectLiteralExpression(details))
|
|
460
|
+
return;
|
|
461
|
+
for (const property of details.properties) {
|
|
462
|
+
if (!ts.isPropertyAssignment(property))
|
|
463
|
+
continue;
|
|
464
|
+
if (property.name.getText() !== 'status')
|
|
465
|
+
continue;
|
|
466
|
+
const status = Number(property.initializer.getText());
|
|
467
|
+
if (Number.isFinite(status))
|
|
468
|
+
statuses.set(name.text, status);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
const scan = (sourceFile) => {
|
|
472
|
+
for (const statement of sourceFile.statements) {
|
|
473
|
+
if (!ts.isExpressionStatement(statement))
|
|
474
|
+
continue;
|
|
475
|
+
const call = statement.expression;
|
|
476
|
+
if (!ts.isCallExpression(call) || !ts.isIdentifier(call.expression))
|
|
477
|
+
continue;
|
|
478
|
+
if (call.expression.text === 'addError') {
|
|
479
|
+
const [name, details] = call.arguments;
|
|
480
|
+
if (name && details)
|
|
481
|
+
record(name, details);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (call.expression.text !== 'addErrors')
|
|
485
|
+
continue;
|
|
486
|
+
const [list] = call.arguments;
|
|
487
|
+
if (!list || !ts.isArrayLiteralExpression(list))
|
|
488
|
+
continue;
|
|
489
|
+
for (const entry of list.elements) {
|
|
490
|
+
if (!ts.isArrayLiteralExpression(entry))
|
|
491
|
+
continue;
|
|
492
|
+
const [name, details] = entry.elements;
|
|
493
|
+
if (name && details)
|
|
494
|
+
record(name, details);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
499
|
+
if (!sourceFile.isDeclarationFile) {
|
|
500
|
+
scan(sourceFile);
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
if (!sourceFile.text.includes('PikkuError'))
|
|
504
|
+
continue;
|
|
505
|
+
const emitted = sourceFile.fileName.replace(/\.d\.([cm]?ts)$/, '.$1');
|
|
506
|
+
if (emitted === sourceFile.fileName)
|
|
507
|
+
continue;
|
|
508
|
+
const source = ts.sys.readFile(emitted.replace(/\.ts$/, '.js'));
|
|
509
|
+
if (source === undefined)
|
|
510
|
+
continue;
|
|
511
|
+
scan(ts.createSourceFile(emitted, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS));
|
|
512
|
+
}
|
|
513
|
+
return statuses;
|
|
514
|
+
};
|
|
515
|
+
export const collectSurface = async (packageDir, { importsSubpath, subpaths, snippets } = {}) => {
|
|
220
516
|
const root = resolve(packageDir);
|
|
221
517
|
const packageJson = await readJson(join(root, 'package.json'));
|
|
222
518
|
if (!packageJson)
|
|
@@ -275,6 +571,7 @@ export const collectSurface = async (packageDir, { importsSubpath, subpaths } =
|
|
|
275
571
|
checkJs: false,
|
|
276
572
|
});
|
|
277
573
|
const checker = program.getTypeChecker();
|
|
574
|
+
const errorStatuses = collectErrorStatuses(program);
|
|
278
575
|
return entries.map((entry) => {
|
|
279
576
|
const sourceFile = program.getSourceFile(join(root, entry.entryFile));
|
|
280
577
|
const moduleSymbol = sourceFile
|
|
@@ -287,15 +584,28 @@ export const collectSurface = async (packageDir, { importsSubpath, subpaths } =
|
|
|
287
584
|
const file = declarationFileOf(symbol, checker);
|
|
288
585
|
const kind = kindOf(symbol, checker);
|
|
289
586
|
const docs = documentationOf(symbol, checker);
|
|
587
|
+
const tags = jsDocTagsOf(symbol, checker);
|
|
588
|
+
const name = symbol.getName();
|
|
589
|
+
const target = aliasTargetOf(symbol, checker);
|
|
590
|
+
const type = typeOfSymbol(target, kind, checker);
|
|
591
|
+
const location = target.declarations?.[0];
|
|
592
|
+
const examples = examplesOf(tags, name, snippets);
|
|
593
|
+
const members = type ? membersOf(type, kind, checker, program, root) : [];
|
|
290
594
|
symbols.push({
|
|
291
|
-
name
|
|
595
|
+
name,
|
|
292
596
|
kind,
|
|
293
597
|
declaredAt: file ? relative(root, file) : entry.entryFile,
|
|
294
598
|
declaredIn: file,
|
|
295
|
-
deprecated: isDeprecated(
|
|
296
|
-
deprecatedReason: deprecationReason(
|
|
599
|
+
deprecated: isDeprecated(tags),
|
|
600
|
+
deprecatedReason: deprecationReason(tags),
|
|
297
601
|
summary: summaryOf(docs),
|
|
298
602
|
docs,
|
|
603
|
+
signature: type
|
|
604
|
+
? signatureOf(name, type, kind, location, checker)
|
|
605
|
+
: undefined,
|
|
606
|
+
members: members.length > 0 ? members : undefined,
|
|
607
|
+
examples: examples.length > 0 ? examples : undefined,
|
|
608
|
+
status: errorStatuses.get(name),
|
|
299
609
|
});
|
|
300
610
|
}
|
|
301
611
|
return { ...entry, symbols };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { getCLIVersion } from '../../utils/get-cli-version.js';
|
|
5
5
|
import { buildSurfaceDoc } from './build-surface-doc.js';
|
|
6
|
+
import { collectSnippets } from './collect-snippets.js';
|
|
6
7
|
/**
|
|
7
8
|
* Build-time entry point: `@pikku/cli` ships the surface doc, so it is computed
|
|
8
9
|
* once when the CLI is built rather than by every project that consumes it.
|
|
9
10
|
* `build.sh` generates the two projects it reads — one application, one addon —
|
|
10
11
|
* and points this at them.
|
|
11
12
|
*/
|
|
12
|
-
const usage = `Usage: generate-surface-doc --app <dir> --addon <dir> --out <file
|
|
13
|
+
const usage = `Usage: generate-surface-doc --app <dir> --addon <dir> --snippets <dir> --out <file> [--snippets-out <file>] [--snippets-meta-out <file>]`;
|
|
13
14
|
const parseArgs = (argv) => {
|
|
14
15
|
const parsed = {};
|
|
15
16
|
for (let index = 0; index < argv.length; index += 2) {
|
|
@@ -22,19 +23,53 @@ const parseArgs = (argv) => {
|
|
|
22
23
|
}
|
|
23
24
|
return parsed;
|
|
24
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* The one region a marker cannot reach: `pikku.config.json` is parsed as strict
|
|
28
|
+
* JSON, so the scenario environments a doc has to show cannot be fenced in
|
|
29
|
+
* place. Read straight off the project's own config instead of being retyped.
|
|
30
|
+
*/
|
|
31
|
+
const addScenarioConfig = async (projectDir, snippets, origins) => {
|
|
32
|
+
try {
|
|
33
|
+
const config = JSON.parse(await readFile(join(projectDir, 'pikku.config.json'), 'utf8'));
|
|
34
|
+
if (!config.scenarios)
|
|
35
|
+
return;
|
|
36
|
+
snippets.set('scenarioConfig', JSON.stringify({ scenarios: config.scenarios }, null, 2));
|
|
37
|
+
origins.set('scenarioConfig', 'pikku.config.json');
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
25
43
|
const main = async (argv) => {
|
|
26
44
|
const args = parseArgs(argv);
|
|
27
|
-
const { app, addon, out } = args;
|
|
28
|
-
|
|
45
|
+
const { app, addon, out, snippets: snippetsDir } = args;
|
|
46
|
+
const snippetsOut = args['snippets-out'];
|
|
47
|
+
if (!app || !addon || !out || !snippetsDir)
|
|
29
48
|
throw new Error(usage);
|
|
49
|
+
const origins = new Map();
|
|
50
|
+
const snippets = await collectSnippets(resolve(snippetsDir), new Map(), origins);
|
|
51
|
+
await addScenarioConfig(resolve(snippetsDir), snippets, origins);
|
|
30
52
|
const doc = await buildSurfaceDoc({
|
|
31
53
|
version: getCLIVersion(),
|
|
32
54
|
app: { projectDir: app },
|
|
33
55
|
addon: { projectDir: addon },
|
|
56
|
+
snippets,
|
|
34
57
|
});
|
|
35
58
|
const outFile = resolve(out);
|
|
36
59
|
await mkdir(dirname(outFile), { recursive: true });
|
|
37
60
|
await writeFile(outFile, `${JSON.stringify(doc, null, 2)}\n`, 'utf8');
|
|
61
|
+
if (snippetsOut) {
|
|
62
|
+
const snippetsFile = resolve(snippetsOut);
|
|
63
|
+
await mkdir(dirname(snippetsFile), { recursive: true });
|
|
64
|
+
await writeFile(snippetsFile, `${JSON.stringify(Object.fromEntries([...snippets].sort()), null, 2)}\n`, 'utf8');
|
|
65
|
+
process.stdout.write(` snippets: ${snippets.size}\n`);
|
|
66
|
+
}
|
|
67
|
+
const metaOut = args['snippets-meta-out'];
|
|
68
|
+
if (metaOut) {
|
|
69
|
+
const metaFile = resolve(metaOut);
|
|
70
|
+
await mkdir(dirname(metaFile), { recursive: true });
|
|
71
|
+
await writeFile(metaFile, `${JSON.stringify(Object.fromEntries([...origins].sort()), null, 2)}\n`, 'utf8');
|
|
72
|
+
}
|
|
38
73
|
for (const entryPoint of doc.entryPoints) {
|
|
39
74
|
const symbols = entryPoint.leaves.reduce((total, leaf) => total + leaf.symbols.length, 0);
|
|
40
75
|
process.stdout.write(` ${entryPoint.id}: ${entryPoint.leaves.length} leaves, ${symbols} exports\n`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SurfaceDoc, SurfaceEntryPointId } from './surface-doc.types.js';
|
|
2
|
+
export type RenderSurfaceDocOptions = {
|
|
3
|
+
target?: string;
|
|
4
|
+
ai?: boolean;
|
|
5
|
+
entryPoint?: SurfaceEntryPointId;
|
|
6
|
+
};
|
|
7
|
+
export declare class UnknownSurfaceTargetError extends Error {
|
|
8
|
+
readonly target: string;
|
|
9
|
+
readonly suggestions: string[];
|
|
10
|
+
constructor(target: string, suggestions: string[]);
|
|
11
|
+
}
|
|
12
|
+
export declare const renderSurfaceDoc: (doc: SurfaceDoc, { target, ai, entryPoint }?: RenderSurfaceDocOptions) => string;
|