@percepta/create 4.1.6 → 4.1.8

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 (54) hide show
  1. package/dist/{git-ops-BD7JNnal.js → git-ops-BNpQnEc1.js} +1 -1
  2. package/dist/{git-ops-BD7JNnal.js.map → git-ops-BNpQnEc1.js.map} +1 -1
  3. package/dist/{github-D3YOEl91.js → github-BOp8VQCY.js} +1 -1
  4. package/dist/{github-D3YOEl91.js.map → github-BOp8VQCY.js.map} +1 -1
  5. package/dist/index.js +107 -15
  6. package/dist/index.js.map +1 -1
  7. package/dist/{init-BD3EyyLO.js → init-CsuO_mu2.js} +2 -4
  8. package/dist/{init-BD3EyyLO.js.map → init-CsuO_mu2.js.map} +1 -1
  9. package/dist/{register-app-DZg-Pmtd.js → register-app-mNc1oYVK.js} +3 -5
  10. package/dist/{register-app-DZg-Pmtd.js.map → register-app-mNc1oYVK.js.map} +1 -1
  11. package/dist/{register-os-blueprint-Cgq1rXzQ.js → register-os-blueprint-Gdyn0pN1.js} +3 -4
  12. package/dist/{register-os-blueprint-Cgq1rXzQ.js.map → register-os-blueprint-Gdyn0pN1.js.map} +1 -1
  13. package/dist/{status-K6raTwwu.js → status-BrK9v1yb.js} +3 -3
  14. package/dist/{status-K6raTwwu.js.map → status-BrK9v1yb.js.map} +1 -1
  15. package/dist/{sync-Bi958-2W.js → sync-DC5DhIBT.js} +3 -3
  16. package/dist/{sync-Bi958-2W.js.map → sync-DC5DhIBT.js.map} +1 -1
  17. package/dist/{upstream-CAraZeSS.js → upstream-PNL6DGtl.js} +3 -3
  18. package/dist/{upstream-CAraZeSS.js.map → upstream-PNL6DGtl.js.map} +1 -1
  19. package/package.json +3 -3
  20. package/template-versions.json +2 -2
  21. package/templates/monorepo/auth/src/drizzle/migrations/meta/0000_snapshot.json +547 -0
  22. package/templates/monorepo/package.json.template +6 -6
  23. package/templates/monorepo/pnpm-workspace.yaml +1 -1
  24. package/templates/webapp/AGENTS.md +38 -16
  25. package/templates/webapp/README.md +56 -58
  26. package/templates/webapp/agent-skills/access-control.md +10 -9
  27. package/templates/webapp/agent-skills/database.md +10 -4
  28. package/templates/webapp/agent-skills/inngest.md +10 -8
  29. package/templates/webapp/agent-skills/langfuse.md +7 -5
  30. package/templates/webapp/agent-skills/oneshot.md +15 -13
  31. package/templates/webapp/package.json.template +5 -5
  32. package/templates/webapp/playwright.config.ts +1 -2
  33. package/templates/webapp/src/app/(app)/page.tsx +5 -3
  34. package/templates/webapp/src/app/(auth)/layout.tsx +2 -2
  35. package/templates/webapp/src/app/(settings)/settings/page.tsx +20 -21
  36. package/templates/webapp/src/components/FaroProvider.tsx +1 -2
  37. package/templates/webapp/src/components/Header.tsx +2 -8
  38. package/templates/webapp/src/components/form/FormItem.tsx +1 -1
  39. package/templates/webapp/src/drizzle/db.ts +3 -1
  40. package/templates/webapp/src/drizzle/schema/utils/jsonbFromZod.ts +1 -1
  41. package/templates/webapp/src/instrumentation.ts +3 -6
  42. package/templates/webapp/src/lib/auth-client.ts +3 -2
  43. package/templates/webapp/src/lib/trpc.ts +1 -1
  44. package/templates/webapp/src/server/trpc.ts +1 -1
  45. package/templates/webapp/src/services/DatabaseService.ts +1 -1
  46. package/templates/webapp/src/services/access/AppAccessControl.ts +1 -3
  47. package/templates/webapp/src/services/inngest/AppWorkflowService.ts +1 -1
  48. package/templates/webapp/src/styles/globals.css +13 -2
  49. package/dist/manifest-By1SgOjC.js +0 -59
  50. package/dist/manifest-By1SgOjC.js.map +0 -1
  51. package/dist/template-versions-CEIP9vhl.js +0 -35
  52. package/dist/template-versions-CEIP9vhl.js.map +0 -1
  53. package/dist/validate-dssldJAj.js +0 -14
  54. package/dist/validate-dssldJAj.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { BetterAuthClientOptions } from "better-auth";
