@fernir2/saas-kit-cli 0.1.16 → 0.1.18

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 (133) hide show
  1. package/base-repo/app-constants/aliases.cjs.js +1 -1
  2. package/base-repo/app-constants/aliases.js +1 -1
  3. package/base-repo/app-constants/project-paths.cjs.js +1 -1
  4. package/base-repo/app-constants/project-paths.js +1 -1
  5. package/cli/.env +55 -0
  6. package/level2/cli/create-saas-kit-app/bin/index.cjs.js +4 -4
  7. package/level2/cli/create-saas-kit-app/bin/index.js +3 -3
  8. package/level2/fd-toolbox/api/api-client.cjs.js +1 -1
  9. package/level2/fd-toolbox/api/api-client.js +1 -1
  10. package/level2/fd-toolbox/api/api-path-names.cjs.js +2 -2
  11. package/level2/fd-toolbox/api/api-paths.cjs.js +1 -1
  12. package/level2/fd-toolbox/api/api-paths.js +1 -1
  13. package/level2/fd-toolbox/api/base-api.cjs.js +1 -1
  14. package/level2/fd-toolbox/api/base-api.js +1 -1
  15. package/level2/fd-toolbox/auth/login-states.cjs.js +1 -1
  16. package/level2/fd-toolbox/auth/login-states.js +1 -1
  17. package/level2/fd-toolbox/auth/session-storage.cjs.js +1 -1
  18. package/level2/fd-toolbox/auth/session-storage.js +1 -1
  19. package/level2/fd-toolbox/auth/tokens.cjs.js +1 -1
  20. package/level2/fd-toolbox/auth/tokens.js +1 -1
  21. package/level2/fd-toolbox/constants/constants.cjs.js +1 -1
  22. package/level2/fd-toolbox/constants/constants.js +1 -1
  23. package/level2/fd-toolbox/enums/enums.cjs.js +1 -1
  24. package/level2/fd-toolbox/enums/enums.js +1 -1
  25. package/level2/fd-toolbox/errors/error-handler.cjs.js +1 -1
  26. package/level2/fd-toolbox/errors/error-handler.js +1 -1
  27. package/level2/fd-toolbox/errors/errors.cjs.js +1 -1
  28. package/level2/fd-toolbox/errors/errors.js +1 -1
  29. package/level2/fd-toolbox/errors/problem-details.cjs.js +1 -1
  30. package/level2/fd-toolbox/errors/problem-details.js +1 -1
  31. package/level2/fd-toolbox/functions/value-checking-functions.cjs.js +1 -1
  32. package/level2/fd-toolbox/functions/value-checking-functions.js +1 -1
  33. package/level2/fd-toolbox/http/url/urls.cjs.js +1 -1
  34. package/level2/fd-toolbox/http/url/urls.js +1 -1
  35. package/level2/fd-toolbox/infra/env-config.cjs.js +2 -2
  36. package/level2/fd-toolbox/infra/env-config.js +2 -2
  37. package/level2/fd-toolbox/infra/env-functions.cjs.js +1 -1
  38. package/level2/fd-toolbox/infra/env-functions.js +1 -1
  39. package/level2/fd-toolbox/infra/env-schema.cjs.js +2 -2
  40. package/level2/fd-toolbox/infra/env-schema.js +2 -2
  41. package/level2/fd-toolbox/infra/env-store.cjs.js +1 -1
  42. package/level2/fd-toolbox/infra/env-store.js +1 -1
  43. package/level2/fd-toolbox/lib/environments.cjs.js +1 -1
  44. package/level2/fd-toolbox/lib/environments.js +1 -1
  45. package/level2/fd-toolbox/lib/utils.cjs.js +1 -1
  46. package/level2/fd-toolbox/lib/utils.js +1 -1
  47. package/level2/fd-toolbox/local-storage/local-storage.cjs.js +1 -1
  48. package/level2/fd-toolbox/local-storage/local-storage.js +1 -1
  49. package/level2/fd-toolbox/logging/loggers.cjs.js +1 -1
  50. package/level2/fd-toolbox/logging/loggers.js +1 -1
  51. package/level2/fd-toolbox/notifications.cjs.js +2 -2
  52. package/level2/fd-toolbox/notifications.js +2 -2
  53. package/level2/fd-toolbox/odata/odata-constants.cjs.js +1 -1
  54. package/level2/fd-toolbox/odata/odata-constants.js +1 -1
  55. package/level2/fd-toolbox/odata/odatas.cjs.js +1 -1
  56. package/level2/fd-toolbox/odata/odatas.js +1 -1
  57. package/level2/fd-toolbox/odata/services/odata-filters.cjs.js +1 -1
  58. package/level2/fd-toolbox/odata/services/odata-filters.js +1 -1
  59. package/level2/fd-toolbox/paths/paths-names.cjs.js +2 -2
  60. package/level2/fd-toolbox/paths/paths-names.js +1 -1
  61. package/level2/fd-toolbox/routing/login-routers.cjs.js +1 -1
  62. package/level2/fd-toolbox/routing/login-routers.js +1 -1
  63. package/level2/fd-toolbox/routing/paths.cjs.js +1 -1
  64. package/level2/fd-toolbox/routing/paths.js +1 -1
  65. package/level2/fd-toolbox/strings/strings-constants.cjs.js +1 -1
  66. package/level2/fd-toolbox/strings/strings-constants.js +1 -1
  67. package/level2/fd-toolbox/strings/strings.cjs.js +1 -1
  68. package/level2/fd-toolbox/strings/strings.js +1 -1
  69. package/level2/fd-toolbox/types/ensure-type.cjs.js +1 -1
  70. package/level2/fd-toolbox/types/ensure-type.js +1 -1
  71. package/level2/fd-toolbox-core/core/name-of.cjs.js +1 -1
  72. package/level2/fd-toolbox-core/core/name-of.js +1 -1
  73. package/level2/fd-toolbox-core/types/resource-with-id.cjs.js +1 -1
  74. package/level2/fd-toolbox-core/types/resource-with-id.js +1 -1
  75. package/package.json +3 -3
  76. package/LICENSE +0 -45
  77. package/bin/index.js +0 -262
  78. package/cli/.gitlab-ci.yml +0 -15
  79. package/cli/.husky/commit-msg +0 -1
  80. package/cli/.husky/pre-commit +0 -2
  81. package/cli/README.md +0 -101
  82. package/cli/bin/index.ts +0 -359
  83. package/cli/constants/path.js +0 -54
  84. package/cli/drizzle.config.ts +0 -12
  85. package/cli/eslint.config.js +0 -10
  86. package/cli/global-setup.ts +0 -25
  87. package/cli/next.config.js +0 -55
  88. package/cli/npm-commands/gen-meta/index.ts +0 -3
  89. package/cli/npm-commands/gen-schema/index.ts +0 -5
  90. package/cli/npm-commands/migrate-db/index.ts +0 -5
  91. package/cli/npm-commands/migrate-db/migrate-db.ts +0 -15
  92. package/cli/npm-commands/seed-db/index.ts +0 -5
  93. package/cli/npm-commands/seed-db/seed-db.ts +0 -15
  94. package/cli/package-template.json +0 -61
  95. package/cli/playwright.config.ts +0 -34
  96. package/cli/postcss.config.mjs +0 -9
  97. package/cli/server.ts +0 -41
  98. package/cli/src/app/api/v1/[resourceName]/[id]/route.ts/route.ts +0 -11
  99. package/cli/src/app/api/v1/[resourceName]/route.ts/route.ts +0 -14
  100. package/cli/src/app/api/v1/[resourceName]/upsert/route.ts/route.ts +0 -3
  101. package/cli/src/app/api/v1/log/route.ts/route.ts +0 -7
  102. package/cli/src/app/api/v1/otheruser/[id]/route.ts/route.ts +0 -14
  103. package/cli/src/app/api/v1/otheruser/route.ts/route.ts +0 -7
  104. package/cli/src/app/api/v1/password/forgotpassword/route.ts/route.ts +0 -3
  105. package/cli/src/app/api/v1/password/resetpassword/route.ts/route.ts +0 -3
  106. package/cli/src/app/api/v1/payment/method/route.ts/route.ts +0 -4
  107. package/cli/src/app/api/v1/payment/route.ts/route.ts +0 -3
  108. package/cli/src/app/api/v1/payment/verify-fail/route.ts/route.ts +0 -3
  109. package/cli/src/app/api/v1/payment/verify-success/route.ts/route.ts +0 -3
  110. package/cli/src/app/api/v1/preload/route.ts/route.ts +0 -3
  111. package/cli/src/app/api/v1/searchable-resources/route.ts/route.ts +0 -11
  112. package/cli/src/app/api/v1/searchresult/route.ts/route.ts +0 -35
  113. package/cli/src/app/api/v1/sign-in/route.ts/route.ts +0 -3
  114. package/cli/src/app/api/v1/sign-out/route.ts/route.ts +0 -3
  115. package/cli/src/app/api/v1/sign-up/route.ts/route.ts +0 -3
  116. package/cli/src/app/api/v1/subscription/cancel/route.ts/route.ts +0 -3
  117. package/cli/src/app/api/v1/subscription/create/route.ts/route.ts +0 -3
  118. package/cli/src/app/api/v1/subscription/update/route.ts/route.ts +0 -3
  119. package/cli/src/app/api/v1/uimeta/route.ts/route.ts +0 -3
  120. package/cli/src/app/api/v1/uimetas/route.ts/route.ts +0 -3
  121. package/cli/src/app/api/v1/userpermission/route.ts/route.ts +0 -3
  122. package/cli/src/app/api/v1/visible-workspace/route.ts/route.ts +0 -5
  123. package/cli/src/app/api/v1/workspace/change/route.ts/route.ts +0 -5
  124. package/cli/src/app/favicon.ico +0 -0
  125. package/cli/src/app/globals.css +0 -1
  126. package/cli/src/app/layout.tsx +0 -44
  127. package/cli/src/app/page.tsx +0 -9
  128. package/cli/src/app/styles/common.css +0 -74
  129. package/cli/src/app/styles/rich-text-editor.css +0 -130
  130. package/cli/tailwind.config.ts +0 -13
  131. package/cli/tsconfig.declaration.json +0 -48
  132. package/cli/tsconfig.json +0 -65
  133. package/cli/tsconfig.server.json +0 -14
