partweave 0.1.1 → 0.2.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "partweave",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A modular full-stack scaffolder — pick the parts you need (Django server, Next.js web, Expo mobile) and generate only that code, wired together.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"create-partweave": "dist/create-bin.js"
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
|
-
"dist",
|
|
41
|
+
"dist/**/*.js",
|
|
42
42
|
"modules",
|
|
43
43
|
"README.md",
|
|
44
44
|
"LICENSE"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/create.ts","../src/compose.ts","../src/inject.ts","../src/fsutil.ts","../src/render.ts","../src/pm.ts","../src/rootgen.ts","../src/types.ts","../src/registry.ts","../src/paths.ts","../src/projectmanifest.ts","../src/resolve.ts","../src/prompts.ts"],"sourcesContent":["import { existsSync, readdirSync } from \"node:fs\";\nimport { basename, resolve } from \"node:path\";\nimport { intro, log, note, outro, spinner } from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { buildContext, compose, selectedTargets } from \"../compose.js\";\nimport {\n detectJsPm,\n detectPyPm,\n JS_PMS,\n PY_PMS,\n type JsPm,\n type PyPm,\n} from \"../pm.js\";\nimport { Registry } from \"../registry.js\";\nimport { writeProjectManifest } from \"../projectmanifest.js\";\nimport { slugify } from \"../render.js\";\nimport { resolveModules, validateApps } from \"../resolve.js\";\nimport { promptCreate, type RawChoices } from \"../prompts.js\";\nimport { APPS, type AppName } from \"../types.js\";\n\nexport interface CreateFlags {\n name?: string;\n dir?: string;\n server?: boolean;\n web?: boolean;\n mobile?: boolean;\n with?: string; // comma-separated module ids\n jsPm?: string; // pnpm | npm\n pyPm?: string; // uv | pip\n yes?: boolean;\n force?: boolean;\n}\n\n/** Validate a --js-pm/--py-pm flag, or fall back to what's installed. */\nfunction resolvePm<T extends string>(\n value: string | undefined,\n allowed: readonly T[],\n detect: () => T,\n flag: string,\n): T {\n if (value === undefined) return detect();\n if ((allowed as readonly string[]).includes(value)) return value as T;\n log.error(`Invalid ${flag} \"${value}\". Choose one of: ${allowed.join(\", \")}.`);\n process.exit(1);\n}\n\nfunction appsFromFlags(flags: CreateFlags): AppName[] | null {\n const explicit = [\"server\", \"web\", \"mobile\"].some(\n (k) => flags[k as keyof CreateFlags] !== undefined,\n );\n if (!explicit) return null;\n const apps = APPS.filter((a) => flags[a] === true);\n // if the user only passed --no-* flags, treat the rest as enabled\n if (apps.length === 0) return APPS.filter((a) => flags[a] !== false);\n return apps;\n}\n\nfunction defaultModules(registry: Registry, apps: AppName[]): string[] {\n const present = new Set<string>(apps);\n if (apps.includes(\"web\") || apps.includes(\"mobile\")) present.add(\"shared\");\n return registry\n .features()\n .filter((m) => m.manifest.default)\n .filter((m) => m.manifest.targets.some((t) => present.has(t)))\n .filter((m) => m.manifest.requiresApps.every((a) => apps.includes(a)))\n .map((m) => m.manifest.id);\n}\n\nexport async function runCreate(flags: CreateFlags): Promise<void> {\n intro(pc.bgCyan(pc.black(\" partweave \")) + pc.dim(\" full-stack scaffolder\"));\n const registry = new Registry();\n\n const flagApps = appsFromFlags(flags);\n const nonInteractive = flags.yes === true || flagApps !== null;\n\n const jsPm: JsPm = resolvePm(flags.jsPm, JS_PMS, detectJsPm, \"--js-pm\");\n const pyPm: PyPm = resolvePm(flags.pyPm, PY_PMS, detectPyPm, \"--py-pm\");\n\n let choices: RawChoices;\n if (nonInteractive) {\n const apps = flagApps ?? [...APPS];\n const name = flags.name ?? \"my-app\";\n const outDir = resolve(flags.dir ?? `./${slugify(name)}`);\n const modules =\n flags.with !== undefined\n ? flags.with.split(\",\").map((s) => s.trim()).filter(Boolean)\n : defaultModules(registry, apps);\n choices = { projectName: name, outDir, apps, modules, jsPm, pyPm };\n } else {\n choices = await promptCreate(registry, {\n projectName: flags.name,\n outDir: flags.dir ? resolve(flags.dir) : undefined,\n // pre-select an explicitly-passed --js-pm/--py-pm; otherwise the prompt\n // defaults to whatever is installed.\n jsPm: flags.jsPm ? jsPm : undefined,\n pyPm: flags.pyPm ? pyPm : undefined,\n });\n }\n\n // guard: don't clobber a non-empty directory\n if (existsSync(choices.outDir) && readdirSync(choices.outDir).length > 0 && !flags.force) {\n log.error(`${choices.outDir} exists and is not empty. Use --force to override.`);\n process.exit(1);\n }\n\n // resolve module dependencies / conflicts\n let resolved;\n try {\n resolved = resolveModules(registry, choices.modules);\n } catch (err) {\n log.error((err as Error).message);\n process.exit(1);\n }\n if (resolved.autoAdded.length) {\n log.info(`Added required components: ${resolved.autoAdded.join(\", \")}`);\n }\n try {\n validateApps(registry, resolved.modules, choices.apps);\n } catch (err) {\n log.error((err as Error).message);\n process.exit(1);\n }\n\n const s = spinner();\n s.start(\"Scaffolding\");\n let result;\n try {\n const selection = {\n projectName: choices.projectName,\n outDir: choices.outDir,\n apps: choices.apps,\n modules: resolved.modules,\n jsPm: choices.jsPm,\n pyPm: choices.pyPm,\n };\n const targets = selectedTargets(buildContext(selection));\n result = compose({\n selection,\n registry,\n scaffoldTargets: targets,\n wireTargets: targets,\n rootFiles: \"all\",\n });\n } catch (err) {\n s.stop(\"Failed\");\n log.error((err as Error).message);\n process.exit(1);\n }\n s.stop(`Created ${result.written.length} files`);\n\n writeProjectManifest(choices.outDir, {\n name: choices.projectName,\n apps: choices.apps,\n modules: resolved.modules,\n jsPm: choices.jsPm,\n pyPm: choices.pyPm,\n });\n\n const rel = basename(choices.outDir);\n const steps = [`cd ${rel}`, \"make bootstrap\"];\n if (choices.apps.includes(\"server\")) steps.push(\"make db-up && make migrate\", \"make server\");\n if (choices.apps.includes(\"web\")) steps.push(\"make web\");\n if (choices.apps.includes(\"mobile\")) steps.push(\"make mobile\");\n note(steps.join(\"\\n\"), \"Next steps\");\n\n if (result.notes.length) note(result.notes.join(\"\\n\"), \"Notes\");\n outro(pc.green(\"Done.\"));\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n appendEnv,\n injectAtAnchor,\n mergePackageJsonDeps,\n} from \"./inject.js\";\nimport { copyTree, listFiles, writeFileEnsured } from \"./fsutil.js\";\nimport { DEFAULT_JS_PM, DEFAULT_PY_PM } from \"./pm.js\";\nimport type { Registry } from \"./registry.js\";\nimport { isBinaryPath, slugify } from \"./render.js\";\nimport {\n buildBaseEnv,\n buildCiWorkflows,\n buildMakefile,\n buildNpmrc,\n buildPipSyncScript,\n buildJsWorkspace,\n buildReadme,\n buildRootPackageJson,\n buildServerDockerfile,\n buildTsconfigBase,\n buildTurboJson,\n} from \"./rootgen.js\";\nimport {\n CONVENIENCE_ANCHORS,\n type Module,\n type RenderContext,\n type Selection,\n TARGET_DEST,\n type TargetName,\n type WiringForTarget,\n} from \"./types.js\";\n\n/** Which computed root files to (re)write. */\nexport type RootFilesMode = \"all\" | \"structural\" | \"none\";\n\nexport interface ComposeOptions {\n selection: Selection;\n registry: Registry;\n /** copy the bare _core scaffold for these targets (new apps) */\n scaffoldTargets: Set<TargetName>;\n /** copy module files + apply wiring for these targets */\n wireTargets: Set<TargetName>;\n /** which computed root files to (re)write: all (create), structural (add-app), none (add-module) */\n rootFiles: RootFilesMode;\n}\n\nexport interface ComposeResult {\n written: string[];\n notes: string[];\n}\n\nexport function buildContext(selection: Selection): RenderContext {\n const hasServer = selection.apps.includes(\"server\");\n const hasWeb = selection.apps.includes(\"web\");\n const hasMobile = selection.apps.includes(\"mobile\");\n const hasShared = hasWeb || hasMobile;\n const hasApiClient = hasServer && (hasWeb || hasMobile);\n return {\n projectName: selection.projectName,\n projectSlug: slugify(selection.projectName),\n description: `${selection.projectName} — generated with partweave.`,\n apps: selection.apps,\n hasServer,\n hasWeb,\n hasMobile,\n hasShared,\n hasApiClient,\n jsPm: selection.jsPm ?? DEFAULT_JS_PM,\n pyPm: selection.pyPm ?? DEFAULT_PY_PM,\n };\n}\n\nexport function selectedTargets(ctx: RenderContext): Set<TargetName> {\n const t = new Set<TargetName>([\"root\"]);\n if (ctx.hasServer) t.add(\"server\");\n if (ctx.hasWeb) t.add(\"web\");\n if (ctx.hasMobile) t.add(\"mobile\");\n if (ctx.hasShared) t.add(\"shared\");\n if (ctx.hasApiClient) t.add(\"api-client\");\n return t;\n}\n\nconst COPY_ORDER: TargetName[] = [\n \"root\",\n \"server\",\n \"web\",\n \"mobile\",\n \"shared\",\n \"api-client\",\n];\n\n/** Scan a directory tree for `<partweave:id>` anchors → the files that contain them. */\nfunction buildAnchorIndex(dir: string): Map<string, string[]> {\n const index = new Map<string, string[]>();\n const re = /<partweave:([\\w-]+)>/g;\n for (const rel of listFiles(dir)) {\n const abs = join(dir, rel);\n if (isBinaryPath(abs)) continue;\n const content = readFileSync(abs, \"utf8\");\n let m: RegExpExecArray | null;\n while ((m = re.exec(content))) {\n const id = m[1];\n const arr = index.get(id) ?? [];\n if (!arr.includes(abs)) arr.push(abs);\n index.set(id, arr);\n }\n }\n return index;\n}\n\n/** Collect every anchor→lines injection a module contributes to one target. */\nfunction anchorInjections(w: WiringForTarget): Record<string, string[]> {\n const out: Record<string, string[]> = {};\n const push = (anchor: string, lines: string[] | undefined) => {\n if (!lines?.length) return;\n out[anchor] = [...(out[anchor] ?? []), ...lines];\n };\n for (const [field, anchor] of Object.entries(CONVENIENCE_ANCHORS)) {\n push(anchor, (w as Record<string, string[] | undefined>)[field]);\n }\n if (w.anchors) for (const [a, lines] of Object.entries(w.anchors)) push(a, lines);\n return out;\n}\n\nfunction injectIntoFiles(\n index: Map<string, string[]>,\n anchorId: string,\n lines: string[],\n targetLabel: string,\n): void {\n const files = index.get(anchorId);\n if (!files || files.length === 0) {\n throw new Error(\n `Wiring error: anchor <partweave:${anchorId}> not found in ${targetLabel}. ` +\n `Add the anchor to the _core/${targetLabel} scaffold.`,\n );\n }\n for (const file of files) {\n const content = readFileSync(file, \"utf8\");\n const { content: next } = injectAtAnchor(content, anchorId, lines);\n writeFileSync(file, next);\n }\n}\n\nfunction applyWiring(\n outDir: string,\n targets: Set<TargetName>,\n modules: Module[],\n): void {\n // one anchor index per present target directory\n const indexes = new Map<TargetName, Map<string, string[]>>();\n for (const t of targets) {\n indexes.set(t, buildAnchorIndex(join(outDir, TARGET_DEST[t])));\n }\n\n for (const mod of modules) {\n for (const t of mod.manifest.targets) {\n if (!targets.has(t)) continue;\n const wiring = mod.manifest.wiring[t];\n if (!wiring) continue;\n const index = indexes.get(t)!;\n const targetDir = join(outDir, TARGET_DEST[t]);\n\n // anchor-based wiring\n for (const [anchor, lines] of Object.entries(anchorInjections(wiring))) {\n injectIntoFiles(index, anchor, lines, t);\n }\n\n // dependency merging\n if (wiring.deps?.length) {\n if (t === \"server\") {\n // Python deps → inject into pyproject's <partweave:deps> anchor\n const lines = wiring.deps.map((d) => `\"${d}\",`);\n injectIntoFiles(index, \"deps\", lines, t);\n } else {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const merged = mergePackageJsonDeps(\n readFileSync(pkgPath, \"utf8\"),\n wiring.deps,\n );\n writeFileSync(pkgPath, merged);\n }\n }\n }\n }\n }\n}\n\nfunction applyEnv(outDir: string, modules: Module[]): void {\n const envPath = join(outDir, \".env.example\");\n let body = existsSync(envPath) ? readFileSync(envPath, \"utf8\") : \"\";\n for (const mod of modules) {\n if (Object.keys(mod.manifest.env).length === 0) continue;\n body = appendEnv(body, mod.manifest.env, mod.manifest.title);\n }\n if (body) writeFileSync(envPath, body);\n}\n\n/** Derived, selection-dependent monorepo shell files (safe to regenerate). */\nfunction writeStructuralRootFiles(\n outDir: string,\n ctx: RenderContext,\n modules: Module[],\n): void {\n // pnpm lists workspace members in pnpm-workspace.yaml; npm lists them in\n // package.json's \"workspaces\" field (built by buildRootPackageJson).\n const workspace = buildJsWorkspace(ctx);\n if (workspace) writeFileEnsured(join(outDir, \"pnpm-workspace.yaml\"), workspace);\n const rootPkg = buildRootPackageJson(ctx);\n if (rootPkg) writeFileEnsured(join(outDir, \"package.json\"), rootPkg);\n const turbo = buildTurboJson(ctx);\n if (turbo) writeFileEnsured(join(outDir, \"turbo.json\"), turbo);\n const tsbase = buildTsconfigBase(ctx);\n if (tsbase) writeFileEnsured(join(outDir, \"tsconfig.base.json\"), tsbase);\n const npmrc = buildNpmrc(ctx);\n if (npmrc) writeFileEnsured(join(outDir, \".npmrc\"), npmrc);\n // pip path: a helper that installs the server's deps from pyproject into .venv.\n const pipSync = buildPipSyncScript(ctx);\n if (pipSync) writeFileEnsured(join(outDir, \"apps/server/scripts/sync_deps.py\"), pipSync);\n const hasDocker = modules.some((m) => m.manifest.id === \"docker\");\n writeFileEnsured(join(outDir, \"Makefile\"), buildMakefile(ctx, hasDocker));\n writeFileEnsured(join(outDir, \".env.example\"), buildBaseEnv(ctx));\n}\n\nexport function compose(opts: ComposeOptions): ComposeResult {\n const { selection, registry, scaffoldTargets, wireTargets, rootFiles } = opts;\n const ctx = buildContext(selection);\n const outDir = selection.outDir;\n const modules = selection.modules.map((id) => registry.require(id));\n const written: string[] = [];\n\n // 1. scaffold bare _core for new targets\n for (const t of COPY_ORDER) {\n if (!scaffoldTargets.has(t)) continue;\n const src = join(registry.modulesDir, \"_core\", t);\n if (existsSync(src)) {\n written.push(...copyTree(src, join(outDir, TARGET_DEST[t]), ctx));\n }\n }\n\n // 2. computed root files (env is re-appended by applyEnv below, idempotently)\n if (rootFiles !== \"none\") writeStructuralRootFiles(outDir, ctx, modules);\n if (rootFiles === \"all\") {\n writeFileEnsured(join(outDir, \"README.md\"), buildReadme(ctx, modules));\n }\n\n // 3. module files for the targets being wired\n for (const mod of modules) {\n for (const t of mod.manifest.targets) {\n if (!wireTargets.has(t)) continue;\n const src = join(mod.dir, t);\n if (existsSync(src)) {\n written.push(...copyTree(src, join(outDir, TARGET_DEST[t]), ctx));\n }\n }\n }\n\n // 4. wiring (restricted to the targets being wired)\n applyWiring(outDir, wireTargets, modules);\n\n // 5. env\n applyEnv(outDir, modules);\n\n // 6. CI workflows — the `ci` component is a codegen marker (no template\n // files); it emits per-app, path-filtered GitHub Actions for present apps.\n if (selection.modules.includes(\"ci\")) {\n for (const [rel, content] of Object.entries(buildCiWorkflows(ctx))) {\n writeFileEnsured(join(outDir, rel), content);\n written.push(rel);\n }\n }\n\n // 6b. Server Dockerfile — emitted from code (not a copied template) so it can\n // target uv or pip. The `docker` module still ships .dockerignore + compose.\n if (selection.modules.includes(\"docker\") && ctx.hasServer) {\n const rel = \"apps/server/Dockerfile\";\n writeFileEnsured(join(outDir, rel), buildServerDockerfile(ctx));\n written.push(rel);\n }\n\n // 7. notes\n const notes = modules.flatMap((m) => m.manifest.notes);\n return { written, notes };\n}\n","/**\n * Wiring primitives: deterministic, idempotent injection at anchor comments and\n * dependency merging. All functions take file *content* and return new content,\n * so callers control IO.\n */\n\n/** Build the regex that finds an anchor line for a given id. */\nfunction anchorRegex(anchorId: string): RegExp {\n // matches any line containing `<partweave:anchorId>` (comment syntax agnostic)\n return new RegExp(`^([ \\\\t]*).*<partweave:${escapeRe(anchorId)}>.*$`, \"m\");\n}\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Inserts `lines` immediately before the `<partweave:anchorId>` line, matching its\n * indentation. Idempotent: a line already present (trimmed) is skipped.\n * Returns the new content and how many lines were actually inserted.\n */\nexport function injectAtAnchor(\n content: string,\n anchorId: string,\n lines: string[],\n): { content: string; inserted: number } {\n if (lines.length === 0) return { content, inserted: 0 };\n const re = anchorRegex(anchorId);\n const match = re.exec(content);\n if (!match) {\n throw new Error(`Anchor <partweave:${anchorId}> not found in target file`);\n }\n const indent = match[1] ?? \"\";\n const existing = new Set(\n content.split(\"\\n\").map((l) => l.trim()).filter(Boolean),\n );\n const toInsert = lines.filter((l) => !existing.has(l.trim()));\n if (toInsert.length === 0) return { content, inserted: 0 };\n\n const block = toInsert.map((l) => (l ? indent + l : \"\")).join(\"\\n\") + \"\\n\";\n const anchorStart = match.index;\n const newContent =\n content.slice(0, anchorStart) + block + content.slice(anchorStart);\n return { content: newContent, inserted: toInsert.length };\n}\n\nexport function hasAnchor(content: string, anchorId: string): boolean {\n return anchorRegex(anchorId).test(content);\n}\n\n/** Parse \"name@version\" (supports scoped @scope/name@version). */\nexport function parseDep(dep: string): { name: string; version: string } {\n const at = dep.lastIndexOf(\"@\");\n if (at > 0) {\n return { name: dep.slice(0, at), version: dep.slice(at + 1) };\n }\n return { name: dep, version: \"latest\" };\n}\n\n/** Merge npm deps into a package.json string, sorted, idempotent. */\nexport function mergePackageJsonDeps(\n pkgJson: string,\n deps: string[],\n field: \"dependencies\" | \"devDependencies\" = \"dependencies\",\n): string {\n if (deps.length === 0) return pkgJson;\n const pkg = JSON.parse(pkgJson) as Record<string, unknown>;\n const bucket = (pkg[field] as Record<string, string> | undefined) ?? {};\n for (const dep of deps) {\n const { name, version } = parseDep(dep);\n if (!(name in bucket)) bucket[name] = version;\n }\n pkg[field] = Object.fromEntries(\n Object.entries(bucket).sort(([a], [b]) => a.localeCompare(b)),\n );\n return JSON.stringify(pkg, null, 2) + \"\\n\";\n}\n\n/** Append env keys to a .env.example body, skipping ones already present. */\nexport function appendEnv(\n envBody: string,\n entries: Record<string, string>,\n heading?: string,\n): string {\n const keys = Object.keys(entries);\n if (keys.length === 0) return envBody;\n const present = new Set(\n envBody\n .split(\"\\n\")\n .map((l) => l.split(\"=\")[0]?.trim())\n .filter(Boolean),\n );\n const missing = keys.filter((k) => !present.has(k));\n if (missing.length === 0) return envBody;\n let out = envBody.replace(/\\n*$/, \"\\n\");\n if (heading) out += `\\n# ${heading}\\n`;\n for (const k of missing) out += `${k}=${entries[k]}\\n`;\n return out;\n}\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { isBinaryPath, render } from \"./render.js\";\nimport type { RenderContext } from \"./types.js\";\n\nexport function ensureDir(dir: string): void {\n mkdirSync(dir, { recursive: true });\n}\n\nexport function readIfExists(p: string): string | null {\n return existsSync(p) ? readFileSync(p, \"utf8\") : null;\n}\n\nexport function writeFileEnsured(p: string, content: string): void {\n ensureDir(dirname(p));\n writeFileSync(p, content);\n}\n\n/** List every file (recursively) under `root`, as paths relative to `root`. */\nexport function listFiles(root: string): string[] {\n const out: string[] = [];\n const walk = (dir: string): void => {\n for (const name of readdirSync(dir)) {\n const abs = join(dir, name);\n if (statSync(abs).isDirectory()) walk(abs);\n else out.push(relative(root, abs));\n }\n };\n if (existsSync(root)) walk(root);\n return out;\n}\n\n/**\n * Copy a template tree into `destRoot`, rendering text files through {{tokens}}.\n * Skips the module.json manifest. `gitignore` files are renamed from the safe\n * `_gitignore` template name back to `.gitignore` on copy.\n */\nexport function copyTree(\n srcRoot: string,\n destRoot: string,\n ctx: RenderContext,\n): string[] {\n const written: string[] = [];\n for (const rel of listFiles(srcRoot)) {\n if (rel === \"module.json\") continue;\n const src = join(srcRoot, rel);\n const destRel = rel.replace(/(^|\\/)_gitignore$/, \"$1.gitignore\");\n const dest = join(destRoot, destRel);\n ensureDir(dirname(dest));\n if (isBinaryPath(src)) {\n cpSync(src, dest);\n } else {\n writeFileSync(dest, render(readFileSync(src, \"utf8\"), ctx));\n }\n written.push(destRel);\n }\n return written;\n}\n","import type { RenderContext } from \"./types.js\";\n\n/**\n * Minimal, collision-safe templating: replaces only `{{ known.token }}` where\n * the token is a known key. React's `style={{ ... }}` and JS `${...}` never\n * match, because the inner text must be a dotted identifier immediately closed\n * by `}}`. Unknown tokens are left untouched.\n */\nconst TOKEN = /\\{\\{\\s*([\\w.]+)\\s*\\}\\}/g;\n\nexport function buildScalars(ctx: RenderContext): Record<string, string> {\n return {\n projectName: ctx.projectName,\n projectSlug: ctx.projectSlug,\n description: ctx.description,\n // Java/Android package segments allow underscores but not hyphens.\n packageId: \"com.example.\" + ctx.projectSlug.replace(/-/g, \"_\"),\n \"apps.list\": ctx.apps.join(\", \"),\n };\n}\n\nexport function render(content: string, ctx: RenderContext): string {\n const scalars = buildScalars(ctx);\n return content.replace(TOKEN, (whole, key: string) => {\n if (Object.prototype.hasOwnProperty.call(scalars, key)) return scalars[key];\n return whole; // leave unknown tokens as-is\n });\n}\n\n/** Files that must be copied byte-for-byte (never templated). */\nconst BINARY_EXT = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".ttf\",\n \".otf\",\n \".woff\",\n \".woff2\",\n \".pdf\",\n \".zip\",\n]);\n\nexport function isBinaryPath(p: string): boolean {\n const dot = p.lastIndexOf(\".\");\n if (dot === -1) return false;\n return BINARY_EXT.has(p.slice(dot).toLowerCase());\n}\n\nexport function slugify(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/-{2,}/g, \"-\");\n}\n","import { spawnSync } from \"node:child_process\";\n\n/**\n * Package-manager abstraction. Generated projects can use pnpm or npm for the\n * JS/TS workspace, and uv or pip for the Django server — this module maps a\n * chosen manager to the exact commands, so the Makefile / CI / package.json the\n * generator emits speak whichever tool the user actually has installed.\n */\n\nexport const JS_PMS = [\"pnpm\", \"npm\"] as const;\nexport type JsPm = (typeof JS_PMS)[number];\n\nexport const PY_PMS = [\"uv\", \"pip\"] as const;\nexport type PyPm = (typeof PY_PMS)[number];\n\nexport const DEFAULT_JS_PM: JsPm = \"pnpm\";\nexport const DEFAULT_PY_PM: PyPm = \"uv\";\n\nexport interface JsPmProfile {\n name: JsPm;\n /** install every workspace's dependencies */\n install: string;\n /** run a package.json script in one workspace member (by its package name) */\n run(pkg: string, script: string): string;\n /** run a script in every workspace that defines it */\n runAll(script: string): string;\n /** value for package.json \"packageManager\", or null to omit the field */\n packageManagerField: string | null;\n /** pnpm declares members in pnpm-workspace.yaml; npm uses \"workspaces\" in package.json */\n usesWorkspaceYaml: boolean;\n /** pnpm's symlinked store breaks Expo, so a mobile project needs a hoisted .npmrc; npm is already flat */\n needsHoistNpmrc: boolean;\n}\n\nconst PNPM_VERSION = \"pnpm@10.20.0\";\n\nexport function jsPmProfile(name: JsPm): JsPmProfile {\n if (name === \"npm\") {\n return {\n name,\n install: \"npm install\",\n run: (pkg, script) => `npm run ${script} -w ${pkg}`,\n runAll: (script) => `npm run ${script} --workspaces --if-present`,\n packageManagerField: null,\n usesWorkspaceYaml: false,\n needsHoistNpmrc: false,\n };\n }\n return {\n name: \"pnpm\",\n install: \"pnpm install\",\n run: (pkg, script) => `pnpm --filter ${pkg} ${script}`,\n runAll: (script) => `pnpm -r ${script}`,\n packageManagerField: PNPM_VERSION,\n usesWorkspaceYaml: true,\n needsHoistNpmrc: true,\n };\n}\n\nexport interface PyPmProfile {\n name: PyPm;\n /**\n * Commands (already `&&`-joined) to create/refresh the server's environment\n * from pyproject.toml, run *inside* apps/server. Used by `make bootstrap`,\n * CI, and `partweave add`.\n */\n syncInServer: string;\n /** run a console command (e.g. \"python manage.py migrate\") inside the server env */\n run(cmd: string): string;\n /** pip needs a generated helper to install deps from pyproject; uv reads it natively */\n needsSyncScript: boolean;\n}\n\n/** Create/refresh a local .venv from pyproject and install its deps (pip path). */\nconst PIP_SYNC =\n \"python3 -m venv .venv && .venv/bin/python -m pip install -U pip && \" +\n \".venv/bin/python scripts/sync_deps.py\";\n\nexport function pyPmProfile(name: PyPm): PyPmProfile {\n if (name === \"pip\") {\n return {\n name,\n syncInServer: PIP_SYNC,\n run: (cmd) => `.venv/bin/${cmd}`,\n needsSyncScript: true,\n };\n }\n return {\n name: \"uv\",\n syncInServer: \"uv sync\",\n run: (cmd) => `uv run ${cmd}`,\n needsSyncScript: false,\n };\n}\n\n/** Is a command available on PATH? Used to pick sensible PM defaults. */\nexport function hasCommand(cmd: string): boolean {\n try {\n const probe =\n process.platform === \"win32\"\n ? spawnSync(\"where\", [cmd], { stdio: \"ignore\" })\n : spawnSync(\"sh\", [\"-c\", `command -v ${cmd}`], { stdio: \"ignore\" });\n return probe.status === 0;\n } catch {\n return false;\n }\n}\n\n/** Prefer pnpm/uv when installed, else fall back to the universally-available npm/pip. */\nexport function detectJsPm(): JsPm {\n return hasCommand(\"pnpm\") ? \"pnpm\" : \"npm\";\n}\nexport function detectPyPm(): PyPm {\n return hasCommand(\"uv\") ? \"uv\" : \"pip\";\n}\n","import { randomBytes } from \"node:crypto\";\nimport { jsPmProfile, pyPmProfile } from \"./pm.js\";\nimport type { Module, RenderContext } from \"./types.js\";\n\n/**\n * The monorepo shell files that depend on *which* parts were selected are built\n * here in code (rather than copied from a template), so a server-only project\n * never mentions pnpm and a mobile-only project never mentions Postgres. These\n * builders also speak the project's chosen package managers (pnpm/npm, uv/pip).\n */\n\n/** JS/TS workspace member list. */\nfunction jsMembers(ctx: RenderContext): string[] {\n const members: string[] = [];\n if (ctx.hasWeb) members.push(\"apps/web\");\n if (ctx.hasMobile) members.push(\"apps/mobile\");\n if (ctx.hasShared) members.push(\"packages/shared\");\n if (ctx.hasApiClient) members.push(\"packages/api-client\");\n return members;\n}\n\n/**\n * pnpm declares workspace members in pnpm-workspace.yaml. npm declares them in\n * package.json instead (see buildRootPackageJson), so this returns null for npm.\n */\nexport function buildJsWorkspace(ctx: RenderContext): string | null {\n if (!jsPmProfile(ctx.jsPm).usesWorkspaceYaml) return null;\n const members = jsMembers(ctx);\n if (members.length === 0) return null;\n return \"packages:\\n\" + members.map((m) => ` - \"${m}\"`).join(\"\\n\") + \"\\n\";\n}\n\nexport function buildRootPackageJson(ctx: RenderContext): string | null {\n const anyJs = ctx.hasWeb || ctx.hasMobile || ctx.hasShared;\n if (!anyJs) return null;\n const pm = jsPmProfile(ctx.jsPm);\n const scripts: Record<string, string> = {};\n if (ctx.hasWeb) scripts[\"dev:web\"] = pm.run(\"web\", \"dev\");\n if (ctx.hasMobile) scripts[\"dev:mobile\"] = pm.run(\"mobile\", \"start\");\n if (ctx.hasApiClient) scripts[\"gen:api\"] = pm.run(\"@app/api-client\", \"generate\");\n scripts[\"typecheck\"] = pm.runAll(\"typecheck\");\n const pkg: Record<string, unknown> = {\n name: ctx.projectSlug,\n version: \"0.1.0\",\n private: true,\n };\n if (pm.packageManagerField) pkg.packageManager = pm.packageManagerField;\n // npm keeps its workspace member list here (pnpm uses pnpm-workspace.yaml).\n if (!pm.usesWorkspaceYaml) pkg.workspaces = jsMembers(ctx);\n pkg.scripts = scripts;\n pkg.devDependencies = { typescript: \"^5.7.2\" };\n return JSON.stringify(pkg, null, 2) + \"\\n\";\n}\n\nexport function buildMakefile(ctx: RenderContext, hasDocker: boolean): string {\n const js = jsPmProfile(ctx.jsPm);\n const py = pyPmProfile(ctx.pyPm);\n const L: string[] = [];\n const phony: string[] = [];\n const add = (name: string, body: string[], help: string) => {\n phony.push(name);\n L.push(`${name}: ## ${help}`);\n for (const line of body) L.push(`\\t${line}`);\n L.push(\"\");\n };\n\n L.push(\"# \" + ctx.projectName + \" — dev tasks\");\n L.push(\".DEFAULT_GOAL := help\");\n L.push(\"\");\n\n const bootstrap: string[] = [];\n if (ctx.hasWeb || ctx.hasMobile || ctx.hasShared) bootstrap.push(js.install);\n // Each Makefile recipe line runs in its own shell, so keep `cd` and the sync\n // command on one `&&`-joined line.\n if (ctx.hasServer) bootstrap.push(`cd apps/server && ${py.syncInServer}`);\n if (bootstrap.length) add(\"bootstrap\", bootstrap, \"install all dependencies\");\n\n if (ctx.hasServer) {\n if (hasDocker) {\n add(\n \"db-up\",\n [\n '@docker info >/dev/null 2>&1 || { echo \"Docker isn\\'t running — start Docker Desktop and wait for it to be ready, then retry.\"; exit 1; }',\n // Load the project's .env (if present) so POSTGRES_* there drive the container.\n \"docker compose $$([ -f .env ] && echo --env-file .env) -f infra/docker-compose.yml up -d db\",\n ],\n \"start Postgres (needs Docker running)\",\n );\n add(\"db-down\", [\"docker compose -f infra/docker-compose.yml down\"], \"stop Postgres\");\n }\n add(\"migrate\", [`cd apps/server && ${py.run(\"python manage.py migrate\")}`], \"run migrations\");\n add(\n \"server\",\n [`cd apps/server && ${py.run(\"python manage.py runserver 0.0.0.0:8000\")}`],\n \"run the Django dev server\",\n );\n add(\n \"superuser\",\n [`cd apps/server && ${py.run(\"python manage.py createsuperuser\")}`],\n \"create an admin user\",\n );\n }\n if (ctx.hasWeb) add(\"web\", [js.run(\"web\", \"dev\")], \"run the Next.js dev server\");\n if (ctx.hasMobile) add(\"mobile\", [js.run(\"mobile\", \"start\")], \"run the Expo dev server\");\n if (ctx.hasApiClient)\n add(\"gen-api\", [js.run(\"@app/api-client\", \"generate\")], \"regenerate the typed API client\");\n\n L.push(\n \"help: ## show this help\",\n '\\t@grep -E \\'^[a-zA-Z_-]+:.*?## .*$$\\' $(MAKEFILE_LIST) | awk \\'BEGIN {FS = \":.*?## \"}; {printf \" \\\\033[36m%-12s\\\\033[0m %s\\\\n\", $$1, $$2}\\'',\n \"\",\n \".PHONY: \" + [...phony, \"help\"].join(\" \"),\n \"\",\n );\n return L.join(\"\\n\");\n}\n\nexport function buildTurboJson(ctx: RenderContext): string | null {\n if (!(ctx.hasWeb || ctx.hasMobile || ctx.hasShared)) return null;\n return (\n JSON.stringify(\n {\n $schema: \"https://turbo.build/schema.json\",\n tasks: {\n build: { dependsOn: [\"^build\"], outputs: [\"dist/**\", \".next/**\"] },\n dev: { cache: false, persistent: true },\n typecheck: { dependsOn: [\"^build\"] },\n lint: {},\n },\n },\n null,\n 2,\n ) + \"\\n\"\n );\n}\n\nexport function buildTsconfigBase(ctx: RenderContext): string | null {\n if (!(ctx.hasWeb || ctx.hasMobile || ctx.hasShared)) return null;\n return (\n JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n lib: [\"ES2023\"],\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n isolatedModules: true,\n },\n },\n null,\n 2,\n ) + \"\\n\"\n );\n}\n\n/**\n * React Native / Expo behave badly with pnpm's symlinked store, so a mobile\n * project pins a hoisted node_modules layout. npm already installs flat, so it\n * needs no .npmrc.\n */\nexport function buildNpmrc(ctx: RenderContext): string | null {\n if (!ctx.hasMobile) return null;\n if (!jsPmProfile(ctx.jsPm).needsHoistNpmrc) return null;\n return [\n \"# Expo / React Native need a flat node_modules layout.\",\n \"node-linker=hoisted\",\n \"shamefully-hoist=true\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function buildBaseEnv(ctx: RenderContext): string {\n const lines: string[] = [\n \"# Environment for \" + ctx.projectName,\n \"#\",\n \"# Every value the app reads from the environment lives here. Copy this file to\",\n \"# `.env` and adjust as needed — the server, web/mobile apps, and each component\",\n \"# read their configuration from it, so there's nothing to configure elsewhere.\",\n \"\",\n ];\n if (ctx.hasServer) {\n lines.push(\n \"# --- server ---\",\n \"# Unique per-project key generated at scaffold time; signs sessions and JWTs.\",\n \"# Use a separate secret value in production (and never commit the real one).\",\n `DJANGO_SECRET_KEY=${randomBytes(48).toString(\"base64url\")}`,\n \"DJANGO_DEBUG=true\",\n \"DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1\",\n \"# Web origins allowed to call the API when DEBUG is off (comma-separated).\",\n \"# In DEBUG every origin is allowed, so this is only needed in production.\",\n \"# DJANGO_CORS_ALLOWED_ORIGINS=https://app.example.com\",\n \"# DATABASE_URL — the server uses local SQLite by default; set a database URL\",\n \"# to switch (the `db-postgres` component sets a Postgres DSN here for you).\",\n \"\",\n );\n }\n if (ctx.hasWeb) {\n lines.push(\"# --- web ---\", \"NEXT_PUBLIC_API_URL=http://localhost:8000\", \"\");\n }\n if (ctx.hasMobile) {\n lines.push(\n \"# --- mobile (Expo) ---\",\n \"# In dev the app auto-detects your machine's LAN IP so a physical device can\",\n \"# reach the server — leave this unset. Set it for simulators or production,\",\n \"# in the environment or apps/mobile/.env (Expo reads EXPO_PUBLIC_* from there).\",\n \"# EXPO_PUBLIC_API_URL=http://localhost:8000\",\n \"\",\n );\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Per-app GitHub Actions with path filters, so a change to one app only runs\n * that app's pipeline. Returns { relativePath: content } for present apps.\n */\n/** GitHub Actions steps (8-space indented, under `steps:`) that set up the JS PM and install. */\nfunction jsCiSteps(ctx: RenderContext): string {\n if (ctx.jsPm === \"npm\") {\n return ` - uses: actions/setup-node@v4\n with:\n node-version: 20\n - run: npm install`;\n }\n return ` - uses: pnpm/action-setup@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 20\n cache: pnpm\n - run: pnpm install --frozen-lockfile`;\n}\n\n/** GitHub Actions steps that set up the Python PM, install deps, and run checks (working-directory: apps/server). */\nfunction serverCiSteps(ctx: RenderContext): string {\n const py = pyPmProfile(ctx.pyPm);\n if (ctx.pyPm === \"pip\") {\n return ` - uses: actions/setup-python@v5\n with:\n python-version: \"3.12\"\n - run: ${py.syncInServer}\n - run: ${py.run(\"ruff check .\")}\n - run: ${py.run(\"python manage.py migrate\")}\n - run: ${py.run(\"pytest -q\")}`;\n }\n return ` - uses: astral-sh/setup-uv@v5\n - run: ${py.syncInServer}\n - run: ${py.run(\"ruff check .\")}\n - run: ${py.run(\"python manage.py migrate\")}\n - run: ${py.run(\"pytest -q\")}`;\n}\n\nexport function buildCiWorkflows(ctx: RenderContext): Record<string, string> {\n const js = jsPmProfile(ctx.jsPm);\n const out: Record<string, string> = {};\n if (ctx.hasServer) {\n out[\".github/workflows/server.yml\"] = `name: server\non:\n push:\n paths: [\"apps/server/**\", \".github/workflows/server.yml\"]\n pull_request:\n paths: [\"apps/server/**\", \".github/workflows/server.yml\"]\njobs:\n test:\n runs-on: ubuntu-latest\n defaults:\n run:\n working-directory: apps/server\n steps:\n - uses: actions/checkout@v4\n${serverCiSteps(ctx)}\n`;\n }\n if (ctx.hasWeb) {\n out[\".github/workflows/web.yml\"] = `name: web\non:\n push:\n paths: [\"apps/web/**\", \"packages/**\", \".github/workflows/web.yml\"]\n pull_request:\n paths: [\"apps/web/**\", \"packages/**\", \".github/workflows/web.yml\"]\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${jsCiSteps(ctx)}\n - run: ${js.run(\"web\", \"typecheck\")}\n - run: ${js.run(\"web\", \"build\")}\n`;\n }\n if (ctx.hasMobile) {\n out[\".github/workflows/mobile.yml\"] = `name: mobile\non:\n push:\n paths: [\"apps/mobile/**\", \"packages/**\", \".github/workflows/mobile.yml\"]\n pull_request:\n paths: [\"apps/mobile/**\", \"packages/**\", \".github/workflows/mobile.yml\"]\njobs:\n typecheck:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${jsCiSteps(ctx)}\n - run: ${js.run(\"mobile\", \"typecheck\")}\n`;\n }\n return out;\n}\n\nexport function buildReadme(\n ctx: RenderContext,\n modules: Module[],\n): string {\n const parts: string[] = [];\n parts.push(`# ${ctx.projectName}`, \"\", ctx.description, \"\");\n parts.push(\"Generated with **partweave** — a modular full-stack scaffolder.\", \"\");\n\n parts.push(\"## What's inside\", \"\");\n if (ctx.hasServer) parts.push(`- \\`apps/server\\` — Django + DRF API (managed by \\`${ctx.pyPm}\\`)`);\n if (ctx.hasWeb) parts.push(\"- `apps/web` — Next.js web app\");\n if (ctx.hasMobile) parts.push(\"- `apps/mobile` — Expo (React Native) app\");\n if (ctx.hasShared) parts.push(\"- `packages/shared` — shared TypeScript interfaces & schemas\");\n if (ctx.hasApiClient) parts.push(\"- `packages/api-client` — typed client generated from the API's OpenAPI schema\");\n parts.push(\"\");\n\n if (modules.length) {\n parts.push(\"### Components\", \"\");\n for (const m of modules) parts.push(`- **${m.manifest.title}** — ${m.manifest.description ?? \"\"}`);\n parts.push(\"\");\n }\n\n parts.push(\"## Getting started\", \"\", \"```sh\", \"make bootstrap\");\n if (ctx.hasServer) parts.push(\"make db-up && make migrate\", \"make server # http://localhost:8000\");\n if (ctx.hasWeb) parts.push(\"make web # http://localhost:3000\");\n if (ctx.hasMobile) parts.push(\"make mobile # Expo dev server\");\n parts.push(\"```\", \"\");\n\n parts.push(\"Copy `.env.example` to `.env` and fill in values before running.\", \"\");\n return parts.join(\"\\n\");\n}\n\n/**\n * Production Dockerfile for the Django server. Emitted from code (not copied as\n * a template) so it can target uv or pip — the `docker` module only ships\n * .dockerignore and the Postgres compose file.\n */\nexport function buildServerDockerfile(ctx: RenderContext): string {\n if (ctx.pyPm === \"pip\") {\n return `# Production image for the Django server (pip / venv).\nFROM python:3.12-slim\n\nENV PYTHONUNBUFFERED=1 \\\\\n PYTHONDONTWRITEBYTECODE=1\n\nWORKDIR /app\n\nCOPY . .\nRUN python3 -m venv .venv \\\\\n && .venv/bin/python -m pip install -U pip \\\\\n && .venv/bin/python scripts/sync_deps.py --no-dev\n\nEXPOSE 8000\nCMD [\".venv/bin/gunicorn\", \"config.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]\n`;\n }\n return `# Production image for the Django server, built with uv.\nFROM python:3.12-slim\n\nENV PYTHONUNBUFFERED=1 \\\\\n PYTHONDONTWRITEBYTECODE=1 \\\\\n UV_COMPILE_BYTECODE=1 \\\\\n UV_LINK_MODE=copy\n\nWORKDIR /app\n\n# uv binary from the official distroless image\nCOPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv\n\nCOPY . .\nRUN uv sync --no-dev\n\nEXPOSE 8000\nCMD [\"uv\", \"run\", \"gunicorn\", \"config.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]\n`;\n}\n\n/**\n * Helper script for the pip path: installs the server's dependencies from\n * pyproject.toml into ./.venv. Re-runnable — used by `make bootstrap`, CI, the\n * production Docker build (`--no-dev`), and after `partweave add`. Returns\n * null when the project uses uv (which reads pyproject natively).\n */\nexport function buildPipSyncScript(ctx: RenderContext): string | null {\n if (!ctx.hasServer || !pyPmProfile(ctx.pyPm).needsSyncScript) return null;\n return `#!/usr/bin/env python3\n\"\"\"Install this app's dependencies from pyproject.toml into the active venv.\n\nThe pip/venv counterpart to \\`uv sync\\`. Run it (via the venv's Python) after\nadding a component so new dependencies are picked up:\n\n .venv/bin/python scripts/sync_deps.py # runtime + dev deps\n .venv/bin/python scripts/sync_deps.py --no-dev # runtime deps only (prod)\n\"\"\"\nimport subprocess\nimport sys\nimport tomllib\nfrom pathlib import Path\n\nno_dev = \"--no-dev\" in sys.argv[1:]\npyproject = Path(__file__).resolve().parent.parent / \"pyproject.toml\"\ndata = tomllib.loads(pyproject.read_text())\ndeps = list(data.get(\"project\", {}).get(\"dependencies\", []))\nif not no_dev:\n deps += data.get(\"dependency-groups\", {}).get(\"dev\", [])\nif deps:\n subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", *deps])\n`;\n}\n","import { z } from \"zod\";\nimport type { JsPm, PyPm } from \"./pm.js\";\n\n/**\n * A \"target\" is a destination sub-project inside the generated monorepo.\n * `_core/<target>/` holds the bare scaffold; every module contributes files\n * and wiring per target.\n */\nexport const TARGETS = [\n \"root\",\n \"server\",\n \"web\",\n \"mobile\",\n \"shared\",\n \"api-client\",\n] as const;\nexport type TargetName = (typeof TARGETS)[number];\n\n/** Where each target's files land in the generated project. */\nexport const TARGET_DEST: Record<TargetName, string> = {\n root: \".\",\n server: \"apps/server\",\n web: \"apps/web\",\n mobile: \"apps/mobile\",\n shared: \"packages/shared\",\n \"api-client\": \"packages/api-client\",\n};\n\n/** The three user-facing \"apps\" that can be toggled on/off. */\nexport const APPS = [\"server\", \"web\", \"mobile\"] as const;\nexport type AppName = (typeof APPS)[number];\n\n/**\n * Named convenience wiring fields map to well-known anchors in the _core\n * scaffolds. `<partweave:installed-apps>` etc. `anchors` is the generic escape hatch.\n */\nconst WiringForTargetSchema = z.object({\n installedApps: z.array(z.string()).optional(), // server → <partweave:installed-apps>\n urls: z.array(z.string()).optional(), // server → <partweave:urls>\n settings: z.array(z.string()).optional(), // server → <partweave:settings>\n providers: z.array(z.string()).optional(), // web/mobile → <partweave:providers>\n routes: z.array(z.string()).optional(), // web/mobile → <partweave:routes>\n deps: z.array(z.string()).optional(), // merged into pyproject/package.json\n anchors: z.record(z.array(z.string())).optional(), // generic anchorId → lines\n});\nexport type WiringForTarget = z.infer<typeof WiringForTargetSchema>;\n\n/** Maps a convenience field name to its well-known anchor id. */\nexport const CONVENIENCE_ANCHORS: Record<string, string> = {\n installedApps: \"installed-apps\",\n urls: \"urls\",\n settings: \"settings\",\n providers: \"providers\",\n routes: \"routes\",\n};\n\nexport const ManifestSchema = z.object({\n id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/, \"id must be kebab-case\"),\n title: z.string(),\n description: z.string().optional(),\n /** \"app\" = a top-level toggle (server/web/mobile); \"feature\" = a component. */\n kind: z.enum([\"app\", \"feature\"]).default(\"feature\"),\n /** which target sub-projects this module contributes to */\n targets: z.array(z.enum(TARGETS)).min(1),\n /** apps that MUST be selected for this module to work (e.g. auth needs server) */\n requiresApps: z.array(z.enum(APPS)).default([]),\n /** modules that must also be present (auto-selected) */\n requires: z.array(z.string()).default([]),\n /** modules that cannot coexist with this one */\n conflicts: z.array(z.string()).default([]),\n /** capability/interface this module satisfies (for conflict grouping) */\n provides: z.string().optional(),\n /** env keys → default value, appended to .env.example */\n env: z.record(z.string()).default({}),\n /** per-target wiring (files are copied separately from wiring injection) */\n wiring: z.record(z.enum(TARGETS), WiringForTargetSchema).default({}),\n /** whether this module is offered by default in the interactive picker */\n default: z.boolean().default(false),\n /** notes printed after generation */\n notes: z.array(z.string()).default([]),\n});\nexport type Manifest = z.infer<typeof ManifestSchema>;\n\n/** A manifest plus its absolute directory on disk. */\nexport interface Module {\n manifest: Manifest;\n dir: string;\n}\n\n/** The fully-resolved choice the composer acts on. */\nexport interface Selection {\n projectName: string;\n /** absolute output directory */\n outDir: string;\n /** chosen apps */\n apps: AppName[];\n /** chosen feature module ids (already dependency-resolved) */\n modules: string[];\n /** JS/TS package manager for the workspace (defaults to pnpm) */\n jsPm?: JsPm;\n /** Python package manager for the server (defaults to uv) */\n pyPm?: PyPm;\n}\n\n/** Template variables available to every copied text file via {{token}}. */\nexport interface RenderContext {\n projectName: string;\n projectSlug: string;\n description: string;\n apps: AppName[];\n hasServer: boolean;\n hasWeb: boolean;\n hasMobile: boolean;\n hasShared: boolean;\n hasApiClient: boolean;\n /** JS/TS package manager (pnpm | npm) */\n jsPm: JsPm;\n /** Python package manager (uv | pip) */\n pyPm: PyPm;\n}\n","import { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findModulesDir } from \"./paths.js\";\nimport { ManifestSchema, type Module } from \"./types.js\";\n\n/**\n * Loads every module manifest from the catalog. A \"module\" is any directory\n * under modules/ (except `_core`) that contains a `module.json`.\n */\nexport class Registry {\n readonly modulesDir: string;\n private readonly byId = new Map<string, Module>();\n\n constructor(modulesDir = findModulesDir()) {\n this.modulesDir = modulesDir;\n this.load();\n }\n\n private load(): void {\n for (const name of readdirSync(this.modulesDir)) {\n if (name === \"_core\" || name.startsWith(\".\")) continue;\n const dir = join(this.modulesDir, name);\n if (!statSync(dir).isDirectory()) continue;\n const manifestPath = join(dir, \"module.json\");\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(manifestPath, \"utf8\"));\n } catch {\n throw new Error(`Module \"${name}\" is missing a valid module.json`);\n }\n const parsed = ManifestSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(\n `Invalid module.json for \"${name}\":\\n${parsed.error.toString()}`,\n );\n }\n if (parsed.data.id !== name) {\n throw new Error(\n `Module dir \"${name}\" does not match manifest id \"${parsed.data.id}\"`,\n );\n }\n this.byId.set(parsed.data.id, { manifest: parsed.data, dir });\n }\n }\n\n get(id: string): Module | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): Module {\n const m = this.byId.get(id);\n if (!m) throw new Error(`Unknown module: \"${id}\"`);\n return m;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n all(): Module[] {\n return [...this.byId.values()];\n }\n\n /** Feature modules (not app-kind), sorted for stable display. */\n features(): Module[] {\n return this.all()\n .filter((m) => m.manifest.kind === \"feature\")\n .sort((a, b) => a.manifest.id.localeCompare(b.manifest.id));\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Locate the `modules/` catalog. Order:\n * 1. PARTWEAVE_MODULES_DIR env override\n * 2. walk up from this file looking for a `modules/_core` folder\n * Works whether run from src (tsx) or dist (built).\n */\nexport function findModulesDir(): string {\n const override = process.env.PARTWEAVE_MODULES_DIR;\n if (override) {\n const abs = resolve(override);\n if (existsSync(join(abs, \"_core\"))) return abs;\n throw new Error(`PARTWEAVE_MODULES_DIR=${override} has no _core/ inside it`);\n }\n\n let cur = here;\n for (let i = 0; i < 8; i++) {\n const candidate = join(cur, \"modules\");\n if (existsSync(join(candidate, \"_core\"))) return candidate;\n const parent = dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n throw new Error(\n \"Could not locate the modules/ catalog. Set PARTWEAVE_MODULES_DIR to point at it.\",\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { writeFileEnsured } from \"./fsutil.js\";\nimport type { JsPm, PyPm } from \"./pm.js\";\nimport type { AppName } from \"./types.js\";\n\n/**\n * A small record written into every generated project (`.partweave/manifest.json`)\n * so `partweave add` knows what apps and components are already installed —\n * and which package managers the project uses, so later `add`s stay consistent.\n */\nexport interface ProjectManifest {\n name: string;\n apps: AppName[];\n modules: string[];\n /** JS/TS package manager (defaults to pnpm for projects generated before this existed) */\n jsPm?: JsPm;\n /** Python package manager (defaults to uv for older projects) */\n pyPm?: PyPm;\n}\n\nconst REL = \".partweave/manifest.json\";\n\nexport function readProjectManifest(dir: string): ProjectManifest | null {\n const p = join(dir, REL);\n if (!existsSync(p)) return null;\n try {\n return JSON.parse(readFileSync(p, \"utf8\")) as ProjectManifest;\n } catch {\n return null;\n }\n}\n\nexport function writeProjectManifest(dir: string, pm: ProjectManifest): void {\n writeFileEnsured(join(dir, REL), JSON.stringify(pm, null, 2) + \"\\n\");\n}\n","import type { Registry } from \"./registry.js\";\nimport type { AppName } from \"./types.js\";\n\nexport interface ResolveResult {\n /** final module id list, dependency-complete, stably ordered */\n modules: string[];\n /** ids that were pulled in automatically to satisfy `requires` */\n autoAdded: string[];\n}\n\n/**\n * Expands `requires` transitively and rejects `conflicts`. Throws with a clear\n * message on unknown ids or conflicting pairs.\n */\nexport function resolveModules(\n registry: Registry,\n chosen: string[],\n): ResolveResult {\n const requested = new Set(chosen);\n const resolved = new Set<string>();\n const autoAdded = new Set<string>();\n\n const visit = (id: string, stack: string[]): void => {\n if (resolved.has(id)) return;\n if (stack.includes(id)) {\n throw new Error(\n `Circular module dependency: ${[...stack, id].join(\" → \")}`,\n );\n }\n const mod = registry.get(id);\n if (!mod) {\n throw new Error(`Unknown module: \"${id}\"`);\n }\n for (const dep of mod.manifest.requires) {\n if (!requested.has(dep)) autoAdded.add(dep);\n visit(dep, [...stack, id]);\n }\n resolved.add(id);\n };\n\n for (const id of chosen) visit(id, []);\n\n // conflict detection (both explicit `conflicts` and same `provides` capability)\n const provided = new Map<string, string>(); // capability → module id\n for (const id of resolved) {\n const mod = registry.require(id);\n for (const c of mod.manifest.conflicts) {\n if (resolved.has(c)) {\n throw new Error(`Modules \"${id}\" and \"${c}\" conflict and cannot both be selected.`);\n }\n }\n const cap = mod.manifest.provides;\n if (cap) {\n const other = provided.get(cap);\n if (other && other !== id) {\n throw new Error(\n `Modules \"${id}\" and \"${other}\" both provide \"${cap}\"; pick one.`,\n );\n }\n provided.set(cap, id);\n }\n }\n\n // stable order: sort by (number of deps, id) so deps precede dependents\n const order = [...resolved].sort((a, b) => {\n const da = registry.require(a).manifest.requires.length;\n const db = registry.require(b).manifest.requires.length;\n return da - db || a.localeCompare(b);\n });\n\n return { modules: order, autoAdded: [...autoAdded].sort() };\n}\n\n/**\n * Ensures every resolved module's `requiresApps` are in the chosen app set.\n * Throws a clear message listing the offending module → missing app.\n */\nexport function validateApps(\n registry: Registry,\n moduleIds: string[],\n apps: AppName[],\n): void {\n const have = new Set(apps);\n const problems: string[] = [];\n for (const id of moduleIds) {\n const mod = registry.require(id);\n for (const app of mod.manifest.requiresApps) {\n if (!have.has(app)) {\n problems.push(`\"${mod.manifest.id}\" needs the ${app} app`);\n }\n }\n }\n if (problems.length) {\n throw new Error(\n `Incompatible selection:\\n - ${problems.join(\"\\n - \")}\\n` +\n `Enable the required app(s) or drop the component(s).`,\n );\n }\n}\n","import {\n cancel,\n confirm,\n isCancel,\n multiselect,\n select,\n text,\n} from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { resolve } from \"node:path\";\nimport {\n detectJsPm,\n detectPyPm,\n hasCommand,\n type JsPm,\n type PyPm,\n} from \"./pm.js\";\nimport type { Registry } from \"./registry.js\";\nimport { slugify } from \"./render.js\";\nimport { APPS, type AppName, type TargetName } from \"./types.js\";\n\nexport interface RawChoices {\n projectName: string;\n outDir: string;\n apps: AppName[];\n modules: string[];\n jsPm: JsPm;\n pyPm: PyPm;\n}\n\n/** Controls hint for checkbox (multiselect) prompts. */\nconst MULTI_HINT = pc.dim(\"↑/↓ move · space toggle · a all · enter confirm\");\n\nfunction bail<T>(v: T | symbol): asserts v is T {\n if (isCancel(v)) {\n cancel(\"Cancelled.\");\n process.exit(0);\n }\n}\n\n/** Interactive flow for `create`. */\nexport async function promptCreate(\n registry: Registry,\n defaults: Partial<RawChoices>,\n): Promise<RawChoices> {\n const nameRaw = await text({\n message: \"Project name\",\n placeholder: \"my-project\",\n initialValue: defaults.projectName ?? \"\",\n validate: (v) => (v.trim() ? undefined : \"Required\"),\n });\n bail(nameRaw);\n const projectName = nameRaw.trim();\n\n const dirRaw = await text({\n message: \"Target directory\",\n initialValue: defaults.outDir ?? `./${slugify(projectName)}`,\n validate: (v) => (v.trim() ? undefined : \"Required\"),\n });\n bail(dirRaw);\n const outDir = resolve(dirRaw.trim());\n\n const appsRaw = await multiselect({\n message: `Which apps? ${MULTI_HINT}`,\n options: [\n { value: \"server\", label: \"Server\", hint: \"Django + DRF\" },\n { value: \"web\", label: \"Web\", hint: \"Next.js\" },\n { value: \"mobile\", label: \"Mobile\", hint: \"Expo / React Native\" },\n ],\n initialValues: (defaults.apps as string[]) ?? [...APPS],\n required: true,\n });\n bail(appsRaw);\n const apps = appsRaw as AppName[];\n\n // only offer components relevant to (and compatible with) the chosen apps\n const present = new Set<TargetName>(apps);\n if (apps.includes(\"web\") || apps.includes(\"mobile\")) present.add(\"shared\");\n const relevant = registry\n .features()\n .filter((m) => m.manifest.targets.some((t) => present.has(t)))\n .filter((m) => m.manifest.requiresApps.every((a) => apps.includes(a)));\n\n let modules: string[] = [];\n if (relevant.length) {\n const modsRaw = await multiselect({\n message: `Which components? (deps auto-added) ${MULTI_HINT}`,\n options: relevant.map((m) => ({\n value: m.manifest.id,\n label: m.manifest.title,\n hint: m.manifest.description,\n })),\n initialValues: relevant\n .filter((m) => m.manifest.default)\n .map((m) => m.manifest.id),\n required: false,\n });\n bail(modsRaw);\n modules = modsRaw as string[];\n }\n\n // Package managers — default to an explicit flag, else what's installed.\n const anyJs = apps.includes(\"web\") || apps.includes(\"mobile\");\n let jsPm: JsPm = defaults.jsPm ?? detectJsPm();\n if (anyJs) {\n const jsRaw = await select({\n message: \"JS/TS package manager\",\n initialValue: jsPm,\n options: [\n { value: \"pnpm\", label: \"pnpm\", hint: hasCommand(\"pnpm\") ? \"detected\" : \"not found on PATH\" },\n { value: \"npm\", label: \"npm\", hint: \"ships with Node\" },\n ],\n });\n bail(jsRaw);\n jsPm = jsRaw as JsPm;\n }\n\n let pyPm: PyPm = defaults.pyPm ?? detectPyPm();\n if (apps.includes(\"server\")) {\n const pyRaw = await select({\n message: \"Python package manager (server)\",\n initialValue: pyPm,\n options: [\n { value: \"uv\", label: \"uv\", hint: hasCommand(\"uv\") ? \"detected · fast\" : \"not found on PATH\" },\n { value: \"pip\", label: \"pip + venv\", hint: \"ships with Python\" },\n ],\n });\n bail(pyRaw);\n pyPm = pyRaw as PyPm;\n }\n\n const ok = await confirm({\n message: `Scaffold ${apps.join(\" + \")}${modules.length ? \" with \" + modules.join(\", \") : \"\"} into ${outDir}?`,\n });\n bail(ok);\n if (!ok) {\n cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n return { projectName, outDir, apps, modules, jsPm, pyPm };\n}\n"],"mappings":"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","names":["existsSync","readdirSync","resolve","pc","existsSync","readFileSync","writeFileSync","join","join","readFileSync","writeFileSync","existsSync","readdirSync","readFileSync","statSync","join","existsSync","dirname","join","readdirSync","join","statSync","readFileSync","existsSync","readFileSync","join","join","existsSync","readFileSync","resolve","resolve","pc","resolve","s","existsSync","readdirSync"]}
|
package/dist/create-bin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/create-bin.ts"],"sourcesContent":["import { runCreate, type CreateFlags } from \"./commands/create.js\";\nimport { Command } from \"commander\";\n\n/**\n * Dedicated `create-partweave` binary: same as `partweave create` but the create\n * command is the top-level program (npm-init style).\n */\nconst program = new Command();\nprogram\n .name(\"create-partweave\")\n .description(\"Scaffold a new full-stack project\")\n .argument(\"[name]\", \"project name\")\n .option(\"-d, --dir <path>\", \"target directory\")\n .option(\"--server\", \"include the Django server\")\n .option(\"--no-server\", \"exclude the server\")\n .option(\"--web\", \"include the Next.js web app\")\n .option(\"--no-web\", \"exclude the web app\")\n .option(\"--mobile\", \"include the Expo mobile app\")\n .option(\"--no-mobile\", \"exclude the mobile app\")\n .option(\"--with <ids>\", \"comma-separated component ids\")\n .option(\"--js-pm <pm>\", \"JS package manager: pnpm | npm (default: auto-detect)\")\n .option(\"--py-pm <pm>\", \"Python package manager: uv | pip (default: auto-detect)\")\n .option(\"-y, --yes\", \"skip prompts; use flags/defaults\")\n .option(\"-f, --force\", \"write into a non-empty directory\")\n .action(async (name: string | undefined, opts: Record<string, unknown>) => {\n const flags: CreateFlags = { ...(opts as CreateFlags), name };\n await runCreate(flags);\n });\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n"],"mappings":";;;;;;AACA,SAAS,eAAe;AAMxB,IAAM,UAAU,IAAI,QAAQ;AAC5B,QACG,KAAK,kBAAkB,EACvB,YAAY,mCAAmC,EAC/C,SAAS,UAAU,cAAc,EACjC,OAAO,oBAAoB,kBAAkB,EAC7C,OAAO,YAAY,2BAA2B,EAC9C,OAAO,eAAe,oBAAoB,EAC1C,OAAO,SAAS,6BAA6B,EAC7C,OAAO,YAAY,qBAAqB,EACxC,OAAO,YAAY,6BAA6B,EAChD,OAAO,eAAe,wBAAwB,EAC9C,OAAO,gBAAgB,+BAA+B,EACtD,OAAO,gBAAgB,uDAAuD,EAC9E,OAAO,gBAAgB,yDAAyD,EAChF,OAAO,aAAa,kCAAkC,EACtD,OAAO,eAAe,kCAAkC,EACxD,OAAO,OAAO,MAA0B,SAAkC;AACzE,QAAM,QAAqB,EAAE,GAAI,MAAsB,KAAK;AAC5D,QAAM,UAAU,KAAK;AACvB,CAAC;AAEH,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,QAAQ;AAC9C,UAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,GAAG;AACtD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/add.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { runAdd } from \"./commands/add.js\";\nimport { runCreate, type CreateFlags } from \"./commands/create.js\";\n\nexport { runCreate, runAdd };\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"partweave\")\n .description(\"A modular full-stack scaffolder — pick parts, generate only that code.\")\n .version(\"0.1.0\");\n\n program\n .command(\"create\", { isDefault: true })\n .argument(\"[name]\", \"project name\")\n .description(\"Scaffold a new project\")\n .option(\"-d, --dir <path>\", \"target directory\")\n .option(\"--server\", \"include the Django server\")\n .option(\"--no-server\", \"exclude the server\")\n .option(\"--web\", \"include the Next.js web app\")\n .option(\"--no-web\", \"exclude the web app\")\n .option(\"--mobile\", \"include the Expo mobile app\")\n .option(\"--no-mobile\", \"exclude the mobile app\")\n .option(\"--with <ids>\", \"comma-separated component ids (e.g. auth,docker,ci)\")\n .option(\"--js-pm <pm>\", \"JS package manager: pnpm | npm (default: auto-detect)\")\n .option(\"--py-pm <pm>\", \"Python package manager: uv | pip (default: auto-detect)\")\n .option(\"-y, --yes\", \"skip prompts; use flags/defaults\")\n .option(\"-f, --force\", \"write into a non-empty directory\")\n .action(async (name: string | undefined, opts: Record<string, unknown>) => {\n const flags: CreateFlags = { ...(opts as CreateFlags), name: name ?? (opts.name as string) };\n await runCreate(flags);\n });\n\n program\n .command(\"add\")\n .argument(\"<items...>\", \"apps (server/web/mobile) or component ids to add\")\n .description(\"Add an app or component to an existing generated project\")\n .option(\"-d, --dir <path>\", \"project directory (default: cwd)\")\n .action(async (items: string[], opts: { dir?: string }) => {\n await runAdd(items, opts);\n });\n\n return program;\n}\n\nexport async function main(argv: string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync(argv);\n}\n\n// Executed directly (partweave bin)\nmain().catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n","import { resolve } from \"node:path\";\nimport { intro, log, note, outro, spinner } from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { buildContext, compose, selectedTargets } from \"../compose.js\";\nimport {\n DEFAULT_JS_PM,\n DEFAULT_PY_PM,\n jsPmProfile,\n pyPmProfile,\n} from \"../pm.js\";\nimport {\n readProjectManifest,\n writeProjectManifest,\n type ProjectManifest,\n} from \"../projectmanifest.js\";\nimport { Registry } from \"../registry.js\";\nimport { resolveModules, validateApps } from \"../resolve.js\";\nimport { APPS, type AppName, type Selection, type TargetName } from \"../types.js\";\n\nexport interface AddFlags {\n dir?: string;\n}\n\nconst isApp = (id: string): id is AppName =>\n (APPS as readonly string[]).includes(id);\n\nconst sel = (pm: ProjectManifest, dir: string, apps: AppName[]): Selection => ({\n projectName: pm.name,\n outDir: dir,\n apps,\n modules: pm.modules,\n jsPm: pm.jsPm,\n pyPm: pm.pyPm,\n});\n\n/**\n * `partweave add <server|web|mobile|component...>` — grow an existing project.\n * Apps scaffold a new sub-project (and pull in the app-side of installed\n * components); components wire a new feature into the current apps.\n */\nexport async function runAdd(ids: string[], flags: AddFlags): Promise<void> {\n intro(pc.bgCyan(pc.black(\" partweave \")) + pc.dim(\" add\"));\n const dir = resolve(flags.dir ?? process.cwd());\n\n const pm = readProjectManifest(dir);\n if (!pm) {\n log.error(\n `No partweave project found at ${dir} (missing .partweave/manifest.json). ` +\n `Run this from inside a generated project, or pass --dir.`,\n );\n process.exit(1);\n }\n if (ids.length === 0) {\n log.error(\n \"Specify what to add — an app (`server`/`web`/`mobile`) or a component \" +\n \"(e.g. `partweave add storage`).\",\n );\n process.exit(1);\n }\n\n const registry = new Registry();\n const appIds = ids.filter(isApp);\n const moduleIds = ids.filter((id) => !isApp(id));\n\n // Apps first, so components added in the same call can rely on them.\n let manifest: ProjectManifest = pm!;\n if (appIds.length) manifest = addApps(registry, dir, manifest, appIds);\n if (moduleIds.length) manifest = addModules(registry, dir, manifest, moduleIds);\n\n const js = jsPmProfile(manifest.jsPm ?? DEFAULT_JS_PM);\n const py = pyPmProfile(manifest.pyPm ?? DEFAULT_PY_PM);\n const reinstall: string[] = [];\n if (manifest.apps.some((a) => a === \"web\" || a === \"mobile\")) reinstall.push(js.install);\n if (manifest.apps.includes(\"server\"))\n reinstall.push(`cd apps/server && ${py.syncInServer} && ${py.run(\"python manage.py migrate\")}`);\n if (reinstall.length) note(reinstall.join(\"\\n\"), \"Sync deps\");\n outro(pc.green(\"Done.\"));\n}\n\nfunction addApps(\n registry: Registry,\n dir: string,\n pm: ProjectManifest,\n appIds: AppName[],\n): ProjectManifest {\n const already = appIds.filter((a) => pm.apps.includes(a));\n const toAdd = appIds.filter((a) => !pm.apps.includes(a));\n if (already.length) log.info(`Already present: ${already.join(\", \")}`);\n if (toAdd.length === 0) return pm;\n\n const newApps = [...pm.apps, ...toAdd];\n const oldTargets = selectedTargets(buildContext(sel(pm, dir, pm.apps)));\n const newTargets = selectedTargets(buildContext(sel(pm, dir, newApps)));\n const scaffold = new Set<TargetName>(\n [...newTargets].filter((t) => !oldTargets.has(t)),\n );\n\n const s = spinner();\n s.start(`Adding app(s): ${toAdd.join(\", \")}`);\n try {\n // Wire ALL installed components into the new targets (e.g. adding `web` to a\n // server+auth project brings in auth's login page + provider).\n compose({\n selection: { ...sel(pm, dir, newApps), modules: pm.modules },\n registry,\n scaffoldTargets: scaffold,\n wireTargets: scaffold,\n rootFiles: \"structural\",\n });\n } catch (err) {\n s.stop(\"Failed\");\n log.error((err as Error).message);\n process.exit(1);\n }\n s.stop(`Added ${toAdd.join(\", \")}`);\n\n const updated = { ...pm, apps: newApps };\n writeProjectManifest(dir, updated);\n return updated;\n}\n\nfunction addModules(\n registry: Registry,\n dir: string,\n pm: ProjectManifest,\n moduleIds: string[],\n): ProjectManifest {\n let resolved;\n try {\n resolved = resolveModules(registry, [...pm.modules, ...moduleIds]);\n validateApps(registry, resolved.modules, pm.apps);\n } catch (err) {\n log.error((err as Error).message);\n process.exit(1);\n }\n const installed = new Set(pm.modules);\n const delta = resolved.modules.filter((id) => !installed.has(id));\n if (delta.length === 0) {\n log.info(\"Requested component(s) already installed.\");\n return pm;\n }\n const extra = delta.filter((id) => !moduleIds.includes(id));\n if (extra.length) log.info(`Also adding required components: ${extra.join(\", \")}`);\n\n const wireTargets = selectedTargets(buildContext(sel(pm, dir, pm.apps)));\n const s = spinner();\n s.start(`Adding ${delta.join(\", \")}`);\n let result;\n try {\n result = compose({\n selection: { ...sel(pm, dir, pm.apps), modules: delta },\n registry,\n scaffoldTargets: new Set(),\n wireTargets,\n rootFiles: \"none\",\n });\n } catch (err) {\n s.stop(\"Failed\");\n log.error((err as Error).message);\n process.exit(1);\n }\n s.stop(`Wired in ${delta.length} component(s)`);\n if (result.notes.length) note(result.notes.join(\"\\n\"), \"Notes\");\n\n const updated = { ...pm, modules: resolved.modules };\n writeProjectManifest(dir, updated);\n return updated;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,eAAe;AACxB,SAAS,OAAO,KAAK,MAAM,OAAO,eAAe;AACjD,OAAO,QAAQ;AAqBf,IAAM,QAAQ,CAAC,OACZ,KAA2B,SAAS,EAAE;AAEzC,IAAM,MAAM,CAAC,IAAqB,KAAa,UAAgC;AAAA,EAC7E,aAAa,GAAG;AAAA,EAChB,QAAQ;AAAA,EACR;AAAA,EACA,SAAS,GAAG;AAAA,EACZ,MAAM,GAAG;AAAA,EACT,MAAM,GAAG;AACX;AAOA,eAAsB,OAAO,KAAe,OAAgC;AAC1E,QAAM,GAAG,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC;AACzD,QAAM,MAAM,QAAQ,MAAM,OAAO,QAAQ,IAAI,CAAC;AAE9C,QAAM,KAAK,oBAAoB,GAAG;AAClC,MAAI,CAAC,IAAI;AACP,QAAI;AAAA,MACF,iCAAiC,GAAG;AAAA,IAEtC;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,IAAI,WAAW,GAAG;AACpB,QAAI;AAAA,MACF;AAAA,IAEF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,IAAI,SAAS;AAC9B,QAAM,SAAS,IAAI,OAAO,KAAK;AAC/B,QAAM,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;AAG/C,MAAI,WAA4B;AAChC,MAAI,OAAO,OAAQ,YAAW,QAAQ,UAAU,KAAK,UAAU,MAAM;AACrE,MAAI,UAAU,OAAQ,YAAW,WAAW,UAAU,KAAK,UAAU,SAAS;AAE9E,QAAM,KAAK,YAAY,SAAS,QAAQ,aAAa;AACrD,QAAM,KAAK,YAAY,SAAS,QAAQ,aAAa;AACrD,QAAM,YAAsB,CAAC;AAC7B,MAAI,SAAS,KAAK,KAAK,CAAC,MAAM,MAAM,SAAS,MAAM,QAAQ,EAAG,WAAU,KAAK,GAAG,OAAO;AACvF,MAAI,SAAS,KAAK,SAAS,QAAQ;AACjC,cAAU,KAAK,qBAAqB,GAAG,YAAY,OAAO,GAAG,IAAI,0BAA0B,CAAC,EAAE;AAChG,MAAI,UAAU,OAAQ,MAAK,UAAU,KAAK,IAAI,GAAG,WAAW;AAC5D,QAAM,GAAG,MAAM,OAAO,CAAC;AACzB;AAEA,SAAS,QACP,UACA,KACA,IACA,QACiB;AACjB,QAAM,UAAU,OAAO,OAAO,CAAC,MAAM,GAAG,KAAK,SAAS,CAAC,CAAC;AACxD,QAAM,QAAQ,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;AACvD,MAAI,QAAQ,OAAQ,KAAI,KAAK,oBAAoB,QAAQ,KAAK,IAAI,CAAC,EAAE;AACrE,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,UAAU,CAAC,GAAG,GAAG,MAAM,GAAG,KAAK;AACrC,QAAM,aAAa,gBAAgB,aAAa,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC;AACtE,QAAM,aAAa,gBAAgB,aAAa,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC;AACtE,QAAM,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;AAAA,EAClD;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,kBAAkB,MAAM,KAAK,IAAI,CAAC,EAAE;AAC5C,MAAI;AAGF,YAAQ;AAAA,MACN,WAAW,EAAE,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,SAAS,GAAG,QAAQ;AAAA,MAC3D;AAAA,MACA,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,MAAE,KAAK,QAAQ;AACf,QAAI,MAAO,IAAc,OAAO;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,IAAE,KAAK,SAAS,MAAM,KAAK,IAAI,CAAC,EAAE;AAElC,QAAM,UAAU,EAAE,GAAG,IAAI,MAAM,QAAQ;AACvC,uBAAqB,KAAK,OAAO;AACjC,SAAO;AACT;AAEA,SAAS,WACP,UACA,KACA,IACA,WACiB;AACjB,MAAI;AACJ,MAAI;AACF,eAAW,eAAe,UAAU,CAAC,GAAG,GAAG,SAAS,GAAG,SAAS,CAAC;AACjE,iBAAa,UAAU,SAAS,SAAS,GAAG,IAAI;AAAA,EAClD,SAAS,KAAK;AACZ,QAAI,MAAO,IAAc,OAAO;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,YAAY,IAAI,IAAI,GAAG,OAAO;AACpC,QAAM,QAAQ,SAAS,QAAQ,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;AAChE,MAAI,MAAM,WAAW,GAAG;AACtB,QAAI,KAAK,2CAA2C;AACpD,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,SAAS,EAAE,CAAC;AAC1D,MAAI,MAAM,OAAQ,KAAI,KAAK,oCAAoC,MAAM,KAAK,IAAI,CAAC,EAAE;AAEjF,QAAM,cAAc,gBAAgB,aAAa,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC;AACvE,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,UAAU,MAAM,KAAK,IAAI,CAAC,EAAE;AACpC,MAAI;AACJ,MAAI;AACF,aAAS,QAAQ;AAAA,MACf,WAAW,EAAE,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,GAAG,SAAS,MAAM;AAAA,MACtD;AAAA,MACA,iBAAiB,oBAAI,IAAI;AAAA,MACzB;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,MAAE,KAAK,QAAQ;AACf,QAAI,MAAO,IAAc,OAAO;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,IAAE,KAAK,YAAY,MAAM,MAAM,eAAe;AAC9C,MAAI,OAAO,MAAM,OAAQ,MAAK,OAAO,MAAM,KAAK,IAAI,GAAG,OAAO;AAE9D,QAAM,UAAU,EAAE,GAAG,IAAI,SAAS,SAAS,QAAQ;AACnD,uBAAqB,KAAK,OAAO;AACjC,SAAO;AACT;;;ADjKO,SAAS,eAAwB;AACtC,QAAM,UAAU,IAAI,QAAQ;AAC5B,UACG,KAAK,WAAW,EAChB,YAAY,6EAAwE,EACpF,QAAQ,OAAO;AAElB,UACG,QAAQ,UAAU,EAAE,WAAW,KAAK,CAAC,EACrC,SAAS,UAAU,cAAc,EACjC,YAAY,wBAAwB,EACpC,OAAO,oBAAoB,kBAAkB,EAC7C,OAAO,YAAY,2BAA2B,EAC9C,OAAO,eAAe,oBAAoB,EAC1C,OAAO,SAAS,6BAA6B,EAC7C,OAAO,YAAY,qBAAqB,EACxC,OAAO,YAAY,6BAA6B,EAChD,OAAO,eAAe,wBAAwB,EAC9C,OAAO,gBAAgB,qDAAqD,EAC5E,OAAO,gBAAgB,uDAAuD,EAC9E,OAAO,gBAAgB,yDAAyD,EAChF,OAAO,aAAa,kCAAkC,EACtD,OAAO,eAAe,kCAAkC,EACxD,OAAO,OAAO,MAA0B,SAAkC;AACzE,UAAM,QAAqB,EAAE,GAAI,MAAsB,MAAM,QAAS,KAAK,KAAgB;AAC3F,UAAM,UAAU,KAAK;AAAA,EACvB,CAAC;AAEH,UACG,QAAQ,KAAK,EACb,SAAS,cAAc,kDAAkD,EACzE,YAAY,0DAA0D,EACtE,OAAO,oBAAoB,kCAAkC,EAC7D,OAAO,OAAO,OAAiB,SAA2B;AACzD,UAAM,OAAO,OAAO,IAAI;AAAA,EAC1B,CAAC;AAEH,SAAO;AACT;AAEA,eAAsB,KAAK,OAAiB,QAAQ,MAAqB;AACvE,QAAM,aAAa,EAAE,WAAW,IAAI;AACtC;AAGA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,GAAG;AACtD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|