1
+ import type { BetterAuthClientOptions } from "better-auth";
2
2
  import { adminClient } from "better-auth/client/plugins";
3
3
  import { createAuthClient } from "better-auth/react";
4
4
 
@@ -6,4 +6,5 @@ const adminPlugin: ReturnType<typeof adminClient> = adminClient();
6
6
  const options = {
7
7
  plugins: [adminPlugin],
8
8
  } satisfies BetterAuthClientOptions;
9
- export const authClient: ReturnType<typeof createAuthClient<typeof options>> = createAuthClient(options);
9
+ export const authClient: ReturnType<typeof createAuthClient<typeof options>> =
10
+ createAuthClient(options);
@@ -1,7 +1,7 @@
1
1
  import { createTRPCClient, httpBatchLink } from "@trpc/client";
2
2
  import { createTRPCContext } from "@trpc/tanstack-react-query";
3
3
  import superjson from "superjson";
4
- import { type AppRouter } from "../server/api/root";
4
+ import type { AppRouter } from "../server/api/root";
5
5
 
6
6
  export const trpcClient = createTRPCClient<AppRouter>({
7
7
  links: [
@@ -4,11 +4,11 @@ import { TRPCError, initTRPC } from "@trpc/server";
4
4
  import superjson from "superjson";
5
5
  import { accessManifest } from "../access/access.manifest";
6
6
  import { type BetterAuthSession, getServerSession } from "../lib/auth";
7
- import { AuthContextService } from "../services/AuthContextService";
8
7
  import {
9
8
  getAccessControl,
10
9
  toUserSubject,
11
10
  } from "../services/access/AppAccessControl";
11
+ import { AuthContextService } from "../services/AuthContextService";
12
12
  import { getTracer } from "../services/logger/AppLogger";
13
13
 
14
14
  export interface Context {
@@ -1,5 +1,5 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
- import { type NodePgDatabase } from "drizzle-orm/node-postgres";
2
+ import type { NodePgDatabase } from "drizzle-orm/node-postgres";
3
3
  import { db } from "../drizzle/db";
4
4
 
5
5
  export class DatabaseService {
@@ -43,9 +43,7 @@ export function canManageDefaultRoles(userId: string): Promise<boolean> {
43
43
  return appAccessRuntime.canManageDefaultRoles(userId);
44
44
  }
45
45
 
46
- export function canManageDefaultRolesStrong(
47
- userId: string,
48
- ): Promise<boolean> {
46
+ export function canManageDefaultRolesStrong(userId: string): Promise<boolean> {
49
47
  return appAccessRuntime.canManageDefaultRolesStrong(userId);
50
48
  }
51
49
 
@@ -1,5 +1,5 @@
1
+ import type { ExampleEventPayload } from "./events/payloads/ExampleEventPayload";
1
2
  import { type AppInngest, InngestService } from "./InngestService";
2
- import { type ExampleEventPayload } from "./events/payloads/ExampleEventPayload";
3
3
 
4
4
  type AppWorkflowClient = Pick<AppInngest, "send">;
5
5
 
@@ -204,7 +204,9 @@ body {
204
204
  border-radius: var(--radius-lg);
205
205
  padding: 0.25rem 0.375rem 0.25rem 0.75rem;
206
206
  color: var(--foreground);
207
- transition: background 150ms ease, color 150ms ease;
207
+ transition:
208
+ background 150ms ease,
209
+ color 150ms ease;
208
210
  }
209
211
 
210
212
  .app-account-text {
@@ -423,7 +425,16 @@ body {
423
425
  height: 2.25rem;
424
426
  border-bottom: 2px solid var(--primary);
425
427
  background:
426
- linear-gradient(135deg, transparent 14%, var(--accent) 15% 18%, transparent 19% 32%, var(--accent) 33% 36%, transparent 37% 52%, var(--accent) 53% 56%, transparent 57%),
428
+ linear-gradient(
429
+ 135deg,
430
+ transparent 14%,
431
+ var(--accent) 15% 18%,
432
+ transparent 19% 32%,
433
+ var(--accent) 33% 36%,
434
+ transparent 37% 52%,
435
+ var(--accent) 53% 56%,
436
+ transparent 57%
437
+ ),
427
438
  linear-gradient(to top, var(--accent), transparent 68%);
428
439
  }
429
440
 
@@ -1,59 +0,0 @@
1
- import path from "node:path";
2
- import fs from "fs-extra";
3
- //#region src/utils/design-theme.ts
4
- const VALID_MOSAIC_DESIGN_THEMES = [
5
- "paper",
6
- "modern",
7
- "dense"
8
- ];
9
- const DEFAULT_MOSAIC_DESIGN_THEME = "modern";
10
- function isValidMosaicDesignTheme(value) {
11
- return typeof value === "string" && VALID_MOSAIC_DESIGN_THEMES.includes(value);
12
- }
13
- //#endregion
14
- //#region src/utils/manifest.ts
15
- const MANIFEST_FILENAME = ".mosaic-template.json";
16
- function getManifestPath(dir) {
17
- return path.join(dir, MANIFEST_FILENAME);
18
- }
19
- async function readManifest(dir) {
20
- const manifestPath = getManifestPath(dir);
21
- if (!await fs.pathExists(manifestPath)) throw new Error(`No ${MANIFEST_FILENAME} found in ${dir}. Run 'create init' to create one.`);
22
- const content = await fs.readFile(manifestPath, "utf-8");
23
- try {
24
- return JSON.parse(content);
25
- } catch (error) {
26
- throw new Error(`Invalid JSON in ${MANIFEST_FILENAME}: ${error.message}`);
27
- }
28
- }
29
- async function writeManifest(dir, manifest) {
30
- const manifestPath = getManifestPath(dir);
31
- await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
32
- }
33
- async function manifestExists(dir) {
34
- return fs.pathExists(getManifestPath(dir));
35
- }
36
- function derivePlaceholders(appName, appTitle, repoName = appName, customerSlug = repoName, designTheme = DEFAULT_MOSAIC_DESIGN_THEME) {
37
- const nameSnake = appName.replace(/-/g, "_");
38
- const repoNameSnake = repoName.replace(/-/g, "_");
39
- return {
40
- __APP_NAME__: appName,
41
- __APP_TITLE__: appTitle,
42
- __DB_NAME__: nameSnake + "_db",
43
- __APP_NAME_UPPER__: appName.toUpperCase(),
44
- __APP_NAME_SNAKE__: nameSnake,
45
- __REPO_NAME__: repoName,
46
- __REPO_NAME_SNAKE__: repoNameSnake,
47
- __CUSTOMER_SLUG__: customerSlug,
48
- __MOSAIC_DESIGN_THEME__: designTheme
49
- };
50
- }
51
- function resolveMosaicTemplatePath(options) {
52
- if (options.mosaicTemplatePath) return path.resolve(options.mosaicTemplatePath);
53
- if (process.env.MOSAIC_TEMPLATE_PATH) return path.resolve(process.env.MOSAIC_TEMPLATE_PATH);
54
- throw new Error("Mosaic repo path required. Use --mosaic-template-path or set MOSAIC_TEMPLATE_PATH.");
55
- }
56
- //#endregion
57
- export { writeManifest as a, isValidMosaicDesignTheme as c, resolveMosaicTemplatePath as i, manifestExists as n, DEFAULT_MOSAIC_DESIGN_THEME as o, readManifest as r, VALID_MOSAIC_DESIGN_THEMES as s, derivePlaceholders as t };
58
-
59
- //# sourceMappingURL=manifest-By1SgOjC.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manifest-By1SgOjC.js","names":[],"sources":["../src/utils/design-theme.ts","../src/utils/manifest.ts"],"sourcesContent":["export const VALID_MOSAIC_DESIGN_THEMES = [\"paper\", \"modern\", \"dense\"] as const;\n\nexport type MosaicDesignTheme = (typeof VALID_MOSAIC_DESIGN_THEMES)[number];\n\nexport const DEFAULT_MOSAIC_DESIGN_THEME: MosaicDesignTheme = \"modern\";\n\nexport function isValidMosaicDesignTheme(\n value: unknown,\n): value is MosaicDesignTheme {\n return (\n typeof value === \"string\" &&\n VALID_MOSAIC_DESIGN_THEMES.includes(value as MosaicDesignTheme)\n );\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport {\n DEFAULT_MOSAIC_DESIGN_THEME,\n type MosaicDesignTheme,\n} from \"./design-theme.js\";\n\nexport interface MosaicManifest {\n templateType: string;\n templateVersion: string;\n templateCommit: string;\n createdAt: string;\n lastSyncedAt?: string;\n placeholders: Record<string, string>;\n source: {\n templatePath: string;\n };\n}\n\nconst MANIFEST_FILENAME = \".mosaic-template.json\";\n\nexport function getManifestPath(dir: string): string {\n return path.join(dir, MANIFEST_FILENAME);\n}\n\nexport async function readManifest(dir: string): Promise<MosaicManifest> {\n const manifestPath = getManifestPath(dir);\n if (!(await fs.pathExists(manifestPath))) {\n throw new Error(\n `No ${MANIFEST_FILENAME} found in ${dir}. Run 'create init' to create one.`,\n );\n }\n const content = await fs.readFile(manifestPath, \"utf-8\");\n try {\n return JSON.parse(content) as MosaicManifest;\n } catch (error) {\n throw new Error(\n `Invalid JSON in ${MANIFEST_FILENAME}: ${(error as Error).message}`,\n );\n }\n}\n\nexport async function writeManifest(\n dir: string,\n manifest: MosaicManifest,\n): Promise<void> {\n const manifestPath = getManifestPath(dir);\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + \"\\n\");\n}\n\nexport async function manifestExists(dir: string): Promise<boolean> {\n return fs.pathExists(getManifestPath(dir));\n}\n\nexport function derivePlaceholders(\n appName: string,\n appTitle: string,\n repoName = appName,\n customerSlug = repoName,\n designTheme: MosaicDesignTheme = DEFAULT_MOSAIC_DESIGN_THEME,\n): Record<string, string> {\n const nameSnake = appName.replace(/-/g, \"_\");\n const repoNameSnake = repoName.replace(/-/g, \"_\");\n return {\n __APP_NAME__: appName,\n __APP_TITLE__: appTitle,\n __DB_NAME__: nameSnake + \"_db\",\n __APP_NAME_UPPER__: appName.toUpperCase(),\n __APP_NAME_SNAKE__: nameSnake,\n __REPO_NAME__: repoName,\n __REPO_NAME_SNAKE__: repoNameSnake,\n __CUSTOMER_SLUG__: customerSlug,\n __MOSAIC_DESIGN_THEME__: designTheme,\n };\n}\n\nexport function resolveMosaicTemplatePath(options: {\n mosaicTemplatePath?: string;\n}): string {\n if (options.mosaicTemplatePath)\n return path.resolve(options.mosaicTemplatePath);\n if (process.env.MOSAIC_TEMPLATE_PATH)\n return path.resolve(process.env.MOSAIC_TEMPLATE_PATH);\n throw new Error(\n \"Mosaic repo path required. Use --mosaic-template-path or set MOSAIC_TEMPLATE_PATH.\",\n );\n}\n"],"mappings":";;;AAAA,MAAa,6BAA6B;CAAC;CAAS;CAAU;CAAQ;AAItE,MAAa,8BAAiD;AAE9D,SAAgB,yBACd,OAC4B;AAC5B,QACE,OAAO,UAAU,YACjB,2BAA2B,SAAS,MAA2B;;;;ACQnE,MAAM,oBAAoB;AAE1B,SAAgB,gBAAgB,KAAqB;AACnD,QAAO,KAAK,KAAK,KAAK,kBAAkB;;AAG1C,eAAsB,aAAa,KAAsC;CACvE,MAAM,eAAe,gBAAgB,IAAI;AACzC,KAAI,CAAE,MAAM,GAAG,WAAW,aAAa,CACrC,OAAM,IAAI,MACR,MAAM,kBAAkB,YAAY,IAAI,oCACzC;CAEH,MAAM,UAAU,MAAM,GAAG,SAAS,cAAc,QAAQ;AACxD,KAAI;AACF,SAAO,KAAK,MAAM,QAAQ;UACnB,OAAO;AACd,QAAM,IAAI,MACR,mBAAmB,kBAAkB,IAAK,MAAgB,UAC3D;;;AAIL,eAAsB,cACpB,KACA,UACe;CACf,MAAM,eAAe,gBAAgB,IAAI;AACzC,OAAM,GAAG,UAAU,cAAc,KAAK,UAAU,UAAU,MAAM,EAAE,GAAG,KAAK;;AAG5E,eAAsB,eAAe,KAA+B;AAClE,QAAO,GAAG,WAAW,gBAAgB,IAAI,CAAC;;AAG5C,SAAgB,mBACd,SACA,UACA,WAAW,SACX,eAAe,UACf,cAAiC,6BACT;CACxB,MAAM,YAAY,QAAQ,QAAQ,MAAM,IAAI;CAC5C,MAAM,gBAAgB,SAAS,QAAQ,MAAM,IAAI;AACjD,QAAO;EACL,cAAc;EACd,eAAe;EACf,aAAa,YAAY;EACzB,oBAAoB,QAAQ,aAAa;EACzC,oBAAoB;EACpB,eAAe;EACf,qBAAqB;EACrB,mBAAmB;EACnB,yBAAyB;EAC1B;;AAGH,SAAgB,0BAA0B,SAE/B;AACT,KAAI,QAAQ,mBACV,QAAO,KAAK,QAAQ,QAAQ,mBAAmB;AACjD,KAAI,QAAQ,IAAI,qBACd,QAAO,KAAK,QAAQ,QAAQ,IAAI,qBAAqB;AACvD,OAAM,IAAI,MACR,qFACD"}
@@ -1,35 +0,0 @@
1
- import path from "node:path";
2
- import fs from "fs-extra";
3
- import { fileURLToPath } from "node:url";
4
- //#region src/utils/case-converters.ts
5
- /** Lowercase, hyphenated, npm-package-name-safe form: "My Cool App" → "my-cool-app". */
6
- function toKebabCase(str) {
7
- return str.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
8
- }
9
- /** Display form derived from a kebab-case name: "my-cool-app" → "My Cool App". */
10
- function toTitleCase(str) {
11
- return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
12
- }
13
- /** Identifier form for env vars and DB names: "my-cool-app" → "my_cool_app". */
14
- function toSnakeCase(str) {
15
- return str.replace(/-/g, "_");
16
- }
17
- //#endregion
18
- //#region src/utils/template-versions.ts
19
- const FALLBACK_TEMPLATE_VERSION = "1.0.0";
20
- function readTemplateVersions() {
21
- const currentDir = path.dirname(fileURLToPath(import.meta.url));
22
- const candidates = [path.resolve(currentDir, "../template-versions.json"), path.resolve(currentDir, "../../template-versions.json")];
23
- for (const versionsPath of candidates) try {
24
- const content = fs.readFileSync(versionsPath, "utf-8");
25
- return JSON.parse(content);
26
- } catch {}
27
- return {};
28
- }
29
- function getTemplateVersion(templateType) {
30
- return readTemplateVersions()[templateType] ?? FALLBACK_TEMPLATE_VERSION;
31
- }
32
- //#endregion
33
- export { toTitleCase as i, toKebabCase as n, toSnakeCase as r, getTemplateVersion as t };
34
-
35
- //# sourceMappingURL=template-versions-CEIP9vhl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-versions-CEIP9vhl.js","names":[],"sources":["../src/utils/case-converters.ts","../src/utils/template-versions.ts"],"sourcesContent":["/** Lowercase, hyphenated, npm-package-name-safe form: \"My Cool App\" → \"my-cool-app\". */\nexport function toKebabCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/** Display form derived from a kebab-case name: \"my-cool-app\" → \"My Cool App\". */\nexport function toTitleCase(str: string): string {\n return str\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/** Identifier form for env vars and DB names: \"my-cool-app\" → \"my_cool_app\". */\nexport function toSnakeCase(str: string): string {\n return str.replace(/-/g, \"_\");\n}\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport fs from \"fs-extra\";\n\nconst FALLBACK_TEMPLATE_VERSION = \"1.0.0\";\n\nexport function readTemplateVersions(): Record<string, string> {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(currentDir, \"../template-versions.json\"),\n path.resolve(currentDir, \"../../template-versions.json\"),\n ];\n\n for (const versionsPath of candidates) {\n try {\n const content = fs.readFileSync(versionsPath, \"utf-8\");\n return JSON.parse(content);\n } catch {\n // Try the next path. Source tests and bundled CLI resolve differently.\n }\n }\n\n return {};\n}\n\nexport function getTemplateVersion(templateType: string): string {\n return readTemplateVersions()[templateType] ?? FALLBACK_TEMPLATE_VERSION;\n}\n"],"mappings":";;;;;AACA,SAAgB,YAAY,KAAqB;AAC/C,QAAO,IACJ,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,IAAI,CACnB,QAAQ,UAAU,GAAG;;;AAI1B,SAAgB,YAAY,KAAqB;AAC/C,QAAO,IACJ,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,IAAI;;;AAId,SAAgB,YAAY,KAAqB;AAC/C,QAAO,IAAI,QAAQ,MAAM,IAAI;;;;ACf/B,MAAM,4BAA4B;AAElC,SAAgB,uBAA+C;CAC7D,MAAM,aAAa,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;CAC/D,MAAM,aAAa,CACjB,KAAK,QAAQ,YAAY,4BAA4B,EACrD,KAAK,QAAQ,YAAY,+BAA+B,CACzD;AAED,MAAK,MAAM,gBAAgB,WACzB,KAAI;EACF,MAAM,UAAU,GAAG,aAAa,cAAc,QAAQ;AACtD,SAAO,KAAK,MAAM,QAAQ;SACpB;AAKV,QAAO,EAAE;;AAGX,SAAgB,mBAAmB,cAA8B;AAC/D,QAAO,sBAAsB,CAAC,iBAAiB"}
@@ -1,14 +0,0 @@
1
- import validateNpmPackageName from "validate-npm-package-name";
2
- //#region src/utils/validate.ts
3
- function validateProjectName(name) {
4
- const result = validateNpmPackageName(name);
5
- if (!result.validForNewPackages) return {
6
- valid: false,
7
- error: [...result.errors || [], ...result.warnings || []][0] || "Invalid package name"
8
- };
9
- return { valid: true };
10
- }
11
- //#endregion
12
- export { validateProjectName as t };
13
-
14
- //# sourceMappingURL=validate-dssldJAj.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-dssldJAj.js","names":[],"sources":["../src/utils/validate.ts"],"sourcesContent":["import validateNpmPackageName from \"validate-npm-package-name\";\n\nexport interface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\nexport function validateProjectName(name: string): ValidationResult {\n const result = validateNpmPackageName(name);\n\n if (!result.validForNewPackages) {\n const errors = [...(result.errors || []), ...(result.warnings || [])];\n return {\n valid: false,\n error: errors[0] || \"Invalid package name\",\n };\n }\n\n return { valid: true };\n}\n"],"mappings":";;AAOA,SAAgB,oBAAoB,MAAgC;CAClE,MAAM,SAAS,uBAAuB,KAAK;AAE3C,KAAI,CAAC,OAAO,oBAEV,QAAO;EACL,OAAO;EACP,OAAO,CAHO,GAAI,OAAO,UAAU,EAAE,EAAG,GAAI,OAAO,YAAY,EAAE,CAGpD,CAAC,MAAM;EACrB;AAGH,QAAO,EAAE,OAAO,MAAM"}