@sb-codex/create-sb-app 0.0.1 → 0.0.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.
Files changed (2) hide show
  1. package/dist/index.js +106 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  // src/index.ts
4
4
  import {
5
- existsSync,
6
- readdirSync,
7
- readFileSync,
8
- writeFileSync,
9
- rmSync,
5
+ existsSync as existsSync2,
6
+ readdirSync as readdirSync2,
7
+ readFileSync as readFileSync2,
8
+ writeFileSync as writeFileSync2,
9
+ rmSync as rmSync2,
10
10
  copyFileSync
11
11
  } from "fs";
12
- import { join, extname, basename } from "path";
12
+ import { join as join2, extname, basename } from "path";
13
13
  import { execSync } from "child_process";
14
14
  import {
15
15
  intro,
@@ -76,6 +76,85 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
76
76
  "build"
77
77
  ]);
78
78
 
79
+ // src/transform.ts
80
+ import {
81
+ existsSync,
82
+ readFileSync,
83
+ writeFileSync,
84
+ rmSync,
85
+ readdirSync
86
+ } from "fs";
87
+ import { join } from "path";
88
+ function readJson(path) {
89
+ return JSON.parse(readFileSync(path, "utf8"));
90
+ }
91
+ function writeJson(path, data) {
92
+ writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
93
+ }
94
+ function applyAppsOnly(targetDir) {
95
+ const packagesDir = join(targetDir, "packages");
96
+ const pkgMap = /* @__PURE__ */ new Map();
97
+ if (existsSync(packagesDir)) {
98
+ for (const entry of readdirSync(packagesDir, { withFileTypes: true })) {
99
+ if (!entry.isDirectory()) continue;
100
+ const pj = join(packagesDir, entry.name, "package.json");
101
+ if (!existsSync(pj)) continue;
102
+ const pkg = readJson(pj);
103
+ const name = pkg.name;
104
+ if (typeof name === "string" && name.startsWith("@sb-codex/")) {
105
+ pkgMap.set(name, {
106
+ version: String(pkg.version ?? "0.0.0"),
107
+ peerDependencies: pkg.peerDependencies ?? {}
108
+ });
109
+ }
110
+ }
111
+ }
112
+ const appsDir = join(targetDir, "apps");
113
+ if (existsSync(appsDir)) {
114
+ for (const entry of readdirSync(appsDir, { withFileTypes: true })) {
115
+ if (!entry.isDirectory()) continue;
116
+ const pj = join(appsDir, entry.name, "package.json");
117
+ if (!existsSync(pj)) continue;
118
+ const pkg = readJson(pj);
119
+ const deps = pkg.dependencies ?? {};
120
+ const devDeps = pkg.devDependencies ?? {};
121
+ let changed = false;
122
+ for (const depName of Object.keys(deps)) {
123
+ const info = pkgMap.get(depName);
124
+ if (!info) continue;
125
+ deps[depName] = `^${info.version}`;
126
+ changed = true;
127
+ for (const [peer, range] of Object.entries(info.peerDependencies)) {
128
+ if (!deps[peer] && !devDeps[peer]) deps[peer] = range;
129
+ }
130
+ }
131
+ if (changed) {
132
+ pkg.dependencies = deps;
133
+ writeJson(pj, pkg);
134
+ }
135
+ }
136
+ }
137
+ if (existsSync(packagesDir)) rmSync(packagesDir, { recursive: true, force: true });
138
+ const wsPath = join(targetDir, "pnpm-workspace.yaml");
139
+ if (existsSync(wsPath)) {
140
+ const kept = readFileSync(wsPath, "utf8").split(/\r?\n/).filter((line) => !/['"]packages\/\*['"]/.test(line)).join("\n");
141
+ writeFileSync(wsPath, kept);
142
+ }
143
+ const rootPj = join(targetDir, "package.json");
144
+ if (existsSync(rootPj)) {
145
+ const pkg = readJson(rootPj);
146
+ const pnpm = pkg.pnpm;
147
+ if (pnpm?.overrides) {
148
+ for (const key of Object.keys(pnpm.overrides)) {
149
+ if (key.startsWith("@sb-codex/")) delete pnpm.overrides[key];
150
+ }
151
+ }
152
+ writeJson(rootPj, pkg);
153
+ }
154
+ const changesetDir = join(targetDir, ".changeset");
155
+ if (existsSync(changesetDir)) rmSync(changesetDir, { recursive: true, force: true });
156
+ }
157
+
79
158
  // src/index.ts
80
159
  var TEMPLATE = "github:SB-SLIM/react-app-starter";
81
160
  function bail(message) {
@@ -107,14 +186,14 @@ function parseFlags(argv) {
107
186
  return flags;
108
187
  }
109
188
  function collectTextFiles(dir, acc = []) {
110
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
189
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
111
190
  if (entry.isDirectory()) {
112
191
  if (SKIP_DIRS.has(entry.name)) continue;
113
- collectTextFiles(join(dir, entry.name), acc);
192
+ collectTextFiles(join2(dir, entry.name), acc);
114
193
  } else if (entry.isFile()) {
115
194
  const name = entry.name;
116
195
  if (TEXT_EXTENSIONS.has(extname(name)) || name.startsWith(".env")) {
117
- acc.push(join(dir, name));
196
+ acc.push(join2(dir, name));
118
197
  }
119
198
  }
120
199
  }
@@ -135,8 +214,8 @@ async function main() {
135
214
  if (isCancel(answer)) bail("Cancelled.");
136
215
  target = answer;
137
216
  }
138
- const targetDir = join(process.cwd(), target);
139
- if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {
217
+ const targetDir = join2(process.cwd(), target);
218
+ if (existsSync2(targetDir) && readdirSync2(targetDir).length > 0) {
140
219
  bail(`Directory "${target}" already exists and is not empty.`);
141
220
  }
142
221
  let name;
@@ -184,16 +263,15 @@ async function main() {
184
263
  bail(err instanceof Error ? err.message : String(err));
185
264
  }
186
265
  s.stop("Template downloaded");
187
- const selfDir = join(targetDir, "packages", "create-sb-app");
188
- if (existsSync(selfDir)) rmSync(selfDir, { recursive: true, force: true });
189
- const gitDir = join(targetDir, ".git");
190
- if (existsSync(gitDir)) rmSync(gitDir, { recursive: true, force: true });
191
- const lockfile = join(targetDir, "pnpm-lock.yaml");
192
- if (existsSync(lockfile)) rmSync(lockfile, { force: true });
266
+ applyAppsOnly(targetDir);
267
+ const gitDir = join2(targetDir, ".git");
268
+ if (existsSync2(gitDir)) rmSync2(gitDir, { recursive: true, force: true });
269
+ const lockfile = join2(targetDir, "pnpm-lock.yaml");
270
+ if (existsSync2(lockfile)) rmSync2(lockfile, { force: true });
193
271
  s.start("Personalizing project");
194
272
  const replacements = buildReplacements(answers);
195
273
  for (const file of collectTextFiles(targetDir)) {
196
- let content = readFileSync(file, "utf8");
274
+ let content = readFileSync2(file, "utf8");
197
275
  let changed = false;
198
276
  for (const { find, replace } of replacements) {
199
277
  if (find.test(content)) {
@@ -201,17 +279,17 @@ async function main() {
201
279
  changed = true;
202
280
  }
203
281
  }
204
- if (changed) writeFileSync(file, content);
282
+ if (changed) writeFileSync2(file, content);
205
283
  }
206
- const rootPkgPath = join(targetDir, "package.json");
207
- if (existsSync(rootPkgPath)) {
208
- const pkg = JSON.parse(readFileSync(rootPkgPath, "utf8"));
284
+ const rootPkgPath = join2(targetDir, "package.json");
285
+ if (existsSync2(rootPkgPath)) {
286
+ const pkg = JSON.parse(readFileSync2(rootPkgPath, "utf8"));
209
287
  pkg.name = answers.name;
210
- writeFileSync(rootPkgPath, JSON.stringify(pkg, null, 2) + "\n");
288
+ writeFileSync2(rootPkgPath, JSON.stringify(pkg, null, 2) + "\n");
211
289
  }
212
- const envExample = join(targetDir, ".env.example");
213
- const envFile = join(targetDir, ".env");
214
- if (existsSync(envExample) && !existsSync(envFile)) {
290
+ const envExample = join2(targetDir, ".env.example");
291
+ const envFile = join2(targetDir, ".env");
292
+ if (existsSync2(envExample) && !existsSync2(envFile)) {
215
293
  copyFileSync(envExample, envFile);
216
294
  }
217
295
  s.stop("Project personalized");
@@ -229,13 +307,13 @@ async function main() {
229
307
  " server Fastify 5 + tRPC v11 + Pino (stateless API)",
230
308
  " web Next.js 15 marketing site",
231
309
  " e2e Playwright",
232
- pc.bold("packages/ (@sb-codex/* plugins, workspace:^)"),
310
+ pc.bold("@sb-codex/* plugins (from npm)"),
233
311
  " core \xB7 config \xB7 db \xB7 auth \xB7 api-contracts \xB7 jobs \xB7 ui-components",
234
312
  pc.bold("infra/"),
235
313
  " docker \xB7 compose \xB7 traefik",
236
314
  "",
237
315
  pc.dim("Multi-tenant: Postgres + RLS, x-workspace-slug header."),
238
- pc.dim("Docs: docs/architecture.md \xB7 docs/roadmap.md \xB7 docs/plugins/")
316
+ pc.dim("Plugins resolved from npm \u2014 no packages/ folder.")
239
317
  ].join("\n"),
240
318
  "Architecture"
241
319
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sb-codex/create-sb-app",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "description": "Scaffold a new multi-tenant SaaS project from the sb-codex starter.",
6
6
  "type": "module",
7
7
  "license": "MIT",