@simplysm/sd-cli 13.0.70 → 13.0.72

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 (103) hide show
  1. package/dist/commands/init.d.ts +4 -5
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +26 -8
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/sd-cli-entry.d.ts.map +1 -1
  6. package/dist/sd-cli-entry.js +0 -20
  7. package/dist/sd-cli-entry.js.map +1 -1
  8. package/package.json +4 -4
  9. package/src/commands/init.ts +40 -21
  10. package/src/sd-cli-entry.ts +0 -24
  11. package/templates/init/{.prettierrc.yaml.hbs → .prettierrc.yaml} +1 -1
  12. package/templates/init/eslint.config.ts +15 -0
  13. package/templates/init/mise.toml +3 -0
  14. package/templates/init/package.json.hbs +8 -7
  15. package/templates/init/packages/client-admin/index.html.hbs +144 -0
  16. package/templates/init/packages/client-admin/package.json.hbs +26 -0
  17. package/templates/init/packages/client-admin/public/assets/logo-landscape.png +0 -0
  18. package/templates/init/packages/client-admin/public/assets/logo.png +0 -0
  19. package/templates/init/packages/client-admin/src/App.tsx +42 -0
  20. package/templates/init/packages/client-admin/src/dev/DevDialog.tsx +34 -0
  21. package/templates/{add-client/__CLIENT__/src/main.css.hbs → init/packages/client-admin/src/main.css} +1 -1
  22. package/templates/init/packages/client-admin/src/main.tsx.hbs +146 -0
  23. package/templates/init/packages/client-admin/src/providers/AppServiceProvider.tsx.hbs +103 -0
  24. package/templates/init/packages/client-admin/src/providers/AppStructureProvider.tsx +84 -0
  25. package/templates/init/packages/client-admin/src/providers/AuthProvider.tsx.hbs +71 -0
  26. package/templates/init/packages/client-admin/src/providers/configureSharedData.ts.hbs +67 -0
  27. package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +132 -0
  28. package/templates/init/packages/client-admin/src/views/home/HomeView.tsx +108 -0
  29. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +262 -0
  30. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +271 -0
  31. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +154 -0
  32. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +123 -0
  33. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +52 -0
  34. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +125 -0
  35. package/templates/init/packages/client-admin/src/views/home/main/MainView.tsx.hbs +13 -0
  36. package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +248 -0
  37. package/templates/init/packages/client-admin/src/views/home/system/system-log/SystemLogSheet.tsx.hbs +169 -0
  38. package/templates/init/packages/client-admin/src/views/not-found/NotFoundView.tsx +15 -0
  39. package/templates/init/packages/client-admin/tailwind.config.ts +10 -0
  40. package/templates/init/packages/db-main/package.json.hbs +13 -0
  41. package/templates/init/packages/db-main/src/MainDbContext.ts +20 -0
  42. package/templates/init/packages/db-main/src/dataLogExt.ts +127 -0
  43. package/templates/init/packages/db-main/src/index.ts +10 -0
  44. package/templates/init/packages/db-main/src/tables/Employee.ts +24 -0
  45. package/templates/init/packages/db-main/src/tables/EmployeeConfig.ts +13 -0
  46. package/templates/init/packages/db-main/src/tables/Role.ts +9 -0
  47. package/templates/init/packages/db-main/src/tables/RolePermission.ts +13 -0
  48. package/templates/init/packages/db-main/src/tables/_DataLog.ts +19 -0
  49. package/templates/init/packages/db-main/src/tables/_Log.ts +16 -0
  50. package/templates/init/packages/server/package.json.hbs +20 -0
  51. package/templates/init/packages/server/public-dev/dev//354/264/210/352/270/260/355/231/224.xlsx +0 -0
  52. package/templates/init/packages/server/src/index.ts +4 -0
  53. package/templates/init/packages/server/src/main.ts.hbs +34 -0
  54. package/templates/init/packages/server/src/services/AuthService.ts.hbs +171 -0
  55. package/templates/init/packages/server/src/services/DevService.ts.hbs +94 -0
  56. package/templates/init/packages/server/src/services/EmployeeService.ts.hbs +122 -0
  57. package/templates/init/packages/server/src/services/RoleService.ts.hbs +59 -0
  58. package/templates/init/{pnpm-workspace.yaml.hbs → pnpm-workspace.yaml} +3 -1
  59. package/templates/init/sd.config.ts.hbs +30 -1
  60. package/templates/init/tests/e2e/package.json.hbs +16 -0
  61. package/templates/init/tests/e2e/src/e2e.spec.ts +36 -0
  62. package/templates/init/tests/e2e/src/employee-crud.ts +204 -0
  63. package/templates/init/tests/e2e/src/login.ts +61 -0
  64. package/templates/init/tests/e2e/vitest.setup.ts.hbs +220 -0
  65. package/templates/init/tsconfig.json.hbs +0 -11
  66. package/templates/init/{vitest.config.ts.hbs → vitest.config.ts} +16 -12
  67. package/tests/infra/WorkerManager.spec.ts +1 -1
  68. package/tests/replace-deps.spec.ts +2 -2
  69. package/tests/run-lint.spec.ts +6 -6
  70. package/tests/run-typecheck.spec.ts +3 -3
  71. package/tests/sd-cli.spec.ts +1 -1
  72. package/dist/commands/add-client.d.ts +0 -18
  73. package/dist/commands/add-client.d.ts.map +0 -1
  74. package/dist/commands/add-client.js +0 -79
  75. package/dist/commands/add-client.js.map +0 -6
  76. package/dist/commands/add-server.d.ts +0 -18
  77. package/dist/commands/add-server.d.ts.map +0 -1
  78. package/dist/commands/add-server.js +0 -83
  79. package/dist/commands/add-server.js.map +0 -6
  80. package/dist/utils/config-editor.d.ts +0 -17
  81. package/dist/utils/config-editor.d.ts.map +0 -1
  82. package/dist/utils/config-editor.js +0 -79
  83. package/dist/utils/config-editor.js.map +0 -6
  84. package/src/commands/add-client.ts +0 -126
  85. package/src/commands/add-server.ts +0 -138
  86. package/src/utils/config-editor.ts +0 -141
  87. package/templates/add-client/__CLIENT__/index.html.hbs +0 -13
  88. package/templates/add-client/__CLIENT__/package.json.hbs +0 -16
  89. package/templates/add-client/__CLIENT__/src/App.tsx.hbs +0 -65
  90. package/templates/add-client/__CLIENT__/src/appStructure.ts.hbs +0 -20
  91. package/templates/add-client/__CLIENT__/src/main.tsx.hbs +0 -24
  92. package/templates/add-client/__CLIENT__/src/pages/HomePage.tsx.hbs +0 -9
  93. package/templates/add-client/__CLIENT__/tailwind.config.ts.hbs +0 -15
  94. package/templates/add-server/__SERVER__/package.json.hbs +0 -10
  95. package/templates/add-server/__SERVER__/src/main.ts.hbs +0 -14
  96. package/templates/init/.gitignore.hbs +0 -26
  97. package/templates/init/.npmrc.hbs +0 -1
  98. package/templates/init/eslint.config.ts.hbs +0 -5
  99. package/templates/init/mise.toml.hbs +0 -3
  100. package/tests/config-editor.spec.ts +0 -160
  101. /package/templates/init/{.prettierignore.hbs → .prettierignore} +0 -0
  102. /package/templates/{add-client/__CLIENT__ → init/packages/client-admin}/public/favicon.ico +0 -0
  103. /package/templates/init/{stylelint.config.ts.hbs → stylelint.config.ts} +0 -0
