Skip to content

Commit

Permalink
Avoid naming collisions when creating new storefronts with link (#1860
Browse files Browse the repository at this point in the history
)

* Append random hash to Storefront names if already in use

* Don't re-parse storefronts; generate nicer random name

* prettier, changeset
  • Loading branch information
gfscott committed Mar 18, 2024
1 parent da95bb1 commit 34fbae2
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-apricots-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': patch
---

Handle duplicate storefront names when running `link` command
25 changes: 21 additions & 4 deletions packages/cli/src/commands/hydrogen/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {login} from '../../lib/auth.js';
import type {AdminSession} from '../../lib/auth.js';
import {
type HydrogenStorefront,
type ParsedHydrogenStorefront,
generateRandomName,
handleStorefrontSelection,
} from '../../lib/onboarding/common.js';

Expand Down Expand Up @@ -104,7 +106,7 @@ export async function linkStorefront(
}
}

const storefronts = await getStorefronts(session);
const storefronts: ParsedHydrogenStorefront[] = await getStorefronts(session);

let selectedStorefront: HydrogenStorefront | undefined;

Expand Down Expand Up @@ -134,7 +136,11 @@ export async function linkStorefront(
selectedStorefront = await handleStorefrontSelection(storefronts);

if (!selectedStorefront) {
selectedStorefront = await createNewStorefront(root, session);
selectedStorefront = await createNewStorefront(
root,
session,
storefronts,
);
}
}

Expand All @@ -143,12 +149,23 @@ export async function linkStorefront(
return selectedStorefront;
}

async function createNewStorefront(root: string, session: AdminSession) {
async function createNewStorefront(
root: string,
session: AdminSession,
storefronts: ParsedHydrogenStorefront[],
) {
const projectDirectory = basename(root);
let defaultProjectName = titleize(projectDirectory);
const nameAlreadyUsed = storefronts.some(
({title}: {title: string}) => title === defaultProjectName,
);
if (nameAlreadyUsed) {
defaultProjectName = generateRandomName();
}

const projectName = await renderTextPrompt({
message: 'New storefront name',
defaultValue: titleize(projectDirectory),
defaultValue: defaultProjectName,
});

let storefront: HydrogenStorefront | undefined;
Expand Down
73 changes: 73 additions & 0 deletions packages/cli/src/lib/onboarding/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ export type HydrogenStorefront = {
productionUrl: string;
};

export type ParsedHydrogenStorefront = HydrogenStorefront & {parsedId: string};

export async function handleStorefrontSelection(
storefronts: HydrogenStorefront[],
): Promise<HydrogenStorefront | undefined> {
Expand Down Expand Up @@ -754,3 +756,74 @@ function normalizeRoutePath(routePath: string) {
.replace(/[\[\]]/g, '') // Remove brackets
.replace(/:\w*Handle/i, ':handle'); // Replace arbitrary handle names with a standard `:handle`
}

export function generateRandomName() {
function getRandomElement(arr: string[]) {
return arr[Math.floor(Math.random() * arr.length)];
}
const geographicalFeature = getRandomElement([
'Bay',
'Bend',
'Cape',
'Cliff',
'Cove',
'Creek',
'Dale',
'Dune',
'Fjord',
'Glade',
'Gulf',
'Hill',
'Isle',
'Knoll',
'Lake',
'Loch',
'Mesa',
'Peak',
'Pond',
'Quay',
'Reef',
'Ridge',
'Rise',
'River',
'Road',
'Shore',
'Strait',
'Stream',
'Vale',
'Valley',
'View',
'Vista',
]);
const colorNames = getRandomElement([
'Crimson',
'Azure',
'Coral',
'Fuchsia',
'Indigo',
'Ivory',
'Lavender',
'Lime',
'Magenta',
'Maroon',
'Orchid',
'Peach',
'Plum',
'Quartz',
'Salmon',
'Teal',
'Turquoise',
'Violet',
'Yellow',
'Ebony',
'Jade',
'Lilac',
'Mint',
'Onyx',
'Pearl',
'Ruby',
'Sapphire',
'Topaz',
]);
return `${colorNames} ${geographicalFeature}`;
}

0 comments on commit 34fbae2

Please sign in to comment.