Skip to content

Commit

Permalink
feat(installer): #450 add tanstack migrator with support for mdx
Browse files Browse the repository at this point in the history
  • Loading branch information
sdorra committed Jan 7, 2025
1 parent 9e1bcfc commit 0794bb7
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/installer/src/migration/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ describe("findMigrator", () => {
expect(migrator.name).toBe("remix");
});

it("should find tanstack migrator", () => {
const migrator = findMigrator({
name: "tanstack",
dependencies: {
"@tanstack/start": "^1.95.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vinxi": "0.5.1"
},
});
expect(migrator).not.toBe(null);
expect(migrator.name).toBe("tanstack");
});

it("should throw error if migrator could not be found", () => {
expect(() =>
findMigrator({
Expand Down
2 changes: 2 additions & 0 deletions packages/installer/src/migration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { migratorRemix } from "./remix.js";
import { migratorVinxi } from "./vinxi.js";
import { migratorVite } from "./vite.js";
import { migratorSvelteKit } from "./sveltekit.js";
import { migratorTanStack } from "./tanstack.js";

const migrators = [
migratorNextJS,
migratorRemix,
migratorQwik,
migratorTanStack,
migratorVinxi,
migratorSvelteKit,
migratorVite,
Expand Down
196 changes: 196 additions & 0 deletions packages/installer/src/migration/tanstack.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { PackageJson } from "src/packageJson.js";
import { describe, expect, it } from "vitest";
import { migratorTanStack } from "./tanstack.js";

describe("tanstack migrator", () => {
const packageJson: PackageJson = {
name: "something",
};

describe("isResponsible", () => {
it("should be responsible for TanStack Start", () => {
const responsible = migratorTanStack.isResponsible({
name: "something",
dependencies: {
"@tanstack/start": "^1.95.1"
},
});
expect(responsible).toBe(true);
});

it("should be responsible for TanStack Start in dev dependencies", () => {
const responsible = migratorTanStack.isResponsible({
name: "something",
devDependencies: {
"@tanstack/start": "^1.95.1"
},
});
expect(responsible).toBe(true);
});

it("should not be responsible for next.js", () => {
const responsible = migratorTanStack.isResponsible({
name: "something",
dependencies: {
next: "14.3.1",
},
});
expect(responsible).toBe(false);
});

it("should not be responsible for vinxi", () => {
const responsible = migratorTanStack.isResponsible({
name: "something",
dependencies: {
vinxi: "0.5.1",
},
});
expect(responsible).toBe(false);
});
});

describe("options", () => {
it("should parse options", () => {
const options = migratorTanStack.options.parse({ demoContent: "none" });
expect(options).toEqual({ demoContent: "none" });
});
});

describe("migration", () => {
it("should return tasks without demo content", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "none",
},
);

const names = migration.map((task) => task.name);
expect(names).toEqual([
"Install dependencies",
"Add alias to tsconfig",
"Modify vinxi configuration",
"Add .content-collections to .gitignore",
"Create configuration file",
]);
});

it("should return tasks with demo content", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "markdown",
},
);

const names = migration.map((task) => task.name);
expect(names).toEqual([
"Install dependencies",
"Add alias to tsconfig",
"Modify vinxi configuration",
"Add .content-collections to .gitignore",
"Create configuration file",
"Create demo content",
]);
});

it("should add markdown package with markdown demo content", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "markdown",
},
);

const addDependenciesTask = migration.find(
(task) => task.name === "Install dependencies",
);
if (!addDependenciesTask) {
throw new Error("Task not found");
}

// @ts-expect-error - we know it's there
const dependencies = addDependenciesTask.devDependencies;
expect(dependencies).toContain("@content-collections/markdown");
});

it("should add mdx package with mdx demo content", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "mdx",
},
);

const addDependenciesTask = migration.find(
(task) => task.name === "Install dependencies",
);
if (!addDependenciesTask) {
throw new Error("Task not found");
}

// @ts-expect-error - we know it's there
const dependencies = addDependenciesTask.devDependencies;
expect(dependencies).toContain("@content-collections/mdx");
});

it("should not add markdown package without demo content", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "none",
},
);

const addDependenciesTask = migration.find(
(task) => task.name === "Install dependencies",
);
if (!addDependenciesTask) {
throw new Error("Task not found");
}

// @ts-expect-error - we know it's there
const dependencies = addDependenciesTask.devDependencies;
expect(dependencies).not.toContain("@content-collections/markdown");
});

it("should add core and vite packages", async () => {
const migration = await migratorTanStack.createMigration(
{
directory: "directory",
packageJson,
},
{
demoContent: "none",
},
);

const addDependenciesTask = migration.find(
(task) => task.name === "Install dependencies",
);
if (!addDependenciesTask) {
throw new Error("Task not found");
}

// @ts-expect-error - we know it's there
const dependencies = addDependenciesTask.devDependencies;
expect(dependencies).toContain("@content-collections/core");
expect(dependencies).toContain("@content-collections/vinxi");
});
});
});
48 changes: 48 additions & 0 deletions packages/installer/src/migration/tanstack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { z } from "zod";
import { defineMigrator } from "./migrator.js";
import { createConfiguration } from "./tasks/config.js";
import { createDemoContent } from "./tasks/demo.js";
import { addDependencies } from "./tasks/dependencies.js";
import { addToGitIgnore } from "./tasks/gitignore.js";
import { modifyVinxiConfig } from "./tasks/vinxi.js";
import { addAliasToTsConfig } from "./tasks/tsconfig.js";

export const migratorTanStack = defineMigrator({
name: "tanstack",
options: z.object({
demoContent: z
.enum(["none", "markdown", "mdx"])
.default("markdown")
.describe("Type of demo content"),
}),
isResponsible: (packageJson) =>
Boolean(packageJson.dependencies?.["@tanstack/start"]) ||
Boolean(packageJson.devDependencies?.["@tanstack/start"]),
async createMigration({ directory, packageJson }, { demoContent }) {
const packages = [
"@content-collections/core",
"@content-collections/vinxi",
];

if (demoContent === "markdown") {
packages.push("@content-collections/markdown");
} else if (demoContent === "mdx") {
packages.push("@content-collections/mdx");
}


const tasks = [
addDependencies(directory, packageJson, [], packages),
addAliasToTsConfig(directory),
modifyVinxiConfig(directory),
addToGitIgnore(directory),
createConfiguration(directory, demoContent),
];

if (demoContent !== "none") {
tasks.push(createDemoContent(directory, demoContent));
}

return tasks;
},
});

0 comments on commit 0794bb7

Please sign in to comment.