@@ -1,18 +0,0 @@
1
- /**
2
- * Add-client command options
3
- */
4
- export interface AddClientOptions {
5
- }
6
- /**
7
- * Add client package to the project.
8
- *
9
- * 1. Verify project root (sd.config.ts exists)
10
- * 2. Interactive prompt (name suffix, router usage)
11
- * 3. Check for duplicate package directory
12
- * 4. Render Handlebars template
13
- * 5. Add package entry to sd.config.ts (ts-morph)
14
- * 6. Add tailwind configuration to eslint.config.ts (if first client)
15
- * 7. pnpm install
16
- */
17
- export declare function runAddClient(_options: AddClientOptions): Promise<void>;
18
- //# sourceMappingURL=add-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-client.d.ts","sourceRoot":"","sources":["..\\..\\src\\commands\\add-client.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,gBAAgB;CAAG;AASpC;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyF5E"}
@@ -1,79 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { input, confirm } from "@inquirer/prompts";
4
- import { consola } from "consola";
5
- import { renderTemplateDir } from "../utils/template.js";
6
- import { addPackageToSdConfig, addTailwindToEslintConfig } from "../utils/config-editor.js";
7
- import { execa } from "execa";
8
- import { findPackageRoot } from "../utils/package-utils.js";
9
- async function runAddClient(_options) {
10
- const cwd = process.cwd();
11
- const logger = consola.withTag("sd:cli:add-client");
12
- if (!fs.existsSync(path.join(cwd, "sd.config.ts"))) {
13
- consola.error("Cannot find sd.config.ts. Please run from the project root.");
14
- process.exitCode = 1;
15
- return;
16
- }
17
- const projectName = path.basename(cwd);
18
- const clientSuffix = await input({
19
- message: "Enter client name suffix (client-___):",
20
- validate: (value) => {
21
- if (!value.trim()) return "Please enter a name.";
22
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
23
- return true;
24
- }
25
- });
26
- const useRouter = await confirm({
27
- message: "Do you want to use router?",
28
- default: true
29
- });
30
- const clientName = `client-${clientSuffix}`;
31
- const packageDir = path.join(cwd, "packages", clientName);
32
- if (fs.existsSync(packageDir)) {
33
- consola.error(`packages/${clientName} directory already exists.`);
34
- process.exitCode = 1;
35
- return;
36
- }
37
- const pkgRoot = findPackageRoot(import.meta.dirname);
38
- const templateDir = path.join(pkgRoot, "templates", "add-client");
39
- const context = {
40
- projectName,
41
- clientSuffix,
42
- clientName,
43
- router: useRouter
44
- };
45
- const dirReplacements = {
46
- __CLIENT__: clientName
47
- };
48
- logger.info(`Creating ${clientName} package...`);
49
- await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
50
- logger.success(`packages/${clientName} created successfully`);
51
- const sdConfigPath = path.join(cwd, "sd.config.ts");
52
- const added = addPackageToSdConfig(sdConfigPath, clientName, { target: "client" });
53
- if (added) {
54
- logger.success("sd.config.ts updated successfully");
55
- } else {
56
- consola.warn(`"${clientName}" already exists in sd.config.ts.`);
57
- }
58
- const eslintConfigPath = path.join(cwd, "eslint.config.ts");
59
- if (fs.existsSync(eslintConfigPath)) {
60
- const tailwindAdded = addTailwindToEslintConfig(eslintConfigPath, clientName);
61
- if (tailwindAdded) {
62
- logger.success("Added tailwind configuration to eslint.config.ts");
63
- }
64
- }
65
- logger.info("Running pnpm install...");
66
- await execa("pnpm", ["install"], { cwd });
67
- logger.success("pnpm install completed");
68
- consola.box(
69
- [
70
- `Client "${clientName}" has been added!`,
71
- "",
72
- ` pnpm dev ${clientName} Run development server`
73
- ].join("\n")
74
- );
75
- }
76
- export {
77
- runAddClient
78
- };
79
- //# sourceMappingURL=add-client.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/commands/add-client.ts"],
4
- "mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,OAAO,eAAe;AAC/B,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAS,sBAAsB,iCAAiC;AAChE,SAAS,aAAa;AACtB,SAAS,uBAAuB;AA2BhC,eAAsB,aAAa,UAA2C;AAC5E,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,QAAQ,QAAQ,mBAAmB;AAGlD,MAAI,CAAC,GAAG,WAAW,KAAK,KAAK,KAAK,cAAc,CAAC,GAAG;AAClD,YAAQ,MAAM,6DAA6D;AAC3E,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,cAAc,KAAK,SAAS,GAAG;AAGrC,QAAM,eAAe,MAAM,MAAM;AAAA,IAC/B,SAAS;AAAA,IACT,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAM,KAAK,EAAG,QAAO;AAC1B,UAAI,CAAC,oBAAoB,KAAK,KAAK,EAAG,QAAO;AAC7C,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,YAAY,MAAM,QAAQ;AAAA,IAC9B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,aAAa,UAAU,YAAY;AAGzC,QAAM,aAAa,KAAK,KAAK,KAAK,YAAY,UAAU;AACxD,MAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,YAAQ,MAAM,YAAY,UAAU,4BAA4B;AAChE,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,UAAU,gBAAgB,YAAY,OAAO;AACnD,QAAM,cAAc,KAAK,KAAK,SAAS,aAAa,YAAY;AAEhE,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AAEA,QAAM,kBAAkB;AAAA,IACtB,YAAY;AAAA,EACd;AAEA,SAAO,KAAK,YAAY,UAAU,aAAa;AAC/C,QAAM,kBAAkB,aAAa,KAAK,KAAK,KAAK,UAAU,GAAG,SAAS,eAAe;AACzF,SAAO,QAAQ,YAAY,UAAU,uBAAuB;AAG5D,QAAM,eAAe,KAAK,KAAK,KAAK,cAAc;AAClD,QAAM,QAAQ,qBAAqB,cAAc,YAAY,EAAE,QAAQ,SAAS,CAAC;AACjF,MAAI,OAAO;AACT,WAAO,QAAQ,mCAAmC;AAAA,EACpD,OAAO;AACL,YAAQ,KAAK,IAAI,UAAU,mCAAmC;AAAA,EAChE;AAGA,QAAM,mBAAmB,KAAK,KAAK,KAAK,kBAAkB;AAC1D,MAAI,GAAG,WAAW,gBAAgB,GAAG;AACnC,UAAM,gBAAgB,0BAA0B,kBAAkB,UAAU;AAC5E,QAAI,eAAe;AACjB,aAAO,QAAQ,kDAAkD;AAAA,IACnE;AAAA,EACF;AAGA,SAAO,KAAK,yBAAyB;AACrC,QAAM,MAAM,QAAQ,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC;AACxC,SAAO,QAAQ,wBAAwB;AAGvC,UAAQ;AAAA,IACN;AAAA,MACE,WAAW,UAAU;AAAA,MACrB;AAAA,MACA,cAAc,UAAU;AAAA,IAC1B,EAAE,KAAK,IAAI;AAAA,EACb;AACF;",
5
- "names": []
6
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Add-server command options
3
- */
4
- export interface AddServerOptions {
5
- }
6
- /**
7
- * Adds a server package to the project.
8
- *
9
- * 1. Verify project root
10
- * 2. Interactive prompts (name suffix, client selection)
11
- * 3. Check for duplicate package directory
12
- * 4. Render Handlebars template
13
- * 5. Add server package entry to sd.config.ts
14
- * 6. Update server field in selected clients
15
- * 7. Run pnpm install
16
- */
17
- export declare function runAddServer(_options: AddServerOptions): Promise<void>;
18
- //# sourceMappingURL=add-server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-server.d.ts","sourceRoot":"","sources":["..\\..\\src\\commands\\add-server.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,gBAAgB;CAAG;AA0BpC;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoF5E"}
@@ -1,83 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { input, checkbox } from "@inquirer/prompts";
4
- import { consola } from "consola";
5
- import { renderTemplateDir } from "../utils/template.js";
6
- import { addPackageToSdConfig, setClientServerInSdConfig } from "../utils/config-editor.js";
7
- import { execa } from "execa";
8
- import { findPackageRoot } from "../utils/package-utils.js";
9
- function findClientPackages(sdConfigPath) {
10
- const content = fs.readFileSync(sdConfigPath, "utf-8");
11
- const clients = [];
12
- const regex = /"([^"]+)":\s*\{[^}]*target:\s*"client"/g;
13
- let match;
14
- while ((match = regex.exec(content)) != null) {
15
- clients.push(match[1]);
16
- }
17
- return clients;
18
- }
19
- async function runAddServer(_options) {
20
- const cwd = process.cwd();
21
- const logger = consola.withTag("sd:cli:add-server");
22
- const sdConfigPath = path.join(cwd, "sd.config.ts");
23
- if (!fs.existsSync(sdConfigPath)) {
24
- consola.error("Cannot find sd.config.ts. Please run this from the project root.");
25
- process.exitCode = 1;
26
- return;
27
- }
28
- const projectName = path.basename(cwd);
29
- const serverSuffix = await input({
30
- message: 'Server name suffix (leave empty for "server"):',
31
- validate: (value) => {
32
- if (value.trim() === "") return true;
33
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
34
- return true;
35
- }
36
- });
37
- const serverName = serverSuffix.trim() === "" ? "server" : `server-${serverSuffix}`;
38
- const clientPackages = findClientPackages(sdConfigPath);
39
- let selectedClients = [];
40
- if (clientPackages.length > 0) {
41
- selectedClients = await checkbox({
42
- message: "Select the clients this server will serve:",
43
- choices: clientPackages.map((name) => ({ name, value: name }))
44
- });
45
- }
46
- const packageDir = path.join(cwd, "packages", serverName);
47
- if (fs.existsSync(packageDir)) {
48
- consola.error(`packages/${serverName} directory already exists.`);
49
- process.exitCode = 1;
50
- return;
51
- }
52
- const pkgRoot = findPackageRoot(import.meta.dirname);
53
- const templateDir = path.join(pkgRoot, "templates", "add-server");
54
- const context = {
55
- projectName,
56
- serverName,
57
- port: 3e3
58
- };
59
- const dirReplacements = {
60
- __SERVER__: serverName
61
- };
62
- logger.info(`Creating ${serverName} package...`);
63
- await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
64
- logger.success(`packages/${serverName} created successfully`);
65
- const added = addPackageToSdConfig(sdConfigPath, serverName, { target: "server" });
66
- if (added) {
67
- logger.success("Server package added to sd.config.ts");
68
- } else {
69
- consola.warn(`"${serverName}" already exists in sd.config.ts.`);
70
- }
71
- for (const clientName of selectedClients) {
72
- setClientServerInSdConfig(sdConfigPath, clientName, serverName);
73
- logger.info(`Set ${clientName} server to "${serverName}"`);
74
- }
75
- logger.info("Running pnpm install...");
76
- await execa("pnpm", ["install"], { cwd });
77
- logger.success("pnpm install completed");
78
- consola.box(`Server "${serverName}" has been added!`);
79
- }
80
- export {
81
- runAddServer
82
- };
83
- //# sourceMappingURL=add-server.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/commands/add-server.ts"],
4
- "mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,OAAO,gBAAgB;AAChC,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAS,sBAAsB,iCAAiC;AAChE,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAgBhC,SAAS,mBAAmB,cAAgC;AAC1D,QAAM,UAAU,GAAG,aAAa,cAAc,OAAO;AACrD,QAAM,UAAoB,CAAC;AAG3B,QAAM,QAAQ;AACd,MAAI;AACJ,UAAQ,QAAQ,MAAM,KAAK,OAAO,MAAM,MAAM;AAC5C,YAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EACvB;AACA,SAAO;AACT;AAiBA,eAAsB,aAAa,UAA2C;AAC5E,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,QAAQ,QAAQ,mBAAmB;AAGlD,QAAM,eAAe,KAAK,KAAK,KAAK,cAAc;AAClD,MAAI,CAAC,GAAG,WAAW,YAAY,GAAG;AAChC,YAAQ,MAAM,kEAAkE;AAChF,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,cAAc,KAAK,SAAS,GAAG;AAGrC,QAAM,eAAe,MAAM,MAAM;AAAA,IAC/B,SAAS;AAAA,IACT,UAAU,CAAC,UAAU;AACnB,UAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAChC,UAAI,CAAC,oBAAoB,KAAK,KAAK,EAAG,QAAO;AAC7C,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,aAAa,aAAa,KAAK,MAAM,KAAK,WAAW,UAAU,YAAY;AAGjF,QAAM,iBAAiB,mBAAmB,YAAY;AACtD,MAAI,kBAA4B,CAAC;AAEjC,MAAI,eAAe,SAAS,GAAG;AAC7B,sBAAkB,MAAM,SAAS;AAAA,MAC/B,SAAS;AAAA,MACT,SAAS,eAAe,IAAI,CAAC,UAAU,EAAE,MAAM,OAAO,KAAK,EAAE;AAAA,IAC/D,CAAC;AAAA,EACH;AAGA,QAAM,aAAa,KAAK,KAAK,KAAK,YAAY,UAAU;AACxD,MAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,YAAQ,MAAM,YAAY,UAAU,4BAA4B;AAChE,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,UAAU,gBAAgB,YAAY,OAAO;AACnD,QAAM,cAAc,KAAK,KAAK,SAAS,aAAa,YAAY;AAEhE,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AAEA,QAAM,kBAAkB;AAAA,IACtB,YAAY;AAAA,EACd;AAEA,SAAO,KAAK,YAAY,UAAU,aAAa;AAC/C,QAAM,kBAAkB,aAAa,KAAK,KAAK,KAAK,UAAU,GAAG,SAAS,eAAe;AACzF,SAAO,QAAQ,YAAY,UAAU,uBAAuB;AAG5D,QAAM,QAAQ,qBAAqB,cAAc,YAAY,EAAE,QAAQ,SAAS,CAAC;AACjF,MAAI,OAAO;AACT,WAAO,QAAQ,sCAAsC;AAAA,EACvD,OAAO;AACL,YAAQ,KAAK,IAAI,UAAU,mCAAmC;AAAA,EAChE;AAGA,aAAW,cAAc,iBAAiB;AACxC,8BAA0B,cAAc,YAAY,UAAU;AAC9D,WAAO,KAAK,OAAO,UAAU,eAAe,UAAU,GAAG;AAAA,EAC3D;AAGA,SAAO,KAAK,yBAAyB;AACrC,QAAM,MAAM,QAAQ,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC;AACxC,SAAO,QAAQ,wBAAwB;AAGvC,UAAQ,IAAI,WAAW,UAAU,mBAAmB;AACtD;",
5
- "names": []
6
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Add new package entry to packages object in sd.config.ts
3
- *
4
- * @returns true: success, false: already exists
5
- */
6
- export declare function addPackageToSdConfig(configPath: string, packageName: string, config: Record<string, unknown>): boolean;
7
- /**
8
- * Set server field for specific client in sd.config.ts
9
- */
10
- export declare function setClientServerInSdConfig(configPath: string, clientName: string, serverName: string): void;
11
- /**
12
- * Add tailwindcss config block to eslint.config.ts
13
- *
14
- * @returns true: added, false: already exists
15
- */
16
- export declare function addTailwindToEslintConfig(configPath: string, clientName: string): boolean;
17
- //# sourceMappingURL=config-editor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-editor.d.ts","sourceRoot":"","sources":["..\\..\\src\\utils\\config-editor.ts"],"names":[],"mappings":"AAyCA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAsBT;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CAyBN;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CA2BzF"}
@@ -1,79 +0,0 @@
1
- import { Project, SyntaxKind } from "ts-morph";
2
- function findPackagesObject(configPath) {
3
- const project = new Project();
4
- const sourceFile = project.addSourceFileAtPath(configPath);
5
- const configVar = sourceFile.getVariableDeclarationOrThrow("config");
6
- const arrowFn = configVar.getInitializerIfKindOrThrow(SyntaxKind.ArrowFunction);
7
- const body = arrowFn.getBody();
8
- let returnObj;
9
- if (body.isKind(SyntaxKind.ParenthesizedExpression)) {
10
- returnObj = body.getExpressionIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
11
- } else if (body.isKind(SyntaxKind.Block)) {
12
- const returnStmt = body.getFirstDescendantByKindOrThrow(SyntaxKind.ReturnStatement);
13
- returnObj = returnStmt.getExpressionIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
14
- } else {
15
- throw new Error("Unable to recognize structure of sd.config.ts");
16
- }
17
- const packagesProp = returnObj.getPropertyOrThrow("packages").asKindOrThrow(SyntaxKind.PropertyAssignment);
18
- const packagesObj = packagesProp.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
19
- return { project, packagesObj };
20
- }
21
- function addPackageToSdConfig(configPath, packageName, config) {
22
- const { project, packagesObj } = findPackagesObject(configPath);
23
- const existing = packagesObj.getProperty(`"${packageName}"`) ?? packagesObj.getProperty(packageName);
24
- if (existing) {
25
- return false;
26
- }
27
- const configStr = JSON.stringify(config).replace(/"([^"]+)":/g, "$1: ").replace(/"/g, '"');
28
- packagesObj.addPropertyAssignment({
29
- name: `"${packageName}"`,
30
- initializer: configStr
31
- });
32
- project.saveSync();
33
- return true;
34
- }
35
- function setClientServerInSdConfig(configPath, clientName, serverName) {
36
- const { project, packagesObj } = findPackagesObject(configPath);
37
- const clientPropNode = packagesObj.getProperty(`"${clientName}"`) ?? packagesObj.getProperty(clientName);
38
- if (clientPropNode == null) {
39
- throw new Error(`Client "${clientName}" not found in sd.config.ts`);
40
- }
41
- const clientProp = clientPropNode.asKindOrThrow(SyntaxKind.PropertyAssignment);
42
- const clientObj = clientProp.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
43
- const serverProp = clientObj.getProperty("server");
44
- if (serverProp) {
45
- serverProp.remove();
46
- }
47
- clientObj.addPropertyAssignment({
48
- name: "server",
49
- initializer: `"${serverName}"`
50
- });
51
- project.saveSync();
52
- }
53
- function addTailwindToEslintConfig(configPath, clientName) {
54
- const project = new Project();
55
- const sourceFile = project.addSourceFileAtPath(configPath);
56
- const defaultExport = sourceFile.getFirstDescendantByKindOrThrow(
57
- SyntaxKind.ArrayLiteralExpression
58
- );
59
- const text = defaultExport.getText();
60
- if (text.includes("tailwindcss")) {
61
- return false;
62
- }
63
- defaultExport.addElement(`{
64
- files: ["**/*.{ts,tsx}"],
65
- settings: {
66
- tailwindcss: {
67
- config: "packages/${clientName}/tailwind.config.ts",
68
- },
69
- },
70
- }`);
71
- project.saveSync();
72
- return true;
73
- }
74
- export {
75
- addPackageToSdConfig,
76
- addTailwindToEslintConfig,
77
- setClientServerInSdConfig
78
- };
79
- //# sourceMappingURL=config-editor.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/config-editor.ts"],
4
- "mappings": "AAAA,SAAS,SAAS,kBAAgD;AAQlE,SAAS,mBAAmB,YAG1B;AACA,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,aAAa,QAAQ,oBAAoB,UAAU;AAGzD,QAAM,YAAY,WAAW,8BAA8B,QAAQ;AACnE,QAAM,UAAU,UAAU,4BAA4B,WAAW,aAAa;AAG9E,QAAM,OAAO,QAAQ,QAAQ;AAC7B,MAAI;AAEJ,MAAI,KAAK,OAAO,WAAW,uBAAuB,GAAG;AACnD,gBAAY,KAAK,2BAA2B,WAAW,uBAAuB;AAAA,EAChF,WAAW,KAAK,OAAO,WAAW,KAAK,GAAG;AACxC,UAAM,aAAa,KAAK,gCAAgC,WAAW,eAAe;AAClF,gBAAY,WAAW,2BAA2B,WAAW,uBAAuB;AAAA,EACtF,OAAO;AACL,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAGA,QAAM,eAAe,UAClB,mBAAmB,UAAU,EAC7B,cAAc,WAAW,kBAAkB;AAC9C,QAAM,cAAc,aAAa,4BAA4B,WAAW,uBAAuB;AAE/F,SAAO,EAAE,SAAS,YAAY;AAChC;AAOO,SAAS,qBACd,YACA,aACA,QACS;AACT,QAAM,EAAE,SAAS,YAAY,IAAI,mBAAmB,UAAU;AAG9D,QAAM,WACJ,YAAY,YAAY,IAAI,WAAW,GAAG,KAAK,YAAY,YAAY,WAAW;AACpF,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,KAAK,UAAU,MAAM,EACpC,QAAQ,eAAe,MAAM,EAC7B,QAAQ,MAAM,GAAG;AAEpB,cAAY,sBAAsB;AAAA,IAChC,MAAM,IAAI,WAAW;AAAA,IACrB,aAAa;AAAA,EACf,CAAC;AAED,UAAQ,SAAS;AACjB,SAAO;AACT;AAKO,SAAS,0BACd,YACA,YACA,YACM;AACN,QAAM,EAAE,SAAS,YAAY,IAAI,mBAAmB,UAAU;AAE9D,QAAM,iBACJ,YAAY,YAAY,IAAI,UAAU,GAAG,KAAK,YAAY,YAAY,UAAU;AAClF,MAAI,kBAAkB,MAAM;AAC1B,UAAM,IAAI,MAAM,WAAW,UAAU,6BAA6B;AAAA,EACpE;AAEA,QAAM,aAAa,eAAe,cAAc,WAAW,kBAAkB;AAC7E,QAAM,YAAY,WAAW,4BAA4B,WAAW,uBAAuB;AAG3F,QAAM,aAAa,UAAU,YAAY,QAAQ;AACjD,MAAI,YAAY;AACd,eAAW,OAAO;AAAA,EACpB;AAGA,YAAU,sBAAsB;AAAA,IAC9B,MAAM;AAAA,IACN,aAAa,IAAI,UAAU;AAAA,EAC7B,CAAC;AAED,UAAQ,SAAS;AACnB;AAOO,SAAS,0BAA0B,YAAoB,YAA6B;AACzF,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,aAAa,QAAQ,oBAAoB,UAAU;AAGzD,QAAM,gBAAgB,WAAW;AAAA,IAC/B,WAAW;AAAA,EACb;AAGA,QAAM,OAAO,cAAc,QAAQ;AACnC,MAAI,KAAK,SAAS,aAAa,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,gBAAc,WAAW;AAAA;AAAA;AAAA;AAAA,4BAIC,UAAU;AAAA;AAAA;AAAA,IAGlC;AAEF,UAAQ,SAAS;AACjB,SAAO;AACT;",
5
- "names": []
6
- }
@@ -1,126 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { input, confirm } from "@inquirer/prompts";
4
- import { consola } from "consola";
5
- import { renderTemplateDir } from "../utils/template";
6
- import { addPackageToSdConfig, addTailwindToEslintConfig } from "../utils/config-editor";
7
- import { execa } from "execa";
8
- import { findPackageRoot } from "../utils/package-utils";
9
-
10
- //#region Types
11
-
12
- /**
13
- * Add-client command options
14
- */
15
- export interface AddClientOptions {}
16
-
17
- //#endregion
18
-
19
- //#region Utilities
20
- //#endregion
21
-
22
- //#region Main
23
-
24
- /**
25
- * Add client package to the project.
26
- *
27
- * 1. Verify project root (sd.config.ts exists)
28
- * 2. Interactive prompt (name suffix, router usage)
29
- * 3. Check for duplicate package directory
30
- * 4. Render Handlebars template
31
- * 5. Add package entry to sd.config.ts (ts-morph)
32
- * 6. Add tailwind configuration to eslint.config.ts (if first client)
33
- * 7. pnpm install
34
- */
35
- export async function runAddClient(_options: AddClientOptions): Promise<void> {
36
- const cwd = process.cwd();
37
- const logger = consola.withTag("sd:cli:add-client");
38
-
39
- // 1. Verify project root
40
- if (!fs.existsSync(path.join(cwd, "sd.config.ts"))) {
41
- consola.error("Cannot find sd.config.ts. Please run from the project root.");
42
- process.exitCode = 1;
43
- return;
44
- }
45
-
46
- // Project name
47
- const projectName = path.basename(cwd);
48
-
49
- // 2. Interactive prompt
50
- const clientSuffix = await input({
51
- message: "Enter client name suffix (client-___):",
52
- validate: (value) => {
53
- if (!value.trim()) return "Please enter a name.";
54
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
55
- return true;
56
- },
57
- });
58
-
59
- const useRouter = await confirm({
60
- message: "Do you want to use router?",
61
- default: true,
62
- });
63
-
64
- const clientName = `client-${clientSuffix}`;
65
-
66
- // 3. Check for duplicate package directory
67
- const packageDir = path.join(cwd, "packages", clientName);
68
- if (fs.existsSync(packageDir)) {
69
- consola.error(`packages/${clientName} directory already exists.`);
70
- process.exitCode = 1;
71
- return;
72
- }
73
-
74
- // 4. Render template
75
- const pkgRoot = findPackageRoot(import.meta.dirname);
76
- const templateDir = path.join(pkgRoot, "templates", "add-client");
77
-
78
- const context = {
79
- projectName,
80
- clientSuffix,
81
- clientName,
82
- router: useRouter,
83
- };
84
-
85
- const dirReplacements = {
86
- __CLIENT__: clientName,
87
- };
88
-
89
- logger.info(`Creating ${clientName} package...`);
90
- await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
91
- logger.success(`packages/${clientName} created successfully`);
92
-
93
- // 5. Update sd.config.ts
94
- const sdConfigPath = path.join(cwd, "sd.config.ts");
95
- const added = addPackageToSdConfig(sdConfigPath, clientName, { target: "client" });
96
- if (added) {
97
- logger.success("sd.config.ts updated successfully");
98
- } else {
99
- consola.warn(`"${clientName}" already exists in sd.config.ts.`);
100
- }
101
-
102
- // 6. Add tailwind configuration to eslint.config.ts (if first client)
103
- const eslintConfigPath = path.join(cwd, "eslint.config.ts");
104
- if (fs.existsSync(eslintConfigPath)) {
105
- const tailwindAdded = addTailwindToEslintConfig(eslintConfigPath, clientName);
106
- if (tailwindAdded) {
107
- logger.success("Added tailwind configuration to eslint.config.ts");
108
- }
109
- }
110
-
111
- // 7. pnpm install
112
- logger.info("Running pnpm install...");
113
- await execa("pnpm", ["install"], { cwd });
114
- logger.success("pnpm install completed");
115
-
116
- // Done
117
- consola.box(
118
- [
119
- `Client "${clientName}" has been added!`,
120
- "",
121
- ` pnpm dev ${clientName} Run development server`,
122
- ].join("\n"),
123
- );
124
- }
125
-
126
- //#endregion
@@ -1,138 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { input, checkbox } from "@inquirer/prompts";
4
- import { consola } from "consola";
5
- import { renderTemplateDir } from "../utils/template";
6
- import { addPackageToSdConfig, setClientServerInSdConfig } from "../utils/config-editor";
7
- import { execa } from "execa";
8
- import { findPackageRoot } from "../utils/package-utils";
9
-
10
- //#region Types
11
-
12
- /**
13
- * Add-server command options
14
- */
15
- export interface AddServerOptions {}
16
-
17
- //#endregion
18
-
19
- //#region Utilities
20
-
21
- /**
22
- * Reads sd.config.ts and returns a list of package names with target "client".
23
- */
24
- function findClientPackages(sdConfigPath: string): string[] {
25
- const content = fs.readFileSync(sdConfigPath, "utf-8");
26
- const clients: string[] = [];
27
-
28
- // Find client packages using simple pattern matching
29
- const regex = /"([^"]+)":\s*\{[^}]*target:\s*"client"/g;
30
- let match: RegExpExecArray | null;
31
- while ((match = regex.exec(content)) != null) {
32
- clients.push(match[1]);
33
- }
34
- return clients;
35
- }
36
-
37
- //#endregion
38
-
39
- //#region Main
40
-
41
- /**
42
- * Adds a server package to the project.
43
- *
44
- * 1. Verify project root
45
- * 2. Interactive prompts (name suffix, client selection)
46
- * 3. Check for duplicate package directory
47
- * 4. Render Handlebars template
48
- * 5. Add server package entry to sd.config.ts
49
- * 6. Update server field in selected clients
50
- * 7. Run pnpm install
51
- */
52
- export async function runAddServer(_options: AddServerOptions): Promise<void> {
53
- const cwd = process.cwd();
54
- const logger = consola.withTag("sd:cli:add-server");
55
-
56
- // 1. Verify project root
57
- const sdConfigPath = path.join(cwd, "sd.config.ts");
58
- if (!fs.existsSync(sdConfigPath)) {
59
- consola.error("Cannot find sd.config.ts. Please run this from the project root.");
60
- process.exitCode = 1;
61
- return;
62
- }
63
-
64
- const projectName = path.basename(cwd);
65
-
66
- // 2. Interactive prompts
67
- const serverSuffix = await input({
68
- message: 'Server name suffix (leave empty for "server"):',
69
- validate: (value) => {
70
- if (value.trim() === "") return true; // Allow empty value
71
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
72
- return true;
73
- },
74
- });
75
-
76
- const serverName = serverSuffix.trim() === "" ? "server" : `server-${serverSuffix}`;
77
-
78
- // Client selection (if existing clients are present)
79
- const clientPackages = findClientPackages(sdConfigPath);
80
- let selectedClients: string[] = [];
81
-
82
- if (clientPackages.length > 0) {
83
- selectedClients = await checkbox({
84
- message: "Select the clients this server will serve:",
85
- choices: clientPackages.map((name) => ({ name, value: name })),
86
- });
87
- }
88
-
89
- // 3. Check for duplicate package directory
90
- const packageDir = path.join(cwd, "packages", serverName);
91
- if (fs.existsSync(packageDir)) {
92
- consola.error(`packages/${serverName} directory already exists.`);
93
- process.exitCode = 1;
94
- return;
95
- }
96
-
97
- // 4. Render template
98
- const pkgRoot = findPackageRoot(import.meta.dirname);
99
- const templateDir = path.join(pkgRoot, "templates", "add-server");
100
-
101
- const context = {
102
- projectName,
103
- serverName,
104
- port: 3000,
105
- };
106
-
107
- const dirReplacements = {
108
- __SERVER__: serverName,
109
- };
110
-
111
- logger.info(`Creating ${serverName} package...`);
112
- await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
113
- logger.success(`packages/${serverName} created successfully`);
114
-
115
- // 5. Add server package to sd.config.ts
116
- const added = addPackageToSdConfig(sdConfigPath, serverName, { target: "server" });
117
- if (added) {
118
- logger.success("Server package added to sd.config.ts");
119
- } else {
120
- consola.warn(`"${serverName}" already exists in sd.config.ts.`);
121
- }
122
-
123
- // 6. Update server field in selected clients
124
- for (const clientName of selectedClients) {
125
- setClientServerInSdConfig(sdConfigPath, clientName, serverName);
126
- logger.info(`Set ${clientName} server to "${serverName}"`);
127
- }
128
-
129
- // 7. Run pnpm install
130
- logger.info("Running pnpm install...");
131
- await execa("pnpm", ["install"], { cwd });
132
- logger.success("pnpm install completed");
133
-
134
- // Done
135
- consola.box(`Server "${serverName}" has been added!`);
136
- }
137
-
138
- //#endregion