package/cli/bin/index.ts DELETED
@@ -1,359 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { execSync } from "child_process";
4
- import { promises as fsPromises, existsSync, mkdirSync, rmSync, Stats } from "fs";
5
- import { fileURLToPath } from "node:url";
6
- import * as path from "path";
7
- import fs from "node:fs";
8
-
9
- import {
10
- toolsFoldersToReplace,
11
- additionalFoldersToCreate,
12
- } from "@packages/base-repo/constants/create-app-constants";
13
-
14
- import { logStringError, logInfoRaw } from "@packages/level2/fd-toolbox/logging/loggers";
15
-
16
- import { WithIndexer } from "@packages/level2/fd-toolbox-core/types/with-indexer";
17
-
18
- import { projectName } from "@packages/level2/fd-toolbox/constants/constants";
19
-
20
- import { allFilesToCopy } from "@packages/level2/npm-commands/build-npm/path";
21
-
22
- import { createError } from "@packages/level2/fd-toolbox/errors/errors";
23
-
24
- import { folders } from "@packages/base-repo/app-constants/project-paths";
25
-
26
- import { npmPackages } from "@packages/base-repo/constants/packages";
27
-
28
- import { aliasSymbols } from "@packages/base-repo/app-constants/aliases";
29
-
30
- import { isString, isWithIndexer } from "@packages/level2/fd-toolbox/types/ensure-type";
31
-
32
- interface PackageJson {
33
- name?: string;
34
- dependencies?: WithIndexer<string>;
35
- devDependencies?: WithIndexer<string>;
36
- [key: string]: unknown;
37
- }
38
-
39
- interface FileEntry {
40
- name: string;
41
- isDirectory(): boolean;
42
- }
43
-
44
- const requiredNodeVersion = "v18.0.0";
45
-
46
- if (process.version < requiredNodeVersion) {
47
- logStringError(`Node.js ${requiredNodeVersion}+ is required`);
48
- process.exit(1);
49
- }
50
-
51
- const filename = fileURLToPath(import.meta.url);
52
- const dir = path.dirname(filename);
53
- const repoRoot = path.resolve(dir, "..");
54
- const saasKitRoot = path.resolve(dir, "@../..");
55
-
56
- const envLocalPath: string = path.join(dir, `../${folders.cli}/.env`);
57
- const envTemplate: string = fs.readFileSync(envLocalPath, "utf8");
58
-
59
- const foldersToIgnore: string[] = [`${folders.cli}/constants`];
60
-
61
- function runCommand(command: string, cwd?: string) {
62
- logInfoRaw(`Executing: ${command}`);
63
-
64
- try {
65
- execSync(command, { stdio: "inherit", cwd: cwd ?? process.cwd() });
66
- } catch (error) {
67
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
68
- logStringError(`Error executing: ${command}`);
69
- logStringError(errorMessage);
70
- process.exit(1);
71
- }
72
- }
73
-
74
- function checkTargetFolder(targetDir: string) {
75
- if (existsSync(targetDir)) {
76
- logStringError(`Error: Folder "${path.basename(targetDir)}" already exists.`);
77
- process.exit(1);
78
- }
79
- }
80
-
81
- function getCreateNextAppVersion() {
82
- const packageJsonPath: string = path.resolve(saasKitRoot, "package.json");
83
- const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
84
-
85
- return String(packageJson.devDependencies?.["next"] ?? packageJson.dependencies?.["next"] ?? "latest");
86
- }
87
-
88
- function createNextProject(projectTitle: string, targetDir: string) {
89
- logInfoRaw("Creating Next.js project...");
90
-
91
- const createNextAppVersion = getCreateNextAppVersion();
92
- const createCommand: string = [
93
- `npx create-next-app@${createNextAppVersion} "${projectTitle}"`,
94
- "--typescript",
95
- "--tailwind",
96
- "--eslint",
97
- "--app",
98
- "--src-dir",
99
- "--turbopack",
100
- "--no-import-alias",
101
- "--no-git",
102
- ].join(" ");
103
-
104
- runCommand(createCommand, path.dirname(targetDir));
105
- logInfoRaw("Next.js project created!");
106
- }
107
-
108
- async function createEnvFile(targetDir: string) {
109
- logInfoRaw("Creating .env file with default values...");
110
-
111
- const envPath: string = path.join(targetDir, ".env");
112
-
113
- try {
114
- await fsPromises.writeFile(envPath, envTemplate, "utf8");
115
- logInfoRaw(".env file created with values!");
116
- } catch (error) {
117
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
118
- logStringError("Error creating .env file:");
119
- logStringError(errorMessage);
120
- throw error;
121
- }
122
- }
123
-
124
- async function overridePackageJson(targetDir: string) {
125
- const targetPackageJsonPath: string = path.join(targetDir, "package.json");
126
- // "name" is omitted in package.json; renamed to package-template.json so NX ignores it as a project.
127
- const cliPackageJsonPath: string = path.join(repoRoot, `${folders.cli}/package-template.json`);
128
-
129
- try {
130
- const targetPackageJson: PackageJson = JSON.parse(
131
- await fsPromises.readFile(targetPackageJsonPath, "utf8"),
132
- );
133
- const name = targetPackageJson.name;
134
-
135
- const cliPackageJson: PackageJson = JSON.parse(await fsPromises.readFile(cliPackageJsonPath, "utf8"));
136
-
137
- const finalPackageJson: PackageJson = {
138
- ...cliPackageJson,
139
- name: name,
140
- };
141
-
142
- await fsPromises.writeFile(
143
- targetPackageJsonPath,
144
- `${JSON.stringify(finalPackageJson, null, 2)}\n`,
145
- "utf8",
146
- );
147
- } catch (error) {
148
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
149
- logStringError("Error overriding package.json:");
150
- logStringError(errorMessage);
151
- throw error;
152
- }
153
- }
154
-
155
- function replaceImports(content: string) {
156
- // Approved
157
- // eslint-disable-next-line sonarjs/slow-regex
158
- const importRegex = /(import\s+[^'"]*from\s+["'])([^"']+)(["'])/g;
159
-
160
- return content.replace(importRegex, (match, p1, importPath, p3) => {
161
- if (!importPath.startsWith(aliasSymbols.atSign) || importPath.startsWith(npmPackages.saasKit)) {
162
- return match;
163
- }
164
-
165
- if (
166
- importPath.startsWith(aliasSymbols.atSign + folders.server) ||
167
- importPath.includes(`/${folders.server}/`)
168
- ) {
169
- return `${p1}${npmPackages.saasKitServer}${p3}`;
170
- }
171
-
172
- return `${p1}${npmPackages.saasKit}${p3}`;
173
- });
174
- }
175
-
176
- async function copyProjectFiles(targetDir: string) {
177
- logInfoRaw(`Copying ${projectName} files...`);
178
-
179
- for (const file of allFilesToCopy) {
180
- const cliFile = `${folders.cli}/${file}`;
181
- const srcPath: string = path.join(repoRoot, cliFile);
182
-
183
- const processedFile = replaceToolsFolder(file);
184
-
185
- const destPath: string = path.join(targetDir, processedFile);
186
-
187
- if (existsSync(srcPath)) {
188
- const stats: Stats = await fsPromises.stat(srcPath);
189
-
190
- if (stats.isDirectory()) {
191
- await copyDirectoryContents(srcPath, destPath);
192
- } else {
193
- await copyAndProcessFile(srcPath, destPath);
194
- }
195
- } else {
196
- logInfoRaw(`Source file not found: ${cliFile}`);
197
- }
198
- }
199
-
200
- logInfoRaw("Files copied and imports updated!");
201
- }
202
-
203
- function replaceToolsFolder(file: string) {
204
- let processedFile = file;
205
-
206
- for (const [folderPrefix, replacements] of Object.entries(toolsFoldersToReplace)) {
207
- if (processedFile.startsWith(folderPrefix) && isWithIndexer<string>(replacements)) {
208
- const typedReplacements: WithIndexer<string> = replacements;
209
-
210
- for (const key in typedReplacements) {
211
- const value = typedReplacements[key];
212
-
213
- if (isString(value)) {
214
- processedFile = processedFile.replace(key, value);
215
- }
216
- }
217
-
218
- break;
219
- }
220
- }
221
-
222
- return processedFile;
223
- }
224
-
225
- function shouldIgnorePath(filePath: string, basePath: string, isDirectory = false) {
226
- const relativePath = path.relative(basePath, filePath);
227
- const pathParts = relativePath.split(path.sep);
228
-
229
- const relativeFromRepo = path.relative(repoRoot, filePath).replace(/\\/g, "/");
230
-
231
- return (
232
- (isDirectory && foldersToIgnore.includes(relativeFromRepo)) ||
233
- foldersToIgnore.some((ignoreFolder) => pathParts.some((part) => part === ignoreFolder))
234
- );
235
- }
236
-
237
- async function copyDirectoryContents(srcDir: string, destDir: string) {
238
- if (!existsSync(destDir)) {
239
- mkdirSync(destDir, { recursive: true });
240
- }
241
-
242
- try {
243
- const entries: FileEntry[] = await fsPromises.readdir(srcDir, { withFileTypes: true });
244
-
245
- for (const entry of entries) {
246
- const srcPath: string = path.join(srcDir, entry.name);
247
- const destPath: string = path.join(destDir, entry.name);
248
-
249
- if (!shouldIgnorePath(srcPath, srcDir, entry.isDirectory())) {
250
- if (entry.isDirectory()) {
251
- await copyDirectoryContents(srcPath, destPath);
252
- } else {
253
- await copyAndProcessFile(srcPath, destPath);
254
- }
255
- }
256
- }
257
- } catch (error) {
258
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
259
- logStringError(`Error reading directory ${srcDir}: ${errorMessage}`);
260
- throw error;
261
- }
262
- }
263
-
264
- async function copyAndProcessFile(srcPath: string, destPath: string) {
265
- const destDir: string = path.dirname(destPath);
266
-
267
- if (!existsSync(destDir)) {
268
- mkdirSync(destDir, { recursive: true });
269
- }
270
-
271
- const stats: Stats = await fsPromises.stat(srcPath);
272
-
273
- if (stats.isDirectory()) {
274
- await copyDirectoryContents(srcPath, destPath);
275
- } else {
276
- const content: string = await fsPromises.readFile(srcPath, "utf8");
277
- const processedContent: string = replaceImports(content);
278
- await fsPromises.writeFile(destPath, processedContent, "utf8");
279
- }
280
- }
281
-
282
- function createAdditionalFolders(targetDir: string) {
283
- for (const folder of additionalFoldersToCreate) {
284
- const folderPath: string = path.join(targetDir, folder);
285
-
286
- if (!existsSync(folderPath)) {
287
- mkdirSync(folderPath, { recursive: true });
288
- logInfoRaw(`Created folder: ${folder}`);
289
- }
290
- }
291
-
292
- logInfoRaw("Additional folders created!");
293
- }
294
-
295
- async function main() {
296
- const args: string[] = process.argv.slice(2);
297
-
298
- if (args.length < 1) {
299
- logStringError("Error: Specify folder name. Example: npx create-saas-kit-app <folder-name>");
300
- process.exit(1);
301
- }
302
-
303
- const folderName: string = args[0];
304
- const targetDir: string = path.resolve(process.cwd(), folderName);
305
-
306
- logInfoRaw(`\nCreating ${projectName} project "${folderName}"...\n`);
307
-
308
- try {
309
- checkTargetFolder(targetDir);
310
- createNextProject(folderName, targetDir);
311
- await copyProjectFiles(targetDir);
312
- await overridePackageJson(targetDir);
313
- createAdditionalFolders(targetDir);
314
- await createEnvFile(targetDir);
315
- await updateLayoutTitle(targetDir, folderName);
316
-
317
- logInfoRaw(`\n${projectName} project "${folderName}" is ready!`);
318
- logInfoRaw("Next steps:");
319
- logInfoRaw(` cd ${folderName}`);
320
- logInfoRaw(" npm run prod");
321
- logInfoRaw(" npm start");
322
- } catch (error) {
323
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
324
- logStringError("Error:");
325
- logStringError(errorMessage);
326
-
327
- if (existsSync(targetDir)) {
328
- logInfoRaw("Cleaning up...");
329
- rmSync(targetDir, { recursive: true, force: true });
330
- }
331
-
332
- process.exit(1);
333
- }
334
- }
335
-
336
- async function updateLayoutTitle(targetDir: string, folderName: string) {
337
- const layoutPath = path.join(targetDir, "src/app/layout.tsx");
338
-
339
- if (!existsSync(layoutPath)) {
340
- throw createError(`layout.tsx not found at ${layoutPath}, cannot update title.`);
341
- }
342
-
343
- let content = await fsPromises.readFile(layoutPath, "utf8");
344
- const titleRegex = /"SaaS Kit"/g;
345
-
346
- if (!titleRegex.test(content)) {
347
- throw createError("SaaS Kit not found in layout.tsx, cannot update title.");
348
- }
349
-
350
- content = content.replace(titleRegex, `"${folderName}"`);
351
- await fsPromises.writeFile(layoutPath, content, "utf8");
352
- }
353
-
354
- main().catch((error) => {
355
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
356
- logStringError("Unhandled error:");
357
- logStringError(errorMessage);
358
- process.exit(1);
359
- });
@@ -1,54 +0,0 @@
1
- import { projectPaths, clientPaths } from "../../packages/base-repo/app-constants/project-paths.js";
2
- export const filesToCopy = ["", "git"];
3
- export const rootFilesToCopy = [
4
- ".gitignore",
5
- ".gitlab-ci.yml",
6
- "postcss.config.mjs",
7
- "tsconfig.declaration.json",
8
- "README.md",
9
- ".husky",
10
- "server.ts",
11
- ];
12
- export const appFilesToCopy = [
13
- clientPaths.styles,
14
- `${projectPaths.app}/favicon.ico`,
15
- `${projectPaths.app}/globals.css`,
16
- `${projectPaths.app}/layout.tsx`,
17
- `${projectPaths.app}/page.tsx`,
18
- ];
19
- export const apiRoutesToCopy = [
20
- `${projectPaths.apiV1}/searchable-resources/route.ts`,
21
- `${projectPaths.apiV1}/searchresult/route.ts`,
22
- `${projectPaths.apiV1}/workspace/change/route.ts`,
23
- `${projectPaths.apiV1}/visible-workspace/route.ts`,
24
- `${projectPaths.apiV1}/userpermission/route.ts`,
25
- `${projectPaths.apiV1}/user-feature/is-enabled/route.ts`,
26
- `${projectPaths.apiV1}/uimetas/route.ts`,
27
- `${projectPaths.apiV1}/uimeta/route.ts`,
28
- `${projectPaths.apiV1}/subscription/update/route.ts`,
29
- `${projectPaths.apiV1}/subscription/create/route.ts`,
30
- `${projectPaths.apiV1}/subscription/cancel/route.ts`,
31
- `${projectPaths.apiV1}/sign-up/route.ts`,
32
- `${projectPaths.apiV1}/sign-out/route.ts`,
33
- `${projectPaths.apiV1}/sign-in/route.ts`,
34
- `${projectPaths.apiV1}/preload/route.ts`,
35
- `${projectPaths.apiV1}/payment/route.ts`,
36
- `${projectPaths.apiV1}/payment/verify-success/route.ts`,
37
- `${projectPaths.apiV1}/payment/verify-fail/route.ts`,
38
- `${projectPaths.apiV1}/payment/method/route.ts`,
39
- `${projectPaths.apiV1}/password/resetpassword/route.ts`,
40
- `${projectPaths.apiV1}/password/forgotpassword/route.ts`,
41
- `${projectPaths.apiV1}/otheruser/route.ts`,
42
- `${projectPaths.apiV1}/otheruser/[id]/route.ts`,
43
- `${projectPaths.apiV1}/log/route.ts`,
44
- `${projectPaths.apiV1}/blob/[filename]/route.ts`,
45
- `${projectPaths.apiV1}/[resourceName]/route.ts`,
46
- `${projectPaths.apiV1}/[resourceName]/upsert/route.ts`,
47
- `${projectPaths.apiV1}/[resourceName]/[id]/route.ts`,
48
- ];
49
- export const allFilesToCopy = [
50
- ...filesToCopy,
51
- ...rootFilesToCopy,
52
- ...appFilesToCopy,
53
- ...apiRoutesToCopy,
54
- ];
@@ -1,12 +0,0 @@
1
- import { defineConfig } from "drizzle-kit";
2
- import { getRequiredStringEnvSetting, generatedPaths, metaEnvSettingKeys } from "@fernir2/saas-kit";
3
-
4
- const connectionString = getRequiredStringEnvSetting(metaEnvSettingKeys.databaseConnection);
5
-
6
- export default defineConfig({
7
- dialect: "postgresql",
8
- schema: generatedPaths.schema,
9
- dbCredentials: {
10
- url: connectionString,
11
- },
12
- });
@@ -1,10 +0,0 @@
1
- import { baseConfig } from "@fernir2/saas-kit";
2
-
3
- const config = [
4
- ...baseConfig,
5
- {
6
- ignores: ["src/models/*"],
7
- },
8
- ];
9
-
10
- export default config;
@@ -1,25 +0,0 @@
1
- import { test as base, PlaywrightTestArgs, PlaywrightWorkerArgs, TestType } from "playwright/test";
2
- import { initInternalResourceMetasCacheFromJson } from "@fernir2/saas-kit/server";
3
- import { toolboxEnvSettingKeys } from "@fernir2/saas-kit";
4
-
5
- export type WorkerArgs = PlaywrightWorkerArgs & { metaInitialized: void };
6
- export type TestArgs = PlaywrightTestArgs;
7
-
8
- export const test: TestType<TestArgs, WorkerArgs> = base.extend({
9
- metaInitialized: [
10
- // Approved
11
- // eslint-disable-next-line no-empty-pattern
12
- async ({}, use: () => Promise<void>) => {
13
- await initInternalResourceMetasCacheFromJson();
14
- await use();
15
- },
16
- { scope: "worker", auto: true },
17
- ],
18
- });
19
-
20
- export const expect = test.expect;
21
-
22
- export default async function globalSetup() {
23
- process.env[toolboxEnvSettingKeys.appEnv] = "test";
24
- await initInternalResourceMetasCacheFromJson();
25
- }
@@ -1,55 +0,0 @@
1
- import { execSync } from "child_process";
2
- import { folders } from "@fernir2/saas-kit";
3
-
4
- const nextConfig = {
5
- webpack: (config, { isServer }) => {
6
- if (isServer) {
7
- config.watchOptions = {
8
- ignored: [
9
- `**/${folders.nodeModules}/**`,
10
- `**/${folders.next}/**`,
11
- `**/${folders.npmCommands}/**`,
12
- ],
13
- };
14
- config.externals.push({
15
- "@node-rs/argon2": "commonjs @node-rs/argon2",
16
- "cloudflare:sockets": "commonjs cloudflare:sockets",
17
- "node:crypto": "commonjs node:crypto",
18
- "node:fs": "commonjs node:fs",
19
- "node:path": "commonjs node:path",
20
- "node:stream": "commonjs node:stream",
21
- child_process: "commonjs2 child_process",
22
- });
23
- config.module.rules.push({
24
- test: /\.html$/,
25
- use: "raw-loader",
26
- });
27
- }
28
- config.module.rules.push({
29
- test: /\.md$/,
30
- use: "ignore-loader",
31
- });
32
- return config;
33
- },
34
- async rewrites() {
35
- return [
36
- {
37
- source: "/api/:path*",
38
- destination: "/api/v1/:path*",
39
- },
40
- ];
41
- },
42
- redirects() {
43
- return [
44
- {
45
- source: "/",
46
- destination: "/sign-in",
47
- permanent: false,
48
- },
49
- ];
50
- },
51
- };
52
-
53
- nextConfig.cacheMaxMemorySize = 4096;
54
-
55
- export default nextConfig;
@@ -1,3 +0,0 @@
1
- import { combineMeta } from "@fernir2/saas-kit";
2
-
3
- combineMeta();
@@ -1,5 +0,0 @@
1
- import { join } from "path";
2
- import { generateSchema, generatedPaths } from "@fernir2/saas-kit";
3
-
4
- const schemaPath = join(process.cwd(), generatedPaths.schema).replaceAll("\\", "/");
5
- await generateSchema(schemaPath);
@@ -1,5 +0,0 @@
1
- import { runCommand } from "@fernir2/saas-kit";
2
-
3
- export async function migrateDb() {
4
- await runCommand("migrate-db");
5
- }
@@ -1,15 +0,0 @@
1
- import { migrateDatabase, logInfo } from "@fernir2/saas-kit/server";
2
-
3
- async function migrate() {
4
- try {
5
- await migrateDatabase();
6
- logInfo("Database migrations executed successfully");
7
- process.exit(0);
8
- } catch (err) {
9
- if (err instanceof Error) console.error("Error running migrations", err);
10
-
11
- process.exit(1);
12
- }
13
- }
14
-
15
- migrate();
@@ -1,5 +0,0 @@
1
- import { runCommand } from "@fernir2/saas-kit";
2
-
3
- export async function seedDb() {
4
- await runCommand("seed-db");
5
- }
@@ -1,15 +0,0 @@
1
- import { seedDatabase, logInfo } from "@fernir2/saas-kit/server";
2
-
3
- async function seed() {
4
- try {
5
- await seedDatabase();
6
- logInfo("Database seeded successfully");
7
- process.exit(0);
8
- } catch (err) {
9
- if (err instanceof Error) console.error("Error seeding database", err);
10
-
11
- process.exit(1);
12
- }
13
- }
14
-
15
- seed();
@@ -1,61 +0,0 @@
1
- {
2
- "version": "0.1.0",
3
- "private": true,
4
- "type": "module",
5
- "scripts": {
6
- "dev": "npx tsx --tsconfig tsconfig.server.json server.ts",
7
- "build": "next build && tsc --project tsconfig.server.json",
8
- "lint": "eslint -c eslint.config.js",
9
- "gen-schema": "npx tsx tools/npm-commands/gen-schema/index.ts",
10
- "gen-meta": "npx tsx tools/npm-commands/gen-meta/index.ts",
11
- "init-db": "npm run migrate-db && npm run seed-db",
12
- "setup": "npm run gen-meta && npm run gen-schema && npm run init-db",
13
- "start": "npm run setup && npm run dev",
14
- "prod": "npm run setup && npm run build && npx tsx server.ts",
15
- "migrate-db": "npx tsx tools/npm-commands/migrate-db/index.ts",
16
- "seed-db": "npx tsx tools/npm-commands/seed-db/index.ts"
17
- },
18
- "dependencies": {
19
- "@fernir2/saas-kit": "0.0.144",
20
- "@node-rs/argon2": "2.0.2",
21
- "drizzle-orm": "0.41.0",
22
- "eslint-plugin-github": "6.0.0",
23
- "eslint-plugin-import": "2.32.0",
24
- "eslint-plugin-sonarjs": "3.0.5",
25
- "geist": "1.3.1",
26
- "next": "15.4.5",
27
- "quill": "2.0.3",
28
- "react": "18",
29
- "react-dom": "18",
30
- "socket.io-client": "4.8.1",
31
- "tailwindcss-animate": "1.0.7"
32
- },
33
- "devDependencies": {
34
- "playwright": "1.52.0",
35
- "@eslint/eslintrc": "3.3.1",
36
- "@eslint/js": "9.35.0",
37
- "@types/node": "24.5.1",
38
- "@types/react": "18",
39
- "@types/react-dom": "18",
40
- "@typescript-eslint/eslint-plugin": "8.43.0",
41
- "@typescript-eslint/eslint-plugin-tslint": "7.0.2",
42
- "@typescript-eslint/parser": "8.43.0",
43
- "drizzle-kit": "0.28.1",
44
- "eslint": "9.35.0",
45
- "eslint-config-next": "15.5.2",
46
- "eslint-config-prettier": "9.1.0",
47
- "eslint-plugin-react": "7.37.5",
48
- "eslint-plugin-react-compiler": "19.1.0-rc.2",
49
- "eslint-plugin-react-hooks": "5.2.0",
50
- "eslint-plugin-react-refresh": "0.4.20",
51
- "eslint-plugin-tailwindcss": "3.18.2",
52
- "husky": "9.1.7",
53
- "postcss": "8",
54
- "prettier": "3.6.2",
55
- "prettier-plugin-tailwindcss": "0.6.14",
56
- "tailwindcss": "3.4.1",
57
- "tsx": "4.19.1",
58
- "typescript": "5.9.2",
59
- "esbuild": "0.19.12"
60
- }
61
- }
@@ -1,34 +0,0 @@
1
- import { defineConfig, devices } from "playwright/test";
2
- import { getDotenvConfig } from "@fernir2/saas-kit";
3
-
4
- getDotenvConfig();
5
-
6
- const baseUrl = "http://localhost:8080/";
7
-
8
- export default defineConfig({
9
- timeout: 120000,
10
- testDir: "test/",
11
- fullyParallel: true,
12
- globalSetup: "./global-setup.ts",
13
- workers: undefined,
14
- reporter: "html",
15
- use: {
16
- baseURL: baseUrl,
17
- trace: "on-first-retry",
18
- },
19
- projects: [
20
- {
21
- name: "chromium",
22
- use: { ...devices["Desktop Chrome"] },
23
- },
24
- ],
25
- webServer: {
26
- command: "npm run prod",
27
- url: baseUrl,
28
- reuseExistingServer: true,
29
- timeout: 120000,
30
- env: {
31
- NODE_ENV: "test",
32
- },
33
- },
34
- });
@@ -1,9 +0,0 @@
1
- /** @type {import('postcss-load-config').Config} */
2
- const config = {
3
- plugins: {
4
- tailwindcss: {},
5
- autoprefixer: {},
6
- },
7
- };
8
-
9
- export default config;