Skip to content

Commit

Permalink
add env handling
Browse files Browse the repository at this point in the history
  • Loading branch information
emilwidlund committed Oct 23, 2024
1 parent d87702a commit 3945cb3
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 28 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
node_modules
dist

.env*
.env*

app
polar.ts
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
"dependencies": {
"@inkjs/ui": "^2.0.0",
"@polar-sh/sdk": "^0.13.3",
"@types/cross-spawn": "^6.0.6",
"cross-spawn": "^7.0.3",
"ink": "^4.4.1",
"listr": "^0.14.3",
"meow": "^11.0.0",
"next": "^15.0.1",
"open": "^10.1.0",
"prompts": "^2.4.2",
"react": "^18.2.0",
"standardwebhooks": "1.0.0",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
34 changes: 34 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 27 additions & 20 deletions src/cli.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Polar } from "@polar-sh/sdk";
import meow from "meow";
import { installDependencies } from "./dependencies.js";
import { installDependencies } from "./install.js";
import { login } from "./oauth.js";
import { resolveOrganization } from "./organization.js";
import { resolvePackageName } from "./package.js";
Expand All @@ -15,6 +15,8 @@ import {
import { authenticationDisclaimer } from "./ui/authentication.js";
import { installDisclaimer } from "./ui/install.js";
import { precheckDisclaimer } from "./ui/precheck.js";
import { environmentDisclaimer } from "./ui/environment.js";
import { appendEnvironmentVariables } from "./env.js";

const cli = meow(
`
Expand All @@ -30,10 +32,6 @@ const cli = meow(
{
importMeta: import.meta,
flags: {
skipProduct: {
type: "boolean",
default: false,
},
skipPrecheck: {
type: "boolean",
default: false,
Expand All @@ -51,34 +49,35 @@ const cli = meow(
await precheckDisclaimer();
}

const packageName = await resolvePackageName();
const product = await productPrompt();

if (!cli.flags.skipProduct) {
const product = await productPrompt();
await authenticationDisclaimer();
const code = await login();

await authenticationDisclaimer();
const code = await login();
const api = new Polar({
accessToken: code,
server: "sandbox",
});

const api = new Polar({
accessToken: code,
server: "sandbox",
});
const packageName = await resolvePackageName();
const organization = await resolveOrganization(api, packageName);

const organization = await resolveOrganization(api, packageName);
await createProduct(api, organization, product);

await createProduct(api, organization, product);
}

if (!cli.flags.skipTemplate) {
const templates = await templatePrompt();

await copyPolarClientTemplate();

if (templates.includes("checkout")) {
const shouldCopyCheckout = templates.includes("checkout");
const shouldCopyWebhooks = templates.includes("webhooks");

if (shouldCopyCheckout) {
await copyCheckoutTemplate();
}

if (templates.includes("webhooks")) {
if (shouldCopyWebhooks) {
await copyWebhooksTemplate();
}

Expand All @@ -87,10 +86,18 @@ const cli = meow(

await installDisclaimer(
installDependencies(
templates.includes("webhooks")
shouldCopyWebhooks
? [...baseDependencies, ...webhooksDependencies]
: baseDependencies,
),
);

// Handle environment variables
await environmentDisclaimer(appendEnvironmentVariables( shouldCopyWebhooks ? {
// POLAR_ACCESS_TOKEN: accessToken,
POLAR_ORGANIZATION_ID: organization.id
} : {
POLAR_ORGANIZATION_ID: organization.id
}));
}
})();
41 changes: 41 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import path from 'node:path';
import fs from 'node:fs/promises';

const envFiles = ['.env', '.env.local'];

const resolveEnvPaths = async () => {
const cwd = process.cwd();
const paths = envFiles.map(file => path.join(cwd, file));

const existingFiles = await Promise.all(
paths.map(async (filePath) => {
try {
await fs.access(filePath);
return filePath;
} catch {
return null;
}
})
);

return existingFiles.filter(Boolean);
};

export const appendEnvironmentVariables = async (variables: Record<string, string>) => {
const envPaths = await resolveEnvPaths();

for (const envPath of envPaths) {
if (!envPath) continue;

const envFile = await fs.readFile(envPath, 'utf8');

const newEnvFile = Object.entries(variables).reduce((acc, [key, value]) => {
if (!acc.includes(`${key}=`)) {
return `${acc}\n${key}=${value}`;
}
return acc;
}, envFile);

await fs.writeFile(envPath, newEnvFile);
}
}
6 changes: 2 additions & 4 deletions src/dependencies.ts → src/install.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// @ts-ignore
import spawn from "next/dist/compiled/cross-spawn/index.js";
import spawn from 'cross-spawn'
import { getPkgManager } from "next/dist/lib/helpers/get-pkg-manager.js";

/**
* Spawn a package manager installation with either npm, pnpm, or yarn.
*
* @returns A Promise that resolves once the installation is finished.
*/
const install = (
root: string,
Expand Down Expand Up @@ -43,6 +40,7 @@ const install = (
NODE_ENV: "development",
},
});

child.on("close", (code: number) => {
if (code !== 0) {
reject({ command: `${packageManager} ${args.join(" ")}` });
Expand Down
5 changes: 2 additions & 3 deletions src/prompts/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ export const templatePrompt = async () => {
const { templates } = await prompts({
type: "multiselect",
name: "templates",
message: "Features to setup with your Next.js project",
message: "Polar Features",
instructions: false,
choices: [
{ title: "Checkout Route", value: "checkout", selected: true },
{ title: "Confirmation Page", value: "confirmation", selected: true },
{ title: "Checkout Routes", value: "checkout", selected: true },
{ title: "Webhook Handler", value: "webhooks", selected: true },
],
});
Expand Down
16 changes: 16 additions & 0 deletions src/ui/environment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Spinner } from "@inkjs/ui";
import { render } from "ink";
import React from "react";

export const environmentDisclaimer = async (promise: Promise<void>) => {
const { unmount, clear, waitUntilExit } = render(
<Spinner label="Configuring environment variables..." />,
);

promise.then(() => {
clear();
unmount();
});

await waitUntilExit();
};

0 comments on commit 3945cb3

Please sign in to comment.