@credibledata/cred-cli 0.0.100 → 0.0.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README-DEV.md +2 -2
  2. package/README.md +1 -1
  3. package/coverage/coverage-summary.json +40 -0
  4. package/coverage/tmp/coverage-2152-1789496974457-0.json +1 -0
  5. package/coverage/tmp/coverage-2153-1789496954404-0.json +1 -0
  6. package/dist/client/api.js +6151 -2254
  7. package/dist/client/api.js.map +1 -1
  8. package/dist/client/base.js +1 -1
  9. package/dist/client/common.js +1 -1
  10. package/dist/client/configuration.js +1 -1
  11. package/dist/client/index.js +1 -1
  12. package/dist/clientconfiguration.js +114 -26
  13. package/dist/clientconfiguration.js.map +1 -1
  14. package/dist/clientconfiguration.spec.js +159 -37
  15. package/dist/clientconfiguration.spec.js.map +1 -1
  16. package/dist/commands/add.js +36 -5
  17. package/dist/commands/add.js.map +1 -1
  18. package/dist/commands/connection/createconnections.js +4 -4
  19. package/dist/commands/connection/createconnections.js.map +1 -1
  20. package/dist/commands/connection/createconnections.spec.js +11 -1
  21. package/dist/commands/connection/createconnections.spec.js.map +1 -1
  22. package/dist/commands/connection/deleteconnection.js +4 -4
  23. package/dist/commands/connection/deleteconnection.js.map +1 -1
  24. package/dist/commands/connection/deleteconnection.spec.js +1 -1
  25. package/dist/commands/connection/deleteconnection.spec.js.map +1 -1
  26. package/dist/commands/connection/listconnections.js +4 -4
  27. package/dist/commands/connection/listconnections.js.map +1 -1
  28. package/dist/commands/connection/listconnections.spec.js +1 -1
  29. package/dist/commands/connection/listconnections.spec.js.map +1 -1
  30. package/dist/commands/{project/createproject.js → environment/createenvironment.js} +17 -14
  31. package/dist/commands/environment/createenvironment.js.map +1 -0
  32. package/dist/commands/{project/createproject.spec.js → environment/createenvironment.spec.js} +46 -46
  33. package/dist/commands/environment/createenvironment.spec.js.map +1 -0
  34. package/dist/commands/{project/deleteproject.js → environment/deleteenvironment.js} +9 -9
  35. package/dist/commands/environment/deleteenvironment.js.map +1 -0
  36. package/dist/commands/{project/deleteproject.spec.js → environment/deleteenvironment.spec.js} +29 -29
  37. package/dist/commands/environment/deleteenvironment.spec.js.map +1 -0
  38. package/dist/commands/{project/getproject.js → environment/getenvironment.js} +8 -8
  39. package/dist/commands/environment/getenvironment.js.map +1 -0
  40. package/dist/commands/{project/getproject.spec.js → environment/getenvironment.spec.js} +32 -33
  41. package/dist/commands/environment/getenvironment.spec.js.map +1 -0
  42. package/dist/commands/{project/listprojects.js → environment/listenvironments.js} +10 -10
  43. package/dist/commands/environment/listenvironments.js.map +1 -0
  44. package/dist/commands/{project/listprojects.spec.js → environment/listenvironments.spec.js} +35 -35
  45. package/dist/commands/environment/listenvironments.spec.js.map +1 -0
  46. package/dist/commands/{project/setproject.js → environment/setenvironment.js} +6 -5
  47. package/dist/commands/environment/setenvironment.js.map +1 -0
  48. package/dist/commands/{project/setproject.spec.js → environment/setenvironment.spec.js} +9 -9
  49. package/dist/commands/environment/setenvironment.spec.js.map +1 -0
  50. package/dist/commands/environment/updateenvironment.js +130 -0
  51. package/dist/commands/environment/updateenvironment.js.map +1 -0
  52. package/dist/commands/environment/updateenvironment.spec.js +213 -0
  53. package/dist/commands/environment/updateenvironment.spec.js.map +1 -0
  54. package/dist/commands/get.js +66 -5
  55. package/dist/commands/get.js.map +1 -1
  56. package/dist/commands/legacy.js +9 -0
  57. package/dist/commands/legacy.js.map +1 -0
  58. package/dist/commands/list.js +95 -4
  59. package/dist/commands/list.js.map +1 -1
  60. package/dist/commands/materialization/cancelrun.js +62 -0
  61. package/dist/commands/materialization/cancelrun.js.map +1 -0
  62. package/dist/commands/materialization/getindex.js +52 -0
  63. package/dist/commands/materialization/getindex.js.map +1 -0
  64. package/dist/commands/materialization/getmaterialization.js +54 -0
  65. package/dist/commands/materialization/getmaterialization.js.map +1 -0
  66. package/dist/commands/materialization/getpreaggregate.js +55 -0
  67. package/dist/commands/materialization/getpreaggregate.js.map +1 -0
  68. package/dist/commands/materialization/getrun.js +54 -0
  69. package/dist/commands/materialization/getrun.js.map +1 -0
  70. package/dist/commands/materialization/listindexes.js +58 -0
  71. package/dist/commands/materialization/listindexes.js.map +1 -0
  72. package/dist/commands/materialization/listmaterializations.js +52 -0
  73. package/dist/commands/materialization/listmaterializations.js.map +1 -0
  74. package/dist/commands/materialization/listpreaggregates.js +61 -0
  75. package/dist/commands/materialization/listpreaggregates.js.map +1 -0
  76. package/dist/commands/materialization/listruns.js +60 -0
  77. package/dist/commands/materialization/listruns.js.map +1 -0
  78. package/dist/commands/materialization/rerun.js +111 -0
  79. package/dist/commands/materialization/rerun.js.map +1 -0
  80. package/dist/commands/misc/login.js +16 -2
  81. package/dist/commands/misc/login.js.map +1 -1
  82. package/dist/commands/misc/login.spec.js +133 -5
  83. package/dist/commands/misc/login.spec.js.map +1 -1
  84. package/dist/commands/package/deletepackage.js +4 -4
  85. package/dist/commands/package/deletepackage.js.map +1 -1
  86. package/dist/commands/package/deletepackage.spec.js +1 -1
  87. package/dist/commands/package/deletepackage.spec.js.map +1 -1
  88. package/dist/commands/package/listpackages.js +11 -4
  89. package/dist/commands/package/listpackages.js.map +1 -1
  90. package/dist/commands/package/listpackages.spec.js +13 -1
  91. package/dist/commands/package/listpackages.spec.js.map +1 -1
  92. package/dist/commands/package/publish.js +36 -13
  93. package/dist/commands/package/publish.js.map +1 -1
  94. package/dist/commands/package/publish.spec.js +27 -1
  95. package/dist/commands/package/publish.spec.js.map +1 -1
  96. package/dist/commands/package/updatepackage.js +4 -4
  97. package/dist/commands/package/updatepackage.js.map +1 -1
  98. package/dist/commands/package/updatepackage.spec.js +1 -1
  99. package/dist/commands/package/updatepackage.spec.js.map +1 -1
  100. package/dist/commands/permission/createpermission.js +123 -0
  101. package/dist/commands/permission/createpermission.js.map +1 -0
  102. package/dist/commands/permission/createpermission.spec.js +360 -0
  103. package/dist/commands/permission/createpermission.spec.js.map +1 -0
  104. package/dist/commands/permission/deletepermission.js +86 -0
  105. package/dist/commands/permission/deletepermission.js.map +1 -0
  106. package/dist/commands/permission/getpermission.js +85 -0
  107. package/dist/commands/permission/getpermission.js.map +1 -0
  108. package/dist/commands/permission/listpermissions.js +75 -0
  109. package/dist/commands/permission/listpermissions.js.map +1 -0
  110. package/dist/commands/permission/scope.js +140 -0
  111. package/dist/commands/permission/scope.js.map +1 -0
  112. package/dist/commands/rm.js +26 -4
  113. package/dist/commands/rm.js.map +1 -1
  114. package/dist/commands/set.js +12 -4
  115. package/dist/commands/set.js.map +1 -1
  116. package/dist/commands/update.js +29 -10
  117. package/dist/commands/update.js.map +1 -1
  118. package/dist/commands/version/archive-unarchive-version.js +4 -5
  119. package/dist/commands/version/archive-unarchive-version.js.map +1 -1
  120. package/dist/commands/version/archive-unarchive-version.spec.js +4 -4
  121. package/dist/commands/version/archive-unarchive-version.spec.js.map +1 -1
  122. package/dist/commands/version/listversions.js +4 -4
  123. package/dist/commands/version/listversions.js.map +1 -1
  124. package/dist/commands/version/listversions.spec.js +1 -1
  125. package/dist/commands/version/listversions.spec.js.map +1 -1
  126. package/dist/common/UserGroupId.js +1 -1
  127. package/dist/common/UserGroupId.js.map +1 -1
  128. package/dist/common/UserGroupId.spec.js +2 -4
  129. package/dist/common/UserGroupId.spec.js.map +1 -1
  130. package/dist/constants.js +95 -19
  131. package/dist/constants.js.map +1 -1
  132. package/dist/constants.spec.js +90 -0
  133. package/dist/constants.spec.js.map +1 -0
  134. package/dist/index.js +128 -15
  135. package/dist/index.js.map +1 -1
  136. package/dist/logger.js +5 -1
  137. package/dist/logger.js.map +1 -1
  138. package/openapitools.json +4 -1
  139. package/package.json +10 -9
  140. package/src/client/api.ts +9363 -3093
  141. package/src/client/base.ts +1 -1
  142. package/src/client/common.ts +1 -1
  143. package/src/client/configuration.ts +1 -1
  144. package/src/client/index.ts +1 -1
  145. package/src/clientconfiguration.spec.ts +238 -113
  146. package/src/clientconfiguration.ts +131 -30
  147. package/src/commands/add.ts +78 -12
  148. package/src/commands/connection/createconnections.spec.ts +11 -1
  149. package/src/commands/connection/createconnections.ts +4 -4
  150. package/src/commands/connection/deleteconnection.spec.ts +1 -1
  151. package/src/commands/connection/deleteconnection.ts +4 -4
  152. package/src/commands/connection/listconnections.spec.ts +1 -1
  153. package/src/commands/connection/listconnections.ts +4 -4
  154. package/src/commands/{project/createproject.spec.ts → environment/createenvironment.spec.ts} +56 -54
  155. package/src/commands/{project/createproject.ts → environment/createenvironment.ts} +17 -14
  156. package/src/commands/{project/deleteproject.spec.ts → environment/deleteenvironment.spec.ts} +59 -30
  157. package/src/commands/{project/deleteproject.ts → environment/deleteenvironment.ts} +10 -10
  158. package/src/commands/environment/getenvironment.spec.ts +110 -0
  159. package/src/commands/{project/getproject.ts → environment/getenvironment.ts} +9 -9
  160. package/src/commands/{project/listprojects.spec.ts → environment/listenvironments.spec.ts} +37 -35
  161. package/src/commands/{project/listprojects.ts → environment/listenvironments.ts} +13 -8
  162. package/src/commands/{project/setproject.spec.ts → environment/setenvironment.spec.ts} +8 -8
  163. package/src/commands/{project/setproject.ts → environment/setenvironment.ts} +4 -4
  164. package/src/commands/environment/updateenvironment.spec.ts +386 -0
  165. package/src/commands/environment/updateenvironment.ts +168 -0
  166. package/src/commands/get.ts +131 -9
  167. package/src/commands/legacy.ts +5 -0
  168. package/src/commands/list.ts +204 -9
  169. package/src/commands/materialization/cancelrun.ts +70 -0
  170. package/src/commands/materialization/getindex.ts +55 -0
  171. package/src/commands/materialization/getmaterialization.ts +57 -0
  172. package/src/commands/materialization/getpreaggregate.ts +58 -0
  173. package/src/commands/materialization/getrun.ts +55 -0
  174. package/src/commands/materialization/listindexes.ts +69 -0
  175. package/src/commands/materialization/listmaterializations.ts +53 -0
  176. package/src/commands/materialization/listpreaggregates.ts +74 -0
  177. package/src/commands/materialization/listruns.ts +77 -0
  178. package/src/commands/materialization/rerun.ts +123 -0
  179. package/src/commands/misc/login.spec.ts +165 -7
  180. package/src/commands/misc/login.ts +20 -2
  181. package/src/commands/package/deletepackage.spec.ts +1 -1
  182. package/src/commands/package/deletepackage.ts +4 -4
  183. package/src/commands/package/listpackages.spec.ts +17 -1
  184. package/src/commands/package/listpackages.ts +11 -4
  185. package/src/commands/package/publish.spec.ts +46 -1
  186. package/src/commands/package/publish.ts +38 -13
  187. package/src/commands/package/updatepackage.spec.ts +1 -1
  188. package/src/commands/package/updatepackage.ts +4 -4
  189. package/src/commands/permission/createpermission.spec.ts +507 -0
  190. package/src/commands/permission/createpermission.ts +181 -0
  191. package/src/commands/permission/deletepermission.ts +117 -0
  192. package/src/commands/permission/getpermission.ts +115 -0
  193. package/src/commands/permission/listpermissions.ts +101 -0
  194. package/src/commands/permission/scope.ts +180 -0
  195. package/src/commands/rm.ts +54 -9
  196. package/src/commands/set.ts +13 -4
  197. package/src/commands/update.ts +66 -23
  198. package/src/commands/version/archive-unarchive-version.spec.ts +4 -4
  199. package/src/commands/version/archive-unarchive-version.ts +4 -7
  200. package/src/commands/version/listversions.spec.ts +1 -1
  201. package/src/commands/version/listversions.ts +4 -4
  202. package/src/common/UserGroupId.spec.ts +2 -4
  203. package/src/common/UserGroupId.ts +1 -1
  204. package/src/constants.spec.ts +111 -0
  205. package/src/constants.ts +131 -19
  206. package/src/index.ts +187 -18
  207. package/src/logger.ts +5 -1
  208. package/bun.lock +0 -1158
  209. package/dist/commands/project/createproject.js.map +0 -1
  210. package/dist/commands/project/createproject.spec.js.map +0 -1
  211. package/dist/commands/project/deleteproject.js.map +0 -1
  212. package/dist/commands/project/deleteproject.spec.js.map +0 -1
  213. package/dist/commands/project/getproject.js.map +0 -1
  214. package/dist/commands/project/getproject.spec.js.map +0 -1
  215. package/dist/commands/project/listprojects.js.map +0 -1
  216. package/dist/commands/project/listprojects.spec.js.map +0 -1
  217. package/dist/commands/project/setproject.js.map +0 -1
  218. package/dist/commands/project/setproject.spec.js.map +0 -1
  219. package/dist/commands/project/updateproject.js +0 -68
  220. package/dist/commands/project/updateproject.js.map +0 -1
  221. package/dist/commands/project/updateproject.spec.js +0 -129
  222. package/dist/commands/project/updateproject.spec.js.map +0 -1
  223. package/src/commands/project/getproject.spec.ts +0 -109
  224. package/src/commands/project/updateproject.spec.ts +0 -217
  225. package/src/commands/project/updateproject.ts +0 -82
