@rebasepro/plugin-ai 0.12.0 → 0.12.1-canary.g009ed95

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.
@@ -1,128 +0,0 @@
1
- // Import the diffStrings function from your module
2
- // import { diffStrings } from './your-module';
3
-
4
- import { Change, diffStrings } from "../utils/diffStrings";
5
-
6
- describe("diffStrings", () => {
7
- test("equal strings", () => {
8
- const oldStr = "This is a test string";
9
- const newStr = "This is a test string";
10
- const expected: Change[] = [
11
- {
12
- type: "equal",
13
- value: "This is a test string"
14
- }
15
- ];
16
- expect(diffStrings(oldStr, newStr)).toEqual(expected);
17
- });
18
-
19
- test("insertions only", () => {
20
- const oldStr = "This is a test string";
21
- const newStr = "This is a new test string";
22
- const expected: Change[] = [
23
- {
24
- type: "equal",
25
- value: "This is a"
26
- },
27
- {
28
- type: "insert",
29
- value: " new"
30
- },
31
- {
32
- type: "equal",
33
- value: " test string"
34
- }
35
- ];
36
- expect(diffStrings(oldStr, newStr)).toEqual(expected);
37
- });
38
-
39
- test("deletions only", () => {
40
- const oldStr = "This is an old test string";
41
- const newStr = "This is a test string";
42
- const expected: Change[] = [
43
- {
44
- type: "equal",
45
- value: "This is a"
46
- },
47
- {
48
- type: "delete",
49
- value: "n old"
50
- },
51
- {
52
- type: "equal",
53
- value: " test string"
54
- }
55
- ];
56
- expect(diffStrings(oldStr, newStr)).toEqual(expected);
57
- });
58
-
59
- test("insertions and deletions", () => {
60
- const oldStr = "This is an old test string";
61
- const newStr = "This is a new modified test string";
62
- // The LCS algorithm finds the longest common substrings correctly
63
- // Even though the output is more granular, it correctly represents the diff
64
- const expected: Change[] = [
65
- {
66
- type: "equal",
67
- value: "This is a"
68
- },
69
- {
70
- type: "insert",
71
- value: " "
72
- },
73
- {
74
- type: "equal",
75
- value: "n"
76
- },
77
- {
78
- type: "insert",
79
- value: "ew"
80
- },
81
- {
82
- type: "equal",
83
- value: " "
84
- },
85
- {
86
- type: "insert",
87
- value: "m"
88
- },
89
- {
90
- type: "equal",
91
- value: "o"
92
- },
93
- {
94
- type: "delete",
95
- value: "l"
96
- },
97
- {
98
- type: "insert",
99
- value: "difie"
100
- },
101
- {
102
- type: "equal",
103
- value: "d test string"
104
- }
105
- ];
106
- expect(diffStrings(oldStr, newStr)).toEqual(expected);
107
- });
108
-
109
- test("completely different strings", () => {
110
- const oldStr = "Old string";
111
- const newStr = "New string";
112
- const expected: Change[] = [
113
- {
114
- type: "delete",
115
- value: "Old"
116
- },
117
- {
118
- type: "insert",
119
- value: "New"
120
- },
121
- {
122
- type: "equal",
123
- value: " string"
124
- }
125
- ];
126
- expect(diffStrings(oldStr, newStr)).toEqual(expected);
127
- });
128
- });
@@ -1,117 +0,0 @@
1
- import { countStringCharacters } from "../utils/strings_counter";
2
- import type { Properties } from "@rebasepro/types";
3
-
4
- describe("countStringCharacters", () => {
5
- it("counts characters in a string property", () => {
6
- const values = { title: "Hello World" };
7
- const properties: Properties = {
8
- title: { name: "title",
9
- type: "string" }
10
- };
11
- expect(countStringCharacters(values, properties)).toBe(11);
12
- });
13
-
14
- it("counts characters in a number property (stringified)", () => {
15
- const values = { price: 12345 };
16
- const properties: Properties = {
17
- price: { name: "price",
18
- type: "number" }
19
- };
20
- expect(countStringCharacters(values, properties)).toBe(5);
21
- });
22
-
23
- it("skips disabled properties", () => {
24
- const values = { title: "Hello",
25
- hidden: "Secret" };
26
- const properties: Properties = {
27
- title: { name: "title",
28
- type: "string" },
29
- hidden: { name: "hidden",
30
- type: "string",
31
- admin: { disabled: true } }
32
- };
33
- expect(countStringCharacters(values, properties)).toBe(5);
34
- });
35
-
36
- it("counts array of strings", () => {
37
- const values = { tags: ["hello", "world", "test"] };
38
- const properties: Properties = {
39
- tags: {
40
- name: "tags",
41
- type: "array",
42
- of: { name: "tag",
43
- type: "string" }
44
- }
45
- };
46
- // "hello" (5) + "world" (5) + "test" (4) = 14
47
- expect(countStringCharacters(values, properties)).toBe(14);
48
- });
49
-
50
- it("recurses into map properties", () => {
51
- const values = {
52
- address: { city: "New York",
53
- country: "USA" }
54
- };
55
- const properties: Properties = {
56
- address: {
57
- name: "address",
58
- type: "map",
59
- properties: {
60
- city: { name: "city",
61
- type: "string" },
62
- country: { name: "country",
63
- type: "string" }
64
- }
65
- }
66
- };
67
- // "New York" (8) + "USA" (3) = 11
68
- expect(countStringCharacters(values, properties)).toBe(11);
69
- });
70
-
71
- it("returns 0 for empty values", () => {
72
- const properties: Properties = {
73
- title: { name: "title",
74
- type: "string" }
75
- };
76
- expect(countStringCharacters({}, properties)).toBe(0);
77
- });
78
-
79
- it("handles mixed property types", () => {
80
- const values = {
81
- title: "Hello",
82
- count: 42,
83
- active: true,
84
- tags: ["a", "bb"]
85
- };
86
- const properties: Properties = {
87
- title: { name: "title",
88
- type: "string" },
89
- count: { name: "count",
90
- type: "number" },
91
- active: { name: "active",
92
- type: "boolean" },
93
- tags: {
94
- name: "tags",
95
- type: "array",
96
- of: { name: "tag",
97
- type: "string" }
98
- }
99
- };
100
- // "Hello" (5) + "42" (2) + "a" (1) + "bb" (2) = 10
101
- expect(countStringCharacters(values, properties)).toBe(10);
102
- });
103
-
104
- it("handles null values in array gracefully", () => {
105
- const values = { tags: [null, "hello", null] };
106
- const properties: Properties = {
107
- tags: {
108
- name: "tags",
109
- type: "array",
110
- of: { name: "tag",
111
- type: "string" }
112
- }
113
- };
114
- // null?.length = 0, "hello" = 5, null?.length = 0
115
- expect(countStringCharacters(values, properties)).toBe(5);
116
- });
117
- });
@@ -1,53 +0,0 @@
1
- import { getAppendableSuggestion } from "../utils/suggestions";
2
-
3
- describe("getAppendableSuggestion", () => {
4
- it("returns the remaining part when suggestion starts with value", () => {
5
- const result = getAppendableSuggestion("Hello World", "Hello");
6
- expect(result).toBe(" World");
7
- });
8
-
9
- it("returns undefined when suggestion does not start with value", () => {
10
- const result = getAppendableSuggestion("Goodbye World", "Hello");
11
- expect(result).toBeUndefined();
12
- });
13
-
14
- it("performs case-insensitive matching", () => {
15
- const result = getAppendableSuggestion("Hello World", "hello");
16
- expect(result).toBe(" World");
17
- });
18
-
19
- it("returns undefined for number suggestion", () => {
20
- const result = getAppendableSuggestion(42, "4");
21
- expect(result).toBeUndefined();
22
- });
23
-
24
- it("returns undefined for undefined suggestion", () => {
25
- const result = getAppendableSuggestion(undefined, "hello");
26
- expect(result).toBeUndefined();
27
- });
28
-
29
- it("returns undefined for non-string value", () => {
30
- const result = getAppendableSuggestion("Hello", 42);
31
- expect(result).toBeUndefined();
32
- });
33
-
34
- it("returns full suggestion when value is empty string", () => {
35
- const result = getAppendableSuggestion("Hello World", "");
36
- expect(result).toBe("Hello World");
37
- });
38
-
39
- it("handles whitespace trimming", () => {
40
- const result = getAppendableSuggestion("Hello World", "Hello");
41
- expect(result).toBe(" World");
42
- });
43
-
44
- it("returns empty string when suggestion equals value", () => {
45
- const result = getAppendableSuggestion("Hello", "Hello");
46
- expect(result).toBe("");
47
- });
48
-
49
- it("returns undefined when value is longer than suggestion", () => {
50
- const result = getAppendableSuggestion("Hi", "Hello World");
51
- expect(result).toBeUndefined();
52
- });
53
- });
@@ -1,70 +0,0 @@
1
- type ChangeType = "equal" | "delete" | "insert";
2
-
3
- export interface Change {
4
- type: ChangeType;
5
- value: string;
6
- }
7
-
8
- export function diffStrings(oldStr: string, newStr: string): Change[] {
9
- // Find the longest common substring
10
- function longestCommonSubstring(s1: string, s2: string): string {
11
- const longest = { start: 0,
12
- length: 0 };
13
- const matrix = new Array(s1.length + 1).fill(null).map(() => new Array(s2.length + 1).fill(0));
14
-
15
- for (let i = 1; i <= s1.length; i++) {
16
- for (let j = 1; j <= s2.length; j++) {
17
- if (s1[i - 1] === s2[j - 1]) {
18
- matrix[i][j] = matrix[i - 1][j - 1] + 1;
19
- if (matrix[i][j] > longest.length) {
20
- longest.start = i - matrix[i][j];
21
- longest.length = matrix[i][j];
22
- }
23
- }
24
- }
25
- }
26
-
27
- return s1.slice(longest.start, longest.start + longest.length);
28
- }
29
-
30
- // Recursively find changes and create Change objects
31
- function findChanges(s1: string, s2: string): Change[] {
32
- if (s1 === s2) return s1.length > 0 ? [{
33
- type: "equal",
34
- value: s1
35
- }] : [];
36
-
37
- const common = longestCommonSubstring(s1, s2);
38
-
39
- if (common.length === 0) {
40
- const changes: Change[] = [];
41
- if (s1.length > 0) {
42
- changes.push({ type: "delete",
43
- value: s1 });
44
- }
45
- if (s2.length > 0) {
46
- changes.push({ type: "insert",
47
- value: s2 });
48
- }
49
- return changes;
50
- }
51
-
52
- const s1Before = s1.slice(0, s1.indexOf(common));
53
- const s1After = s1.slice(s1.indexOf(common) + common.length);
54
- const s2Before = s2.slice(0, s2.indexOf(common));
55
- const s2After = s2.slice(s2.indexOf(common) + common.length);
56
-
57
- const changesBefore = findChanges(s1Before, s2Before);
58
- const changesAfter = findChanges(s1After, s2After);
59
-
60
- return [
61
- ...changesBefore,
62
- { type: "equal",
63
- value: common },
64
- ...changesAfter
65
- ];
66
- }
67
-
68
- return findChanges(oldStr, newStr);
69
- }
70
-
@@ -1,22 +0,0 @@
1
- import { EntityValues, Properties, Property } from "@rebasepro/types";
2
-
3
- export function countStringCharacters(values: EntityValues<any>, properties: Properties) {
4
- let count = 0;
5
-
6
- for (const key in values) {
7
- const value = values[key];
8
- const property: Property = properties[key];
9
-
10
- if (property && !property.admin?.disabled) {
11
- if (property.type === "string" || property.type === "number") {
12
- count += String(value).length;
13
- } else if (property.type === "array" && Array.isArray(value) && property.of && !Array.isArray(property.of) && property.of.type === "string") {
14
- count += (value as string[]).reduce((acc, curr) => acc + (curr?.length ?? 0), 0);
15
- } else if (property.type === "map" && property.properties && typeof value === "object") {
16
- count += countStringCharacters(value, property.properties);
17
- }
18
- }
19
- }
20
-
21
- return count;
22
- }
@@ -1,6 +0,0 @@
1
- export function getAppendableSuggestion(suggestion: string | number | undefined, value: unknown): string | undefined {
2
- const suggestionIncludesValue = typeof suggestion === "string" && typeof value === "string" && suggestion.toLowerCase().trim().startsWith(value.toLowerCase().trim());
3
- return (typeof value === "string" && suggestionIncludesValue)
4
- ? suggestion.substring(suggestion.toLowerCase().trim().indexOf(value.toLowerCase().trim()) + value.trim().length)
5
- : undefined;
6
- }