@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
@@ -1,7 +1,9 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import { Command } from "commander";
2
3
  import { controlPlanesByEnv, Environment } from "../constants";
3
4
  import { updatePackage } from "./package/updatepackage";
4
- import { updateProject } from "./project/updateproject";
5
+ import { updateEnvironment } from "./environment/updateenvironment";
6
+ import { warnProjectDeprecated } from "./legacy";
5
7
 
6
8
  export const registerUpdateCommands = (
7
9
  cli: Command,
@@ -12,28 +14,69 @@ export const registerUpdateCommands = (
12
14
  .description("Update a resource")
13
15
  .argument("<resource>", "The resource to update");
14
16
 
15
- update
16
- .command("project")
17
- .description("Update a project.")
18
- .argument("<projectName>", "The name of the project to update.")
19
- .option(
20
- "--replication <replicationCount>",
21
- "The new replication count (must be at least 1).",
22
- parseInt,
23
- )
24
- .option("--debug")
25
- .option("-y, --yes", "Skip confirmation.")
26
- .action((projectName, options) => {
27
- updateProject(
28
- controlPlanesByEnv[environment],
29
- projectName,
30
- {
31
- replicationCount: options.replication,
32
- },
33
- options.debug,
34
- options.yes,
35
- );
36
- });
17
+ const updateEnvironmentAction = (environmentName: string, options: any) => {
18
+ updateEnvironment(
19
+ controlPlanesByEnv[environment],
20
+ environmentName,
21
+ {
22
+ replicationCount: options.replication,
23
+ gitModeling: options.gitModeling,
24
+ gitRepositoryOwner: options.gitRepositoryOwner,
25
+ gitRepositoryName: options.gitRepositoryName,
26
+ gitBaseBranch: options.gitBaseBranch,
27
+ },
28
+ options.debug,
29
+ options.yes,
30
+ );
31
+ };
32
+
33
+ // Declared once and applied to both the environment command and its deprecated
34
+ // project alias, so the alias cannot drift into accepting a different set.
35
+ const environmentOptions = (command: Command) =>
36
+ command
37
+ .option(
38
+ "--replication <replicationCount>",
39
+ "The new replication count (must be at least 1).",
40
+ parseInt,
41
+ )
42
+ .option(
43
+ "--git-modeling <true|false>",
44
+ "Enroll (or un-enroll) this environment for git-backed modeling drafts.",
45
+ )
46
+ .option(
47
+ "--git-repository-owner <owner>",
48
+ "GitHub owner of the repository holding this environment's draft branches.",
49
+ )
50
+ .option(
51
+ "--git-repository-name <name>",
52
+ "GitHub repository name, paired with --git-repository-owner.",
53
+ )
54
+ .option(
55
+ "--git-base-branch <branch>",
56
+ 'Branch draft branches fork from. Pass "" to all three git-repository options to unset the repository.',
57
+ )
58
+ .option("--debug")
59
+ .option("-y, --yes", "Skip confirmation.");
60
+
61
+ environmentOptions(
62
+ update
63
+ .command("environment")
64
+ .description("Update an environment.")
65
+ .argument(
66
+ "<environmentName>",
67
+ "The name of the environment to update.",
68
+ ),
69
+ ).action(updateEnvironmentAction);
70
+
71
+ environmentOptions(
72
+ update
73
+ .command("project")
74
+ .description("[deprecated] Alias for 'update environment'.")
75
+ .argument("<projectName>", "The name of the environment to update."),
76
+ ).action((projectName, options) => {
77
+ warnProjectDeprecated("update environment");
78
+ updateEnvironmentAction(projectName, options);
79
+ });
37
80
 
38
81
  update
39
82
  .command("package")
@@ -50,7 +50,7 @@ describe("archive-unarchive-version", () => {
50
50
 
51
51
  expect(axiosStub.calledOnce).to.be.true;
52
52
  expect(axiosStub.firstCall.args[0]).to.equal(
53
- "http://test-server/organizations/test-org/projects/test-project/packages/test-package/versions/1.0.0",
53
+ "http://test-server/organizations/test-org/environments/test-project/packages/test-package/versions/1.0.0",
54
54
  );
55
55
  expect(axiosStub.firstCall.args[1]).to.deep.equal({
56
56
  archiveStatus: "archive",
@@ -96,7 +96,7 @@ describe("archive-unarchive-version", () => {
96
96
 
97
97
  expect(axiosStub.calledOnce).to.be.true;
98
98
  expect(axiosStub.firstCall.args[0]).to.equal(
99
- "http://test-server/organizations/test-org/projects/test-project/packages/test-package/versions/1.0.0",
99
+ "http://test-server/organizations/test-org/environments/test-project/packages/test-package/versions/1.0.0",
100
100
  );
101
101
  expect(axiosStub.firstCall.args[1]).to.deep.equal({
102
102
  archiveStatus: "unarchive",
@@ -215,7 +215,7 @@ describe("archive-unarchive-version", () => {
215
215
  expect(axiosStub.called).to.be.false;
216
216
  expect(
217
217
  loggerStub.error.calledWith(
218
- sinon.match("Please, make sure to set a project"),
218
+ sinon.match("Please, make sure to set an environment"),
219
219
  ),
220
220
  ).to.be.true;
221
221
  });
@@ -425,7 +425,7 @@ describe("archive-unarchive-version", () => {
425
425
  );
426
426
 
427
427
  expect(axiosStub.firstCall.args[0]).to.equal(
428
- "https://api.example.com/organizations/test-org/projects/test-project/packages/my-package/versions/2.0.0",
428
+ "https://api.example.com/organizations/test-org/environments/test-project/packages/my-package/versions/2.0.0",
429
429
  );
430
430
  });
431
431
 
@@ -47,15 +47,15 @@ async function updateVersionArchiveStatus(
47
47
  ) {
48
48
  const clientConfig = new ClientConfiguration();
49
49
  const organizationName = clientConfig.getOrganization();
50
- const projectName = clientConfig.getProject();
50
+ const environmentName = clientConfig.getProject();
51
51
 
52
52
  if (!clientConfig.doesConfigExists()) {
53
53
  logger.error("Please, make sure that you are logged in");
54
54
  return;
55
55
  }
56
56
 
57
- if (!projectName) {
58
- logger.error("Please, make sure to set a project");
57
+ if (!environmentName) {
58
+ logger.error("Please, make sure to set an environment");
59
59
  return;
60
60
  }
61
61
 
@@ -81,12 +81,9 @@ async function updateVersionArchiveStatus(
81
81
  logger.info(
82
82
  `${action === "archive" ? "Archiving" : "Unarchiving"} version ${packageName}/${versionId}`,
83
83
  );
84
- console.log(
85
- `${packageServer}/organizations/${organizationName}/projects/${projectName}/packages/${packageName}/versions/${versionId}`,
86
- );
87
84
  try {
88
85
  const response = await axios.patch(
89
- `${packageServer}/organizations/${organizationName}/projects/${projectName}/packages/${packageName}/versions/${versionId}`,
86
+ `${packageServer}/organizations/${organizationName}/environments/${environmentName}/packages/${packageName}/versions/${versionId}`,
90
87
  {
91
88
  archiveStatus: action,
92
89
  },
@@ -119,7 +119,7 @@ describe("list-versions", () => {
119
119
  expect(listVersionsStub.called).to.be.false;
120
120
  expect(
121
121
  loggerStub.error.calledWith(
122
- sinon.match("Please, make sure to set a project"),
122
+ sinon.match("Please, make sure to set an environment"),
123
123
  ),
124
124
  ).to.be.true;
125
125
  });
@@ -13,15 +13,15 @@ export async function listVersions(
13
13
  ) {
14
14
  const clientConfig = new ClientConfiguration();
15
15
  const organizationName = clientConfig.getOrganization();
16
- const projectName = clientConfig.getProject();
16
+ const environmentName = clientConfig.getProject();
17
17
 
18
18
  if (!clientConfig.doesConfigExists()) {
19
19
  logger.error("Please, make sure that you are logged in");
20
20
  return;
21
21
  }
22
22
 
23
- if (!projectName) {
24
- logger.error("Please, make sure to set a project");
23
+ if (!environmentName) {
24
+ logger.error("Please, make sure to set an environment");
25
25
  return;
26
26
  }
27
27
 
@@ -29,7 +29,7 @@ export async function listVersions(
29
29
  const packageName = packagePath.replace("/", "");
30
30
  const response = await versionsApi.listVersions(
31
31
  organizationName,
32
- projectName,
32
+ environmentName,
33
33
  packageName,
34
34
  {
35
35
  baseURL: controlPlane,
@@ -107,11 +107,9 @@ describe("UserGroupId", () => {
107
107
  expect(id.isPublicAccess()).to.be.false;
108
108
  });
109
109
 
110
- it("should return false for user:* (checks originalValue not resourceName)", () => {
111
- // isPublicAccess checks this.originalValue === "*" which is never true
112
- // since originalValue is the full string "user:*"
110
+ it("should return true for user:* (the public-access wildcard)", () => {
113
111
  const id = UserGroupId.forPublicAccess();
114
- expect(id.isPublicAccess()).to.be.false;
112
+ expect(id.isPublicAccess()).to.be.true;
115
113
  });
116
114
  });
117
115
  });
@@ -131,7 +131,7 @@ export class UserGroupId {
131
131
 
132
132
  public isPublicAccess(): boolean {
133
133
  return (
134
- this.resourceType === ResourceType.USER && this.originalValue === "*"
134
+ this.resourceType === ResourceType.USER && this.resourceName === "*"
135
135
  );
136
136
  }
137
137
  }
@@ -0,0 +1,111 @@
1
+ import { expect } from "chai";
2
+ import {
3
+ CLUSTER_BY_ENVIRONMENT,
4
+ DEFAULT_ENVIRONMENT_BY_CLUSTER,
5
+ getAuth0OrganizationIdForCliLogin,
6
+ getCliOrgConfig,
7
+ } from "./constants";
8
+
9
+ describe("constants", () => {
10
+ describe("DEFAULT_ENVIRONMENT_BY_CLUSTER", () => {
11
+ it("defaults gcp to production", () => {
12
+ expect(DEFAULT_ENVIRONMENT_BY_CLUSTER.gcp).to.equal("production");
13
+ });
14
+
15
+ it("defaults aws to videoamp", () => {
16
+ expect(DEFAULT_ENVIRONMENT_BY_CLUSTER.aws).to.equal("videoamp");
17
+ });
18
+ });
19
+
20
+ describe("CLUSTER_BY_ENVIRONMENT", () => {
21
+ it("places videoamp on aws", () => {
22
+ expect(CLUSTER_BY_ENVIRONMENT.videoamp).to.equal("aws");
23
+ });
24
+
25
+ it("places every other env on gcp", () => {
26
+ expect(CLUSTER_BY_ENVIRONMENT.production).to.equal("gcp");
27
+ expect(CLUSTER_BY_ENVIRONMENT.staging).to.equal("gcp");
28
+ expect(CLUSTER_BY_ENVIRONMENT.dev).to.equal("gcp");
29
+ expect(CLUSTER_BY_ENVIRONMENT.localhost).to.equal("gcp");
30
+ expect(CLUSTER_BY_ENVIRONMENT["e2e-test"]).to.equal("gcp");
31
+ });
32
+
33
+ it("agrees with DEFAULT_ENVIRONMENT_BY_CLUSTER round-trip", () => {
34
+ for (const cluster of ["gcp", "aws"] as const) {
35
+ const defaultEnv = DEFAULT_ENVIRONMENT_BY_CLUSTER[cluster];
36
+ expect(CLUSTER_BY_ENVIRONMENT[defaultEnv]).to.equal(cluster);
37
+ }
38
+ });
39
+ });
40
+
41
+ describe("getCliOrgConfig", () => {
42
+ it("returns the videoamp registry entry", () => {
43
+ const cfg = getCliOrgConfig("videoamp");
44
+ expect(cfg).to.not.be.undefined;
45
+ expect(cfg!.cliOrgName).to.equal("videoamp");
46
+ });
47
+
48
+ it("lists videoamp's supported clusters and default", () => {
49
+ const cfg = getCliOrgConfig("videoamp")!;
50
+ expect(cfg.supportedClusters).to.have.members(["gcp", "aws"]);
51
+ expect(cfg.defaultCluster).to.be.oneOf(cfg.supportedClusters);
52
+ });
53
+
54
+ it("exposes the aws Auth0 org id for videoamp", () => {
55
+ const cfg = getCliOrgConfig("videoamp")!;
56
+ expect(cfg.auth0OrganizationIds?.aws).to.equal("org_nMRKafeSuxOiuJeG");
57
+ });
58
+
59
+ it("is case-insensitive on the org name", () => {
60
+ expect(getCliOrgConfig("VideoAmp")?.cliOrgName).to.equal("videoamp");
61
+ expect(getCliOrgConfig("VIDEOAMP")?.cliOrgName).to.equal("videoamp");
62
+ });
63
+
64
+ it("returns undefined for unregistered orgs (default gcp/device-flow path)", () => {
65
+ expect(getCliOrgConfig("acme")).to.be.undefined;
66
+ expect(getCliOrgConfig("some-new-customer")).to.be.undefined;
67
+ });
68
+
69
+ it("guarantees defaultCluster is in supportedClusters for every entry", () => {
70
+ for (const name of ["videoamp"]) {
71
+ const cfg = getCliOrgConfig(name)!;
72
+ expect(cfg.supportedClusters).to.include(cfg.defaultCluster);
73
+ }
74
+ });
75
+ });
76
+
77
+ describe("getAuth0OrganizationIdForCliLogin", () => {
78
+ it("returns the aws Auth0 org id when -c aws is the active cluster", () => {
79
+ expect(getAuth0OrganizationIdForCliLogin("videoamp", "aws")).to.equal(
80
+ "org_nMRKafeSuxOiuJeG",
81
+ );
82
+ });
83
+
84
+ it("returns undefined for videoamp on gcp (no aws-only Auth0 id maps to gcp)", () => {
85
+ expect(getAuth0OrganizationIdForCliLogin("videoamp", "gcp")).to.be
86
+ .undefined;
87
+ });
88
+
89
+ it("falls back to the org's defaultCluster when no cluster is passed", () => {
90
+ const cfg = getCliOrgConfig("videoamp")!;
91
+ const expected = cfg.auth0OrganizationIds?.[cfg.defaultCluster];
92
+ expect(getAuth0OrganizationIdForCliLogin("videoamp")).to.equal(
93
+ expected,
94
+ );
95
+ });
96
+
97
+ it("is case-insensitive on the org name", () => {
98
+ expect(getAuth0OrganizationIdForCliLogin("VideoAmp", "aws")).to.equal(
99
+ "org_nMRKafeSuxOiuJeG",
100
+ );
101
+ });
102
+
103
+ it("returns undefined for unregistered orgs (forces device-code flow)", () => {
104
+ expect(getAuth0OrganizationIdForCliLogin("acme")).to.be.undefined;
105
+ expect(getAuth0OrganizationIdForCliLogin("acme", "aws")).to.be
106
+ .undefined;
107
+ expect(getAuth0OrganizationIdForCliLogin("acme", "gcp")).to.be
108
+ .undefined;
109
+ });
110
+ });
111
+ });
package/src/constants.ts CHANGED
@@ -4,7 +4,8 @@ export type Environment =
4
4
  | "dev"
5
5
  | "localhost"
6
6
  | "e2e-test"
7
- | "videoamp";
7
+ | "videoamp"
8
+ | "aws-dev";
8
9
 
9
10
  export const controlPlanesByEnv: Record<Environment, string> = {
10
11
  production: "https://admin.credibledata.com/api/v0",
@@ -13,6 +14,9 @@ export const controlPlanesByEnv: Record<Environment, string> = {
13
14
  localhost: "http://admin.ms2.localhost/api/v0",
14
15
  "e2e-test": "http://admin.ms2.localhost/api/v0",
15
16
  videoamp: "https://admin.videoamp-aws-us-east-1.credibledata.com/api/v0",
17
+ // The AWS development cell (credible/dev on EKS). Its public hostnames compose onto the shared
18
+ // apex as aws-dev-<service>.credibledata.com, unlike videoamp's, which live under its own zone.
19
+ "aws-dev": "https://aws-dev-admin.credibledata.com/api/v0",
16
20
  };
17
21
 
18
22
  /** Environments that must have an object in `~/.cred` `configPerEnvironment` (avoids undefined on write). */
@@ -61,27 +65,125 @@ export const auth0ConfigsByEnv: Record<
61
65
  clientId: "ge8JL5TJNwqy7bygAaJkD92KdluqEZgO",
62
66
  audience: "https://ms2data.us.auth0.com/api/v2/",
63
67
  },
68
+ // The DEV Auth0 tenant, not production: this cell takes its per-tier secrets from gcp/credible/dev,
69
+ // so it authenticates against the same tenant that dev, staging and localhost do. videoamp is the
70
+ // exception here, being a production cell.
71
+ "aws-dev": {
72
+ domain: "https://dev-auth.credibledata.com",
73
+ clientId: "rr6mzJNj9b104MjCc9xWKPPehq1MJx0L",
74
+ audience: "https://dev-ohaafogw5p8uyx1m.us.auth0.com/api/v2/",
75
+ },
76
+ };
77
+
78
+ /** Clusters a CLI org can target via `cred login <org> -c <cluster>`. */
79
+ export type Cluster = "gcp" | "aws";
80
+
81
+ /** Which cluster each {@link Environment} lives on. */
82
+ export const CLUSTER_BY_ENVIRONMENT: Record<Environment, Cluster> = {
83
+ production: "gcp",
84
+ staging: "gcp",
85
+ dev: "gcp",
86
+ localhost: "gcp",
87
+ "e2e-test": "gcp",
88
+ videoamp: "aws",
89
+ "aws-dev": "aws",
64
90
  };
65
91
 
66
92
  /**
67
- * `cred login <organizationName>` → Auth0 Organization ID for org-branded Universal Login.
93
+ * Default {@link Environment} to switch to when logging into a cluster and the
94
+ * current active env is on a different cluster. Picked per cluster so that
95
+ * `cred login <org> -c aws` flips to videoamp and `-c gcp` flips to production.
96
+ */
97
+ export const DEFAULT_ENVIRONMENT_BY_CLUSTER: Record<Cluster, Environment> = {
98
+ gcp: "production",
99
+ aws: "videoamp",
100
+ };
101
+
102
+ /**
103
+ * Per-org CLI login config. One row per org that needs non-default behavior
104
+ * (multi-cluster support, Auth0 Organizations PKCE, etc.). Orgs not listed here
105
+ * fall back to: gcp cluster only, Device Authorization Flow, no Auth0 org id.
68
106
  *
69
- * Auth0 documents the `organization` parameter on `/authorize` for Organizations
70
- * (https://auth0.com/docs/manage-users/organizations/configure-organizations/use-org-name-authentication-api).
71
- * The Device Authorization Flow documents only `client_id`, `scope`, and `audience` on
72
- * `POST /oauth/device/code` — not `organization`
107
+ * Auth0 docs: `organization` is supported on `/authorize` for Organizations
108
+ * (https://auth0.com/docs/manage-users/organizations/configure-organizations/use-org-name-authentication-api)
109
+ * but NOT on `POST /oauth/device/code`
73
110
  * (https://auth0.com/docs/get-started/authentication-and-authorization-flow/device-authorization-flow/call-your-api-using-the-device-authorization-flow#device-code-parameters),
74
- * so mapped orgs use Authorization Code + PKCE with `organization` on `/authorize` and
75
- * {@link AUTH_CLI_LOOPBACK_REDIRECT_URI}.
76
- *
77
- * Align with app `ORGANIZATION_HOST_ORG_ID_MAP` / `getAuth0OrganizationAuthorizationParams`.
78
- *
79
- * Entries are added when PKCE + Auth0 org id is ready for that CLI name; until then the map may
80
- * stay empty and `login.spec` stubs {@link getAuth0OrganizationIdForCliLogin} for PKCE coverage.
111
+ * so orgs with an `auth0OrganizationIds` entry for the active cluster use Auth Code + PKCE via
112
+ * {@link AUTH_CLI_LOOPBACK_REDIRECT_URI}. Keep aligned with the app's
113
+ * `ORGANIZATION_HOST_ORG_ID_MAP` / `getAuth0OrganizationAuthorizationParams`.
81
114
  */
82
- export const AUTH0_ORGANIZATION_IDS_BY_CLI_ORG_NAME: Record<string, string> = {
83
- // videoamp: "org_nMRKafeSuxOiuJeG",
84
- };
115
+ export interface CliOrgConfig {
116
+ /** Lowercase CLI org name (what the user types after `cred login`). */
117
+ cliOrgName: string;
118
+ /** Clusters this org can be logged into. */
119
+ supportedClusters: Cluster[];
120
+ /** Cluster used when `-c/--cluster` is omitted. Must be in `supportedClusters`. */
121
+ defaultCluster: Cluster;
122
+ /**
123
+ * Auth0 Organization ID per cluster. Presence triggers the PKCE + `organization=<id>`
124
+ * `/authorize` flow on that cluster; absence falls back to Device Authorization Flow.
125
+ */
126
+ auth0OrganizationIds?: Partial<Record<Cluster, string>>;
127
+ }
128
+
129
+ const CLI_ORG_CONFIGS: CliOrgConfig[] = [
130
+ {
131
+ cliOrgName: "videoamp",
132
+ supportedClusters: ["gcp", "aws"],
133
+ defaultCluster: "gcp",
134
+ auth0OrganizationIds: {
135
+ aws: "org_nMRKafeSuxOiuJeG",
136
+ },
137
+ },
138
+ {
139
+ // Exists on both clouds -- gcp dev and the aws development cell both have a `demo` org -- so
140
+ // both are listed. Registered at all only because an UNREGISTERED org is assumed gcp-only
141
+ // (`supportedClusters ?? ["gcp"]`), which is why `cred login demo` on an aws cell reports the
142
+ // org as unavailable rather than anything about the cell.
143
+ //
144
+ // defaultCluster stays gcp so a bare `cred login demo` behaves exactly as it did before this
145
+ // entry existed; reach the aws cell with `-c aws`.
146
+ //
147
+ // No auth0OrganizationIds: their presence selects the PKCE + loopback flow, whose redirect
148
+ // (127.0.0.1:18240/callback) is registered on the production Auth0 tenant only. Omitting them
149
+ // selects the Device Authorization Flow, which needs no callback URL and therefore works on a
150
+ // cell authenticating against the dev tenant.
151
+ cliOrgName: "demo",
152
+ supportedClusters: ["gcp", "aws"],
153
+ defaultCluster: "gcp",
154
+ },
155
+ {
156
+ // The tenant the PROBES measure, on every cell in both clouds -- probe_organization in
157
+ // stacks/{aws,gcp}/services. Distinct from `demo` above, which is a cell's own first
158
+ // organization; a cell has both, and they were seeded by different bootstrap steps.
159
+ //
160
+ // Needed for the same reason the `demo` entry is, and missed for a reason worth naming: the
161
+ // gcp-only fallback (`supportedClusters ?? ["gcp"]`) makes an unregistered org work perfectly
162
+ // on gcp, so nothing surfaced until an operator tried to reach the fixture on an AWS cell and
163
+ // got "Organization 'k6-experiments' is not available on the aws cluster" -- a message about
164
+ // the org, for a fact about this list. Asserted against the recipe by
165
+ // test_probe_organization_is_reachable_on_its_cells_clusters.
166
+ //
167
+ // defaultCluster gcp and no auth0OrganizationIds, both for the reasons given on `demo`: a bare
168
+ // `cred login k6-experiments` keeps behaving exactly as it did before this entry existed, and
169
+ // the Device Authorization Flow is the one that works against a cell on the dev Auth0 tenant.
170
+ cliOrgName: "k6-experiments",
171
+ supportedClusters: ["gcp", "aws"],
172
+ defaultCluster: "gcp",
173
+ },
174
+ ];
175
+
176
+ const CLI_ORG_CONFIGS_BY_NAME: Record<string, CliOrgConfig> =
177
+ Object.fromEntries(
178
+ CLI_ORG_CONFIGS.map((c) => [c.cliOrgName.toLowerCase(), c]),
179
+ );
180
+
181
+ /** Returns the registry entry for an org, or `undefined` if it uses defaults (gcp + device flow). */
182
+ export function getCliOrgConfig(
183
+ organizationName: string,
184
+ ): CliOrgConfig | undefined {
185
+ return CLI_ORG_CONFIGS_BY_NAME[organizationName.toLowerCase()];
186
+ }
85
187
 
86
188
  /**
87
189
  * Allowlisted on the Auth0 Native application (CLI) as an Allowed Callback URL for PKCE logins
@@ -89,12 +191,22 @@ export const AUTH0_ORGANIZATION_IDS_BY_CLI_ORG_NAME: Record<string, string> = {
89
191
  */
90
192
  export const AUTH_CLI_LOOPBACK_REDIRECT_URI = "http://127.0.0.1:18240/callback";
91
193
 
194
+ /**
195
+ * Auth0 Organization ID for the given CLI org on the cluster it is logging into.
196
+ * Returning a value selects the Auth Code + PKCE branch in `login()`; `undefined`
197
+ * falls back to Device Authorization Flow.
198
+ *
199
+ * `cluster` defaults to the org's `defaultCluster` (or `gcp` for unregistered orgs)
200
+ * so callers that don't yet know the active cluster keep working.
201
+ */
92
202
  export function getAuth0OrganizationIdForCliLogin(
93
203
  organizationName: string,
204
+ cluster?: Cluster,
94
205
  ): string | undefined {
95
- return AUTH0_ORGANIZATION_IDS_BY_CLI_ORG_NAME[
96
- organizationName.toLowerCase()
97
- ];
206
+ const cfg = getCliOrgConfig(organizationName);
207
+ if (!cfg) return undefined;
208
+ const targetCluster = cluster ?? cfg.defaultCluster;
209
+ return cfg.auth0OrganizationIds?.[targetCluster];
98
210
  }
99
211
 
100
212
  // Time constants in ms