@01.software/init 0.1.2

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/dist/index.mjs ADDED
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import pc2 from "picocolors";
5
+
6
+ // src/detect.ts
7
+ import fs from "fs";
8
+ import path from "path";
9
+ function detectProject(cwd) {
10
+ const pkgPath = path.join(cwd, "package.json");
11
+ const hasPackageJson = fs.existsSync(pkgPath);
12
+ let isNextProject = false;
13
+ let hasSdk = false;
14
+ if (hasPackageJson) {
15
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
16
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
17
+ isNextProject = "next" in allDeps;
18
+ hasSdk = "@01.software/sdk" in allDeps;
19
+ }
20
+ let packageManager = null;
21
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
22
+ packageManager = "pnpm";
23
+ } else if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
24
+ packageManager = "yarn";
25
+ } else if (fs.existsSync(path.join(cwd, "bun.lockb")) || fs.existsSync(path.join(cwd, "bun.lock"))) {
26
+ packageManager = "bun";
27
+ } else if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
28
+ packageManager = "npm";
29
+ }
30
+ const srcDir = fs.existsSync(path.join(cwd, "src", "app"));
31
+ return { hasPackageJson, isNextProject, packageManager, hasSdk, srcDir };
32
+ }
33
+
34
+ // src/prompts.ts
35
+ import prompts from "prompts";
36
+ async function promptUser(hasSdk, detectedPm) {
37
+ const onCancel = () => {
38
+ throw new Error("cancelled");
39
+ };
40
+ if (hasSdk) {
41
+ const { proceed } = await prompts(
42
+ {
43
+ type: "confirm",
44
+ name: "proceed",
45
+ message: "@01.software/sdk is already installed. Re-initialize?",
46
+ initial: false
47
+ },
48
+ { onCancel }
49
+ );
50
+ if (!proceed) return null;
51
+ }
52
+ let packageManager;
53
+ if (!detectedPm) {
54
+ const { pm } = await prompts(
55
+ {
56
+ type: "select",
57
+ name: "pm",
58
+ message: "Which package manager do you use?",
59
+ choices: [
60
+ { title: "npm", value: "npm" },
61
+ { title: "pnpm", value: "pnpm" },
62
+ { title: "yarn", value: "yarn" },
63
+ { title: "bun", value: "bun" }
64
+ ]
65
+ },
66
+ { onCancel }
67
+ );
68
+ packageManager = pm;
69
+ }
70
+ const response = await prompts(
71
+ [
72
+ {
73
+ type: "text",
74
+ name: "clientKey",
75
+ message: "Client Key (optional, saved to .env)",
76
+ initial: ""
77
+ }
78
+ ],
79
+ { onCancel }
80
+ );
81
+ return { ...response, packageManager };
82
+ }
83
+
84
+ // src/init.ts
85
+ import fs2 from "fs";
86
+ import path2 from "path";
87
+ import { execSync } from "child_process";
88
+ import pc from "picocolors";
89
+
90
+ // src/templates.ts
91
+ function getClientTemplate() {
92
+ return `import { createBrowserClient } from '@01.software/sdk'
93
+
94
+ export const client = createBrowserClient({
95
+ clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
96
+ })
97
+ `;
98
+ }
99
+ function getQueryProviderTemplate() {
100
+ return `'use client'
101
+
102
+ import { QueryClientProvider } from '@tanstack/react-query'
103
+ import { client } from './client'
104
+
105
+ export function QueryProvider({ children }: { children: React.ReactNode }) {
106
+ return (
107
+ <QueryClientProvider client={client.queryClient}>
108
+ {children}
109
+ </QueryClientProvider>
110
+ )
111
+ }
112
+ `;
113
+ }
114
+ function getServerTemplate() {
115
+ return `import { createServerClient } from '@01.software/sdk'
116
+
117
+ export const serverClient = createServerClient({
118
+ clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
119
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
120
+ })
121
+ `;
122
+ }
123
+ function getPageTemplate() {
124
+ return `'use client'
125
+
126
+ import { client } from '@/lib/software/client'
127
+
128
+ export default function Home() {
129
+ const { data, isLoading } = client.query.useQuery({
130
+ collection: 'products',
131
+ options: { limit: 10 },
132
+ })
133
+
134
+ return (
135
+ <main style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>
136
+ <h1>My App</h1>
137
+ <p>Built with <a href="https://01.software">01.software</a> SDK</p>
138
+
139
+ <h2>Products</h2>
140
+ {isLoading ? (
141
+ <p>Loading...</p>
142
+ ) : (
143
+ <ul>
144
+ {data?.docs.map((product) => (
145
+ <li key={product.id}>{product.title ?? product.id}</li>
146
+ ))}
147
+ {data?.docs.length === 0 && <li>No products found</li>}
148
+ </ul>
149
+ )}
150
+ </main>
151
+ )
152
+ }
153
+ `;
154
+ }
155
+ function getEnvContent(clientKey) {
156
+ return `
157
+ # 01.software
158
+ NEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}
159
+ SOFTWARE_SECRET_KEY=
160
+ `;
161
+ }
162
+
163
+ // src/init.ts
164
+ async function init(cwd, info, answers) {
165
+ const { packageManager, srcDir } = info;
166
+ const baseDir = srcDir ? path2.join(cwd, "src") : cwd;
167
+ console.log(pc.dim(" Installing @01.software/sdk and @tanstack/react-query..."));
168
+ const wsPatched = packageManager === "pnpm" && patchPnpmWorkspace(cwd);
169
+ const pkgs = "@01.software/sdk @tanstack/react-query";
170
+ const pnpmFlag = hasPnpmWorkspace(cwd) ? " -w" : "";
171
+ const addCmd = packageManager === "pnpm" ? `pnpm add${pnpmFlag} ${pkgs}` : packageManager === "yarn" ? `yarn add ${pkgs}` : packageManager === "bun" ? `bun add ${pkgs}` : `npm add ${pkgs}`;
172
+ try {
173
+ execSync(addCmd, { cwd, stdio: "pipe" });
174
+ } catch (error) {
175
+ const err = error;
176
+ const msg = String(err.stderr || "").trim() || String(err.stdout || "").trim() || String(error);
177
+ console.log(pc.red(" Failed to install dependencies:"));
178
+ console.log(pc.dim(` ${msg}`));
179
+ throw error;
180
+ } finally {
181
+ if (wsPatched) restorePnpmWorkspace(cwd);
182
+ }
183
+ const libDir = path2.join(baseDir, "lib", "software");
184
+ fs2.mkdirSync(libDir, { recursive: true });
185
+ const clientPath = path2.join(libDir, "client.ts");
186
+ if (fs2.existsSync(clientPath)) {
187
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, clientPath), pc.dim("(already exists)"));
188
+ } else {
189
+ fs2.writeFileSync(clientPath, getClientTemplate());
190
+ console.log(pc.green(" Created"), relativePath(cwd, clientPath));
191
+ }
192
+ const queryProviderPath = path2.join(libDir, "query-provider.tsx");
193
+ if (fs2.existsSync(queryProviderPath)) {
194
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, queryProviderPath), pc.dim("(already exists)"));
195
+ } else {
196
+ fs2.writeFileSync(queryProviderPath, getQueryProviderTemplate());
197
+ console.log(pc.green(" Created"), relativePath(cwd, queryProviderPath));
198
+ }
199
+ const serverPath = path2.join(libDir, "server.ts");
200
+ if (fs2.existsSync(serverPath)) {
201
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, serverPath), pc.dim("(already exists)"));
202
+ } else {
203
+ fs2.writeFileSync(serverPath, getServerTemplate());
204
+ console.log(pc.green(" Created"), relativePath(cwd, serverPath));
205
+ }
206
+ const appDir = path2.join(baseDir, "app");
207
+ const pagePath = path2.join(appDir, "page.tsx");
208
+ if (!fs2.existsSync(pagePath)) {
209
+ fs2.mkdirSync(appDir, { recursive: true });
210
+ fs2.writeFileSync(pagePath, getPageTemplate());
211
+ console.log(pc.green(" Created"), relativePath(cwd, pagePath));
212
+ }
213
+ const envPath = path2.join(cwd, ".env");
214
+ const envContent = getEnvContent(answers.clientKey || "");
215
+ if (fs2.existsSync(envPath)) {
216
+ const existing = fs2.readFileSync(envPath, "utf-8");
217
+ if (existing.includes("NEXT_PUBLIC_SOFTWARE_CLIENT_KEY")) {
218
+ console.log(pc.yellow(" Skipped"), ".env", pc.dim("(keys already present)"));
219
+ } else {
220
+ fs2.appendFileSync(envPath, envContent);
221
+ console.log(pc.green(" Updated"), ".env");
222
+ }
223
+ } else {
224
+ fs2.writeFileSync(envPath, envContent.trimStart());
225
+ console.log(pc.green(" Created"), ".env");
226
+ }
227
+ }
228
+ function relativePath(cwd, filePath) {
229
+ return path2.relative(cwd, filePath);
230
+ }
231
+ var WS_FILE = "pnpm-workspace.yaml";
232
+ var WS_BACKUP = "pnpm-workspace.yaml.bak";
233
+ function hasPnpmWorkspace(cwd) {
234
+ return fs2.existsSync(path2.join(cwd, WS_FILE));
235
+ }
236
+ function patchPnpmWorkspace(cwd) {
237
+ const wsPath = path2.join(cwd, WS_FILE);
238
+ if (!fs2.existsSync(wsPath)) return false;
239
+ const content = fs2.readFileSync(wsPath, "utf-8");
240
+ if (content.includes("packages:")) return false;
241
+ fs2.copyFileSync(wsPath, path2.join(cwd, WS_BACKUP));
242
+ fs2.writeFileSync(wsPath, content.trimEnd() + "\npackages: []\n");
243
+ return true;
244
+ }
245
+ function restorePnpmWorkspace(cwd) {
246
+ const backupPath = path2.join(cwd, WS_BACKUP);
247
+ if (!fs2.existsSync(backupPath)) return;
248
+ fs2.copyFileSync(backupPath, path2.join(cwd, WS_FILE));
249
+ fs2.unlinkSync(backupPath);
250
+ }
251
+
252
+ // src/index.ts
253
+ async function main() {
254
+ const cwd = process.cwd();
255
+ console.log();
256
+ console.log(pc2.bold(" @01.software/init"));
257
+ console.log(pc2.dim(" Initialize 01.software SDK in your Next.js project"));
258
+ console.log();
259
+ const info = detectProject(cwd);
260
+ if (!info.hasPackageJson) {
261
+ console.log(pc2.red(" No package.json found in the current directory."));
262
+ console.log(pc2.dim(" Run this command inside an existing Next.js project."));
263
+ console.log();
264
+ process.exit(1);
265
+ }
266
+ if (!info.isNextProject) {
267
+ console.log(pc2.red(" This does not appear to be a Next.js project."));
268
+ console.log(pc2.dim(" Create one first: npx create-next-app my-app"));
269
+ console.log();
270
+ process.exit(1);
271
+ }
272
+ if (info.packageManager) {
273
+ console.log(pc2.dim(` Detected: Next.js / ${info.packageManager} / ${info.srcDir ? "src/app" : "app"}`));
274
+ } else {
275
+ console.log(pc2.dim(` Detected: Next.js / ${info.srcDir ? "src/app" : "app"}`));
276
+ }
277
+ console.log();
278
+ try {
279
+ const answers = await promptUser(info.hasSdk, info.packageManager);
280
+ if (!answers) {
281
+ console.log(pc2.yellow(" Cancelled."));
282
+ process.exit(0);
283
+ }
284
+ const resolvedPm = info.packageManager ?? answers.packageManager ?? "npm";
285
+ const resolvedInfo = { ...info, packageManager: resolvedPm };
286
+ console.log();
287
+ await init(cwd, resolvedInfo, answers);
288
+ const run = resolvedPm === "npm" ? "npm run" : resolvedPm;
289
+ console.log();
290
+ console.log(pc2.green(" Done!"));
291
+ console.log();
292
+ console.log(" Next steps:");
293
+ console.log();
294
+ console.log(pc2.dim(" Add the QueryProvider to your root layout:"));
295
+ console.log();
296
+ console.log(pc2.cyan(" import { QueryProvider } from '@/lib/software/query-provider'"));
297
+ console.log();
298
+ console.log(pc2.dim(" Wrap children with <QueryProvider>:"));
299
+ console.log();
300
+ console.log(pc2.cyan(" <QueryProvider>{children}</QueryProvider>"));
301
+ console.log();
302
+ if (!answers.clientKey) {
303
+ console.log(pc2.dim(" Update .env with your API keys"));
304
+ console.log();
305
+ }
306
+ console.log(pc2.cyan(` ${run} dev`));
307
+ console.log();
308
+ } catch (error) {
309
+ if (error instanceof Error && error.message === "cancelled") {
310
+ console.log(pc2.yellow(" Cancelled."));
311
+ process.exit(0);
312
+ }
313
+ console.error(pc2.red(" Error:"), error);
314
+ process.exit(1);
315
+ }
316
+ }
317
+ main();
318
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/detect.ts","../src/prompts.ts","../src/init.ts","../src/templates.ts"],"sourcesContent":["import pc from 'picocolors'\nimport { detectProject } from './detect'\nimport { promptUser } from './prompts'\nimport { init } from './init'\n\nasync function main() {\n const cwd = process.cwd()\n\n console.log()\n console.log(pc.bold(' @01.software/init'))\n console.log(pc.dim(' Initialize 01.software SDK in your Next.js project'))\n console.log()\n\n // 1. Detect project\n const info = detectProject(cwd)\n\n if (!info.hasPackageJson) {\n console.log(pc.red(' No package.json found in the current directory.'))\n console.log(pc.dim(' Run this command inside an existing Next.js project.'))\n console.log()\n process.exit(1)\n }\n\n if (!info.isNextProject) {\n console.log(pc.red(' This does not appear to be a Next.js project.'))\n console.log(pc.dim(' Create one first: npx create-next-app my-app'))\n console.log()\n process.exit(1)\n }\n\n if (info.packageManager) {\n console.log(pc.dim(` Detected: Next.js / ${info.packageManager} / ${info.srcDir ? 'src/app' : 'app'}`))\n } else {\n console.log(pc.dim(` Detected: Next.js / ${info.srcDir ? 'src/app' : 'app'}`))\n }\n console.log()\n\n try {\n // 2. Prompt\n const answers = await promptUser(info.hasSdk, info.packageManager)\n if (!answers) {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n\n // Resolve package manager from detection or user selection\n const resolvedPm = info.packageManager ?? answers.packageManager ?? 'npm'\n const resolvedInfo = { ...info, packageManager: resolvedPm }\n\n // 3. Init\n console.log()\n await init(cwd, resolvedInfo, answers)\n\n // 4. Next steps\n const run = resolvedPm === 'npm' ? 'npm run' : resolvedPm\n\n console.log()\n console.log(pc.green(' Done!'))\n console.log()\n console.log(' Next steps:')\n console.log()\n console.log(pc.dim(' Add the QueryProvider to your root layout:'))\n console.log()\n console.log(pc.cyan(\" import { QueryProvider } from '@/lib/software/query-provider'\"))\n console.log()\n console.log(pc.dim(' Wrap children with <QueryProvider>:'))\n console.log()\n console.log(pc.cyan(' <QueryProvider>{children}</QueryProvider>'))\n console.log()\n if (!answers.clientKey) {\n console.log(pc.dim(' Update .env with your API keys'))\n console.log()\n }\n console.log(pc.cyan(` ${run} dev`))\n console.log()\n } catch (error) {\n if (error instanceof Error && error.message === 'cancelled') {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n console.error(pc.red(' Error:'), error)\n process.exit(1)\n }\n}\n\nmain()\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\nexport interface ProjectInfo {\n hasPackageJson: boolean\n isNextProject: boolean\n packageManager: PackageManager | null // null if no lockfile detected\n hasSdk: boolean\n srcDir: boolean // true if src/app exists, false if app exists at root\n}\n\nexport function detectProject(cwd: string): ProjectInfo {\n const pkgPath = path.join(cwd, 'package.json')\n const hasPackageJson = fs.existsSync(pkgPath)\n\n let isNextProject = false\n let hasSdk = false\n\n if (hasPackageJson) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }\n isNextProject = 'next' in allDeps\n hasSdk = '@01.software/sdk' in allDeps\n }\n\n // Detect package manager from lockfile\n let packageManager: PackageManager | null = null\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {\n packageManager = 'pnpm'\n } else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {\n packageManager = 'yarn'\n } else if (\n fs.existsSync(path.join(cwd, 'bun.lockb')) ||\n fs.existsSync(path.join(cwd, 'bun.lock'))\n ) {\n packageManager = 'bun'\n } else if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {\n packageManager = 'npm'\n }\n\n // Detect src/app vs app directory structure\n const srcDir = fs.existsSync(path.join(cwd, 'src', 'app'))\n\n return { hasPackageJson, isNextProject, packageManager, hasSdk, srcDir }\n}\n","import prompts from 'prompts'\nimport type { PackageManager } from './detect'\n\nexport interface InitAnswers {\n clientKey: string\n packageManager?: PackageManager\n}\n\nexport async function promptUser(\n hasSdk: boolean,\n detectedPm: PackageManager | null,\n): Promise<InitAnswers | null> {\n const onCancel = () => {\n throw new Error('cancelled')\n }\n\n // Confirm re-init if SDK already installed\n if (hasSdk) {\n const { proceed } = await prompts(\n {\n type: 'confirm',\n name: 'proceed',\n message: '@01.software/sdk is already installed. Re-initialize?',\n initial: false,\n },\n { onCancel },\n )\n if (!proceed) return null\n }\n\n // Ask for package manager if no lockfile detected\n let packageManager: PackageManager | undefined\n if (!detectedPm) {\n const { pm } = await prompts(\n {\n type: 'select',\n name: 'pm',\n message: 'Which package manager do you use?',\n choices: [\n { title: 'npm', value: 'npm' },\n { title: 'pnpm', value: 'pnpm' },\n { title: 'yarn', value: 'yarn' },\n { title: 'bun', value: 'bun' },\n ],\n },\n { onCancel },\n )\n packageManager = pm\n }\n\n const response = await prompts(\n [\n {\n type: 'text',\n name: 'clientKey',\n message: 'Client Key (optional, saved to .env)',\n initial: '',\n },\n ],\n { onCancel },\n )\n\n return { ...response, packageManager } as InitAnswers\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync } from 'node:child_process'\nimport pc from 'picocolors'\nimport type { PackageManager, ProjectInfo } from './detect'\n\ntype ResolvedProjectInfo = Omit<ProjectInfo, 'packageManager'> & {\n packageManager: PackageManager\n}\nimport type { InitAnswers } from './prompts'\nimport {\n getClientTemplate,\n getQueryProviderTemplate,\n getServerTemplate,\n getPageTemplate,\n getEnvContent,\n} from './templates'\n\nexport async function init(\n cwd: string,\n info: ResolvedProjectInfo,\n answers: InitAnswers,\n): Promise<void> {\n const { packageManager, srcDir } = info\n const baseDir = srcDir ? path.join(cwd, 'src') : cwd\n\n // 1. Install dependencies\n console.log(pc.dim(' Installing @01.software/sdk and @tanstack/react-query...'))\n\n // pnpm-workspace.yaml without packages: breaks pnpm add — patch temporarily\n const wsPatched = packageManager === 'pnpm' && patchPnpmWorkspace(cwd)\n\n const pkgs = '@01.software/sdk @tanstack/react-query'\n const pnpmFlag = hasPnpmWorkspace(cwd) ? ' -w' : ''\n const addCmd =\n packageManager === 'pnpm'\n ? `pnpm add${pnpmFlag} ${pkgs}`\n : packageManager === 'yarn'\n ? `yarn add ${pkgs}`\n : packageManager === 'bun'\n ? `bun add ${pkgs}`\n : `npm add ${pkgs}`\n\n try {\n execSync(addCmd, { cwd, stdio: 'pipe' })\n } catch (error) {\n const err = error as { stdout?: Buffer; stderr?: Buffer }\n const msg =\n String(err.stderr || '').trim() || String(err.stdout || '').trim() || String(error)\n console.log(pc.red(' Failed to install dependencies:'))\n console.log(pc.dim(` ${msg}`))\n throw error\n } finally {\n if (wsPatched) restorePnpmWorkspace(cwd)\n }\n\n // 2. Write lib/software/client.ts\n const libDir = path.join(baseDir, 'lib', 'software')\n fs.mkdirSync(libDir, { recursive: true })\n\n const clientPath = path.join(libDir, 'client.ts')\n if (fs.existsSync(clientPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, clientPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(clientPath, getClientTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, clientPath))\n }\n\n // 3. Write lib/software/query-provider.tsx\n const queryProviderPath = path.join(libDir, 'query-provider.tsx')\n if (fs.existsSync(queryProviderPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, queryProviderPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(queryProviderPath, getQueryProviderTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, queryProviderPath))\n }\n\n // 4. Write lib/software/server.ts\n const serverPath = path.join(libDir, 'server.ts')\n if (fs.existsSync(serverPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, serverPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(serverPath, getServerTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, serverPath))\n }\n\n // 5. Write app/page.tsx (only if no existing page)\n const appDir = path.join(baseDir, 'app')\n const pagePath = path.join(appDir, 'page.tsx')\n if (!fs.existsSync(pagePath)) {\n fs.mkdirSync(appDir, { recursive: true })\n fs.writeFileSync(pagePath, getPageTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, pagePath))\n }\n\n // 6. Append to .env (skip if keys already present)\n const envPath = path.join(cwd, '.env')\n const envContent = getEnvContent(answers.clientKey || '')\n if (fs.existsSync(envPath)) {\n const existing = fs.readFileSync(envPath, 'utf-8')\n if (existing.includes('NEXT_PUBLIC_SOFTWARE_CLIENT_KEY')) {\n console.log(pc.yellow(' Skipped'), '.env', pc.dim('(keys already present)'))\n } else {\n fs.appendFileSync(envPath, envContent)\n console.log(pc.green(' Updated'), '.env')\n }\n } else {\n fs.writeFileSync(envPath, envContent.trimStart())\n console.log(pc.green(' Created'), '.env')\n }\n}\n\nfunction relativePath(cwd: string, filePath: string): string {\n return path.relative(cwd, filePath)\n}\n\nconst WS_FILE = 'pnpm-workspace.yaml'\nconst WS_BACKUP = 'pnpm-workspace.yaml.bak'\n\nfunction hasPnpmWorkspace(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, WS_FILE))\n}\n\n/** Append packages: [] if pnpm-workspace.yaml exists without it — returns true if patched */\nfunction patchPnpmWorkspace(cwd: string): boolean {\n const wsPath = path.join(cwd, WS_FILE)\n if (!fs.existsSync(wsPath)) return false\n const content = fs.readFileSync(wsPath, 'utf-8')\n if (content.includes('packages:')) return false\n // backup original and append packages: []\n fs.copyFileSync(wsPath, path.join(cwd, WS_BACKUP))\n fs.writeFileSync(wsPath, content.trimEnd() + '\\npackages: []\\n')\n return true\n}\n\n/** Restore original pnpm-workspace.yaml from backup */\nfunction restorePnpmWorkspace(cwd: string): void {\n const backupPath = path.join(cwd, WS_BACKUP)\n if (!fs.existsSync(backupPath)) return\n fs.copyFileSync(backupPath, path.join(cwd, WS_FILE))\n fs.unlinkSync(backupPath)\n}\n","export function getClientTemplate(): string {\n return `import { createBrowserClient } from '@01.software/sdk'\n\nexport const client = createBrowserClient({\n clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,\n})\n`\n}\n\nexport function getQueryProviderTemplate(): string {\n return `'use client'\n\nimport { QueryClientProvider } from '@tanstack/react-query'\nimport { client } from './client'\n\nexport function QueryProvider({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={client.queryClient}>\n {children}\n </QueryClientProvider>\n )\n}\n`\n}\n\nexport function getServerTemplate(): string {\n return `import { createServerClient } from '@01.software/sdk'\n\nexport const serverClient = createServerClient({\n clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,\n secretKey: process.env.SOFTWARE_SECRET_KEY!,\n})\n`\n}\n\nexport function getPageTemplate(): string {\n return `'use client'\n\nimport { client } from '@/lib/software/client'\n\nexport default function Home() {\n const { data, isLoading } = client.query.useQuery({\n collection: 'products',\n options: { limit: 10 },\n })\n\n return (\n <main style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>\n <h1>My App</h1>\n <p>Built with <a href=\"https://01.software\">01.software</a> SDK</p>\n\n <h2>Products</h2>\n {isLoading ? (\n <p>Loading...</p>\n ) : (\n <ul>\n {data?.docs.map((product) => (\n <li key={product.id}>{product.title ?? product.id}</li>\n ))}\n {data?.docs.length === 0 && <li>No products found</li>}\n </ul>\n )}\n </main>\n )\n}\n`\n}\n\nexport function getEnvContent(clientKey: string): string {\n return `\\n# 01.software\nNEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}\nSOFTWARE_SECRET_KEY=\n`\n}"],"mappings":"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","names":["pc","fs","path","path","fs","pc"]}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@01.software/init",
3
+ "version": "0.1.2",
4
+ "description": "Initialize 01.software SDK in your Next.js project",
5
+ "bin": {
6
+ "01-init": "./dist/index.mjs"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "dev": "tsup --watch",
14
+ "check-types": "tsc --noEmit"
15
+ },
16
+ "dependencies": {
17
+ "prompts": "^2.4.2",
18
+ "picocolors": "^1.1.1"
19
+ },
20
+ "devDependencies": {
21
+ "@types/prompts": "^2.4.9",
22
+ "tsup": "^8.5.0",
23
+ "typescript": "^5.9.3"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "license": "MIT"
29
+ }