@postxl/generator 0.74.2 → 1.0.3

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 (189) hide show
  1. package/LICENSE +50 -0
  2. package/README.md +79 -1
  3. package/dist/generator-manager.class.d.ts +59 -0
  4. package/dist/generator-manager.class.js +221 -0
  5. package/dist/generator.class.d.ts +90 -0
  6. package/dist/generator.class.js +32 -0
  7. package/dist/generator.context.d.ts +174 -0
  8. package/dist/generator.context.js +125 -0
  9. package/dist/helpers/branded.types.d.ts +149 -0
  10. package/dist/helpers/branded.types.js +111 -0
  11. package/dist/helpers/config-builder.class.d.ts +27 -0
  12. package/dist/helpers/config-builder.class.js +54 -0
  13. package/dist/helpers/import-generator.class.d.ts +70 -0
  14. package/dist/helpers/import-generator.class.js +166 -0
  15. package/dist/helpers/importable.types.d.ts +52 -0
  16. package/dist/helpers/importable.types.js +15 -0
  17. package/dist/helpers/index-generator.class.d.ts +10 -0
  18. package/dist/helpers/index-generator.class.js +46 -0
  19. package/dist/helpers/index.d.ts +8 -0
  20. package/dist/helpers/index.js +24 -0
  21. package/dist/helpers/package-json.generator.d.ts +56 -0
  22. package/dist/helpers/package-json.generator.js +36 -0
  23. package/dist/helpers/tsconfig.generator.d.ts +1 -0
  24. package/dist/helpers/tsconfig.generator.js +14 -0
  25. package/dist/helpers/verify-context.d.ts +4 -0
  26. package/dist/helpers/verify-context.js +23 -0
  27. package/dist/index.d.ts +5 -0
  28. package/dist/index.js +21 -0
  29. package/dist/utils/checksum.d.ts +10 -0
  30. package/dist/utils/checksum.js +132 -0
  31. package/dist/utils/fs-utils.d.ts +34 -0
  32. package/dist/utils/fs-utils.js +126 -0
  33. package/dist/utils/index.d.ts +10 -0
  34. package/dist/utils/index.js +26 -0
  35. package/dist/utils/jsdoc.d.ts +12 -0
  36. package/dist/utils/jsdoc.js +37 -0
  37. package/dist/utils/lint.d.ts +46 -0
  38. package/dist/utils/lint.js +154 -0
  39. package/dist/utils/lockfile.d.ts +7 -0
  40. package/dist/utils/lockfile.js +80 -0
  41. package/dist/utils/logger.class.d.ts +25 -0
  42. package/dist/utils/logger.class.js +55 -0
  43. package/dist/utils/merge-conflict.d.ts +55 -0
  44. package/dist/utils/merge-conflict.js +264 -0
  45. package/dist/utils/path.d.ts +52 -0
  46. package/dist/utils/path.js +183 -0
  47. package/dist/utils/prettier-config.d.ts +2 -0
  48. package/dist/utils/prettier-config.js +13 -0
  49. package/dist/utils/prettier.d.ts +5 -0
  50. package/dist/utils/prettier.js +67 -0
  51. package/dist/utils/prettier.skiptest.d.ts +1 -0
  52. package/dist/utils/prettier.skiptest.js +22 -0
  53. package/dist/utils/promise.d.ts +2 -0
  54. package/dist/utils/promise.js +10 -0
  55. package/dist/utils/string-functions.d.ts +9 -0
  56. package/dist/utils/string-functions.js +23 -0
  57. package/dist/utils/sync-log-result.d.ts +9 -0
  58. package/dist/utils/sync-log-result.js +90 -0
  59. package/dist/utils/sync.d.ts +143 -0
  60. package/dist/utils/sync.js +325 -0
  61. package/dist/utils/template.d.ts +66 -0
  62. package/dist/utils/template.js +159 -0
  63. package/dist/utils/vfs.class.d.ts +115 -0
  64. package/dist/utils/vfs.class.js +239 -0
  65. package/dist/utils/zip.d.ts +13 -0
  66. package/dist/utils/zip.js +40 -0
  67. package/package.json +53 -31
  68. package/dist/generator.d.ts +0 -13
  69. package/dist/generator.js +0 -455
  70. package/dist/generators/enums/react.generator.d.ts +0 -10
  71. package/dist/generators/enums/react.generator.js +0 -110
  72. package/dist/generators/enums/types.generator.d.ts +0 -10
  73. package/dist/generators/enums/types.generator.js +0 -39
  74. package/dist/generators/indices/data/module.generator.d.ts +0 -9
  75. package/dist/generators/indices/data/module.generator.js +0 -60
  76. package/dist/generators/indices/data/service.generator.d.ts +0 -9
  77. package/dist/generators/indices/data/service.generator.js +0 -249
  78. package/dist/generators/indices/data/types.generator.d.ts +0 -9
  79. package/dist/generators/indices/data/types.generator.js +0 -49
  80. package/dist/generators/indices/dispatcher-service.generator.d.ts +0 -9
  81. package/dist/generators/indices/dispatcher-service.generator.js +0 -107
  82. package/dist/generators/indices/export/class.generator.d.ts +0 -9
  83. package/dist/generators/indices/export/class.generator.js +0 -140
  84. package/dist/generators/indices/export/encoder.generator.d.ts +0 -9
  85. package/dist/generators/indices/export/encoder.generator.js +0 -50
  86. package/dist/generators/indices/import/convert-functions.generator.d.ts +0 -9
  87. package/dist/generators/indices/import/convert-functions.generator.js +0 -509
  88. package/dist/generators/indices/import/decoder.generator.d.ts +0 -9
  89. package/dist/generators/indices/import/decoder.generator.js +0 -40
  90. package/dist/generators/indices/import/service.generator.d.ts +0 -9
  91. package/dist/generators/indices/import/service.generator.js +0 -573
  92. package/dist/generators/indices/import/types.generator.d.ts +0 -9
  93. package/dist/generators/indices/import/types.generator.js +0 -242
  94. package/dist/generators/indices/repositories.generator.d.ts +0 -9
  95. package/dist/generators/indices/repositories.generator.js +0 -25
  96. package/dist/generators/indices/routes.generator.d.ts +0 -9
  97. package/dist/generators/indices/routes.generator.js +0 -29
  98. package/dist/generators/indices/seed-migration.generator.d.ts +0 -9
  99. package/dist/generators/indices/seed-migration.generator.js +0 -36
  100. package/dist/generators/indices/seed-template.generator.d.ts +0 -9
  101. package/dist/generators/indices/seed-template.generator.js +0 -80
  102. package/dist/generators/indices/testids.generator.d.ts +0 -7
  103. package/dist/generators/indices/testids.generator.js +0 -71
  104. package/dist/generators/indices/types.generator.d.ts +0 -10
  105. package/dist/generators/indices/types.generator.js +0 -35
  106. package/dist/generators/indices/update/actiontypes.generator.d.ts +0 -9
  107. package/dist/generators/indices/update/actiontypes.generator.js +0 -49
  108. package/dist/generators/indices/update/module.generator.d.ts +0 -9
  109. package/dist/generators/indices/update/module.generator.js +0 -41
  110. package/dist/generators/indices/update/service.generator.d.ts +0 -9
  111. package/dist/generators/indices/update/service.generator.js +0 -34
  112. package/dist/generators/indices/view/module.generator.d.ts +0 -9
  113. package/dist/generators/indices/view/module.generator.js +0 -39
  114. package/dist/generators/indices/view/service.generator.d.ts +0 -9
  115. package/dist/generators/indices/view/service.generator.js +0 -34
  116. package/dist/generators/models/admin.page.generator.d.ts +0 -7
  117. package/dist/generators/models/admin.page.generator.js +0 -74
  118. package/dist/generators/models/export/encoder.generator.d.ts +0 -9
  119. package/dist/generators/models/export/encoder.generator.js +0 -51
  120. package/dist/generators/models/import/decoder.generator.d.ts +0 -9
  121. package/dist/generators/models/import/decoder.generator.js +0 -148
  122. package/dist/generators/models/react/context.generator.d.ts +0 -9
  123. package/dist/generators/models/react/context.generator.js +0 -71
  124. package/dist/generators/models/react/index.d.ts +0 -10
  125. package/dist/generators/models/react/index.js +0 -31
  126. package/dist/generators/models/react/library.generator.d.ts +0 -10
  127. package/dist/generators/models/react/library.generator.js +0 -94
  128. package/dist/generators/models/react/lookup.generator.d.ts +0 -9
  129. package/dist/generators/models/react/lookup.generator.js +0 -175
  130. package/dist/generators/models/react/modals.generator.d.ts +0 -23
  131. package/dist/generators/models/react/modals.generator.js +0 -710
  132. package/dist/generators/models/repository.generator.d.ts +0 -9
  133. package/dist/generators/models/repository.generator.js +0 -955
  134. package/dist/generators/models/route.generator.d.ts +0 -9
  135. package/dist/generators/models/route.generator.js +0 -92
  136. package/dist/generators/models/seed.generator.d.ts +0 -21
  137. package/dist/generators/models/seed.generator.js +0 -285
  138. package/dist/generators/models/stub.generator.d.ts +0 -9
  139. package/dist/generators/models/stub.generator.js +0 -92
  140. package/dist/generators/models/types.generator.d.ts +0 -9
  141. package/dist/generators/models/types.generator.js +0 -125
  142. package/dist/generators/models/update/service.generator.d.ts +0 -10
  143. package/dist/generators/models/update/service.generator.js +0 -302
  144. package/dist/generators/models/view/service.generator.d.ts +0 -10
  145. package/dist/generators/models/view/service.generator.js +0 -239
  146. package/dist/lib/attributes.d.ts +0 -114
  147. package/dist/lib/attributes.js +0 -2
  148. package/dist/lib/exports.d.ts +0 -45
  149. package/dist/lib/exports.js +0 -90
  150. package/dist/lib/imports.d.ts +0 -65
  151. package/dist/lib/imports.js +0 -114
  152. package/dist/lib/meta.d.ts +0 -1191
  153. package/dist/lib/meta.js +0 -434
  154. package/dist/lib/schema/fields.d.ts +0 -46
  155. package/dist/lib/schema/fields.js +0 -62
  156. package/dist/lib/schema/schema.d.ts +0 -466
  157. package/dist/lib/schema/schema.js +0 -18
  158. package/dist/lib/schema/types.d.ts +0 -201
  159. package/dist/lib/schema/types.js +0 -112
  160. package/dist/lib/serializer.d.ts +0 -15
  161. package/dist/lib/serializer.js +0 -24
  162. package/dist/lib/test-id-collector.d.ts +0 -42
  163. package/dist/lib/test-id-collector.js +0 -53
  164. package/dist/lib/types.d.ts +0 -7
  165. package/dist/lib/types.js +0 -13
  166. package/dist/lib/typescript.d.ts +0 -5
  167. package/dist/lib/typescript.js +0 -22
  168. package/dist/lib/utils/ast.d.ts +0 -29
  169. package/dist/lib/utils/ast.js +0 -23
  170. package/dist/lib/utils/error.d.ts +0 -17
  171. package/dist/lib/utils/error.js +0 -52
  172. package/dist/lib/utils/file.d.ts +0 -10
  173. package/dist/lib/utils/file.js +0 -56
  174. package/dist/lib/utils/jsdoc.d.ts +0 -9
  175. package/dist/lib/utils/jsdoc.js +0 -37
  176. package/dist/lib/utils/logger.d.ts +0 -17
  177. package/dist/lib/utils/logger.js +0 -12
  178. package/dist/lib/utils/string.d.ts +0 -40
  179. package/dist/lib/utils/string.js +0 -187
  180. package/dist/lib/utils/types.d.ts +0 -12
  181. package/dist/lib/utils/types.js +0 -2
  182. package/dist/lib/zod.d.ts +0 -8
  183. package/dist/lib/zod.js +0 -60
  184. package/dist/prisma/attributes.d.ts +0 -21
  185. package/dist/prisma/attributes.js +0 -175
  186. package/dist/prisma/client-path.d.ts +0 -7
  187. package/dist/prisma/client-path.js +0 -29
  188. package/dist/prisma/parse.d.ts +0 -12
  189. package/dist/prisma/parse.js +0 -452
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.format = format;
37
+ const path_1 = require("path");
38
+ const prettier = __importStar(require("prettier"));
39
+ const prettier_config_1 = require("./prettier-config");
40
+ const parsers = {
41
+ '.js': 'babel',
42
+ '.jsx': 'babel',
43
+ '.mjs': 'babel',
44
+ '.ts': 'typescript',
45
+ '.tsx': 'typescript',
46
+ '.json': 'json',
47
+ '.md': 'markdown',
48
+ '.mdx': 'mdx',
49
+ '.html': 'html',
50
+ '.yaml': 'yaml',
51
+ '.yml': 'yaml',
52
+ '.css': 'css',
53
+ };
54
+ async function format({ path, content }) {
55
+ const ext = (0, path_1.extname)(path);
56
+ const parser = parsers[ext];
57
+ if (parser === undefined || typeof content !== 'string') {
58
+ return content;
59
+ }
60
+ try {
61
+ return await prettier.format(content, { ...prettier_config_1.prettierConfig, parser });
62
+ }
63
+ catch (err) {
64
+ console.error(`${content}\n\nFailed to format ${path}\n\n`);
65
+ throw err;
66
+ }
67
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const globals_1 = require("@jest/globals");
4
+ const prettier_1 = require("./prettier");
5
+ // This test currently runs into configuration issues with Jest and Prettier.
6
+ // According to https://github.com/prettier/prettier/issues/15769 this should be fixed in Jest v30,
7
+ // so we will revisit this then. Until then, we disable the test (by renaming the file).
8
+ globals_1.describe.skip('prettier', () => {
9
+ (0, globals_1.test)('should format TypeScript code', async () => {
10
+ const content = `
11
+ const fn = async <T>(data: unknown): T => {
12
+ return data as T
13
+ }`;
14
+ const result = await (0, prettier_1.format)({ path: 'test.ts', content });
15
+ (0, globals_1.expect)(result).toMatchInlineSnapshot(`
16
+ "const fn = async <T,>(data: unknown): T => {
17
+ return data as T
18
+ }
19
+ "
20
+ `);
21
+ });
22
+ });
@@ -0,0 +1,2 @@
1
+ import { Typescript } from './string-functions';
2
+ export declare function promises(tasks: (string | Typescript)[]): Typescript;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promises = promises;
4
+ const string_functions_1 = require("./string-functions");
5
+ function promises(tasks) {
6
+ if (tasks.length === 0) {
7
+ return (0, string_functions_1.ts)('Promise.resolve([]) // NOSONAR - to comply with async interface');
8
+ }
9
+ return (0, string_functions_1.ts)(`Promise.all([\n ${tasks.join(',\n')}]) // NOSONAR`);
10
+ }
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export declare const zTypescript: z.ZodBranded<z.ZodString, "PXL.Typescript">;
3
+ export type Typescript = z.infer<typeof zTypescript>;
4
+ export declare function ts(input: string): string & z.BRAND<"PXL.Typescript">;
5
+ export declare function trimLines(input: string): string;
6
+ /**
7
+ * Removes leading and trailing newlines from the input string.
8
+ */
9
+ export declare function trimNewlines(input: string): string;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.zTypescript = void 0;
4
+ exports.ts = ts;
5
+ exports.trimLines = trimLines;
6
+ exports.trimNewlines = trimNewlines;
7
+ const zod_1 = require("zod");
8
+ exports.zTypescript = zod_1.z.string().brand('PXL.Typescript');
9
+ function ts(input) {
10
+ return exports.zTypescript.parse(input);
11
+ }
12
+ function trimLines(input) {
13
+ return input
14
+ .split('\n')
15
+ .map((l) => l.trim())
16
+ .join('\n');
17
+ }
18
+ /**
19
+ * Removes leading and trailing newlines from the input string.
20
+ */
21
+ function trimNewlines(input) {
22
+ return input.replace(/^\n+/g, '').replace(/\n+$/g, ''); //NOSONAR - regex is only run on code generation, not dependant on user input
23
+ }
@@ -0,0 +1,9 @@
1
+ import { Logger } from './logger.class';
2
+ import { SyncResults } from './sync';
3
+ type LogResultsOptions = {
4
+ showEjectedStats?: boolean;
5
+ showEjectedDiff?: boolean;
6
+ logger?: Logger;
7
+ };
8
+ export declare function logSyncResult(results: SyncResults, options?: LogResultsOptions): void;
9
+ export {};
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logSyncResult = logSyncResult;
4
+ const utils_1 = require("@postxl/utils");
5
+ const logger_class_1 = require("./logger.class");
6
+ const merge_conflict_1 = require("./merge-conflict");
7
+ function logSyncResult(results, options = {}) {
8
+ const logger = options.logger ?? new logger_class_1.Logger();
9
+ // Handle failed sync due to unresolved merge conflicts
10
+ if (!results.success) {
11
+ logger.log((0, utils_1.bold)((0, utils_1.red)('❌ Generation aborted: Unresolved merge conflicts detected')));
12
+ logger.log((0, utils_1.red)(results.error.message));
13
+ logger.log('');
14
+ logger.log((0, utils_1.bold)((0, utils_1.red)(`Files with unresolved merge conflicts (${results.error.filesWithConflicts.length}):`)));
15
+ for (const file of results.error.filesWithConflicts) {
16
+ logger.log((0, utils_1.red)(` └── ${file}`));
17
+ }
18
+ logger.log('');
19
+ logger.log((0, utils_1.yellow)('Please resolve these conflicts before running the generator again.'));
20
+ return;
21
+ }
22
+ const actionGroups = {
23
+ Delete: [],
24
+ MergeConflict: [],
25
+ Write: [],
26
+ NoAction: [],
27
+ Ejected: [],
28
+ };
29
+ for (const [path, result] of Object.entries(results.files)) {
30
+ actionGroups[result.action.type].push(path);
31
+ if (result.isEjected) {
32
+ actionGroups['Ejected'].push(path);
33
+ }
34
+ }
35
+ logActionResult('Delete', actionGroups['Delete'], utils_1.red, 'deleted', logger);
36
+ logActionResult('MergeConflict', actionGroups['MergeConflict'], utils_1.yellow, 'with merge conflicts', logger);
37
+ logActionResult('Write', actionGroups['Write'], utils_1.green, 'written:', logger);
38
+ logActionResult('NoAction', actionGroups['NoAction'], utils_1.cyan, 'unchanged', logger);
39
+ if (options.showEjectedStats) {
40
+ if (actionGroups['Ejected'].length === 0) {
41
+ logger.log('✅ No files ejected');
42
+ }
43
+ else {
44
+ logActionResult('Ejected', actionGroups['Ejected'], utils_1.red, 'ejected:', logger);
45
+ }
46
+ }
47
+ if (options.showEjectedDiff) {
48
+ logEjectedDiff({
49
+ ejectedFiles: actionGroups['Ejected'],
50
+ showEjectedStats: options.showEjectedStats ?? false,
51
+ files: results.files,
52
+ logger,
53
+ });
54
+ }
55
+ if (results.errors.length > 0) {
56
+ logger.log((0, utils_1.bold)((0, utils_1.red)('Errors:')));
57
+ for (const error of results.errors) {
58
+ logger.log((0, utils_1.red)(error.message));
59
+ }
60
+ }
61
+ }
62
+ function logActionResult(action, paths, color, stateDescription, logger) {
63
+ if (paths.length === 0) {
64
+ return;
65
+ }
66
+ const fileLabel = paths.length === 1 ? 'file' : 'files';
67
+ logger.log((0, utils_1.bold)(color(`${paths.length} ${fileLabel} ${stateDescription}`)));
68
+ if (action === 'NoAction') {
69
+ return;
70
+ }
71
+ paths.forEach((path) => {
72
+ logger.log((0, utils_1.gray)(` └── ${path}`));
73
+ });
74
+ }
75
+ function logEjectedDiff({ ejectedFiles, showEjectedStats, files, logger, }) {
76
+ if (ejectedFiles.length === 0) {
77
+ if (!showEjectedStats) {
78
+ logger.log('✅ No files ejected');
79
+ }
80
+ }
81
+ else {
82
+ for (const path of ejectedFiles) {
83
+ logger.log((0, utils_1.bold)((0, utils_1.red)(`Ejected ${path}`)));
84
+ const inputState = files[path].inputState;
85
+ const contentSource = inputState.disk.state === 'hash' ? inputState.disk.content : '';
86
+ const contentIncoming = inputState.virtual.state === 'hash' ? inputState.virtual.content : '';
87
+ logger.log((0, merge_conflict_1.generateDiffSummary)({ contentSource, contentIncoming }));
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * The virtual file system represents a file system that can be manipulated in memory.
3
+ *
4
+ * This sync extension allows a 3-way sync between the file system and the disk.
5
+ *
6
+ * The 3 sources are:
7
+ * 1. The data written by code/the generators to the VFS
8
+ * 2. The hash sums from prior generations (indicating which files were changed)
9
+ * 3. The actual disk files
10
+ *
11
+ * The overall usage pattern is:
12
+ * 1. The VFS initializes with a lock file - and reads the hash sums from the disk
13
+ * 2. The code/generators write to the VFS
14
+ * 3. The VFS "writes" to disk, performing this 3-way sync with the below algorithm
15
+ *
16
+ *
17
+ * ### Algorithm
18
+ *
19
+ * For each file in the VFS we have 3 different states - the file in memory (`virtual`), the hash sum from prior generations from the lock file (`lock`), and the file from disk (`disk`).
20
+ *
21
+ * Each of these 3 states can be "empty" - in case the file was not generated/generated last time/does not exist on disk - or represented by a hash value (`H`).
22
+ *
23
+ * Thus, we have the following potential states for each file:
24
+ * - virtual: `empty` | `Hash1` (hash sum from current generation)
25
+ * - lock: `empty` | `Hash1` | `Hash0` (hash sum from prior generation)
26
+ * - disk: `empty` | `Hash1` | `Hash0` | `HashX` (different hash sum from disk)
27
+ *
28
+ * The below table shows all possible combinations of these states - and the resulting action that needs to be performed:
29
+ *
30
+ * |-------|-------|---------|---------------------------------|---------------------------|
31
+ * | VFS | Lock | Disk | Description | Action on disk |
32
+ * |-------|-------|---------|---------------------------------|---------------------------|
33
+ * | Hash1 | Hash1 | Hash1 | Unchanged | No action |
34
+ * | Hash1 | Hash1 | HashX/0 | Ejected | No action |
35
+ * | Hash1 | Hash1 | empty | Deleted on disk | No action |
36
+ * | Hash1 | Hash0 | Hash1 | Corrupt lock file? | No action |
37
+ * | Hash1 | Hash0 | Hash0 | Changed, not ejected | Update to VFS version |
38
+ * | Hash1 | Hash0 | HashX | Changed, ejected | Create "merge conflict"(2)|
39
+ * | Hash1 | Hash0 | empty | Changed, deleted on disk | Write file (1) |
40
+ * | Hash1 | empty | Hash1 | Corrupt lock file? | No action |
41
+ * | Hash1 | empty | HashX/0 | File ejected, corrupt lock file | Create "merge conflict"(2)|
42
+ * | Hash1 | empty | empty | Newly generated | Write file |
43
+ * |-------|-------|---------|---------------------------------|---------------------------|
44
+ * | empty | Hash0 | Hash0 | Unejected file | Delete file |
45
+ * | empty | Hash0 | HashX | Ejected file was deleted | Delete file (3) |
46
+ * | empty | Hash0 | empty | File was manually deleted first | No action |
47
+ * | empty | empty | HashX | Manual file | No action |
48
+ * | empty | empty | empty | Cannot occur | |
49
+ * |-------|-------|---------|---------------------------------|---------------------------|
50
+ *
51
+ * Notes:
52
+ * (1) In case the file was deleted on disk and changed between the last generation and the current generation, we will write the file to disk. The developer can decide to keep the "restored" file or not. Next time generator runs, it will not be regenerated, as lock file hashes match.
53
+ * (2) In case the file was ejected and changed between the last generation and the current generation, we will overwrite the file on disk - with git "merge conflict" markers. The developer must then decide how to resolve the conflicts.
54
+ * (3) In case the file was deleted by the generator but ejected by the developer, we will delete the file from disk. The developer can decide to revert the deletion or not. Next time generator runs, it will not be regenerated, as lock file hashes match.
55
+ *
56
+ */
57
+ import { Result, TypedError } from '@postxl/utils';
58
+ import { type Checksum } from './checksum';
59
+ import { FileContent, FileErrorTypes } from './fs-utils';
60
+ import * as Path from './path';
61
+ import { VirtualFileSystem } from './vfs.class';
62
+ type SyncParams = {
63
+ vfs: VirtualFileSystem;
64
+ lockFilePath: string;
65
+ diskFilePath: string;
66
+ force: boolean;
67
+ };
68
+ /**
69
+ * Error returned when files with unresolved merge conflicts are detected
70
+ */
71
+ export type UnresolvedMergeConflictsError = {
72
+ type: 'UnresolvedMergeConflictsError';
73
+ message: string;
74
+ filesWithConflicts: Path.PosixPath[];
75
+ };
76
+ export type SyncErrorTypes = FileErrorTypes;
77
+ export type ActionResult = Result<void, TypedError<FileErrorTypes>>;
78
+ export type FileSyncResult = {
79
+ inputState: FileStates;
80
+ action: Action;
81
+ actionResult: ActionResult;
82
+ isEjected: boolean;
83
+ };
84
+ export type FileSyncResults = Record<Path.PosixPath, FileSyncResult>;
85
+ export type SyncResults = {
86
+ success: true;
87
+ errors: TypedError<SyncErrorTypes>[];
88
+ files: FileSyncResults;
89
+ } | {
90
+ success: false;
91
+ error: UnresolvedMergeConflictsError;
92
+ };
93
+ /**
94
+ * Synchronizes the virtual file system with the disk file system.
95
+ *
96
+ * It takes into account the lock file to determine the state of each file.
97
+ * Depending on the state/checksum of each file in VFS, lock file and disk file system,
98
+ * it will perform the appropriate action (write, delete, merge conflict) to update the disk file system.
99
+ *
100
+ * It also updates the lock file with the current state of the VFS.
101
+ *
102
+ * Note: File filtering is now handled at the VFS level, so only files that were added to the VFS
103
+ * (respecting any file pattern filter) will be synced and tracked in the lock file.
104
+ *
105
+ * IMPORTANT: Before writing any files, this function checks if there are any files with unresolved
106
+ * merge conflict markers. If found, the sync will abort immediately and return an error with the
107
+ * list of files that need to be resolved before generation can continue.
108
+ */
109
+ export declare function sync({ vfs, lockFilePath, diskFilePath, force }: SyncParams): Promise<SyncResults>;
110
+ type FileState = {
111
+ state: 'empty';
112
+ } | {
113
+ state: 'hash';
114
+ hash: Checksum;
115
+ };
116
+ type FileStateWithContent = {
117
+ state: 'empty';
118
+ } | {
119
+ state: 'hash';
120
+ hash: Checksum;
121
+ content: FileContent;
122
+ };
123
+ type FileStates = {
124
+ virtual: FileStateWithContent;
125
+ lock: FileState;
126
+ disk: FileStateWithContent;
127
+ };
128
+ export type Action = {
129
+ type: `NoAction`;
130
+ } | {
131
+ type: `Write`;
132
+ content: FileContent;
133
+ } | Action_MergeConflict | {
134
+ type: `Delete`;
135
+ };
136
+ type Action_MergeConflict = {
137
+ type: `MergeConflict`;
138
+ diskContent: FileContent;
139
+ virtualContent: FileContent;
140
+ };
141
+ export type ActionType = Action['type'];
142
+ export declare function executeAction(filePath: Path.PosixPath, action: Action): Promise<ActionResult>;
143
+ export {};