@credibledata/cred-cli 0.0.103 → 0.0.105
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/README.md +106 -1
- package/dist/agent-contract.spec.js +548 -0
- package/dist/agent-contract.spec.js.map +1 -0
- package/dist/browser.js +72 -0
- package/dist/browser.js.map +1 -0
- package/dist/browser.spec.js +125 -0
- package/dist/browser.spec.js.map +1 -0
- package/dist/client/api.js +4137 -1159
- package/dist/client/api.js.map +1 -1
- package/dist/client-codeassist/api.js +476 -0
- package/dist/client-codeassist/api.js.map +1 -0
- package/dist/client-codeassist/base.js +69 -0
- package/dist/client-codeassist/base.js.map +1 -0
- package/dist/client-codeassist/common.js +162 -0
- package/dist/client-codeassist/common.js.map +1 -0
- package/dist/client-codeassist/configuration.js +44 -0
- package/dist/client-codeassist/configuration.js.map +1 -0
- package/dist/client-codeassist/index.js +32 -0
- package/dist/client-codeassist/index.js.map +1 -0
- package/dist/clientconfiguration.js +17 -289
- package/dist/clientconfiguration.js.map +1 -1
- package/dist/clientconfiguration.spec.js +35 -96
- package/dist/clientconfiguration.spec.js.map +1 -1
- package/dist/commands/add.js +103 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/add.spec.js +113 -0
- package/dist/commands/add.spec.js.map +1 -0
- package/dist/commands/connection/createconnections.js +104 -7
- package/dist/commands/connection/createconnections.js.map +1 -1
- package/dist/commands/connection/createconnections.spec.js +35 -1
- package/dist/commands/connection/createconnections.spec.js.map +1 -1
- package/dist/commands/connection/deleteconnection.js +4 -2
- package/dist/commands/connection/deleteconnection.js.map +1 -1
- package/dist/commands/connection/deleteconnection.spec.js +6 -1
- package/dist/commands/connection/deleteconnection.spec.js.map +1 -1
- package/dist/commands/connection/listconnections.js +2 -0
- package/dist/commands/connection/listconnections.js.map +1 -1
- package/dist/commands/connection/updateconnection.js +365 -0
- package/dist/commands/connection/updateconnection.js.map +1 -0
- package/dist/commands/connection/updateconnection.spec.js +625 -0
- package/dist/commands/connection/updateconnection.spec.js.map +1 -0
- package/dist/commands/database/createdatabase.js +52 -0
- package/dist/commands/database/createdatabase.js.map +1 -0
- package/dist/commands/database/database.spec.js +267 -0
- package/dist/commands/database/database.spec.js.map +1 -0
- package/dist/commands/database/deletedatabase.js +91 -0
- package/dist/commands/database/deletedatabase.js.map +1 -0
- package/dist/commands/database/getdatabase.js +97 -0
- package/dist/commands/database/getdatabase.js.map +1 -0
- package/dist/commands/database/listdatabases.js +36 -0
- package/dist/commands/database/listdatabases.js.map +1 -0
- package/dist/commands/database/shared.js +125 -0
- package/dist/commands/database/shared.js.map +1 -0
- package/dist/commands/database/shared.spec.js +109 -0
- package/dist/commands/database/shared.spec.js.map +1 -0
- package/dist/commands/database/updatedatabase.js +39 -0
- package/dist/commands/database/updatedatabase.js.map +1 -0
- package/dist/commands/environment/createenvironment.js +59 -28
- package/dist/commands/environment/createenvironment.js.map +1 -1
- package/dist/commands/environment/createenvironment.spec.js +29 -0
- package/dist/commands/environment/createenvironment.spec.js.map +1 -1
- package/dist/commands/environment/deleteenvironment.js +3 -2
- package/dist/commands/environment/deleteenvironment.js.map +1 -1
- package/dist/commands/environment/deleteenvironment.spec.js +5 -1
- package/dist/commands/environment/deleteenvironment.spec.js.map +1 -1
- package/dist/commands/environment/getenvironment.js +1 -0
- package/dist/commands/environment/getenvironment.js.map +1 -1
- package/dist/commands/environment/listenvironments.js +40 -8
- package/dist/commands/environment/listenvironments.js.map +1 -1
- package/dist/commands/environment/listenvironments.spec.js +41 -2
- package/dist/commands/environment/listenvironments.spec.js.map +1 -1
- package/dist/commands/environment/setenvironment.js +145 -6
- package/dist/commands/environment/setenvironment.js.map +1 -1
- package/dist/commands/environment/setenvironment.spec.js +256 -8
- package/dist/commands/environment/setenvironment.spec.js.map +1 -1
- package/dist/commands/environment/updateenvironment.js +12 -8
- package/dist/commands/environment/updateenvironment.js.map +1 -1
- package/dist/commands/environment/updateenvironment.spec.js +36 -2
- package/dist/commands/environment/updateenvironment.spec.js.map +1 -1
- package/dist/commands/get.js +64 -1
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/group/addmember.js +3 -1
- package/dist/commands/group/addmember.js.map +1 -1
- package/dist/commands/group/addmember.spec.js +7 -2
- package/dist/commands/group/addmember.spec.js.map +1 -1
- package/dist/commands/group/creategroup.js +2 -0
- package/dist/commands/group/creategroup.js.map +1 -1
- package/dist/commands/group/deletegroup.js +3 -1
- package/dist/commands/group/deletegroup.js.map +1 -1
- package/dist/commands/group/deletegroup.spec.js +7 -1
- package/dist/commands/group/deletegroup.spec.js.map +1 -1
- package/dist/commands/group/getgroup.js +2 -0
- package/dist/commands/group/getgroup.js.map +1 -1
- package/dist/commands/group/listgroups.js +2 -0
- package/dist/commands/group/listgroups.js.map +1 -1
- package/dist/commands/group/removemember.js +3 -1
- package/dist/commands/group/removemember.js.map +1 -1
- package/dist/commands/group/removemember.spec.js +7 -2
- package/dist/commands/group/removemember.spec.js.map +1 -1
- package/dist/commands/groupaccesstoken/deleteToken.js +2 -1
- package/dist/commands/groupaccesstoken/deleteToken.js.map +1 -1
- package/dist/commands/groupaccesstoken/groupContainer.js +2 -0
- package/dist/commands/groupaccesstoken/groupContainer.js.map +1 -1
- package/dist/commands/list.js +24 -4
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/materialization/cancelrun.js +3 -1
- package/dist/commands/materialization/cancelrun.js.map +1 -1
- package/dist/commands/materialization/getindex.js +2 -0
- package/dist/commands/materialization/getindex.js.map +1 -1
- package/dist/commands/materialization/getmaterialization.js +2 -0
- package/dist/commands/materialization/getmaterialization.js.map +1 -1
- package/dist/commands/materialization/getpreaggregate.js +2 -0
- package/dist/commands/materialization/getpreaggregate.js.map +1 -1
- package/dist/commands/materialization/getrun.js +2 -0
- package/dist/commands/materialization/getrun.js.map +1 -1
- package/dist/commands/materialization/listindexes.js +2 -0
- package/dist/commands/materialization/listindexes.js.map +1 -1
- package/dist/commands/materialization/listmaterializations.js +2 -0
- package/dist/commands/materialization/listmaterializations.js.map +1 -1
- package/dist/commands/materialization/listpreaggregates.js +2 -0
- package/dist/commands/materialization/listpreaggregates.js.map +1 -1
- package/dist/commands/materialization/listruns.js +3 -1
- package/dist/commands/materialization/listruns.js.map +1 -1
- package/dist/commands/materialization/rerun.js +3 -1
- package/dist/commands/materialization/rerun.js.map +1 -1
- package/dist/commands/misc/inquirerHost.js +87 -0
- package/dist/commands/misc/inquirerHost.js.map +1 -0
- package/dist/commands/misc/inquirerHost.spec.js +91 -0
- package/dist/commands/misc/inquirerHost.spec.js.map +1 -0
- package/dist/commands/misc/login.js +348 -58
- package/dist/commands/misc/login.js.map +1 -1
- package/dist/commands/misc/login.spec.js +525 -7
- package/dist/commands/misc/login.spec.js.map +1 -1
- package/dist/commands/misc/logout.js +26 -3
- package/dist/commands/misc/logout.js.map +1 -1
- package/dist/commands/misc/logout.spec.js +52 -12
- package/dist/commands/misc/logout.spec.js.map +1 -1
- package/dist/commands/misc/resolveLoginTarget.spec.js +90 -0
- package/dist/commands/misc/resolveLoginTarget.spec.js.map +1 -0
- package/dist/commands/misc/scope.spec.js +108 -0
- package/dist/commands/misc/scope.spec.js.map +1 -0
- package/dist/commands/misc/set-access-token.js +1 -1
- package/dist/commands/misc/set-access-token.js.map +1 -1
- package/dist/commands/misc/set-access-token.spec.js +13 -2
- package/dist/commands/misc/set-access-token.spec.js.map +1 -1
- package/dist/commands/misc/setup.js +819 -0
- package/dist/commands/misc/setup.js.map +1 -0
- package/dist/commands/misc/setup.spec.js +783 -0
- package/dist/commands/misc/setup.spec.js.map +1 -0
- package/dist/commands/misc/status.js +168 -0
- package/dist/commands/misc/status.js.map +1 -0
- package/dist/commands/misc/status.spec.js +301 -0
- package/dist/commands/misc/status.spec.js.map +1 -0
- package/dist/commands/misc/token.js +57 -0
- package/dist/commands/misc/token.js.map +1 -0
- package/dist/commands/misc/token.spec.js +92 -0
- package/dist/commands/misc/token.spec.js.map +1 -0
- package/dist/commands/package/deletepackage.js +4 -2
- package/dist/commands/package/deletepackage.js.map +1 -1
- package/dist/commands/package/deletepackage.spec.js +7 -1
- package/dist/commands/package/deletepackage.spec.js.map +1 -1
- package/dist/commands/package/getpackage.js +142 -0
- package/dist/commands/package/getpackage.js.map +1 -0
- package/dist/commands/package/getpackage.spec.js +246 -0
- package/dist/commands/package/getpackage.spec.js.map +1 -0
- package/dist/commands/package/listpackages.js +2 -0
- package/dist/commands/package/listpackages.js.map +1 -1
- package/dist/commands/package/publish.archive.spec.js +570 -0
- package/dist/commands/package/publish.archive.spec.js.map +1 -0
- package/dist/commands/package/publish.js +780 -49
- package/dist/commands/package/publish.js.map +1 -1
- package/dist/commands/package/publish.spec.js +451 -8
- package/dist/commands/package/publish.spec.js.map +1 -1
- package/dist/commands/package/updatepackage.js +22 -19
- package/dist/commands/package/updatepackage.js.map +1 -1
- package/dist/commands/package/updatepackage.spec.js +36 -1
- package/dist/commands/package/updatepackage.spec.js.map +1 -1
- package/dist/commands/permission/createpermission.js +3 -1
- package/dist/commands/permission/createpermission.js.map +1 -1
- package/dist/commands/permission/deletepermission.js +6 -3
- package/dist/commands/permission/deletepermission.js.map +1 -1
- package/dist/commands/permission/getpermission.js +2 -0
- package/dist/commands/permission/getpermission.js.map +1 -1
- package/dist/commands/permission/listpermissions.js +2 -0
- package/dist/commands/permission/listpermissions.js.map +1 -1
- package/dist/commands/rm.js +21 -0
- package/dist/commands/rm.js.map +1 -1
- package/dist/commands/set.js +40 -6
- package/dist/commands/set.js.map +1 -1
- package/dist/commands/set.spec.js +123 -0
- package/dist/commands/set.spec.js.map +1 -0
- package/dist/commands/table/addtable.js +155 -0
- package/dist/commands/table/addtable.js.map +1 -0
- package/dist/commands/table/deletetable.js +45 -0
- package/dist/commands/table/deletetable.js.map +1 -0
- package/dist/commands/table/gettable.js +32 -0
- package/dist/commands/table/gettable.js.map +1 -0
- package/dist/commands/table/listtables.js +36 -0
- package/dist/commands/table/listtables.js.map +1 -0
- package/dist/commands/table/table.spec.js +304 -0
- package/dist/commands/table/table.spec.js.map +1 -0
- package/dist/commands/table/tablefile.js +195 -0
- package/dist/commands/table/tablefile.js.map +1 -0
- package/dist/commands/table/tablefile.spec.js +158 -0
- package/dist/commands/table/tablefile.spec.js.map +1 -0
- package/dist/commands/update.js +21 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/version/archive-unarchive-version.js +4 -2
- package/dist/commands/version/archive-unarchive-version.js.map +1 -1
- package/dist/commands/version/archive-unarchive-version.spec.js +6 -1
- package/dist/commands/version/archive-unarchive-version.spec.js.map +1 -1
- package/dist/commands/version/listversions.js +2 -0
- package/dist/commands/version/listversions.js.map +1 -1
- package/dist/common/UserGroupId.js +9 -4
- package/dist/common/UserGroupId.js.map +1 -1
- package/dist/common/UserGroupId.spec.js +5 -0
- package/dist/common/UserGroupId.spec.js.map +1 -1
- package/dist/constants.js +37 -143
- package/dist/constants.js.map +1 -1
- package/dist/index.js +487 -90
- package/dist/index.js.map +1 -1
- package/dist/logger.js +42 -9
- package/dist/logger.js.map +1 -1
- package/dist/session.js +56 -0
- package/dist/session.js.map +1 -0
- package/dist/session.spec.js +103 -0
- package/dist/session.spec.js.map +1 -0
- package/dist/setup-core/briefing.js +176 -0
- package/dist/setup-core/briefing.js.map +1 -0
- package/dist/setup-core/credstore.js +415 -0
- package/dist/setup-core/credstore.js.map +1 -0
- package/dist/setup-core/credstore.spec.js +238 -0
- package/dist/setup-core/credstore.spec.js.map +1 -0
- package/dist/setup-core/environments.js +267 -0
- package/dist/setup-core/environments.js.map +1 -0
- package/dist/setup-core/flow.e2e.js +165 -0
- package/dist/setup-core/flow.e2e.js.map +1 -0
- package/dist/setup-core/flow.js +765 -0
- package/dist/setup-core/flow.js.map +1 -0
- package/dist/setup-core/flow.spec.js +1348 -0
- package/dist/setup-core/flow.spec.js.map +1 -0
- package/dist/setup-core/folderconfig.js +283 -0
- package/dist/setup-core/folderconfig.js.map +1 -0
- package/dist/setup-core/git.js +97 -0
- package/dist/setup-core/git.js.map +1 -0
- package/dist/setup-core/host.js +77 -0
- package/dist/setup-core/host.js.map +1 -0
- package/dist/setup-core/importconnections.js +470 -0
- package/dist/setup-core/importconnections.js.map +1 -0
- package/dist/setup-core/importconnections.spec.js +594 -0
- package/dist/setup-core/importconnections.spec.js.map +1 -0
- package/dist/setup-core/liveness.js +94 -0
- package/dist/setup-core/liveness.js.map +1 -0
- package/dist/setup-core/liveness.spec.js +59 -0
- package/dist/setup-core/liveness.spec.js.map +1 -0
- package/dist/setup-core/localpublisherconfig.js +26 -0
- package/dist/setup-core/localpublisherconfig.js.map +1 -0
- package/dist/setup-core/localpublisherconfig.spec.js +29 -0
- package/dist/setup-core/localpublisherconfig.spec.js.map +1 -0
- package/dist/setup-core/mcpconfig.js +198 -0
- package/dist/setup-core/mcpconfig.js.map +1 -0
- package/dist/setup-core/mcpconfig.spec.js +205 -0
- package/dist/setup-core/mcpconfig.spec.js.map +1 -0
- package/dist/setup-core/packagemanifest.js +55 -0
- package/dist/setup-core/packagemanifest.js.map +1 -0
- package/dist/setup-core/ports.js +182 -0
- package/dist/setup-core/ports.js.map +1 -0
- package/dist/setup-core/ports.spec.js +173 -0
- package/dist/setup-core/ports.spec.js.map +1 -0
- package/dist/setup-core/publisherconfig.js +268 -0
- package/dist/setup-core/publisherconfig.js.map +1 -0
- package/dist/setup-core/publisherconfig.oracle.js +166 -0
- package/dist/setup-core/publisherconfig.oracle.js.map +1 -0
- package/dist/setup-core/publisherconfig.spec.js +277 -0
- package/dist/setup-core/publisherconfig.spec.js.map +1 -0
- package/dist/setup-core/publisherversion.js +26 -0
- package/dist/setup-core/publisherversion.js.map +1 -0
- package/dist/setup-core/readiness.spec.js +161 -0
- package/dist/setup-core/readiness.spec.js.map +1 -0
- package/dist/setup-core/readylines.js +169 -0
- package/dist/setup-core/readylines.js.map +1 -0
- package/dist/setup-core/readylines.spec.js +70 -0
- package/dist/setup-core/readylines.spec.js.map +1 -0
- package/dist/setup-core/refresh.js +348 -0
- package/dist/setup-core/refresh.js.map +1 -0
- package/dist/setup-core/refresh.spec.js +501 -0
- package/dist/setup-core/refresh.spec.js.map +1 -0
- package/dist/setup-core/skills.js +279 -0
- package/dist/setup-core/skills.js.map +1 -0
- package/dist/setup-core/skills.spec.js +334 -0
- package/dist/setup-core/skills.spec.js.map +1 -0
- package/dist/setup-core/supervisor.js +879 -0
- package/dist/setup-core/supervisor.js.map +1 -0
- package/dist/setup-core/supervisor.spec.js +833 -0
- package/dist/setup-core/supervisor.spec.js.map +1 -0
- package/dist/setup-core/writefile.js +61 -0
- package/dist/setup-core/writefile.js.map +1 -0
- package/dist/setup-core/writefile.spec.js +68 -0
- package/dist/setup-core/writefile.spec.js.map +1 -0
- package/dist/utils.js +409 -3
- package/dist/utils.js.map +1 -1
- package/dist/utils.spec.js +373 -2
- package/dist/utils.spec.js.map +1 -1
- package/dist/versioncheck-refresh.js +18 -0
- package/dist/versioncheck-refresh.js.map +1 -0
- package/dist/versioncheck.js +324 -0
- package/dist/versioncheck.js.map +1 -0
- package/dist/versioncheck.spec.js +587 -0
- package/dist/versioncheck.spec.js.map +1 -0
- package/node_modules/@credibledata/cli-auth/dist/index.d.ts +86 -0
- package/node_modules/@credibledata/cli-auth/dist/index.js +102 -0
- package/node_modules/@credibledata/cli-auth/package.json +19 -0
- package/package.json +18 -6
- package/.github/workflows/build.yml +0 -23
- package/.mocharc.json +0 -10
- package/.prettierignore +0 -2
- package/.prettierrc +0 -4
- package/README-DEV.md +0 -40
- package/coverage/coverage-summary.json +0 -40
- package/coverage/tmp/coverage-2152-1789496974457-0.json +0 -1
- package/coverage/tmp/coverage-2153-1789496954404-0.json +0 -1
- package/docker/Dockerfile.ci +0 -18
- package/docker-compose.yml +0 -18
- package/eslint.config.mjs +0 -45
- package/generate-client.sh +0 -27
- package/mocha.setup.ts +0 -4
- package/openapitools.json +0 -10
- package/src/client/.openapi-generator/FILES +0 -9
- package/src/client/.openapi-generator/VERSION +0 -1
- package/src/client/.openapi-generator-ignore +0 -23
- package/src/client/api.ts +0 -15999
- package/src/client/base.ts +0 -86
- package/src/client/common.ts +0 -150
- package/src/client/configuration.ts +0 -110
- package/src/client/git_push.sh +0 -57
- package/src/client/index.ts +0 -18
- package/src/clientconfiguration.spec.ts +0 -615
- package/src/clientconfiguration.ts +0 -364
- package/src/commands/add.ts +0 -191
- package/src/commands/connection/createconnections.spec.ts +0 -413
- package/src/commands/connection/createconnections.ts +0 -109
- package/src/commands/connection/deleteconnection.spec.ts +0 -189
- package/src/commands/connection/deleteconnection.ts +0 -57
- package/src/commands/connection/listconnections.spec.ts +0 -132
- package/src/commands/connection/listconnections.ts +0 -58
- package/src/commands/environment/createenvironment.spec.ts +0 -249
- package/src/commands/environment/createenvironment.ts +0 -73
- package/src/commands/environment/deleteenvironment.spec.ts +0 -152
- package/src/commands/environment/deleteenvironment.ts +0 -48
- package/src/commands/environment/getenvironment.spec.ts +0 -110
- package/src/commands/environment/getenvironment.ts +0 -43
- package/src/commands/environment/listenvironments.spec.ts +0 -123
- package/src/commands/environment/listenvironments.ts +0 -67
- package/src/commands/environment/setenvironment.spec.ts +0 -63
- package/src/commands/environment/setenvironment.ts +0 -14
- package/src/commands/environment/updateenvironment.spec.ts +0 -386
- package/src/commands/environment/updateenvironment.ts +0 -168
- package/src/commands/get.ts +0 -153
- package/src/commands/group/addmember.spec.ts +0 -257
- package/src/commands/group/addmember.ts +0 -85
- package/src/commands/group/creategroup.spec.ts +0 -146
- package/src/commands/group/creategroup.ts +0 -54
- package/src/commands/group/deletegroup.spec.ts +0 -120
- package/src/commands/group/deletegroup.ts +0 -45
- package/src/commands/group/getgroup.spec.ts +0 -129
- package/src/commands/group/getgroup.ts +0 -47
- package/src/commands/group/listgroups.spec.ts +0 -137
- package/src/commands/group/listgroups.ts +0 -45
- package/src/commands/group/removemember.spec.ts +0 -224
- package/src/commands/group/removemember.ts +0 -75
- package/src/commands/groupaccesstoken/createToken.spec.ts +0 -211
- package/src/commands/groupaccesstoken/createToken.ts +0 -72
- package/src/commands/groupaccesstoken/deleteToken.spec.ts +0 -147
- package/src/commands/groupaccesstoken/deleteToken.ts +0 -29
- package/src/commands/groupaccesstoken/groupContainer.ts +0 -83
- package/src/commands/groupaccesstoken/listTokens.spec.ts +0 -147
- package/src/commands/groupaccesstoken/listTokens.ts +0 -29
- package/src/commands/legacy.ts +0 -5
- package/src/commands/list.ts +0 -326
- package/src/commands/materialization/cancelrun.ts +0 -70
- package/src/commands/materialization/getindex.ts +0 -55
- package/src/commands/materialization/getmaterialization.ts +0 -57
- package/src/commands/materialization/getpreaggregate.ts +0 -58
- package/src/commands/materialization/getrun.ts +0 -55
- package/src/commands/materialization/listindexes.ts +0 -69
- package/src/commands/materialization/listmaterializations.ts +0 -53
- package/src/commands/materialization/listpreaggregates.ts +0 -74
- package/src/commands/materialization/listruns.ts +0 -77
- package/src/commands/materialization/rerun.ts +0 -123
- package/src/commands/misc/login.spec.ts +0 -371
- package/src/commands/misc/login.ts +0 -343
- package/src/commands/misc/logout.spec.ts +0 -32
- package/src/commands/misc/logout.ts +0 -9
- package/src/commands/misc/loopbackOAuth.ts +0 -127
- package/src/commands/misc/set-access-token.spec.ts +0 -95
- package/src/commands/misc/set-access-token.ts +0 -32
- package/src/commands/package/deletepackage.spec.ts +0 -164
- package/src/commands/package/deletepackage.ts +0 -58
- package/src/commands/package/listpackages.spec.ts +0 -163
- package/src/commands/package/listpackages.ts +0 -74
- package/src/commands/package/publish.spec.ts +0 -642
- package/src/commands/package/publish.ts +0 -236
- package/src/commands/package/updatepackage.spec.ts +0 -319
- package/src/commands/package/updatepackage.ts +0 -95
- package/src/commands/permission/createpermission.spec.ts +0 -507
- package/src/commands/permission/createpermission.ts +0 -181
- package/src/commands/permission/deletepermission.ts +0 -117
- package/src/commands/permission/getpermission.ts +0 -115
- package/src/commands/permission/listpermissions.ts +0 -101
- package/src/commands/permission/scope.ts +0 -180
- package/src/commands/rm.ts +0 -146
- package/src/commands/set.ts +0 -25
- package/src/commands/update.ts +0 -107
- package/src/commands/version/archive-unarchive-version.spec.ts +0 -456
- package/src/commands/version/archive-unarchive-version.ts +0 -108
- package/src/commands/version/listversions.spec.ts +0 -138
- package/src/commands/version/listversions.ts +0 -45
- package/src/common/UserGroupId.spec.ts +0 -115
- package/src/common/UserGroupId.ts +0 -137
- package/src/constants.spec.ts +0 -111
- package/src/constants.ts +0 -228
- package/src/index.ts +0 -378
- package/src/logger.spec.ts +0 -158
- package/src/logger.ts +0 -90
- package/src/polyfills/file.polyfill.ts +0 -6
- package/src/utils.spec.ts +0 -135
- package/src/utils.ts +0 -115
- package/src/validator.spec.ts +0 -51
- package/src/validator.ts +0 -44
- package/tsconfig.json +0 -17
|
@@ -12,20 +12,247 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CREDIGNORE_FILE = exports.DATA_FILE_SUFFIXES = exports.MAX_DATA_FILE_BYTES = exports.MAX_PACKAGE_BYTES = exports.PUBLISH_EXCLUDES = void 0;
|
|
16
|
+
exports.isDataFile = isDataFile;
|
|
17
|
+
exports.oversizedDataFiles = oversizedDataFiles;
|
|
18
|
+
exports.dataFileTooLargeMessage = dataFileTooLargeMessage;
|
|
19
|
+
exports.publishHelpText = publishHelpText;
|
|
15
20
|
exports.publish = publish;
|
|
21
|
+
exports.readCredignore = readCredignore;
|
|
22
|
+
exports.anyCase = anyCase;
|
|
23
|
+
exports.createPackageArchive = createPackageArchive;
|
|
24
|
+
exports.latestState = latestState;
|
|
25
|
+
exports.nextVersion = nextVersion;
|
|
16
26
|
require("../../polyfills/file.polyfill"); // Native support for File is only available on Node 19.2 or above
|
|
17
27
|
const archiver_1 = __importDefault(require("archiver"));
|
|
28
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
29
|
const crypto_1 = __importDefault(require("crypto"));
|
|
19
30
|
const fs_1 = __importDefault(require("fs"));
|
|
31
|
+
const os_1 = __importDefault(require("os"));
|
|
20
32
|
const path_1 = __importDefault(require("path"));
|
|
21
33
|
const api_1 = require("../../client/api");
|
|
22
34
|
const configuration_1 = require("../../client/configuration");
|
|
23
35
|
const clientconfiguration_1 = require("../../clientconfiguration");
|
|
24
36
|
const logger_1 = require("../../logger");
|
|
37
|
+
const constants_1 = require("../../constants");
|
|
25
38
|
const utils_1 = require("../../utils");
|
|
26
39
|
const validator_1 = require("../../validator");
|
|
40
|
+
const tablefile_1 = require("../table/tablefile");
|
|
27
41
|
const packagesApi = new api_1.PackagesApi(new configuration_1.Configuration());
|
|
28
42
|
const PACKAGE_MANIFEST_NAME = "publisher.json";
|
|
43
|
+
// Error codes returned by createOrUpdatePackage (409) when the package publishes from
|
|
44
|
+
// git and this upload did not come from the merge path — retrying can't fix it.
|
|
45
|
+
const GIT_BACKED_REFUSAL_CODES = new Set([
|
|
46
|
+
"GIT_BACKED_PACKAGE_REQUIRES_DRAFT",
|
|
47
|
+
"GIT_BACKED_PACKAGE_REQUIRES_GIT_VERSION",
|
|
48
|
+
]);
|
|
49
|
+
/** Print what to do instead of retrying a git-backed publish refusal. */
|
|
50
|
+
function printGitBackedRefusal(details, printedServerMessage) {
|
|
51
|
+
const haveCoordinates = (details === null || details === void 0 ? void 0 : details.gitRepositoryOwner) &&
|
|
52
|
+
(details === null || details === void 0 ? void 0 : details.gitRepositoryName) &&
|
|
53
|
+
(details === null || details === void 0 ? void 0 : details.gitBaseBranch);
|
|
54
|
+
// Without coordinates (an older server, or a repository record since cleared) the server's
|
|
55
|
+
// message is the only accurate next step, so no steps are guessed here.
|
|
56
|
+
const nextSteps = haveCoordinates
|
|
57
|
+
? "To publish this change:\n" +
|
|
58
|
+
` 1. git clone https://github.com/${details.gitRepositoryOwner}/${details.gitRepositoryName}\n` +
|
|
59
|
+
` 2. Create a branch and commit your change\n` +
|
|
60
|
+
` 3. Open a pull request into ${details.gitBaseBranch}\n` +
|
|
61
|
+
` 4. Merging the pull request publishes the new version\n\n` +
|
|
62
|
+
"Or edit this package as a draft in Credible and publish from there.\n\n"
|
|
63
|
+
: printedServerMessage
|
|
64
|
+
? "Follow the message above to publish it.\n\n"
|
|
65
|
+
: "Publish it through the environment's git repository, or ask an organization admin " +
|
|
66
|
+
"to check its git settings.\n\n";
|
|
67
|
+
logger_1.logger.error("Nothing was published — this package publishes from git, not from `cred publish`.\n\n" +
|
|
68
|
+
nextSteps +
|
|
69
|
+
"Do not retry this command — publishing again will not succeed.");
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* What never goes into the uploaded package.
|
|
73
|
+
*
|
|
74
|
+
* The first entry is a credential: after `cred init` adopts a local
|
|
75
|
+
* Publisher's connections, the user's original `publisher.config.json` — with
|
|
76
|
+
* the warehouse password in it — is still in the directory, and zipping the
|
|
77
|
+
* whole directory uploaded it into Credible's package store. `.mcp.json.bak` is
|
|
78
|
+
* the same class: `writeMcpConfig` leaves one behind when it could not parse an
|
|
79
|
+
* existing `.mcp.json` (numbered `.bak.1`, `.bak.2` once one exists), and that
|
|
80
|
+
* file is the user's own MCP config, headers and all. The rest are this developer's local wiring (the environment pin, agent
|
|
81
|
+
* config, skills), a checkout's `.git`, and dependencies: none of them is the
|
|
82
|
+
* model.
|
|
83
|
+
*
|
|
84
|
+
* **Every pattern is `**\/`-anchored**, and that is load-bearing rather than
|
|
85
|
+
* stylistic. A bare `publisher.config.json` is a minimatch pattern that matches
|
|
86
|
+
* only at the archive root, so a nested one — a monorepo with a second package
|
|
87
|
+
* below, a vendored example — was zipped and uploaded with the password in it,
|
|
88
|
+
* while `.git` and `node_modules` (already anchored) were correctly excluded at
|
|
89
|
+
* every depth. The exclusion that mattered most was the one anchored least.
|
|
90
|
+
*
|
|
91
|
+
* Fixed rather than read from `.gitignore`: a user without git, or with a
|
|
92
|
+
* `.gitignore` that lists their data files, would get the wrong package. And a
|
|
93
|
+
* list of what to leave out rather than of what to keep, because a model can
|
|
94
|
+
* read a data file of any extension, and a package missing its data is broken.
|
|
95
|
+
*
|
|
96
|
+
* Matched regardless of case (see {@link anyCase}): on macOS
|
|
97
|
+
* `Publisher.config.json` is the same file the Publisher reads. `.credignore`'s
|
|
98
|
+
* patterns are folded the same way, for the same reason: on macOS `secrets/`
|
|
99
|
+
* names the `Secrets/` folder, and git there (`core.ignorecase`) leaves it out.
|
|
100
|
+
*/
|
|
101
|
+
exports.PUBLISH_EXCLUDES = [
|
|
102
|
+
"**/publisher.config.json",
|
|
103
|
+
// Where credentials conventionally live. A package never needs one: the
|
|
104
|
+
// connections it queries through are created with `cred add connection`,
|
|
105
|
+
// not read from a file in the upload.
|
|
106
|
+
"**/.env",
|
|
107
|
+
"**/.env.*",
|
|
108
|
+
"**/*.pem",
|
|
109
|
+
"**/*.key",
|
|
110
|
+
"**/*.p12",
|
|
111
|
+
"**/*.pfx",
|
|
112
|
+
"**/*.p8", // Snowflake key-pair auth
|
|
113
|
+
"**/*credentials*.json",
|
|
114
|
+
"**/credentials", // ~/.aws/credentials, copied into a project
|
|
115
|
+
"**/.git-credentials",
|
|
116
|
+
// SSH private keys, by their default names. The `*` also drops the
|
|
117
|
+
// matching `.pub`, which is harmless but is not a model either.
|
|
118
|
+
"**/id_rsa*",
|
|
119
|
+
"**/id_ed25519*",
|
|
120
|
+
"**/id_ecdsa*",
|
|
121
|
+
"**/id_dsa*",
|
|
122
|
+
"**/profiles.yml", // dbt's warehouse logins
|
|
123
|
+
"**/*service-account*.json",
|
|
124
|
+
"**/*service_account*.json",
|
|
125
|
+
"**/.npmrc",
|
|
126
|
+
"**/.netrc",
|
|
127
|
+
"**/.pgpass",
|
|
128
|
+
"**/.credible/**",
|
|
129
|
+
"**/.git/**",
|
|
130
|
+
"**/node_modules/**",
|
|
131
|
+
"**/.mcp.json",
|
|
132
|
+
// `writeMcpConfig` numbers a second backup `.mcp.json.bak.1`, then `.2`.
|
|
133
|
+
"**/.mcp.json.bak*",
|
|
134
|
+
"**/CLAUDE.md",
|
|
135
|
+
"**/AGENTS.md",
|
|
136
|
+
"**/.claude/**",
|
|
137
|
+
"**/.agents/**",
|
|
138
|
+
"**/.cursor/**",
|
|
139
|
+
// The user's own exclusion list, at any depth: only the root one is read,
|
|
140
|
+
// and a nested one (a vendored example) is no more part of the model.
|
|
141
|
+
"**/.credignore",
|
|
142
|
+
"**/.credignore/**",
|
|
143
|
+
];
|
|
144
|
+
/**
|
|
145
|
+
* The largest package upload the deployed ingress accepts, in bytes.
|
|
146
|
+
*
|
|
147
|
+
* This is nginx's `proxy-body-size = "50m"` on the main ingress in
|
|
148
|
+
* infrastructure/modules/{gcp,aws}/nginx/ingress.tf, and nginx counts `m` as
|
|
149
|
+
* MiB. The controlplane's own multipart limit (1 GB) is far above it, so nginx
|
|
150
|
+
* is what refuses a large package, with a bare HTML 413 page that names no
|
|
151
|
+
* limit. Nothing reads this value from the server, so a change to the ingress
|
|
152
|
+
* must change it too.
|
|
153
|
+
*/
|
|
154
|
+
exports.MAX_PACKAGE_BYTES = 50 * 1024 * 1024;
|
|
155
|
+
/**
|
|
156
|
+
* A size in MiB to one decimal place. The limit is in MiB, so the size is too:
|
|
157
|
+
* printing "MB" would undercount by about 5%.
|
|
158
|
+
*
|
|
159
|
+
* A size other than the limit is rounded away from the limit, so it never
|
|
160
|
+
* prints as the limit itself. Plain rounding would print 49.99 MiB as "50 MiB"
|
|
161
|
+
* next to "the limit is 50 MiB".
|
|
162
|
+
*/
|
|
163
|
+
function mebibytes(bytes, limit = exports.MAX_PACKAGE_BYTES) {
|
|
164
|
+
const tenths = (bytes / (1024 * 1024)) * 10;
|
|
165
|
+
const rounded = bytes > limit
|
|
166
|
+
? Math.ceil(tenths)
|
|
167
|
+
: bytes < limit
|
|
168
|
+
? Math.floor(tenths)
|
|
169
|
+
: tenths;
|
|
170
|
+
return `${rounded / 10} MiB`;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The one message for a package that is too large, used both before the upload
|
|
174
|
+
* and when the server answers 413. Only a 413 reaches the second form: the zip fits under the limit, but the
|
|
175
|
+
* multipart request around it does not.
|
|
176
|
+
*/
|
|
177
|
+
function tooLargeMessage(bytes) {
|
|
178
|
+
const size = bytes > exports.MAX_PACKAGE_BYTES
|
|
179
|
+
? `Package is ${mebibytes(bytes)}; the limit is ${mebibytes(exports.MAX_PACKAGE_BYTES)}.`
|
|
180
|
+
: `Package is ${mebibytes(bytes)}, so close to the ${mebibytes(exports.MAX_PACKAGE_BYTES)} limit that the upload is over it.`;
|
|
181
|
+
return `${size} Nothing was published. Fix: remove or shrink large data files and publish again.`;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The largest data file a package should carry (database-design.md §12.2, D12).
|
|
185
|
+
* A package is models plus small seeds; anything bigger belongs in a database,
|
|
186
|
+
* where it is metered, shared by every package in the environment, and not
|
|
187
|
+
* copied to every worker. In phase 1 a larger file is warned about and still
|
|
188
|
+
* published; the refusal comes with the control plane's check (§12.8).
|
|
189
|
+
*/
|
|
190
|
+
exports.MAX_DATA_FILE_BYTES = 1024 * 1024;
|
|
191
|
+
/**
|
|
192
|
+
* What a model reads with `table('data/…')`: the formats the worker's DuckDB
|
|
193
|
+
* reads by suffix (draft-data-file-upload-design.md §5.1), plus `.xls`, which
|
|
194
|
+
* it does not read but which is a data file all the same. Longest first, so
|
|
195
|
+
* `.csv.gz` is one suffix rather than `.gz`.
|
|
196
|
+
*/
|
|
197
|
+
exports.DATA_FILE_SUFFIXES = [
|
|
198
|
+
".csv.gz",
|
|
199
|
+
".tsv.gz",
|
|
200
|
+
".parquet",
|
|
201
|
+
".ndjson",
|
|
202
|
+
".jsonl",
|
|
203
|
+
".json",
|
|
204
|
+
".xlsx",
|
|
205
|
+
".xls",
|
|
206
|
+
".csv",
|
|
207
|
+
".tsv",
|
|
208
|
+
];
|
|
209
|
+
/**
|
|
210
|
+
* Whether a package path is a data file. A `.json` at the package root is not:
|
|
211
|
+
* `publisher.json` lives there, and §5.1 reads JSON data only below it.
|
|
212
|
+
*/
|
|
213
|
+
function isDataFile(relative) {
|
|
214
|
+
const lower = relative.toLowerCase();
|
|
215
|
+
const suffix = exports.DATA_FILE_SUFFIXES.find((s) => lower.endsWith(s));
|
|
216
|
+
if (!suffix)
|
|
217
|
+
return false;
|
|
218
|
+
return !(suffix === ".json" && !relative.includes("/"));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The data files in `included` over {@link MAX_DATA_FILE_BYTES}. Read from the
|
|
222
|
+
* archive's own list, so a file `.credignore` or the fixed excludes left out
|
|
223
|
+
* can never trip it.
|
|
224
|
+
*/
|
|
225
|
+
function oversizedDataFiles(included, directory) {
|
|
226
|
+
return included
|
|
227
|
+
.filter(isDataFile)
|
|
228
|
+
.map((relative) => ({
|
|
229
|
+
path: relative,
|
|
230
|
+
bytes: fs_1.default.statSync(path_1.default.join(directory, relative)).size,
|
|
231
|
+
}))
|
|
232
|
+
.filter((file) => file.bytes > exports.MAX_DATA_FILE_BYTES);
|
|
233
|
+
}
|
|
234
|
+
/** A shell word for a path in a suggested command. */
|
|
235
|
+
function shellWord(value) {
|
|
236
|
+
return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value)
|
|
237
|
+
? value
|
|
238
|
+
: `'${value.replace(/'/g, "'\\''")}'`;
|
|
239
|
+
}
|
|
240
|
+
/** The warning for one oversized data file, naming the command that moves it into a database. */
|
|
241
|
+
function dataFileTooLargeMessage(file) {
|
|
242
|
+
const table = (0, tablefile_1.defaultTableName)(file.path);
|
|
243
|
+
const tooLarge = `${file.path} is ${mebibytes(file.bytes, exports.MAX_DATA_FILE_BYTES)}; a package data file should be at most ${mebibytes(exports.MAX_DATA_FILE_BYTES, exports.MAX_DATA_FILE_BYTES)}, and a later release will refuse a larger one.`;
|
|
244
|
+
// A database reads xlsx, not the older binary .xls.
|
|
245
|
+
if (file.path.toLowerCase().endsWith(".xls")) {
|
|
246
|
+
return `${tooLarge} Save it as .xlsx or .csv, then put it in a database with cred add table credible <file> and read it as credible.table('${table}').`;
|
|
247
|
+
}
|
|
248
|
+
return `${tooLarge} Put it in a database: cred add table credible ${shellWord(file.path)}, then read it as credible.table('${table}') (the credible-publish-local-data skill does this for every file).`;
|
|
249
|
+
}
|
|
250
|
+
/** Warn about each data file over the cap. The publish goes ahead. */
|
|
251
|
+
function warnOversizedDataFiles(included, directory) {
|
|
252
|
+
for (const file of oversizedDataFiles(included, directory)) {
|
|
253
|
+
logger_1.logger.warn(dataFileTooLargeMessage(file));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
29
256
|
/**
|
|
30
257
|
* Record a publish failure: log it (when the caller has a message of its own to give)
|
|
31
258
|
* and mark the process failed.
|
|
@@ -42,32 +269,101 @@ function failPublish(message) {
|
|
|
42
269
|
}
|
|
43
270
|
process.exitCode = 1;
|
|
44
271
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
272
|
+
/** The user's own exclusions, one pattern per line. See {@link readCredignore}. */
|
|
273
|
+
exports.CREDIGNORE_FILE = ".credignore";
|
|
274
|
+
/**
|
|
275
|
+
* The text after `cred publish --help`'s options. An agent learns the command
|
|
276
|
+
* from `--help` alone (the README does not ship with the CLI), so this states
|
|
277
|
+
* what it reads, what it leaves out, and what `--json` prints. The fixed list is
|
|
278
|
+
* rendered from {@link PUBLISH_EXCLUDES}, so it cannot fall behind it.
|
|
279
|
+
*/
|
|
280
|
+
function publishHelpText() {
|
|
281
|
+
const fixed = exports.PUBLISH_EXCLUDES.map((pattern) => pattern.replace(/^\*\*\//, "").replace(/\/\*\*$/, "/")).filter((name) => name !== exports.CREDIGNORE_FILE && name !== `${exports.CREDIGNORE_FILE}/`);
|
|
282
|
+
// Wrapped to the width of the prose around it.
|
|
283
|
+
const lines = [];
|
|
284
|
+
for (const name of fixed) {
|
|
285
|
+
const last = lines.length - 1;
|
|
286
|
+
if (last >= 0 && lines[last].length + name.length + 2 <= 72) {
|
|
287
|
+
lines[last] += `, ${name}`;
|
|
51
288
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
289
|
+
else {
|
|
290
|
+
if (last >= 0)
|
|
291
|
+
lines[last] += ",";
|
|
292
|
+
lines.push(name);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return `
|
|
296
|
+
Publishes the package in the current directory: ${PACKAGE_MANIFEST_NAME} there
|
|
297
|
+
must have "name" and "version", and every file under it is uploaded except:
|
|
298
|
+
|
|
299
|
+
Always left out, at any depth and in any case:
|
|
300
|
+
${lines.join("\n ")}.
|
|
301
|
+
${exports.CREDIGNORE_FILE}: one path or glob per line, beside ${PACKAGE_MANIFEST_NAME}.
|
|
302
|
+
\`notes.md\` or \`tests/\` match at any depth; \`/docs\` only at the top.
|
|
303
|
+
Matched in any case. Lines starting with \`#\` are comments. A \`!\` line
|
|
304
|
+
is ignored: it can leave files out, never put them back. Only the root
|
|
305
|
+
${exports.CREDIGNORE_FILE} is read, and none is uploaded.
|
|
306
|
+
|
|
307
|
+
A data file (csv, tsv, parquet, json, jsonl, ndjson, xlsx, xls) over 1 MiB is
|
|
308
|
+
published with a warning, and a later release will refuse it: put it in a
|
|
309
|
+
database with \`cred add table credible <file>\` and read it as
|
|
310
|
+
credible.table('<name>').
|
|
311
|
+
|
|
312
|
+
Check the list first with --dry-run (files on stdout, left-out ones on stderr).
|
|
313
|
+
|
|
314
|
+
--json prints one document: organization, environment, package, version,
|
|
315
|
+
url, latest ("now", "when-built" or "no"), latestVersion, excluded, and
|
|
316
|
+
response (the server's reply, whose "warnings" are only there).
|
|
317
|
+
With --dry-run it prints dryRun, package, version, included and excluded.
|
|
318
|
+
|
|
319
|
+
Exit 1 when the publish fails, including a version that is already published
|
|
320
|
+
(a version cannot be replaced: raise "version" in ${PACKAGE_MANIFEST_NAME}).
|
|
321
|
+
After a publish, \`cred get version <package> <version>\` shows whether it has
|
|
322
|
+
built, and \`cred get package <package>\` which version is latest.`;
|
|
323
|
+
}
|
|
324
|
+
function publish(controlPlane_1, replicationCount_1, debug_1, autoConfirm_1, setLatest_1) {
|
|
325
|
+
return __awaiter(this, arguments, void 0, function* (controlPlane, replicationCount, debug, autoConfirm, setLatest,
|
|
326
|
+
// A directory `cred init` pinned to a deployment publishes there: index.ts
|
|
327
|
+
// resolves the pin and passes the store scoped to it, so the token, the
|
|
328
|
+
// organization and the control-plane URL all come from one deployment.
|
|
329
|
+
clientConfig = new clientconfiguration_1.ClientConfiguration(),
|
|
330
|
+
// An organization and environment that override the store's, resolved by
|
|
331
|
+
// the caller so this function has one source for each.
|
|
332
|
+
identity = {}, options = {}) {
|
|
333
|
+
var _a, _b, _c, _d;
|
|
334
|
+
// A dry run skips the login checks: it uploads nothing, and a preview that
|
|
335
|
+
// demanded a login would be no preview for someone not yet signed in.
|
|
336
|
+
let organizationName = "";
|
|
337
|
+
let environmentName = "";
|
|
338
|
+
if (!options.dryRun) {
|
|
339
|
+
if (!clientConfig.doesConfigExists()) {
|
|
340
|
+
failPublish("Please, make sure that you are logged in");
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const tokenValidation = clientConfig.isTokenValid();
|
|
344
|
+
if (!tokenValidation.valid) {
|
|
345
|
+
failPublish(tokenValidation.reason ||
|
|
346
|
+
"Please, make sure that you are logged in");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
56
349
|
}
|
|
57
350
|
if (!(0, validator_1.validateManifest)()) {
|
|
58
351
|
// validateManifest logs its own reason; only the exit code is missing.
|
|
59
352
|
failPublish();
|
|
60
353
|
return;
|
|
61
354
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
355
|
+
if (!options.dryRun) {
|
|
356
|
+
environmentName = (_b = (_a = identity.environment) !== null && _a !== void 0 ? _a : clientConfig.getProject()) !== null && _b !== void 0 ? _b : "";
|
|
357
|
+
organizationName =
|
|
358
|
+
(_d = (_c = identity.organization) !== null && _c !== void 0 ? _c : clientConfig.getOrganization()) !== null && _d !== void 0 ? _d : "";
|
|
359
|
+
if (!organizationName) {
|
|
360
|
+
failPublish("Please, make sure that you are logged in");
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (!environmentName) {
|
|
364
|
+
failPublish("Please, make sure to set an environment");
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
71
367
|
}
|
|
72
368
|
if (!fs_1.default.existsSync(PACKAGE_MANIFEST_NAME)) {
|
|
73
369
|
failPublish(`Failed to publish the package. Could not find ${PACKAGE_MANIFEST_NAME}, please ensure you are in a directory containing ${PACKAGE_MANIFEST_NAME}`);
|
|
@@ -75,29 +371,346 @@ function publish(controlPlane, replicationCount, debug, autoConfirm, setLatest)
|
|
|
75
371
|
}
|
|
76
372
|
const packageManifestJson = fs_1.default.readFileSync(PACKAGE_MANIFEST_NAME);
|
|
77
373
|
const packageManifest = JSON.parse(packageManifestJson.toString());
|
|
374
|
+
// Checked here because the server does not check it for us: a manifest
|
|
375
|
+
// without a version was sent as `version undefined` and came back as an
|
|
376
|
+
// HTTP 500 with nothing to act on.
|
|
377
|
+
for (const field of ["name", "version"]) {
|
|
378
|
+
const value = packageManifest === null || packageManifest === void 0 ? void 0 : packageManifest[field];
|
|
379
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
380
|
+
failPublish(`${PACKAGE_MANIFEST_NAME} has no "${field}". Fix: add "${field}": ${field === "version" ? '"0.0.1"' : '"<package-name>"'} to it and publish again.`);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// The name the server publishes under, so the question asks about the
|
|
385
|
+
// package that will exist. It asked about the folder, which can differ.
|
|
386
|
+
const packageName = packageManifest.name;
|
|
387
|
+
const versionId = packageManifest.version;
|
|
78
388
|
const workingDirectory = process.cwd();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
389
|
+
let extraExcludes;
|
|
390
|
+
try {
|
|
391
|
+
extraExcludes = readCredignore(workingDirectory);
|
|
392
|
+
}
|
|
393
|
+
catch (e) {
|
|
394
|
+
failPublish(e.message);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
// A directory of its own, not `/tmp/<name>.zip`: two publishes of the same
|
|
398
|
+
// name at once wrote, uploaded and deleted one shared file. The zip's name
|
|
399
|
+
// is fixed, never the package's: publisher.json's "name" is not checked
|
|
400
|
+
// until the server sees it, and `"../x"` would write outside this directory.
|
|
401
|
+
const tmpDirectory = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "cred-publish-"));
|
|
402
|
+
const tmpPackagePath = path_1.default.join(tmpDirectory, "package.zip");
|
|
403
|
+
try {
|
|
404
|
+
if (options.dryRun) {
|
|
405
|
+
const { included, excluded, bytes } = yield createPackageArchive(tmpPackagePath, workingDirectory, extraExcludes);
|
|
406
|
+
reportDryRun(packageName, versionId, included, excluded, options);
|
|
407
|
+
// After the report, so the list shows what the manifest went with.
|
|
408
|
+
if (failIfNoManifest(included))
|
|
409
|
+
return;
|
|
410
|
+
// The same checks the real publish makes, so a preview of an
|
|
411
|
+
// oversized package says so instead of passing.
|
|
412
|
+
warnOversizedDataFiles(included, workingDirectory);
|
|
413
|
+
if (bytes > exports.MAX_PACKAGE_BYTES)
|
|
414
|
+
failPublish(tooLargeMessage(bytes));
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
// Built before the question, so the question can say what it is about to
|
|
418
|
+
// send. It was asked first, and what was left out printed only once the
|
|
419
|
+
// upload was under way.
|
|
420
|
+
const { included, excluded, bytes } = yield createPackageArchive(tmpPackagePath, workingDirectory, extraExcludes);
|
|
421
|
+
if (excluded.length) {
|
|
422
|
+
logger_1.logger.info(`Left out of the package: ${excluded.join(", ")}.`);
|
|
423
|
+
}
|
|
424
|
+
if (failIfNoManifest(included))
|
|
425
|
+
return;
|
|
426
|
+
// Before the question, on what the archive took: the per-file warning
|
|
427
|
+
// names the fix, and the zip total is a refusal, since the ingress would
|
|
428
|
+
// refuse the upload anyway.
|
|
429
|
+
warnOversizedDataFiles(included, workingDirectory);
|
|
430
|
+
if (bytes > exports.MAX_PACKAGE_BYTES) {
|
|
431
|
+
failPublish(tooLargeMessage(bytes));
|
|
85
432
|
return;
|
|
86
433
|
}
|
|
434
|
+
if (!autoConfirm) {
|
|
435
|
+
const confirmation = yield (0, utils_1.getConfirmation)(`Publish ${packageName} version ${versionId} (${included.length} file${included.length === 1 ? "" : "s"})? \`cred publish --dry-run\` lists the files.`, clientConfig);
|
|
436
|
+
if (!confirmation) {
|
|
437
|
+
logger_1.logger.info("Operation cancelled.");
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
yield pushTmpPackageToRemoteServer(clientConfig, controlPlane, replicationCount, organizationName, environmentName, tmpPackagePath, packageName, packageManifest.description, versionId, debug, setLatest, bytes, Object.assign(Object.assign({}, options), { excluded }));
|
|
442
|
+
}
|
|
443
|
+
finally {
|
|
444
|
+
removeTmpDirectory(tmpDirectory);
|
|
87
445
|
}
|
|
88
|
-
yield createTmpPackageArchive(tmpPackagePath);
|
|
89
|
-
yield pushTmpPackageToRemoteServer(clientConfig, controlPlane, replicationCount, organizationName, environmentName, tmpPackagePath, packageManifest.name, packageManifest.description, packageManifest.version, debug, setLatest);
|
|
90
|
-
yield removeTmpPackage(tmpPackagePath);
|
|
91
446
|
});
|
|
92
447
|
}
|
|
93
|
-
|
|
94
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Stop when the archive has no `publisher.json`. Only `.credignore` can cause
|
|
450
|
+
* it (the fixed list never names the manifest), and a zip without one was
|
|
451
|
+
* uploaded anyway. An empty archive is this case too.
|
|
452
|
+
*/
|
|
453
|
+
function failIfNoManifest(included) {
|
|
454
|
+
if (included.includes(PACKAGE_MANIFEST_NAME))
|
|
455
|
+
return false;
|
|
456
|
+
// On macOS `Publisher.json` passed the existence check above, but the
|
|
457
|
+
// server, on a case-sensitive filesystem, would not find a manifest.
|
|
458
|
+
const misnamed = included.find((file) => file.toLowerCase() === PACKAGE_MANIFEST_NAME.toLowerCase());
|
|
459
|
+
if (misnamed) {
|
|
460
|
+
failPublish(`The manifest is named ${misnamed}, and the server reads only ${PACKAGE_MANIFEST_NAME}. Fix: rename it to ${PACKAGE_MANIFEST_NAME}, and publish again.`);
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
failPublish(`${exports.CREDIGNORE_FILE} leaves out ${PACKAGE_MANIFEST_NAME}, so the package would have no manifest. Fix: remove the line in ${exports.CREDIGNORE_FILE} that matches ${PACKAGE_MANIFEST_NAME}, and publish again.`);
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
/** `--dry-run`'s report: the file list on stdout, the rest on stderr. */
|
|
467
|
+
function reportDryRun(packageName, versionId, included, excluded, options) {
|
|
468
|
+
if (options.json) {
|
|
469
|
+
console.log(JSON.stringify({
|
|
470
|
+
dryRun: true,
|
|
471
|
+
package: packageName,
|
|
472
|
+
version: versionId,
|
|
473
|
+
included,
|
|
474
|
+
excluded,
|
|
475
|
+
}, null, 2));
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
logger_1.logger.info(`Dry run: nothing was uploaded. ${packageName} version ${versionId} would upload ${included.length} file${included.length === 1 ? "" : "s"}:`);
|
|
479
|
+
for (const file of included)
|
|
480
|
+
console.log(file);
|
|
481
|
+
if (excluded.length) {
|
|
482
|
+
logger_1.logger.info(`Left out of the package: ${excluded.join(", ")}.`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Patterns from `.credignore` in the package directory, in the archive's glob
|
|
487
|
+
* form. Each line is a path or glob relative to that directory. A line with no
|
|
488
|
+
* `/` (other than a trailing one) matches at any depth, as in `.gitignore`;
|
|
489
|
+
* `tests/` or `tests` leaves the whole directory out. A leading `/` or `./`
|
|
490
|
+
* anchors a line to the package directory. Patterns match regardless of case,
|
|
491
|
+
* like the fixed list (see {@link anyCase}). On a case-sensitive filesystem that
|
|
492
|
+
* leaves out a little more than a line names (`secrets/` also takes
|
|
493
|
+
* `Secrets/`), which is the safe direction for a list of what not to upload.
|
|
494
|
+
*
|
|
495
|
+
* It only ever adds exclusions. A `!` line cannot put back a file the fixed
|
|
496
|
+
* list leaves out (a credential, the local wiring), so it is refused with a
|
|
497
|
+
* warning rather than half-honoured.
|
|
498
|
+
*
|
|
499
|
+
* Throws when a `.credignore` exists but cannot be read.
|
|
500
|
+
*/
|
|
501
|
+
function readCredignore(directory) {
|
|
502
|
+
let text;
|
|
503
|
+
try {
|
|
504
|
+
text = fs_1.default.readFileSync(path_1.default.join(directory, exports.CREDIGNORE_FILE)).toString();
|
|
505
|
+
}
|
|
506
|
+
catch (e) {
|
|
507
|
+
// No file is the usual case. Any other failure is not: publishing as if
|
|
508
|
+
// there were no file would upload what the user asked to leave out.
|
|
509
|
+
if (e.code === "ENOENT")
|
|
510
|
+
return [];
|
|
511
|
+
throw new Error(`Could not read ${exports.CREDIGNORE_FILE}: ${e.message}. Fix: make it readable, or delete it, and publish again.`);
|
|
512
|
+
}
|
|
513
|
+
const patterns = [];
|
|
514
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
515
|
+
const line = raw.trim();
|
|
516
|
+
if (!line || line.startsWith("#"))
|
|
517
|
+
continue;
|
|
518
|
+
if (line.startsWith("!")) {
|
|
519
|
+
logger_1.logger.warn(`${exports.CREDIGNORE_FILE}: ignored "${line}". It can only leave files out, not put them back.`);
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const anchored = /^\.?\//.test(line);
|
|
523
|
+
let body = line.replace(/^(?:\.?\/)+/, "").replace(/\/+$/, "");
|
|
524
|
+
if (!body)
|
|
525
|
+
continue;
|
|
526
|
+
// `/!x` names a file called `!x`. Unescaped, the glob would read it as
|
|
527
|
+
// a negation (which leaves out everything but x) or `#x` as a comment.
|
|
528
|
+
if (/^[!#]/.test(body))
|
|
529
|
+
body = `\\${body}`;
|
|
530
|
+
const base = anchored || body.includes("/") ? body : `**/${body}`;
|
|
531
|
+
// Both forms: `tests` may name a file or a directory.
|
|
532
|
+
patterns.push(base, `${base}/**`);
|
|
533
|
+
}
|
|
534
|
+
return patterns;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* `**\/.env` → `**\/.[eE][nN][vV]`. readdir-glob, which archiver matches ignore
|
|
538
|
+
* patterns with, builds its matchers with no case-insensitive option.
|
|
539
|
+
*
|
|
540
|
+
* Inside a bracket class a letter gains its other case in place (`[a-c]` →
|
|
541
|
+
* `[a-cA-C]`): wrapping it in a class of its own would close the outer one and
|
|
542
|
+
* change what the pattern means. A POSIX class (`[:alpha:]`) is copied as is.
|
|
543
|
+
*/
|
|
544
|
+
function anyCase(pattern) {
|
|
545
|
+
let out = "";
|
|
546
|
+
let i = 0;
|
|
547
|
+
while (i < pattern.length) {
|
|
548
|
+
const c = pattern[i];
|
|
549
|
+
if (c === "\\" && i + 1 < pattern.length) {
|
|
550
|
+
const escaped = pattern[i + 1];
|
|
551
|
+
out += isLetter(escaped) ? bothCases(escaped) : c + escaped;
|
|
552
|
+
i += 2;
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
const close = c === "[" ? classEnd(pattern, i) : -1;
|
|
556
|
+
if (close === -1) {
|
|
557
|
+
out += isLetter(c) ? bothCases(c) : c;
|
|
558
|
+
i += 1;
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
out += `[${foldClass(pattern.slice(i + 1, close))}]`;
|
|
562
|
+
i = close + 1;
|
|
563
|
+
}
|
|
564
|
+
return out;
|
|
565
|
+
}
|
|
566
|
+
function isLetter(c) {
|
|
567
|
+
return c !== undefined && /^[a-z]$/i.test(c);
|
|
568
|
+
}
|
|
569
|
+
function bothCases(letter) {
|
|
570
|
+
return `[${letter.toLowerCase()}${letter.toUpperCase()}]`;
|
|
571
|
+
}
|
|
572
|
+
function otherCase(letter) {
|
|
573
|
+
return letter === letter.toLowerCase()
|
|
574
|
+
? letter.toUpperCase()
|
|
575
|
+
: letter.toLowerCase();
|
|
576
|
+
}
|
|
577
|
+
/** The `]` that closes the class opened at `open`, or -1 when none does. */
|
|
578
|
+
function classEnd(pattern, open) {
|
|
579
|
+
let j = open + 1;
|
|
580
|
+
if (pattern[j] === "!" || pattern[j] === "^")
|
|
581
|
+
j += 1;
|
|
582
|
+
// A `]` first in a class is a literal, not its end.
|
|
583
|
+
if (pattern[j] === "]")
|
|
584
|
+
j += 1;
|
|
585
|
+
while (j < pattern.length) {
|
|
586
|
+
const posix = /^\[:[a-z]+:\]/.exec(pattern.slice(j));
|
|
587
|
+
if (posix) {
|
|
588
|
+
j += posix[0].length;
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
if (pattern[j] === "]")
|
|
592
|
+
return j;
|
|
593
|
+
j += 1;
|
|
594
|
+
}
|
|
595
|
+
return -1;
|
|
596
|
+
}
|
|
597
|
+
/** A bracket class's body, with the other case of each letter and range added. */
|
|
598
|
+
function foldClass(body) {
|
|
599
|
+
let kept = "";
|
|
600
|
+
let added = "";
|
|
601
|
+
let j = 0;
|
|
602
|
+
if (body[j] === "!" || body[j] === "^")
|
|
603
|
+
kept += body[j++];
|
|
604
|
+
if (body[j] === "]")
|
|
605
|
+
kept += body[j++];
|
|
606
|
+
while (j < body.length) {
|
|
607
|
+
const posix = /^\[:[a-z]+:\]/.exec(body.slice(j));
|
|
608
|
+
if (posix) {
|
|
609
|
+
kept += posix[0];
|
|
610
|
+
j += posix[0].length;
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
const from = body[j];
|
|
614
|
+
const to = body[j + 2];
|
|
615
|
+
if (body[j + 1] === "-" && to !== undefined) {
|
|
616
|
+
kept += `${from}-${to}`;
|
|
617
|
+
// `a-z` → also `A-Z`. A mixed range such as `A-z` is left alone.
|
|
618
|
+
if (isLetter(from) &&
|
|
619
|
+
isLetter(to) &&
|
|
620
|
+
(from === from.toLowerCase()) === (to === to.toLowerCase())) {
|
|
621
|
+
added += `${otherCase(from)}-${otherCase(to)}`;
|
|
622
|
+
}
|
|
623
|
+
j += 3;
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
kept += from;
|
|
627
|
+
if (isLetter(from))
|
|
628
|
+
added += otherCase(from);
|
|
629
|
+
j += 1;
|
|
630
|
+
}
|
|
631
|
+
return kept + added;
|
|
632
|
+
}
|
|
633
|
+
/** Every file under `directory`, as paths relative to it. Dotfiles included. */
|
|
634
|
+
function listFiles(directory, prefix = "") {
|
|
635
|
+
let entries;
|
|
636
|
+
try {
|
|
637
|
+
entries = fs_1.default.readdirSync(path_1.default.join(directory, prefix), {
|
|
638
|
+
withFileTypes: true,
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
catch (_a) {
|
|
642
|
+
return [];
|
|
643
|
+
}
|
|
644
|
+
const found = [];
|
|
645
|
+
for (const entry of entries) {
|
|
646
|
+
const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
647
|
+
if (entry.isDirectory()) {
|
|
648
|
+
found.push(...listFiles(directory, relative));
|
|
649
|
+
}
|
|
650
|
+
else if (entry.isFile()) {
|
|
651
|
+
found.push(relative);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return found;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Collapse excluded paths to the thing a user recognises.
|
|
658
|
+
*
|
|
659
|
+
* `.claude/skills/x/SKILL.md` and forty siblings are one fact — "your skills
|
|
660
|
+
* were not uploaded" — so a directory-style pattern reports its directory. A
|
|
661
|
+
* file-style pattern reports the path itself, at whatever depth it was found,
|
|
662
|
+
* because `sub/publisher.config.json` is exactly the case the user needs to see
|
|
663
|
+
* named rather than folded into `publisher.config.json`.
|
|
664
|
+
*/
|
|
665
|
+
function describeExclusions(paths) {
|
|
666
|
+
const named = new Set();
|
|
667
|
+
for (const relative of paths) {
|
|
668
|
+
// Only the fixed list's directory patterns fold: they are the ones a
|
|
669
|
+
// user did not write and would not recognise file by file.
|
|
670
|
+
const directoryPattern = exports.PUBLISH_EXCLUDES.map((pattern) => pattern.replace(/^\*\*\//, "")).find((pattern) => pattern.endsWith("/**") &&
|
|
671
|
+
relative
|
|
672
|
+
.toLowerCase()
|
|
673
|
+
.split("/")
|
|
674
|
+
.includes(pattern.slice(0, -3).toLowerCase()));
|
|
675
|
+
if (directoryPattern) {
|
|
676
|
+
const name = directoryPattern.slice(0, -3).toLowerCase();
|
|
677
|
+
const at = relative.toLowerCase().split("/").indexOf(name);
|
|
678
|
+
named.add(relative
|
|
679
|
+
.split("/")
|
|
680
|
+
.slice(0, at + 1)
|
|
681
|
+
.join("/"));
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
named.add(relative);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return [...named].sort();
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Zip `sourceDir` into `packagePath`, minus {@link PUBLISH_EXCLUDES}.
|
|
691
|
+
*
|
|
692
|
+
* Returns what was actually left out, so the caller can say so — a user who
|
|
693
|
+
* sees their `publisher.config.json` was not uploaded learns the rule; one who
|
|
694
|
+
* sees nothing assumes it was.
|
|
695
|
+
*
|
|
696
|
+
* Derived by diffing the directory against what the archive took, rather than
|
|
697
|
+
* by testing each pattern for existence at the top level. The old form could
|
|
698
|
+
* only ever report a root-level hit, so the nested `publisher.config.json` that
|
|
699
|
+
* the anchoring fix now excludes would have been dropped silently — the report
|
|
700
|
+
* would have been wrong in exactly the case it exists to cover.
|
|
701
|
+
*/
|
|
702
|
+
function createPackageArchive(packagePath_1, sourceDir_1) {
|
|
703
|
+
return __awaiter(this, arguments, void 0, function* (packagePath, sourceDir,
|
|
704
|
+
/** `.credignore`'s patterns, added to {@link PUBLISH_EXCLUDES}, never replacing it. */
|
|
705
|
+
extraExcludes = []) {
|
|
95
706
|
logger_1.logger.info("Creating new package version in " + packagePath);
|
|
96
707
|
const output = fs_1.default.createWriteStream(packagePath);
|
|
97
708
|
const archive = (0, archiver_1.default)("zip", {
|
|
98
709
|
zlib: { level: 9 }, // Sets the compression level.
|
|
99
710
|
});
|
|
100
|
-
|
|
711
|
+
const archived = new Set();
|
|
712
|
+
archive.on("entry", (entry) => archived.add(entry.name));
|
|
713
|
+
yield new Promise((resolve, reject) => {
|
|
101
714
|
archive
|
|
102
715
|
.on("warning", function (err) {
|
|
103
716
|
reject(err);
|
|
@@ -105,18 +718,32 @@ function createTmpPackageArchive(packagePath) {
|
|
|
105
718
|
.on("error", function (err) {
|
|
106
719
|
reject(err);
|
|
107
720
|
})
|
|
108
|
-
|
|
721
|
+
// `dot: true` so `.malloy`-adjacent dotfiles the model needs still
|
|
722
|
+
// travel; the exclusions above are the deliberate exceptions.
|
|
723
|
+
.glob("**/*", {
|
|
724
|
+
cwd: sourceDir,
|
|
725
|
+
dot: true,
|
|
726
|
+
nodir: true,
|
|
727
|
+
ignore: [...exports.PUBLISH_EXCLUDES, ...extraExcludes].map(anyCase),
|
|
728
|
+
})
|
|
109
729
|
.pipe(output);
|
|
110
730
|
output.on("close", function () {
|
|
111
731
|
logger_1.logger.info(archive.pointer() + " total bytes");
|
|
112
|
-
resolve(
|
|
732
|
+
resolve();
|
|
113
733
|
});
|
|
114
734
|
archive.finalize();
|
|
115
735
|
});
|
|
736
|
+
const excluded = describeExclusions(listFiles(sourceDir).filter((relative) => !archived.has(relative)));
|
|
737
|
+
return {
|
|
738
|
+
included: [...archived].sort(),
|
|
739
|
+
excluded,
|
|
740
|
+
bytes: archive.pointer(),
|
|
741
|
+
};
|
|
116
742
|
});
|
|
117
743
|
}
|
|
118
|
-
function pushTmpPackageToRemoteServer(
|
|
119
|
-
return __awaiter(this,
|
|
744
|
+
function pushTmpPackageToRemoteServer(clientConfig_1, controlPlane_1, replicationCount_1, organizationName_1, environmentName_1, tmpPackagePath_1, name_1, description_1, versionId_1, debug_1, setLatest_1, bytes_1) {
|
|
745
|
+
return __awaiter(this, arguments, void 0, function* (clientConfig, controlPlane, replicationCount, organizationName, environmentName, tmpPackagePath, name, description, versionId, debug, setLatest, bytes, options = { excluded: [] }) {
|
|
746
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
120
747
|
logger_1.logger.info("Pushing package " + name + " version " + versionId);
|
|
121
748
|
const packageContents = new File([fs_1.default.readFileSync(tmpPackagePath)], tmpPackagePath);
|
|
122
749
|
// Build the post string from an object
|
|
@@ -145,7 +772,8 @@ function pushTmpPackageToRemoteServer(clientConfig, controlPlane, replicationCou
|
|
|
145
772
|
logger_1.logger.debug("Package: " + JSON.stringify(_package));
|
|
146
773
|
logger_1.logger.debug("Version: " + JSON.stringify(version));
|
|
147
774
|
logger_1.logger.debug("Control plane: " + controlPlane);
|
|
148
|
-
logger_1.logger.debug("Client config: " +
|
|
775
|
+
logger_1.logger.debug("Client config: " +
|
|
776
|
+
JSON.stringify((0, utils_1.redactHeaders)(clientConfig.getHeaders())));
|
|
149
777
|
}
|
|
150
778
|
const response = yield packagesApi.createOrUpdatePackage(organizationName, environmentName, name, _package, version, packageContents, md5Hash,
|
|
151
779
|
// draftId / workspace: a zip upload has no git-backed draft, so the server
|
|
@@ -154,11 +782,72 @@ function pushTmpPackageToRemoteServer(clientConfig, controlPlane, replicationCou
|
|
|
154
782
|
baseURL: controlPlane,
|
|
155
783
|
headers: clientConfig.getHeaders(),
|
|
156
784
|
});
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
785
|
+
// The result is data, so it goes to stdout like every other command's
|
|
786
|
+
// result; the progress lines above are logs and go to stderr. On dev
|
|
787
|
+
// both reached stdout through logger.info, and scripts read the URL line.
|
|
788
|
+
const packageUrl = options.deployment
|
|
789
|
+
? (0, constants_1.packageVersionUrl)(options.deployment, organizationName, environmentName, name, versionId)
|
|
790
|
+
: path_1.default.join(organizationName, environmentName, name, versionId);
|
|
791
|
+
const published = response.data;
|
|
792
|
+
const latest = latestState(published, versionId, setLatest);
|
|
793
|
+
if (options.json) {
|
|
794
|
+
console.log(JSON.stringify({
|
|
795
|
+
organization: organizationName,
|
|
796
|
+
environment: environmentName,
|
|
797
|
+
package: name,
|
|
798
|
+
version: versionId,
|
|
799
|
+
url: packageUrl,
|
|
800
|
+
latest,
|
|
801
|
+
latestVersion: (_a = published === null || published === void 0 ? void 0 : published.latestVersion) !== null && _a !== void 0 ? _a : null,
|
|
802
|
+
excluded: options.excluded,
|
|
803
|
+
response: published,
|
|
804
|
+
}, null, 2));
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
console.log(`Package available at: ${packageUrl}`);
|
|
808
|
+
// Only the publish response carries these (a later GET returns none),
|
|
809
|
+
// so this is the one chance to show them.
|
|
810
|
+
for (const warning of (_b = published === null || published === void 0 ? void 0 : published.warnings) !== null && _b !== void 0 ? _b : []) {
|
|
811
|
+
logger_1.logger.warn(describeWarning(warning));
|
|
812
|
+
}
|
|
813
|
+
logger_1.logger.info(describeLatest(latest, name, versionId, published));
|
|
814
|
+
logger_1.logger.info(`Check its build with \`cred get version ${name} ${versionId}\`.`);
|
|
160
815
|
}
|
|
161
816
|
catch (e) {
|
|
817
|
+
if (axios_1.default.isAxiosError(e) &&
|
|
818
|
+
((_c = e.response) === null || _c === void 0 ? void 0 : _c.status) === 409 &&
|
|
819
|
+
GIT_BACKED_REFUSAL_CODES.has((_d = e.response.data) === null || _d === void 0 ? void 0 : _d.code)) {
|
|
820
|
+
// A structured refusal, not a transient failure — printOutError's raw JSON
|
|
821
|
+
// dump would bury the "what to do next" block, so it's skipped here.
|
|
822
|
+
failPublish();
|
|
823
|
+
const serverMessage = (_e = e.response.data) === null || _e === void 0 ? void 0 : _e.message;
|
|
824
|
+
if (serverMessage) {
|
|
825
|
+
logger_1.logger.error(serverMessage);
|
|
826
|
+
}
|
|
827
|
+
printGitBackedRefusal((_f = e.response.data) === null || _f === void 0 ? void 0 : _f.details, Boolean(serverMessage));
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
// nginx refuses an oversized body before the controlplane sees it, and its
|
|
831
|
+
// reply is an HTML page with no limit in it. The size check above catches
|
|
832
|
+
// almost every case; this covers the sliver where the zip fits but the
|
|
833
|
+
// multipart envelope around it does not.
|
|
834
|
+
if (axios_1.default.isAxiosError(e) && ((_g = e.response) === null || _g === void 0 ? void 0 : _g.status) === 413) {
|
|
835
|
+
failPublish(tooLargeMessage(bytes));
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
const conflictMessage = axios_1.default.isAxiosError(e)
|
|
839
|
+
? String((_k = (_j = (_h = e.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.message) !== null && _k !== void 0 ? _k : "")
|
|
840
|
+
: "";
|
|
841
|
+
if (axios_1.default.isAxiosError(e) &&
|
|
842
|
+
((_l = e.response) === null || _l === void 0 ? void 0 : _l.status) === 409 &&
|
|
843
|
+
conflictMessage.startsWith("VersionId already exists")) {
|
|
844
|
+
// The server's own text first, unchanged: credible-cicd-template's
|
|
845
|
+
// cred_publish.sh greps for it to skip a version already published.
|
|
846
|
+
failPublish(conflictMessage);
|
|
847
|
+
// Versions are immutable, so a retry cannot succeed; say what to change.
|
|
848
|
+
logger_1.logger.error(`${name} version ${versionId} is already published, and a version cannot be replaced. Fix: set "version" in ${PACKAGE_MANIFEST_NAME} to a new one, for example "${nextVersion(versionId)}", and publish again.`);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
162
851
|
// The server rejected it: a model that does not compile, or a `#@ persist`
|
|
163
852
|
// declaration the publisher refuses to load.
|
|
164
853
|
failPublish("Failed to publish package");
|
|
@@ -166,15 +855,57 @@ function pushTmpPackageToRemoteServer(clientConfig, controlPlane, replicationCou
|
|
|
166
855
|
}
|
|
167
856
|
});
|
|
168
857
|
}
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
fs_1.default.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
858
|
+
function removeTmpDirectory(directory) {
|
|
859
|
+
try {
|
|
860
|
+
for (const file of fs_1.default.readdirSync(directory)) {
|
|
861
|
+
fs_1.default.unlinkSync(path_1.default.join(directory, file));
|
|
862
|
+
}
|
|
863
|
+
fs_1.default.rmdirSync(directory);
|
|
864
|
+
}
|
|
865
|
+
catch (_a) {
|
|
866
|
+
// Under the OS temp directory, which it cleans; not worth failing over.
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
function latestState(published, versionId, setLatest) {
|
|
870
|
+
if (setLatest || (published === null || published === void 0 ? void 0 : published.latestVersion) === versionId)
|
|
871
|
+
return "now";
|
|
872
|
+
// The server arms auto-promote on publish; the version becomes latest once
|
|
873
|
+
// its indexes and materialized tables are built (VersionLifecycleService).
|
|
874
|
+
if (published === null || published === void 0 ? void 0 : published.autoPromote)
|
|
875
|
+
return "when-built";
|
|
876
|
+
return "no";
|
|
877
|
+
}
|
|
878
|
+
function describeLatest(latest, name, versionId, published) {
|
|
879
|
+
const current = published === null || published === void 0 ? void 0 : published.latestVersion;
|
|
880
|
+
switch (latest) {
|
|
881
|
+
case "now":
|
|
882
|
+
return `Version ${versionId} is now the latest version of ${name}.`;
|
|
883
|
+
case "when-built":
|
|
884
|
+
return (`Version ${versionId} becomes the latest version once its indexes and materialized tables are built` +
|
|
885
|
+
(current ? `; until then the latest is ${current}.` : ".") +
|
|
886
|
+
" --set-latest makes it latest now, before they are built.");
|
|
887
|
+
case "no":
|
|
888
|
+
return (`Version ${versionId} is published but is not the latest` +
|
|
889
|
+
(current ? ` (that is ${current})` : "") +
|
|
890
|
+
`: auto-promote is off for ${name}. Make it latest with \`cred update package ${name} --version ${versionId}\`.`);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* `0.0.1` → `0.0.2`; a version with no trailing number gets `.1`. Keeps the
|
|
895
|
+
* number's zero padding: `1.0.08` → `1.0.09`, not `1.0.9`.
|
|
896
|
+
*/
|
|
897
|
+
function nextVersion(versionId) {
|
|
898
|
+
const match = /^(.*?)(\d+)$/.exec(versionId);
|
|
899
|
+
if (!match)
|
|
900
|
+
return `${versionId}.1`;
|
|
901
|
+
const next = String(Number(match[2]) + 1).padStart(match[2].length, "0");
|
|
902
|
+
return `${match[1]}${next}`;
|
|
903
|
+
}
|
|
904
|
+
/** One publish warning as a line: where it is, then what it says. */
|
|
905
|
+
function describeWarning(warning) {
|
|
906
|
+
var _a;
|
|
907
|
+
const where = [warning.model, warning.subject].filter(Boolean).join(" > ");
|
|
908
|
+
const message = (_a = warning.message) !== null && _a !== void 0 ? _a : "(no message)";
|
|
909
|
+
return where ? `${where}: ${message}` : message;
|
|
179
910
|
}
|
|
180
911
|
//# sourceMappingURL=publish.js.map
|