@@ -7,6 +7,7 @@ import { ClientConfiguration } from "../../clientconfiguration";
7
7
  import {
8
8
  auth0ConfigsByEnv,
9
9
  AUTH_CLI_LOOPBACK_REDIRECT_URI,
10
+ Cluster,
10
11
  Environment,
11
12
  getAuth0OrganizationIdForCliLogin,
12
13
  LOGIN_TIMEOUT_MS,
@@ -17,10 +18,25 @@ import * as loopbackOAuth from "./loopbackOAuth";
17
18
 
18
19
  const organizationsApi = new OrganizationsApi(new Configuration());
19
20
 
21
+ /**
22
+ * True when argv is a `cred login ...` invocation (argv = [node, script,
23
+ * command, ...args]).
24
+ *
25
+ * Recovery from a corrupt `~/.cred` is scoped to this command only and must run
26
+ * at startup (see index.ts), before the eager config reads there. `cred login`
27
+ * is the one command whose job is to (re)establish config and the documented
28
+ * reset path; every other command must stay fail-loud so a stray read never
29
+ * silently resets a user's tokens.
30
+ */
31
+ export function isLoginInvocation(argv: string[]): boolean {
32
+ return argv[2] === "login";
33
+ }
34
+
20
35
  export async function login(
21
36
  organizationName: string,
22
37
  controlPlaneBaseURL?: string,
23
38
  configPath?: string,
39
+ cluster?: Cluster,
24
40
  ) {
25
41
  const config = new ClientConfiguration(configPath);
26
42
  const environment = config.getEnvironment();
@@ -29,8 +45,10 @@ export async function login(
29
45
  return loginM2M(organizationName, config);
30
46
  }
31
47
 
32
- const auth0OrganizationId =
33
- getAuth0OrganizationIdForCliLogin(organizationName);
48
+ const auth0OrganizationId = getAuth0OrganizationIdForCliLogin(
49
+ organizationName,
50
+ cluster,
51
+ );
34
52
  if (auth0OrganizationId) {
35
53
  return loginWithAuthCodePkceOrganization(
36
54
  environment,
@@ -123,7 +123,7 @@ describe("delete-package", () => {
123
123
  expect(deletePackageStub.called).to.be.false;
124
124
  expect(
125
125
  loggerStub.error.calledWith(
126
- sinon.match("Please, make sure to set a project"),
126
+ sinon.match("Please, make sure to set an environment"),
127
127
  ),
128
128
  ).to.be.true;
129
129
  });
@@ -14,7 +14,7 @@ export async function deletePackage(
14
14
  ) {
15
15
  const clientConfig = new ClientConfiguration();
16
16
  const organizationName = clientConfig.getOrganization();
17
- const projectName = clientConfig.getProject();
17
+ const environmentName = clientConfig.getProject();
18
18
  const packageName = packagePath.replace("/", "");
19
19
 
20
20
  if (!clientConfig.doesConfigExists()) {
@@ -22,8 +22,8 @@ export async function deletePackage(
22
22
  return;
23
23
  }
24
24
 
25
- if (!projectName) {
26
- logger.error("Please, make sure to set a project");
25
+ if (!environmentName) {
26
+ logger.error("Please, make sure to set an environment");
27
27
  return;
28
28
  }
29
29
 
@@ -42,7 +42,7 @@ export async function deletePackage(
42
42
  try {
43
43
  await packagesApi.deletePackage(
44
44
  organizationName,
45
- projectName,
45
+ environmentName,
46
46
  packageName,
47
47
  {
48
48
  baseURL: packageServer,
@@ -114,7 +114,7 @@ describe("list-packages", () => {
114
114
  expect(result).to.be.undefined;
115
115
  expect(
116
116
  loggerStub.error.calledWith(
117
- sinon.match("Please, make sure to set a project"),
117
+ sinon.match("Please, make sure to set an environment"),
118
118
  ),
119
119
  ).to.be.true;
120
120
  });
@@ -144,4 +144,20 @@ describe("list-packages", () => {
144
144
 
145
145
  expect(consoleLogStub.called).to.be.true;
146
146
  });
147
+
148
+ it("should exit non-zero and not print on failure in printOutPackages", async () => {
149
+ // On error, listPackages returns undefined. printOutPackages must NOT print
150
+ // `undefined` to stdout (which breaks downstream JSON.parse) and must signal
151
+ // failure with a non-zero exit code.
152
+ listPackagesStub.rejects(new Error("API Error"));
153
+ const prevExitCode = process.exitCode;
154
+ process.exitCode = 0;
155
+
156
+ await printOutPackages("http://test-server", false);
157
+
158
+ expect(consoleLogStub.called).to.be.false;
159
+ expect(process.exitCode).to.equal(1);
160
+
161
+ process.exitCode = prevExitCode;
162
+ });
147
163
  });
@@ -19,15 +19,15 @@ export async function listPackages(
19
19
  ) {
20
20
  const clientConfig = new ClientConfiguration();
21
21
  const organizationName = clientConfig.getOrganization();
22
- const projectName = clientConfig.getProject();
22
+ const environmentName = clientConfig.getProject();
23
23
 
24
24
  if (!clientConfig.doesConfigExists()) {
25
25
  logger.error("Please, make sure that you are logged in");
26
26
  return;
27
27
  }
28
28
 
29
- if (!projectName) {
30
- logger.error("Please, make sure to set a project");
29
+ if (!environmentName) {
30
+ logger.error("Please, make sure to set an environment");
31
31
  return;
32
32
  }
33
33
 
@@ -35,7 +35,7 @@ export async function listPackages(
35
35
  const { limit, offset } = parsePaginationParams(page, pageSize);
36
36
  const response = await packagesApi.listPackages(
37
37
  organizationName,
38
- projectName,
38
+ environmentName,
39
39
  limit,
40
40
  offset,
41
41
  {
@@ -63,5 +63,12 @@ export async function printOutPackages(
63
63
  pageSize?: string | number,
64
64
  ) {
65
65
  const packages = await listPackages(controlPlane, debug, page, pageSize);
66
+ if (!packages) {
67
+ // listPackages already logged the failure (to stderr). Signal failure with
68
+ // a non-zero exit code instead of printing `undefined` to stdout and
69
+ // exiting 0 — otherwise scripts/tests that JSON.parse stdout choke on it.
70
+ process.exitCode = 1;
71
+ return;
72
+ }
66
73
  console.log(prettifyJson(packages));
67
74
  }
@@ -56,7 +56,14 @@ describe("publish", () => {
56
56
  let originalArchiverModule: any;
57
57
  const archiverModulePath = require.resolve("archiver");
58
58
 
59
+ // publish reports failure by setting process.exitCode, so each test starts from a
60
+ // known 0 and the suite restores whatever the runner had — a leaked non-zero would
61
+ // fail the whole mocha run regardless of the assertions.
62
+ let originalExitCode: number | string | undefined;
63
+
59
64
  beforeEach(() => {
65
+ originalExitCode = process.exitCode;
66
+ process.exitCode = 0;
60
67
  sandbox = sinon.createSandbox();
61
68
 
62
69
  // Create mock archive
@@ -142,6 +149,7 @@ describe("publish", () => {
142
149
  });
143
150
 
144
151
  afterEach(() => {
152
+ process.exitCode = originalExitCode;
145
153
  sandbox.restore();
146
154
  // Restore original archiver module
147
155
  if (originalArchiverModule) {
@@ -351,6 +359,10 @@ describe("publish", () => {
351
359
  sinon.match("Please, make sure that you are logged in"),
352
360
  ),
353
361
  ).to.be.true;
362
+ expect(
363
+ process.exitCode,
364
+ "a publish that never ran must not exit 0",
365
+ ).to.equal(1);
354
366
  });
355
367
 
356
368
  it("should handle invalid token", async () => {
@@ -387,6 +399,10 @@ describe("publish", () => {
387
399
  sinon.match("No token found. Please login."),
388
400
  ),
389
401
  ).to.be.true;
402
+ expect(
403
+ process.exitCode,
404
+ "a publish that never ran must not exit 0",
405
+ ).to.equal(1);
390
406
  });
391
407
 
392
408
  it("should handle invalid manifest", async () => {
@@ -395,6 +411,11 @@ describe("publish", () => {
395
411
  await publish("http://test-server", 2, false, true, false);
396
412
 
397
413
  expect(createOrUpdatePackageStub.called).to.be.false;
414
+ // validateManifest logs its own reason, so only the exit code is asserted here.
415
+ expect(
416
+ process.exitCode,
417
+ "a publish that never ran must not exit 0",
418
+ ).to.equal(1);
398
419
  });
399
420
 
400
421
  it("should handle missing organization", async () => {
@@ -416,6 +437,11 @@ describe("publish", () => {
416
437
  sandbox
417
438
  .stub(ClientConfiguration.prototype, "getOrganization")
418
439
  .returns("");
440
+ // publish calls getProject before the organization check — stub it too
441
+ // so we don't fall through into real loadConfig against a stubbed fs.
442
+ sandbox
443
+ .stub(ClientConfiguration.prototype, "getProject")
444
+ .returns("test-project");
419
445
  validateManifestStub.returns(true);
420
446
  sandbox
421
447
  .stub(PackagesApi.prototype, "createOrUpdatePackage")
@@ -435,6 +461,10 @@ describe("publish", () => {
435
461
  sinon.match("Please, make sure that you are logged in"),
436
462
  ),
437
463
  ).to.be.true;
464
+ expect(
465
+ process.exitCode,
466
+ "a publish that never ran must not exit 0",
467
+ ).to.equal(1);
438
468
  });
439
469
 
440
470
  it("should handle missing project", async () => {
@@ -473,9 +503,13 @@ describe("publish", () => {
473
503
  expect(createOrUpdatePackageStub.called).to.be.false;
474
504
  expect(
475
505
  loggerStub.error.calledWith(
476
- sinon.match("Please, make sure to set a project"),
506
+ sinon.match("Please, make sure to set an environment"),
477
507
  ),
478
508
  ).to.be.true;
509
+ expect(
510
+ process.exitCode,
511
+ "a publish that never ran must not exit 0",
512
+ ).to.equal(1);
479
513
  });
480
514
 
481
515
  it("should handle missing publisher.json", async () => {
@@ -495,6 +529,10 @@ describe("publish", () => {
495
529
  ),
496
530
  ),
497
531
  ).to.be.true;
532
+ expect(
533
+ process.exitCode,
534
+ "a publish that never ran must not exit 0",
535
+ ).to.equal(1);
498
536
  });
499
537
 
500
538
  it("should request confirmation when autoConfirm is false", async function () {
@@ -536,6 +574,9 @@ describe("publish", () => {
536
574
  expect(createOrUpdatePackageStub.called).to.be.false;
537
575
  expect(loggerStub.info.calledWith(sinon.match("Operation cancelled."))).to
538
576
  .be.true;
577
+ // Declining the prompt is an answer, not a failure: it can only happen
578
+ // interactively, and a human who said no does not want a failed command.
579
+ expect(process.exitCode, "cancelling is not a failure").to.equal(0);
539
580
  });
540
581
 
541
582
  it("should handle API errors", async function () {
@@ -562,6 +603,10 @@ describe("publish", () => {
562
603
  expect(
563
604
  loggerStub.error.calledWith(sinon.match("Failed to publish package")),
564
605
  ).to.be.true;
606
+ // The log alone is not the contract: CI and scripts wrap `cred publish` and
607
+ // read its exit code, so a rejected publish exiting 0 reports success for a
608
+ // package that was never published.
609
+ expect(process.exitCode).to.equal(1);
565
610
  });
566
611
 
567
612
  it("should log package URL after successful publish", async function () {
@@ -13,6 +13,23 @@ import { validateManifest } from "../../validator";
13
13
  const packagesApi = new PackagesApi(new Configuration());
14
14
  const PACKAGE_MANIFEST_NAME = "publisher.json";
15
15
 
16
+ /**
17
+ * Record a publish failure: log it (when the caller has a message of its own to give)
18
+ * and mark the process failed.
19
+ *
20
+ * Every early return below is a publish that did not happen, so each one has to carry the
21
+ * same non-zero exit as a server rejection. CI and scripts wrap `cred publish` and read
22
+ * its exit code; exiting 0 tells them a package is there when it is not. Declining the
23
+ * confirmation prompt is deliberately NOT routed through here — that is an answer rather
24
+ * than a failure, and it can only happen interactively.
25
+ */
26
+ function failPublish(message?: string): void {
27
+ if (message) {
28
+ logger.error(message);
29
+ }
30
+ process.exitCode = 1;
31
+ }
32
+
16
33
  export async function publish(
17
34
  controlPlane: string,
18
35
  replicationCount: number,
@@ -23,37 +40,39 @@ export async function publish(
23
40
  const clientConfig = new ClientConfiguration();
24
41
 
25
42
  if (!clientConfig.doesConfigExists()) {
26
- logger.error("Please, make sure that you are logged in");
43
+ failPublish("Please, make sure that you are logged in");
27
44
  return;
28
45
  }
29
46
 
30
47
  const tokenValidation = clientConfig.isTokenValid();
31
48
  if (!tokenValidation.valid) {
32
- logger.error(
49
+ failPublish(
33
50
  tokenValidation.reason || "Please, make sure that you are logged in",
34
51
  );
35
52
  return;
36
53
  }
37
54
 
38
55
  if (!validateManifest()) {
56
+ // validateManifest logs its own reason; only the exit code is missing.
57
+ failPublish();
39
58
  return;
40
59
  }
41
60
 
42
- const projectName = clientConfig.getProject();
61
+ const environmentName = clientConfig.getProject();
43
62
  const organizationName = clientConfig.getOrganization();
44
63
 
45
64
  if (!organizationName) {
46
- logger.error("Please, make sure that you are logged in");
65
+ failPublish("Please, make sure that you are logged in");
47
66
  return;
48
67
  }
49
68
 
50
- if (!projectName) {
51
- logger.error("Please, make sure to set a project");
69
+ if (!environmentName) {
70
+ failPublish("Please, make sure to set an environment");
52
71
  return;
53
72
  }
54
73
 
55
74
  if (!fs.existsSync(PACKAGE_MANIFEST_NAME)) {
56
- logger.error(
75
+ failPublish(
57
76
  `Failed to publish the package. Could not find ${PACKAGE_MANIFEST_NAME}, please ensure you are in a directory containing ${PACKAGE_MANIFEST_NAME}`,
58
77
  );
59
78
  return;
@@ -82,7 +101,7 @@ export async function publish(
82
101
  controlPlane,
83
102
  replicationCount,
84
103
  organizationName,
85
- projectName,
104
+ environmentName,
86
105
  tmpPackagePath,
87
106
  packageManifest.name,
88
107
  packageManifest.description,
@@ -126,7 +145,7 @@ async function pushTmpPackageToRemoteServer(
126
145
  controlPlane: string,
127
146
  replicationCount: number,
128
147
  organizationName: string,
129
- projectName: string,
148
+ environmentName: string,
130
149
  tmpPackagePath: string,
131
150
  name: string,
132
151
  description: string,
@@ -164,7 +183,7 @@ async function pushTmpPackageToRemoteServer(
164
183
  if (debug) {
165
184
  logger.debug("Package contents: " + packageContents);
166
185
  logger.debug("Organization name: " + organizationName);
167
- logger.debug("Project name: " + projectName);
186
+ logger.debug("Environment name: " + environmentName);
168
187
  logger.debug("Name: " + name);
169
188
  logger.debug("Package: " + JSON.stringify(_package));
170
189
  logger.debug("Version: " + JSON.stringify(version));
@@ -175,12 +194,16 @@ async function pushTmpPackageToRemoteServer(
175
194
  }
176
195
  const response = await packagesApi.createOrUpdatePackage(
177
196
  organizationName,
178
- projectName,
197
+ environmentName,
179
198
  name,
180
199
  _package,
181
200
  version,
182
201
  packageContents,
183
202
  md5Hash,
203
+ // draftId / workspace: a zip upload has no git-backed draft, so the server
204
+ // records no provenance. Positional because `options` must stay last.
205
+ undefined,
206
+ undefined,
184
207
  {
185
208
  baseURL: controlPlane,
186
209
  headers: clientConfig.getHeaders(),
@@ -190,13 +213,15 @@ async function pushTmpPackageToRemoteServer(
190
213
  logger.info(prettifyJson(response.data));
191
214
  const packageUrl = path.join(
192
215
  organizationName,
193
- projectName,
216
+ environmentName,
194
217
  name,
195
218
  versionId,
196
219
  );
197
220
  logger.info(`Package available at: ${packageUrl}`);
198
221
  } catch (e) {
199
- logger.error("Failed to publish package");
222
+ // The server rejected it: a model that does not compile, or a `#@ persist`
223
+ // declaration the publisher refuses to load.
224
+ failPublish("Failed to publish package");
200
225
  printOutError(e, debug);
201
226
  }
202
227
  }
@@ -188,7 +188,7 @@ describe("set-replication-count", () => {
188
188
 
189
189
  expect(
190
190
  loggerStub.error.calledWith(
191
- sinon.match("Please, make sure to set a project"),
191
+ sinon.match("Please, make sure to set an environment"),
192
192
  ),
193
193
  ).to.be.true;
194
194
  });
@@ -20,15 +20,15 @@ export async function updatePackage(
20
20
  ) {
21
21
  const clientConfig = new ClientConfiguration();
22
22
  const organizationName = clientConfig.getOrganization();
23
- const projectName = clientConfig.getProject();
23
+ const environmentName = clientConfig.getProject();
24
24
 
25
25
  if (!clientConfig.doesConfigExists()) {
26
26
  logger.error("Please, make sure that you are logged in");
27
27
  return;
28
28
  }
29
29
 
30
- if (!projectName) {
31
- logger.error("Please, make sure to set a project");
30
+ if (!environmentName) {
31
+ logger.error("Please, make sure to set an environment");
32
32
  return;
33
33
  }
34
34
 
@@ -68,7 +68,7 @@ export async function updatePackage(
68
68
 
69
69
  const response = await packagesApi.updatePackage(
70
70
  organizationName,
71
- projectName,
71
+ environmentName,
72
72
  packageName,
73
73
  packageUpdate,
74
74
  {