@postxl/generator 0.74.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +50 -0
- package/README.md +79 -1
- package/dist/generator-manager.class.d.ts +59 -0
- package/dist/generator-manager.class.js +221 -0
- package/dist/generator.class.d.ts +90 -0
- package/dist/generator.class.js +32 -0
- package/dist/generator.context.d.ts +174 -0
- package/dist/generator.context.js +125 -0
- package/dist/helpers/branded.types.d.ts +149 -0
- package/dist/helpers/branded.types.js +111 -0
- package/dist/helpers/config-builder.class.d.ts +27 -0
- package/dist/helpers/config-builder.class.js +54 -0
- package/dist/helpers/import-generator.class.d.ts +70 -0
- package/dist/helpers/import-generator.class.js +166 -0
- package/dist/helpers/importable.types.d.ts +52 -0
- package/dist/helpers/importable.types.js +15 -0
- package/dist/helpers/index-generator.class.d.ts +10 -0
- package/dist/helpers/index-generator.class.js +46 -0
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.js +24 -0
- package/dist/helpers/package-json.generator.d.ts +56 -0
- package/dist/helpers/package-json.generator.js +36 -0
- package/dist/helpers/tsconfig.generator.d.ts +1 -0
- package/dist/helpers/tsconfig.generator.js +14 -0
- package/dist/helpers/verify-context.d.ts +4 -0
- package/dist/helpers/verify-context.js +23 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +21 -0
- package/dist/utils/checksum.d.ts +10 -0
- package/dist/utils/checksum.js +132 -0
- package/dist/utils/fs-utils.d.ts +34 -0
- package/dist/utils/fs-utils.js +126 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/jsdoc.d.ts +12 -0
- package/dist/utils/jsdoc.js +37 -0
- package/dist/utils/lint.d.ts +46 -0
- package/dist/utils/lint.js +154 -0
- package/dist/utils/lockfile.d.ts +7 -0
- package/dist/utils/lockfile.js +80 -0
- package/dist/utils/logger.class.d.ts +25 -0
- package/dist/utils/logger.class.js +55 -0
- package/dist/utils/merge-conflict.d.ts +55 -0
- package/dist/utils/merge-conflict.js +264 -0
- package/dist/utils/path.d.ts +52 -0
- package/dist/utils/path.js +183 -0
- package/dist/utils/prettier-config.d.ts +2 -0
- package/dist/utils/prettier-config.js +13 -0
- package/dist/utils/prettier.d.ts +5 -0
- package/dist/utils/prettier.js +67 -0
- package/dist/utils/prettier.skiptest.d.ts +1 -0
- package/dist/utils/prettier.skiptest.js +22 -0
- package/dist/utils/promise.d.ts +2 -0
- package/dist/utils/promise.js +10 -0
- package/dist/utils/string-functions.d.ts +9 -0
- package/dist/utils/string-functions.js +23 -0
- package/dist/utils/sync-log-result.d.ts +9 -0
- package/dist/utils/sync-log-result.js +90 -0
- package/dist/utils/sync.d.ts +143 -0
- package/dist/utils/sync.js +325 -0
- package/dist/utils/template.d.ts +66 -0
- package/dist/utils/template.js +159 -0
- package/dist/utils/vfs.class.d.ts +115 -0
- package/dist/utils/vfs.class.js +239 -0
- package/dist/utils/zip.d.ts +13 -0
- package/dist/utils/zip.js +40 -0
- package/package.json +57 -34
- package/dist/generator.d.ts +0 -13
- package/dist/generator.js +0 -455
- package/dist/generators/enums/react.generator.d.ts +0 -10
- package/dist/generators/enums/react.generator.js +0 -110
- package/dist/generators/enums/types.generator.d.ts +0 -10
- package/dist/generators/enums/types.generator.js +0 -39
- package/dist/generators/indices/data/module.generator.d.ts +0 -9
- package/dist/generators/indices/data/module.generator.js +0 -60
- package/dist/generators/indices/data/service.generator.d.ts +0 -9
- package/dist/generators/indices/data/service.generator.js +0 -249
- package/dist/generators/indices/data/types.generator.d.ts +0 -9
- package/dist/generators/indices/data/types.generator.js +0 -49
- package/dist/generators/indices/dispatcher-service.generator.d.ts +0 -9
- package/dist/generators/indices/dispatcher-service.generator.js +0 -107
- package/dist/generators/indices/export/class.generator.d.ts +0 -9
- package/dist/generators/indices/export/class.generator.js +0 -140
- package/dist/generators/indices/export/encoder.generator.d.ts +0 -9
- package/dist/generators/indices/export/encoder.generator.js +0 -50
- package/dist/generators/indices/import/convert-functions.generator.d.ts +0 -9
- package/dist/generators/indices/import/convert-functions.generator.js +0 -509
- package/dist/generators/indices/import/decoder.generator.d.ts +0 -9
- package/dist/generators/indices/import/decoder.generator.js +0 -40
- package/dist/generators/indices/import/service.generator.d.ts +0 -9
- package/dist/generators/indices/import/service.generator.js +0 -573
- package/dist/generators/indices/import/types.generator.d.ts +0 -9
- package/dist/generators/indices/import/types.generator.js +0 -242
- package/dist/generators/indices/repositories.generator.d.ts +0 -9
- package/dist/generators/indices/repositories.generator.js +0 -25
- package/dist/generators/indices/routes.generator.d.ts +0 -9
- package/dist/generators/indices/routes.generator.js +0 -29
- package/dist/generators/indices/seed-migration.generator.d.ts +0 -9
- package/dist/generators/indices/seed-migration.generator.js +0 -36
- package/dist/generators/indices/seed-template.generator.d.ts +0 -9
- package/dist/generators/indices/seed-template.generator.js +0 -80
- package/dist/generators/indices/testids.generator.d.ts +0 -7
- package/dist/generators/indices/testids.generator.js +0 -71
- package/dist/generators/indices/types.generator.d.ts +0 -10
- package/dist/generators/indices/types.generator.js +0 -35
- package/dist/generators/indices/update/actiontypes.generator.d.ts +0 -9
- package/dist/generators/indices/update/actiontypes.generator.js +0 -49
- package/dist/generators/indices/update/module.generator.d.ts +0 -9
- package/dist/generators/indices/update/module.generator.js +0 -41
- package/dist/generators/indices/update/service.generator.d.ts +0 -9
- package/dist/generators/indices/update/service.generator.js +0 -34
- package/dist/generators/indices/view/module.generator.d.ts +0 -9
- package/dist/generators/indices/view/module.generator.js +0 -39
- package/dist/generators/indices/view/service.generator.d.ts +0 -9
- package/dist/generators/indices/view/service.generator.js +0 -34
- package/dist/generators/models/admin.page.generator.d.ts +0 -7
- package/dist/generators/models/admin.page.generator.js +0 -74
- package/dist/generators/models/export/encoder.generator.d.ts +0 -9
- package/dist/generators/models/export/encoder.generator.js +0 -51
- package/dist/generators/models/import/decoder.generator.d.ts +0 -9
- package/dist/generators/models/import/decoder.generator.js +0 -148
- package/dist/generators/models/react/context.generator.d.ts +0 -9
- package/dist/generators/models/react/context.generator.js +0 -71
- package/dist/generators/models/react/index.d.ts +0 -10
- package/dist/generators/models/react/index.js +0 -31
- package/dist/generators/models/react/library.generator.d.ts +0 -10
- package/dist/generators/models/react/library.generator.js +0 -94
- package/dist/generators/models/react/lookup.generator.d.ts +0 -9
- package/dist/generators/models/react/lookup.generator.js +0 -175
- package/dist/generators/models/react/modals.generator.d.ts +0 -23
- package/dist/generators/models/react/modals.generator.js +0 -710
- package/dist/generators/models/repository.generator.d.ts +0 -9
- package/dist/generators/models/repository.generator.js +0 -955
- package/dist/generators/models/route.generator.d.ts +0 -9
- package/dist/generators/models/route.generator.js +0 -92
- package/dist/generators/models/seed.generator.d.ts +0 -21
- package/dist/generators/models/seed.generator.js +0 -285
- package/dist/generators/models/stub.generator.d.ts +0 -9
- package/dist/generators/models/stub.generator.js +0 -92
- package/dist/generators/models/types.generator.d.ts +0 -9
- package/dist/generators/models/types.generator.js +0 -125
- package/dist/generators/models/update/service.generator.d.ts +0 -10
- package/dist/generators/models/update/service.generator.js +0 -302
- package/dist/generators/models/view/service.generator.d.ts +0 -10
- package/dist/generators/models/view/service.generator.js +0 -239
- package/dist/lib/attributes.d.ts +0 -114
- package/dist/lib/attributes.js +0 -2
- package/dist/lib/exports.d.ts +0 -45
- package/dist/lib/exports.js +0 -90
- package/dist/lib/imports.d.ts +0 -65
- package/dist/lib/imports.js +0 -114
- package/dist/lib/meta.d.ts +0 -1191
- package/dist/lib/meta.js +0 -434
- package/dist/lib/schema/fields.d.ts +0 -46
- package/dist/lib/schema/fields.js +0 -62
- package/dist/lib/schema/schema.d.ts +0 -466
- package/dist/lib/schema/schema.js +0 -18
- package/dist/lib/schema/types.d.ts +0 -201
- package/dist/lib/schema/types.js +0 -112
- package/dist/lib/serializer.d.ts +0 -15
- package/dist/lib/serializer.js +0 -24
- package/dist/lib/test-id-collector.d.ts +0 -42
- package/dist/lib/test-id-collector.js +0 -53
- package/dist/lib/types.d.ts +0 -7
- package/dist/lib/types.js +0 -13
- package/dist/lib/typescript.d.ts +0 -5
- package/dist/lib/typescript.js +0 -22
- package/dist/lib/utils/ast.d.ts +0 -29
- package/dist/lib/utils/ast.js +0 -23
- package/dist/lib/utils/error.d.ts +0 -17
- package/dist/lib/utils/error.js +0 -52
- package/dist/lib/utils/file.d.ts +0 -10
- package/dist/lib/utils/file.js +0 -56
- package/dist/lib/utils/jsdoc.d.ts +0 -9
- package/dist/lib/utils/jsdoc.js +0 -37
- package/dist/lib/utils/logger.d.ts +0 -17
- package/dist/lib/utils/logger.js +0 -12
- package/dist/lib/utils/string.d.ts +0 -40
- package/dist/lib/utils/string.js +0 -187
- package/dist/lib/utils/types.d.ts +0 -12
- package/dist/lib/utils/types.js +0 -2
- package/dist/lib/zod.d.ts +0 -8
- package/dist/lib/zod.js +0 -60
- package/dist/prisma/attributes.d.ts +0 -21
- package/dist/prisma/attributes.js +0 -175
- package/dist/prisma/client-path.d.ts +0 -7
- package/dist/prisma/client-path.js +0 -29
- package/dist/prisma/parse.d.ts +0 -12
- package/dist/prisma/parse.js +0 -452
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type LogFunction = (logMessage: string) => void;
|
|
2
|
+
type Severity = 'info' | 'debug' | 'log' | 'warn' | 'error';
|
|
3
|
+
type Message = {
|
|
4
|
+
severity: Severity;
|
|
5
|
+
message: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A small logger wrapper class.
|
|
9
|
+
*
|
|
10
|
+
* This is meant to simplify testing and logging.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Logger {
|
|
13
|
+
private readonly useConsole;
|
|
14
|
+
private messages;
|
|
15
|
+
constructor(useConsole?: boolean);
|
|
16
|
+
log(logMessage: string): void;
|
|
17
|
+
warn(logMessage: string): void;
|
|
18
|
+
error(logMessage: string): void;
|
|
19
|
+
debug(logMessage: string): void;
|
|
20
|
+
info(logMessage: string): void;
|
|
21
|
+
getMessages(): Message[];
|
|
22
|
+
clearMessages(): void;
|
|
23
|
+
getMessagesAsString(): string;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Logger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A small logger wrapper class.
|
|
6
|
+
*
|
|
7
|
+
* This is meant to simplify testing and logging.
|
|
8
|
+
*/
|
|
9
|
+
class Logger {
|
|
10
|
+
useConsole;
|
|
11
|
+
messages = [];
|
|
12
|
+
constructor(useConsole = true) {
|
|
13
|
+
this.useConsole = useConsole;
|
|
14
|
+
}
|
|
15
|
+
log(logMessage) {
|
|
16
|
+
if (this.useConsole) {
|
|
17
|
+
console.log(logMessage);
|
|
18
|
+
}
|
|
19
|
+
this.messages.push({ severity: 'log', message: logMessage });
|
|
20
|
+
}
|
|
21
|
+
warn(logMessage) {
|
|
22
|
+
if (this.useConsole) {
|
|
23
|
+
console.warn(logMessage);
|
|
24
|
+
}
|
|
25
|
+
this.messages.push({ severity: 'warn', message: logMessage });
|
|
26
|
+
}
|
|
27
|
+
error(logMessage) {
|
|
28
|
+
if (this.useConsole) {
|
|
29
|
+
console.error(logMessage);
|
|
30
|
+
}
|
|
31
|
+
this.messages.push({ severity: 'error', message: logMessage });
|
|
32
|
+
}
|
|
33
|
+
debug(logMessage) {
|
|
34
|
+
if (this.useConsole) {
|
|
35
|
+
console.debug(logMessage);
|
|
36
|
+
}
|
|
37
|
+
this.messages.push({ severity: 'debug', message: logMessage });
|
|
38
|
+
}
|
|
39
|
+
info(logMessage) {
|
|
40
|
+
if (this.useConsole) {
|
|
41
|
+
console.info(logMessage);
|
|
42
|
+
}
|
|
43
|
+
this.messages.push({ severity: 'info', message: logMessage });
|
|
44
|
+
}
|
|
45
|
+
getMessages() {
|
|
46
|
+
return this.messages;
|
|
47
|
+
}
|
|
48
|
+
clearMessages() {
|
|
49
|
+
this.messages = [];
|
|
50
|
+
}
|
|
51
|
+
getMessagesAsString() {
|
|
52
|
+
return this.messages.map((m) => m.message).join('\n');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.Logger = Logger;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FileContent } from './fs-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Standard merge conflict markers used by git and our generator
|
|
4
|
+
*/
|
|
5
|
+
export declare const mergeConflictMarkers: {
|
|
6
|
+
readonly start: "<<<<<<<";
|
|
7
|
+
readonly separator: "=======";
|
|
8
|
+
readonly end: ">>>>>>>";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks if file content contains unresolved merge conflict markers.
|
|
12
|
+
*
|
|
13
|
+
* @param content - The file content to check
|
|
14
|
+
* @returns true if the content contains merge conflict markers, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasMergeConflictMarkers(content: FileContent): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Generates a merged output with conflict markers between two file contents.
|
|
19
|
+
*
|
|
20
|
+
* @param contentSource - The content of the first file as a string.
|
|
21
|
+
* @param contentIncoming - The content of the second file as a string.
|
|
22
|
+
* @param labelSource - Optional label for the first file in conflict markers.
|
|
23
|
+
* @param labelIncoming - Optional label for the second file in conflict markers.
|
|
24
|
+
* @returns The merged content with conflict markers as a string.
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateMergeConflict({ contentSource, contentIncoming, labelSource, labelIncoming, }: {
|
|
27
|
+
contentSource: FileContent;
|
|
28
|
+
contentIncoming: FileContent;
|
|
29
|
+
labelSource?: string;
|
|
30
|
+
labelIncoming?: string;
|
|
31
|
+
}): FileContent;
|
|
32
|
+
/**
|
|
33
|
+
* Generates a summary of the differences between two files: For each conflict,
|
|
34
|
+
* it will show the first 3 lines of each conflict with line counters, i.e.:
|
|
35
|
+
* ```
|
|
36
|
+
* in Red:
|
|
37
|
+
* -X1: [line X1]
|
|
38
|
+
* -X1+1: [line X1+1]
|
|
39
|
+
* -X1-Y1 Z additional lines
|
|
40
|
+
* in Green
|
|
41
|
+
* +X2: [line X2]
|
|
42
|
+
* +X2+1: [line X2+1]
|
|
43
|
+
* +X2-Y2 Z additional lines
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* For same content, it will not show anything.
|
|
47
|
+
*
|
|
48
|
+
* @param contentSource - The content of the first file as a string.
|
|
49
|
+
* @param contentIncoming - The content of the second file as a string.
|
|
50
|
+
* @returns Summary of the diff as a string.
|
|
51
|
+
*/
|
|
52
|
+
export declare function generateDiffSummary({ contentSource, contentIncoming, }: {
|
|
53
|
+
contentSource: FileContent;
|
|
54
|
+
contentIncoming: FileContent;
|
|
55
|
+
}): string;
|
|
@@ -0,0 +1,264 @@
|
|
|
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.mergeConflictMarkers = void 0;
|
|
37
|
+
exports.hasMergeConflictMarkers = hasMergeConflictMarkers;
|
|
38
|
+
exports.generateMergeConflict = generateMergeConflict;
|
|
39
|
+
exports.generateDiffSummary = generateDiffSummary;
|
|
40
|
+
const Diff = __importStar(require("diff"));
|
|
41
|
+
const utils_1 = require("@postxl/utils");
|
|
42
|
+
/**
|
|
43
|
+
* Standard merge conflict markers used by git and our generator
|
|
44
|
+
*/
|
|
45
|
+
exports.mergeConflictMarkers = {
|
|
46
|
+
start: '<<<<<<<',
|
|
47
|
+
separator: '=======',
|
|
48
|
+
end: '>>>>>>>',
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Checks if file content contains unresolved merge conflict markers.
|
|
52
|
+
*
|
|
53
|
+
* @param content - The file content to check
|
|
54
|
+
* @returns true if the content contains merge conflict markers, false otherwise
|
|
55
|
+
*/
|
|
56
|
+
function hasMergeConflictMarkers(content) {
|
|
57
|
+
// Binary content cannot have merge conflict markers
|
|
58
|
+
if (typeof content !== 'string') {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
// Check for all three markers - a proper merge conflict must have all of them
|
|
62
|
+
const hasStart = content.includes(exports.mergeConflictMarkers.start);
|
|
63
|
+
const hasSeparator = content.includes(exports.mergeConflictMarkers.separator);
|
|
64
|
+
const hasEnd = content.includes(exports.mergeConflictMarkers.end);
|
|
65
|
+
return hasStart && hasSeparator && hasEnd;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Normalizes whitespace in a string by:
|
|
69
|
+
* - Normalizing all line endings to Unix format (LF)
|
|
70
|
+
* - Trimming trailing whitespace from each line
|
|
71
|
+
* - Removing empty lines at the end
|
|
72
|
+
* - Removing BOM markers
|
|
73
|
+
*/
|
|
74
|
+
function normalizeWhitespace(content) {
|
|
75
|
+
const normalized = content
|
|
76
|
+
.replaceAll('\r\n', '\n') // Normalize Windows line endings to Unix
|
|
77
|
+
.replaceAll('\n\r', '\n') // Normalize Mac line endings to Unix
|
|
78
|
+
.replaceAll('\r', '\n') // Normalize Mac line endings to Unix
|
|
79
|
+
.replaceAll('\uFEFF', ''); // Remove BOM
|
|
80
|
+
const lines = normalized.split('\n').map((line) => line.trimEnd()); // Trim trailing whitespace from each line
|
|
81
|
+
// Remove trailing empty lines
|
|
82
|
+
while (lines.length > 0 && lines.at(-1) === '') {
|
|
83
|
+
lines.pop();
|
|
84
|
+
}
|
|
85
|
+
return lines.join('\n');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Checks if two arrays of lines differ only in whitespace/spacing
|
|
89
|
+
*/
|
|
90
|
+
function isWhitespaceOnlyDifference(sourceLines, incomingLines) {
|
|
91
|
+
const sourceNormalized = normalizeWhitespace(sourceLines.join('\n'));
|
|
92
|
+
const incomingNormalized = normalizeWhitespace(incomingLines.join('\n'));
|
|
93
|
+
return sourceNormalized === incomingNormalized;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Generates a merged output with conflict markers between two file contents.
|
|
97
|
+
*
|
|
98
|
+
* @param contentSource - The content of the first file as a string.
|
|
99
|
+
* @param contentIncoming - The content of the second file as a string.
|
|
100
|
+
* @param labelSource - Optional label for the first file in conflict markers.
|
|
101
|
+
* @param labelIncoming - Optional label for the second file in conflict markers.
|
|
102
|
+
* @returns The merged content with conflict markers as a string.
|
|
103
|
+
*/
|
|
104
|
+
function generateMergeConflict({ contentSource, contentIncoming, labelSource = 'Manual', labelIncoming = 'Generated', }) {
|
|
105
|
+
// In case the content is binary, we just return the incoming content
|
|
106
|
+
if (typeof contentSource !== 'string' || typeof contentIncoming !== 'string') {
|
|
107
|
+
return contentIncoming;
|
|
108
|
+
}
|
|
109
|
+
// Check if the ENTIRE file differs only in whitespace
|
|
110
|
+
// If so, just return the incoming content to preserve its exact formatting
|
|
111
|
+
const sourceNormalized = normalizeWhitespace(contentSource);
|
|
112
|
+
const incomingNormalized = normalizeWhitespace(contentIncoming);
|
|
113
|
+
if (sourceNormalized === incomingNormalized) {
|
|
114
|
+
return contentIncoming;
|
|
115
|
+
}
|
|
116
|
+
const blocks = new Blocks({ source: contentSource, incoming: contentIncoming });
|
|
117
|
+
let result = '';
|
|
118
|
+
for (const block of blocks.blocks) {
|
|
119
|
+
if (block.type === 'Same') {
|
|
120
|
+
result += block.lines.join('\n') + '\n';
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// Check if this conflict is only due to whitespace differences
|
|
124
|
+
if (isWhitespaceOnlyDifference(block.source, block.incoming)) {
|
|
125
|
+
// If only whitespace differs, use the incoming (generated) version without conflict markers
|
|
126
|
+
// Handle empty incoming array (removed content) - don't add anything
|
|
127
|
+
if (block.incoming.length > 0) {
|
|
128
|
+
result += block.incoming.join('\n') + '\n';
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Real content difference - create conflict markers
|
|
133
|
+
result += `${exports.mergeConflictMarkers.start} ${labelSource}\n`;
|
|
134
|
+
result += block.source.join('\n') + '\n';
|
|
135
|
+
result += `${exports.mergeConflictMarkers.separator}\n`;
|
|
136
|
+
result += block.incoming.join('\n') + '\n';
|
|
137
|
+
result += `${exports.mergeConflictMarkers.end} ${labelIncoming}\n`;
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Generates a summary of the differences between two files: For each conflict,
|
|
143
|
+
* it will show the first 3 lines of each conflict with line counters, i.e.:
|
|
144
|
+
* ```
|
|
145
|
+
* in Red:
|
|
146
|
+
* -X1: [line X1]
|
|
147
|
+
* -X1+1: [line X1+1]
|
|
148
|
+
* -X1-Y1 Z additional lines
|
|
149
|
+
* in Green
|
|
150
|
+
* +X2: [line X2]
|
|
151
|
+
* +X2+1: [line X2+1]
|
|
152
|
+
* +X2-Y2 Z additional lines
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* For same content, it will not show anything.
|
|
156
|
+
*
|
|
157
|
+
* @param contentSource - The content of the first file as a string.
|
|
158
|
+
* @param contentIncoming - The content of the second file as a string.
|
|
159
|
+
* @returns Summary of the diff as a string.
|
|
160
|
+
*/
|
|
161
|
+
function generateDiffSummary({ contentSource, contentIncoming, }) {
|
|
162
|
+
if (typeof contentSource !== 'string' || typeof contentIncoming !== 'string') {
|
|
163
|
+
return 'Binary content, diff not possible';
|
|
164
|
+
}
|
|
165
|
+
let result = '';
|
|
166
|
+
const blocks = new Blocks({ source: contentSource, incoming: contentIncoming });
|
|
167
|
+
let isFirstConflict = true;
|
|
168
|
+
for (const block of blocks.blocks) {
|
|
169
|
+
if (block.type === 'Same') {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
result += summarizeConflictBlock(block, isFirstConflict);
|
|
173
|
+
isFirstConflict = false;
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
class Blocks {
|
|
178
|
+
blocks = [];
|
|
179
|
+
#currentBlock = undefined;
|
|
180
|
+
constructor({ source, incoming }) {
|
|
181
|
+
const diff = Diff.diffLines(source, incoming);
|
|
182
|
+
for (const part of diff) {
|
|
183
|
+
const lines = part.value.trimEnd().split('\n');
|
|
184
|
+
if (part.added) {
|
|
185
|
+
this.#addIncomingDelta(lines);
|
|
186
|
+
}
|
|
187
|
+
else if (part.removed) {
|
|
188
|
+
this.#addSourceDelta(lines);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.#addSame(lines);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
#addIncomingDelta(lines) {
|
|
196
|
+
const block = this.#ensureConflictBlock();
|
|
197
|
+
block.incoming.push(...lines);
|
|
198
|
+
}
|
|
199
|
+
#addSourceDelta(lines) {
|
|
200
|
+
const block = this.#ensureConflictBlock();
|
|
201
|
+
block.source.push(...lines);
|
|
202
|
+
}
|
|
203
|
+
#addSame(lines) {
|
|
204
|
+
const block = this.#ensureSameBlock();
|
|
205
|
+
block.lines.push(...lines);
|
|
206
|
+
}
|
|
207
|
+
#ensureSameBlock() {
|
|
208
|
+
if (this.#currentBlock && this.#currentBlock.type === 'Same') {
|
|
209
|
+
return this.#currentBlock;
|
|
210
|
+
}
|
|
211
|
+
this.#currentBlock = { type: 'Same', lines: [], counters: this.#getNextBlockLineCounters() };
|
|
212
|
+
this.blocks.push(this.#currentBlock);
|
|
213
|
+
return this.#currentBlock;
|
|
214
|
+
}
|
|
215
|
+
#getNextBlockLineCounters() {
|
|
216
|
+
if (!this.#currentBlock) {
|
|
217
|
+
return { incoming: 1, source: 1 };
|
|
218
|
+
}
|
|
219
|
+
const block = this.#currentBlock;
|
|
220
|
+
const incomingLines = block.type === 'Same' ? block.lines.length : block.incoming.length;
|
|
221
|
+
const sourceLines = block.type === 'Same' ? block.lines.length : block.source.length;
|
|
222
|
+
return {
|
|
223
|
+
incoming: block.counters.incoming + incomingLines,
|
|
224
|
+
source: block.counters.source + sourceLines,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
#ensureConflictBlock() {
|
|
228
|
+
if (this.#currentBlock && this.#currentBlock.type === 'Conflict') {
|
|
229
|
+
return this.#currentBlock;
|
|
230
|
+
}
|
|
231
|
+
this.#currentBlock = {
|
|
232
|
+
type: 'Conflict',
|
|
233
|
+
source: [],
|
|
234
|
+
incoming: [],
|
|
235
|
+
isFirstConflict: true,
|
|
236
|
+
counters: this.#getNextBlockLineCounters(),
|
|
237
|
+
};
|
|
238
|
+
this.blocks.push(this.#currentBlock);
|
|
239
|
+
return this.#currentBlock;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function summarizeConflictBlock({ incoming, source, counters }, isFirstConflict) {
|
|
243
|
+
return ((isFirstConflict ? '' : (0, utils_1.gray)('...') + '\n') +
|
|
244
|
+
summarizeChange('-', utils_1.red, source, counters.source) +
|
|
245
|
+
summarizeChange('+', utils_1.green, incoming, counters.incoming));
|
|
246
|
+
}
|
|
247
|
+
function summarizeChange(prefix, colorFn, lines, startLineCounter) {
|
|
248
|
+
if (lines.length === 0) {
|
|
249
|
+
return '';
|
|
250
|
+
}
|
|
251
|
+
let result = '';
|
|
252
|
+
let lineCounter = 0;
|
|
253
|
+
for (const line of lines) {
|
|
254
|
+
lineCounter++;
|
|
255
|
+
if (lineCounter < 3 || lines.length === 3) {
|
|
256
|
+
result += colorFn(`${prefix}${startLineCounter + lineCounter - 1}: ${line}`) + '\n';
|
|
257
|
+
}
|
|
258
|
+
else if (lineCounter === 3) {
|
|
259
|
+
result +=
|
|
260
|
+
colorFn(`${prefix}${startLineCounter + lineCounter - 1}-${startLineCounter + lines.length - 1} additional lines`) + '\n';
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const zPosixPath: z.ZodBranded<z.ZodString, "PXL.PosixPath">;
|
|
3
|
+
/**
|
|
4
|
+
* A path string that has been normalized to use the unix path separator.
|
|
5
|
+
*/
|
|
6
|
+
export type PosixPath = z.infer<typeof zPosixPath>;
|
|
7
|
+
export declare const POSIX_ROOT: string & z.BRAND<"PXL.PosixPath">;
|
|
8
|
+
/**
|
|
9
|
+
* Normalizes a unix or Windows path to use the unix path separator. Additionally,
|
|
10
|
+
* it normalizes the path so that every path is considered absolute.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalize(path: string): PosixPath;
|
|
13
|
+
/**
|
|
14
|
+
* Joins two paths together appending the second path to the first.
|
|
15
|
+
*/
|
|
16
|
+
export declare function join(dir: PosixPath, path: PosixPath | string): PosixPath;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the file name of the given path.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fileName(path: PosixPath): string;
|
|
21
|
+
/**
|
|
22
|
+
* Parses a given string into a path array.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parse(path: PosixPath): PosixPath[];
|
|
25
|
+
/**
|
|
26
|
+
* Tells whether a given dir contains a given target. It expects that both paths are absolute and normalized.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* contains('/foo/bar', '/foo/bar/baz') // true
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function contains(dir: PosixPath, target: PosixPath): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Changes the directory of a given path. If a path is not in the given directory,
|
|
37
|
+
* it will return an unchanged path.
|
|
38
|
+
*/
|
|
39
|
+
export declare function cd(dir: PosixPath, path: PosixPath): PosixPath;
|
|
40
|
+
export declare function isPackageName(name: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the relative path from one file (e.g. current file) to another file
|
|
43
|
+
* assuming that both files have the same starting point (e.g. from `/a` to `/b/c` is `./b/c`).
|
|
44
|
+
*
|
|
45
|
+
* To indicate a folder instead of a file, the path should end with a slash (e.g. `/a/` to `/b/c/` is `../b/c/`).
|
|
46
|
+
*
|
|
47
|
+
* If the referenced file is a package, then we return the package reference (e.g. `@lib/package`).
|
|
48
|
+
*/
|
|
49
|
+
export declare function getRelativePath({ from, to }: {
|
|
50
|
+
from: string;
|
|
51
|
+
to: string;
|
|
52
|
+
}): string;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.POSIX_ROOT = exports.zPosixPath = void 0;
|
|
7
|
+
exports.normalize = normalize;
|
|
8
|
+
exports.join = join;
|
|
9
|
+
exports.fileName = fileName;
|
|
10
|
+
exports.parse = parse;
|
|
11
|
+
exports.contains = contains;
|
|
12
|
+
exports.cd = cd;
|
|
13
|
+
exports.isPackageName = isPackageName;
|
|
14
|
+
exports.getRelativePath = getRelativePath;
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const zod_1 = require("zod");
|
|
17
|
+
exports.zPosixPath = zod_1.z.string().brand('PXL.PosixPath');
|
|
18
|
+
const toPosixPath = (input) => exports.zPosixPath.parse(input);
|
|
19
|
+
exports.POSIX_ROOT = normalize('/');
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes a unix or Windows path to use the unix path separator. Additionally,
|
|
22
|
+
* it normalizes the path so that every path is considered absolute.
|
|
23
|
+
*/
|
|
24
|
+
function normalize(path) {
|
|
25
|
+
const unixPath = path.replace(/\\/g, '/');
|
|
26
|
+
if (/^[A-Za-z]:\//.test(unixPath)) {
|
|
27
|
+
// NOTE: The RegEx also checks that the path starts with a slash,
|
|
28
|
+
// which we don't remove.
|
|
29
|
+
return toPosixPath(unixPath.slice(2));
|
|
30
|
+
}
|
|
31
|
+
if (!unixPath.startsWith('/')) {
|
|
32
|
+
return toPosixPath(`/${unixPath}`);
|
|
33
|
+
}
|
|
34
|
+
return toPosixPath(unixPath);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Joins two paths together appending the second path to the first.
|
|
38
|
+
*/
|
|
39
|
+
function join(dir, path) {
|
|
40
|
+
return normalize(node_path_1.default.posix.join(dir, path));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns the file name of the given path.
|
|
44
|
+
*/
|
|
45
|
+
function fileName(path) {
|
|
46
|
+
const parts = normalize(path).split('/');
|
|
47
|
+
const lastEntry = parts[parts.length - 1];
|
|
48
|
+
if (!lastEntry || lastEntry === '') {
|
|
49
|
+
throw new Error(`Path ${path} does not contain a file name!`);
|
|
50
|
+
}
|
|
51
|
+
return lastEntry;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parses a given string into a path array.
|
|
55
|
+
*/
|
|
56
|
+
function parse(path) {
|
|
57
|
+
const parts = normalize(path).split('/');
|
|
58
|
+
if (parts.length === 0) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
// Remove the first empty string if the path starts with a slash.
|
|
62
|
+
if (parts[0] === '' || parts[0] === '.') {
|
|
63
|
+
parts.shift();
|
|
64
|
+
}
|
|
65
|
+
const resolved = [];
|
|
66
|
+
while (parts.length > 0) {
|
|
67
|
+
// We can safely force unwrap here because we check the length of the array.
|
|
68
|
+
const part = parts.shift();
|
|
69
|
+
if (part === '..') {
|
|
70
|
+
resolved.pop();
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (part === '.') {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (part === '') {
|
|
77
|
+
if (parts.length > 0) {
|
|
78
|
+
console.warn(`Empty subpath in path: ${path}`);
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
resolved.push(normalize(part));
|
|
83
|
+
}
|
|
84
|
+
return resolved;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Tells whether a given dir contains a given target. It expects that both paths are absolute and normalized.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* contains('/foo/bar', '/foo/bar/baz') // true
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
function contains(dir, target) {
|
|
96
|
+
// NOTE: We use the name `dir` because it better portrays the intent of the function, but you can also pass in the filename.
|
|
97
|
+
const dirParts = parse(dir);
|
|
98
|
+
const targetParts = parse(target);
|
|
99
|
+
if (dirParts.length > targetParts.length) {
|
|
100
|
+
// Parent (i.e. a directory) cannot be inside of the target file or directory.
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
for (let i = 0; i < dirParts.length; i++) {
|
|
104
|
+
if (dirParts[i] !== targetParts[i]) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Changes the directory of a given path. If a path is not in the given directory,
|
|
112
|
+
* it will return an unchanged path.
|
|
113
|
+
*/
|
|
114
|
+
function cd(dir, path) {
|
|
115
|
+
if (!contains(dir, path)) {
|
|
116
|
+
return path;
|
|
117
|
+
}
|
|
118
|
+
const chunks = parse(path);
|
|
119
|
+
const dirChunks = parse(dir);
|
|
120
|
+
for (const _ of dirChunks) {
|
|
121
|
+
chunks.shift();
|
|
122
|
+
}
|
|
123
|
+
return normalize(node_path_1.default.posix.join(...chunks));
|
|
124
|
+
}
|
|
125
|
+
function isPackageName(name) {
|
|
126
|
+
//check that name does not include any dots, slashes, backslashes, or spaces
|
|
127
|
+
return !/[./\\\s]/.test(name);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns the relative path from one file (e.g. current file) to another file
|
|
131
|
+
* assuming that both files have the same starting point (e.g. from `/a` to `/b/c` is `./b/c`).
|
|
132
|
+
*
|
|
133
|
+
* To indicate a folder instead of a file, the path should end with a slash (e.g. `/a/` to `/b/c/` is `../b/c/`).
|
|
134
|
+
*
|
|
135
|
+
* If the referenced file is a package, then we return the package reference (e.g. `@lib/package`).
|
|
136
|
+
*/
|
|
137
|
+
function getRelativePath({ from, to }) {
|
|
138
|
+
if (to.startsWith('@') || isPackageName(to)) {
|
|
139
|
+
return to;
|
|
140
|
+
}
|
|
141
|
+
if (from.startsWith('@')) {
|
|
142
|
+
throw new Error(`Cannot resolve relative path from a package (${from}) to a file (${to})!`);
|
|
143
|
+
}
|
|
144
|
+
const fromParts = resolvePath(from);
|
|
145
|
+
const toParts = resolvePath(to);
|
|
146
|
+
// We expect that from value references a file of a file in a given folder.
|
|
147
|
+
// Relative to that file, we need to remove it.
|
|
148
|
+
fromParts.pop();
|
|
149
|
+
// Remove common parts.
|
|
150
|
+
while (fromParts.length > 0 && toParts.length > 0 && fromParts[0] === toParts[0]) {
|
|
151
|
+
fromParts.shift();
|
|
152
|
+
toParts.shift();
|
|
153
|
+
}
|
|
154
|
+
// Add ../ for each remaining part in fromParts.
|
|
155
|
+
const relativePath = fromParts
|
|
156
|
+
.map(() => '..')
|
|
157
|
+
.concat(toParts)
|
|
158
|
+
.join('/');
|
|
159
|
+
if (relativePath.startsWith('.')) {
|
|
160
|
+
return relativePath;
|
|
161
|
+
}
|
|
162
|
+
return `./${relativePath}`;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns a list of folders leading from the root to the referenced file or folder and removes
|
|
166
|
+
* any positional paths.
|
|
167
|
+
*/
|
|
168
|
+
function resolvePath(path) {
|
|
169
|
+
const chunks = path.split('/');
|
|
170
|
+
const resolved = [];
|
|
171
|
+
while (chunks.length > 0) {
|
|
172
|
+
const chunk = chunks.shift();
|
|
173
|
+
if (chunk === '..') {
|
|
174
|
+
resolved.pop();
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (chunk === '.') {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
resolved.push(chunk);
|
|
181
|
+
}
|
|
182
|
+
return resolved;
|
|
183
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// IMPORTANT: To ensure consistency between generated code and repo code,
|
|
3
|
+
// make sure that this file is kept in sync with
|
|
4
|
+
// `./prettier-config.ts`!
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prettierConfig = void 0;
|
|
7
|
+
exports.prettierConfig = {
|
|
8
|
+
semi: false,
|
|
9
|
+
trailingComma: 'all',
|
|
10
|
+
singleQuote: true,
|
|
11
|
+
tabWidth: 2,
|
|
12
|
+
printWidth: 120,
|
|
13
|
+
};
|