Skip to content

Commit

Permalink
feat: next and sanity templates
Browse files Browse the repository at this point in the history
  • Loading branch information
hongaar committed Sep 26, 2023
1 parent c57b055 commit c8fc20d
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 13 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ yarn moker add --template bandersnatch cli
- [`express`](#express)
- [`github-action`](#github-action)
- [`lib`](#lib)
- [`next`](#next)
- [`sanity`](#sanity)
- [Commands](#commands)
- [Contributing](#contributing)
- [Roadmap](#roadmap)
Expand Down Expand Up @@ -451,6 +453,21 @@ _Scope: repo or workspace_
A plain shared library template with the [typescript](#typescript-workspace) and
[jest](#jest-workspace) plugins.
## `next`
_Scope: repo or workspace_
Uses
[create-next-app](https://nextjs.org/docs/pages/api-reference/create-next-app)
to scaffold a Next.js app.
## `sanity`
_Scope: repo or workspace_
Uses [create-sanity](https://www.sanity.io/docs/installation) which
interactively scaffolds a Sanity Studio package.
# Commands
See `moker --help` for a list of available commands.
Expand Down
12 changes: 5 additions & 7 deletions packages/cli/src/commands/add.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
addWorkspace,
applyTemplate,
applyTemplateTask,
formatTask,
installPluginTask,
isMonorepo,
Expand Down Expand Up @@ -55,12 +55,10 @@ export const add = command("add")
}

for (const name of template) {
await task(`Apply template ${name}`, () =>
applyTemplate({
directory: workspaceDirectory,
name: name as string,
}),
);
await applyTemplateTask({
directory: workspaceDirectory,
name: name as string,
});
}

for (const name of plugin) {
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/io.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from "chalk";
import ora from "ora";
import ora, { type Ora } from "ora";

type Log =
| {
Expand Down Expand Up @@ -88,12 +88,15 @@ export async function flushLogs() {
resetMessages();
}

export async function task<T>(title: string, callback: () => Promise<T>) {
export async function task<T>(
title: string,
callback: (spinner: Ora) => Promise<T>,
) {
const spinner = ora(title).start();
let result: T;

try {
result = await callback();
result = await callback(spinner);
} catch (error: any) {
spinner.fail();
logError(error);
Expand Down
24 changes: 21 additions & 3 deletions packages/core/src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@ export type TemplateArgs = { directory: string };

export type Template = {
type: PluginType;
interactive?: boolean;
apply: (args: TemplateArgs) => Promise<void>;
};

type TemplateOptions = {
directory: string;
name: string;
beforeApply?: (template: Template) => any | Promise<any>;
afterApply?: (template: Template) => any | Promise<any>;
};

const CORE_TEMPLATES = [
"bandersnatch",
"common",
"lib",
"cra",
"bandersnatch",
"express",
"github-action",
"lib",
"next",
"sanity",
];

export function isTemplate(template: unknown): template is Template {
Expand Down Expand Up @@ -53,8 +58,21 @@ export async function importTemplate({ directory, name }: TemplateOptions) {
return template;
}

export async function applyTemplate({ directory, name }: TemplateOptions) {
export async function applyTemplate({
directory,
name,
beforeApply,
afterApply,
}: TemplateOptions) {
const template = await importTemplate({ directory, name });

if (beforeApply) {
await beforeApply(template);
}

await template.apply({ directory });

if (afterApply) {
await afterApply(template);
}
}
26 changes: 26 additions & 0 deletions packages/core/src/utils/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
hasPlugin,
loadAllPlugins,
} from "../plugin.js";
import { applyTemplate } from "../template.js";
import { runDependencyQueues } from "../yarn.js";
import { exec } from "./exec.js";

Expand All @@ -19,6 +20,31 @@ export async function formatTask({ directory }: DirOption) {
}
}

export async function applyTemplateTask({
directory,
name,
}: DirOption & { name: string }) {
await task(`Apply template ${name}`, (spinner) =>
applyTemplate({
directory,
name,
beforeApply: (template) => {
if (template.interactive) {
spinner.stopAndPersist({
suffixText: "(interactive mode)",
symbol: "…",
});
}
},
afterApply: (template) => {
if (template.interactive) {
spinner.start();
}
},
}),
);
}

export async function installPluginTask({
directory,
name,
Expand Down
2 changes: 2 additions & 0 deletions packages/templates/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "./cra.js";
export * from "./express.js";
export * from "./githubAction.js";
export * from "./lib.js";
export * from "./next.js";
export * from "./sanity.js";
41 changes: 41 additions & 0 deletions packages/templates/src/next.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
PluginType,
exec,
readPackage,
removeDirectory,
writePackage,
type TemplateArgs,
} from "@mokr/core";
import { basename, dirname } from "node:path";

async function apply({ directory }: TemplateArgs) {
const oldPackage = await readPackage({ directory });

await removeDirectory({ directory });

await exec(
"yarn",
[
"dlx",
"create-next-app",
basename(directory),
"--app",
"--typescript",
"--tailwind",
"--eslint",
"--src-dir",
'--import-alias "@/*"',
"--use-yarn",
],
{
cwd: dirname(directory),
},
);

await writePackage({ directory, data: oldPackage });
}

export const next = {
type: PluginType.RepoOrWorkspace,
apply,
};
47 changes: 47 additions & 0 deletions packages/templates/src/sanity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
PluginType,
exec,
getMonorepoDirectory,
readPackage,
removeDirectory,
writePackage,
type TemplateArgs,
} from "@mokr/core";
import { basename, dirname } from "node:path";

async function apply({ directory }: TemplateArgs) {
const monorepoDirectory = await getMonorepoDirectory({ directory });
const oldPackage = await readPackage({ directory });

await removeDirectory({ directory });

await exec(
"yarn",
[
"dlx",
"create-sanity",
"--output-path",
directory,
"--create-project",
monorepoDirectory
? `${basename(monorepoDirectory)}-project` // Workaround for duplicate workspace name
: basename(directory),
"--dataset-default",
"--typescript",
"--template",
"clean",
],
{
cwd: dirname(directory),
io: "passthrough",
},
);

await writePackage({ directory, data: oldPackage });
}

export const sanity = {
type: PluginType.RepoOrWorkspace,
interactive: true,
apply,
};

0 comments on commit c8fc20d

Please sign in to comment.