create-svc 0.1.36 → 0.1.37
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/package.json +1 -1
- package/src/cli.ts +2 -2
- package/src/gcp.test.ts +36 -0
- package/src/gcp.ts +11 -3
- package/src/naming.ts +3 -3
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1131,7 +1131,7 @@ async function promptForExistingProject(projects: GcpProject[], options: { allow
|
|
|
1131
1131
|
: []),
|
|
1132
1132
|
...projects.map((project) => ({
|
|
1133
1133
|
value: project.projectId,
|
|
1134
|
-
label: project.name,
|
|
1134
|
+
label: project.name ?? project.projectId,
|
|
1135
1135
|
hint: project.projectId,
|
|
1136
1136
|
})),
|
|
1137
1137
|
],
|
|
@@ -1151,7 +1151,7 @@ async function promptForExistingProject(projects: GcpProject[], options: { allow
|
|
|
1151
1151
|
return {
|
|
1152
1152
|
mode: "use_existing" as const,
|
|
1153
1153
|
projectId: project.projectId,
|
|
1154
|
-
projectName: project.name,
|
|
1154
|
+
projectName: project.name ?? project.projectId,
|
|
1155
1155
|
};
|
|
1156
1156
|
}
|
|
1157
1157
|
|
package/src/gcp.test.ts
CHANGED
|
@@ -23,6 +23,42 @@ test("listAccessibleProjects filters deleted projects and sorts by name", async
|
|
|
23
23
|
]);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
test("listAccessibleProjects tolerates projects without a display name", async () => {
|
|
27
|
+
const api: GcpApi = {
|
|
28
|
+
async listProjects() {
|
|
29
|
+
return [{ projectId: "b" }, { projectId: "a", name: "alpha" }];
|
|
30
|
+
},
|
|
31
|
+
async listBillingAccounts() {
|
|
32
|
+
return [];
|
|
33
|
+
},
|
|
34
|
+
async createProject() {},
|
|
35
|
+
async attachBillingAccount() {},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
await expect(listAccessibleProjects(api)).resolves.toEqual([{ projectId: "a", name: "alpha" }, { projectId: "b" }]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("listOpenBillingAccounts tolerates accounts without a display name", async () => {
|
|
42
|
+
const api: GcpApi = {
|
|
43
|
+
async listProjects() {
|
|
44
|
+
return [];
|
|
45
|
+
},
|
|
46
|
+
async listBillingAccounts() {
|
|
47
|
+
return [
|
|
48
|
+
{ name: "billingAccounts/2", displayName: "", open: true },
|
|
49
|
+
{ name: "billingAccounts/1", displayName: "A", open: true },
|
|
50
|
+
];
|
|
51
|
+
},
|
|
52
|
+
async createProject() {},
|
|
53
|
+
async attachBillingAccount() {},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
await expect(listOpenBillingAccounts(api)).resolves.toEqual([
|
|
57
|
+
{ name: "billingAccounts/1", displayName: "A", open: true },
|
|
58
|
+
{ name: "billingAccounts/2", displayName: "", open: true },
|
|
59
|
+
]);
|
|
60
|
+
});
|
|
61
|
+
|
|
26
62
|
test("listOpenBillingAccounts keeps only open accounts", async () => {
|
|
27
63
|
const api: GcpApi = {
|
|
28
64
|
async listProjects() {
|
package/src/gcp.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type GcpProject = {
|
|
2
2
|
projectId: string;
|
|
3
|
-
name
|
|
3
|
+
name?: string;
|
|
4
4
|
lifecycleState?: string;
|
|
5
5
|
};
|
|
6
6
|
|
|
@@ -47,13 +47,13 @@ export function createGcpApi(): GcpApi {
|
|
|
47
47
|
export async function listAccessibleProjects(api = createGcpApi()): Promise<GcpProject[]> {
|
|
48
48
|
return (await api.listProjects())
|
|
49
49
|
.filter((project) => project.projectId && project.lifecycleState !== "DELETE_REQUESTED")
|
|
50
|
-
.sort((left, right) => left.
|
|
50
|
+
.sort((left, right) => projectSortName(left).localeCompare(projectSortName(right)));
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export async function listOpenBillingAccounts(api = createGcpApi()): Promise<BillingAccount[]> {
|
|
54
54
|
return (await api.listBillingAccounts())
|
|
55
55
|
.filter((account) => account.name && account.open)
|
|
56
|
-
.sort((left, right) => left.
|
|
56
|
+
.sort((left, right) => accountSortName(left).localeCompare(accountSortName(right)));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export async function createProject(projectId: string, name: string, api = createGcpApi()) {
|
|
@@ -79,6 +79,14 @@ function runGcloud(args: string[]) {
|
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
function projectSortName(project: GcpProject) {
|
|
83
|
+
return project.name || project.projectId;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function accountSortName(account: BillingAccount) {
|
|
87
|
+
return account.displayName || account.name;
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
function parseJson<T>(value: string, label: string): T {
|
|
83
91
|
try {
|
|
84
92
|
return JSON.parse(value) as T;
|
package/src/naming.ts
CHANGED
|
@@ -108,7 +108,7 @@ export function buildGcpProjectOptions(
|
|
|
108
108
|
serviceName: string,
|
|
109
109
|
projectId: string,
|
|
110
110
|
projectName: string,
|
|
111
|
-
projects: Array<{ projectId: string; name
|
|
111
|
+
projects: Array<{ projectId: string; name?: string }>
|
|
112
112
|
) {
|
|
113
113
|
const servicesProject = projects.find((project) => project.projectId === SERVICES_PROJECT_DEFAULT);
|
|
114
114
|
const remainingProjects = projects.filter((project) => project.projectId !== SERVICES_PROJECT_DEFAULT);
|
|
@@ -120,10 +120,10 @@ export function buildGcpProjectOptions(
|
|
|
120
120
|
projectName: servicesProject?.name ?? SERVICES_PROJECT_NAME_DEFAULT,
|
|
121
121
|
},
|
|
122
122
|
...remainingProjects.map((project) => ({
|
|
123
|
-
label: `Use existing project: ${project.name} (${project.projectId})`,
|
|
123
|
+
label: `Use existing project: ${project.name ?? project.projectId} (${project.projectId})`,
|
|
124
124
|
mode: "use_existing" as const,
|
|
125
125
|
projectId: project.projectId,
|
|
126
|
-
projectName: project.name,
|
|
126
|
+
projectName: project.name ?? project.projectId,
|
|
127
127
|
})),
|
|
128
128
|
{
|
|
129
129
|
label: buildCreateProjectLabel(serviceName, projectId),
|