@ng-atomic/schematics 4.2.0 → 4.3.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/README.md CHANGED
@@ -1,7 +1,6 @@
1
- # schematics
1
+ # @NgAtomic/Schematics
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
4
-
5
- ## Running unit tests
6
-
7
- Run `nx test schematics` to execute the unit tests via [Jest](https://jestjs.io).
3
+ ## How to use
4
+ ```sh
5
+ $ ng g gpt3
6
+ ```
package/collection.json CHANGED
@@ -56,7 +56,12 @@
56
56
  "setup": {
57
57
  "description": "Setup angular-atomic-schematics",
58
58
  "factory": "./src/setup/index#setup",
59
- "schema": "./src/ng-add//schema.json"
59
+ "schema": "./src/ng-add/schema.json"
60
+ },
61
+ "gpt3": {
62
+ "description": "Generate files by GPT-3",
63
+ "factory": "./src/gpt3/index#gpt3",
64
+ "schema": "./src/gpt3/schema.json"
60
65
  }
61
66
  }
62
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-atomic/schematics",
3
- "version": "4.2.0",
3
+ "version": "4.3.1",
4
4
  "license": "MIT",
5
5
  "schematics": "./collection.json",
6
6
  "ng-add": {
@@ -11,6 +11,7 @@
11
11
  "dependencies": {},
12
12
  "peerDependencies": {
13
13
  "@angular/core": "^14.0.0",
14
+ "openai": "^3.1.0",
14
15
  "@angular/common": "^14.0.0",
15
16
  "@angular/router": "^14.0.0",
16
17
  "string-template": "^1.0.0",
@@ -0,0 +1,3 @@
1
+ export declare function parseFilePath(filePath: string, characters?: string[]): string[];
2
+ export declare const convertByWords: (str: string, words: string[]) => string;
3
+ export declare function getEstimateSimilarFilePaths(path: string, files: string[]): string[];
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEstimateSimilarFilePaths = exports.convertByWords = exports.parseFilePath = void 0;
4
+ function parseFilePath(filePath, characters = ['.', '/']) {
5
+ const result = [];
6
+ let word = '';
7
+ for (let i = 0; i < filePath.length; i++) {
8
+ const char = filePath[i];
9
+ if (characters.includes(char)) {
10
+ if (word.length)
11
+ result.push(word);
12
+ result.push(char);
13
+ word = '';
14
+ }
15
+ else {
16
+ word += char;
17
+ }
18
+ }
19
+ result.push(word);
20
+ return result;
21
+ }
22
+ exports.parseFilePath = parseFilePath;
23
+ const convertByWords = (str, words) => {
24
+ return parseFilePath(str).map(c => ~words.indexOf(c) ? words.indexOf(c) : c).join('');
25
+ };
26
+ exports.convertByWords = convertByWords;
27
+ function getEstimateSimilarFilePaths(path, files) {
28
+ const wordSet = new Set([path, ...files].map(path => parseFilePath(path)).flat());
29
+ wordSet.delete('.');
30
+ wordSet.delete('/');
31
+ const words = Array.from(wordSet);
32
+ const results = files.map(file => {
33
+ const distance = levenshteinDistance((0, exports.convertByWords)(path, words), (0, exports.convertByWords)(file, words)) + depthDistance(path, file);
34
+ return [distance, file];
35
+ });
36
+ const min = Math.min(...results.map(([distance]) => distance));
37
+ return results.filter(([distance]) => distance === min).map(([_, file]) => file);
38
+ }
39
+ exports.getEstimateSimilarFilePaths = getEstimateSimilarFilePaths;
40
+ function depthDistance(str1, str2) {
41
+ const depth1 = str1.split('/').length;
42
+ const depth2 = str2.split('/').length;
43
+ return Math.abs(depth1 - depth2);
44
+ }
45
+ function levenshteinDistance(str1, str2) {
46
+ const cost = (a, b) => {
47
+ return a === b ? 0 : 1;
48
+ };
49
+ const d = [];
50
+ for (let i = 0; i <= str1.length; i++) {
51
+ d[i] = [];
52
+ d[i][0] = i;
53
+ }
54
+ for (let j = 0; j <= str2.length; j++) {
55
+ d[0][j] = j;
56
+ }
57
+ for (let i = 1; i <= str1.length; i++) {
58
+ for (let j = 1; j <= str2.length; j++) {
59
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost(str1[i - 1], str2[j - 1]));
60
+ }
61
+ }
62
+ return d[str1.length][str2.length];
63
+ }
64
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../libs/schematics/src/gpt3/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { getEstimateSimilarFilePaths, convertByWords, parseFilePath } from './helpers';
2
+
3
+ describe('getEstimateSimilarFilePaths', () => {
4
+ const FILES = [
5
+ '/projects/app/src/styles.scss',
6
+ '/projects/app/src/app/app.component.html',
7
+ '/projects/app/src/app/_shared/components/example/example.module.ts',
8
+ '/projects/app/src/app/_shared/components/example/example.component.html',
9
+ '/projects/app/src/app/_shared/components/example/example.component.scss',
10
+ '/projects/app/src/app/_shared/components/example/example.component.spec.ts',
11
+ '/projects/app/src/app/_shared/components/example/example.component.ts',
12
+ '/projects/app/src/app/_shared/components/example/example.stories.ts',
13
+ '/projects/app/src/app/_shared/components/example/index.ts',
14
+ '/projects/app/src/app/_shared/components/test/test.module.ts',
15
+ '/projects/app/src/app/_shared/components/test/test.component.html',
16
+ '/projects/app/src/app/_shared/components/test/test.component.scss',
17
+ '/projects/app/src/app/_shared/components/test/test.component.spec.ts',
18
+ '/projects/app/src/app/_shared/components/test/test.component.ts',
19
+ '/projects/app/src/app/_shared/components/test/test.stories.ts',
20
+ '/projects/app/src/app/_shared/components/test/index.ts',
21
+ ];
22
+
23
+ it('', () => {
24
+ const file = '/projects/app/src/app/_shared/components/expected/expected.component.ts';
25
+ const files = getEstimateSimilarFilePaths(file, FILES);
26
+ expect(files).toEqual([
27
+ '/projects/app/src/app/_shared/components/example/example.component.ts',
28
+ '/projects/app/src/app/_shared/components/test/test.component.ts',
29
+ ]);
30
+ });
31
+
32
+ it('', () => {
33
+ const file = '/projects/app/src/app/_shared/components/expected/expected.component.html';
34
+ const files = getEstimateSimilarFilePaths(file, FILES);
35
+ expect(files).toEqual([
36
+ '/projects/app/src/app/_shared/components/example/example.component.html',
37
+ '/projects/app/src/app/_shared/components/test/test.component.html',
38
+ ]);
39
+ });
40
+ });
41
+
42
+ describe('parseFilePath', () => {
43
+ it('should parse file path', () => {
44
+ expect(parseFilePath('/projects/app/src/app/_shared/components/example/example.component.ts')).toEqual([
45
+ '/', 'projects', '/', 'app', '/', 'src', '/', 'app', '/', '_shared', '/',
46
+ 'components', '/', 'example', '/', 'example', '.', 'component', '.', 'ts'
47
+ ]);
48
+ });
49
+ });
50
+
51
+ describe('convertByWords', () => {
52
+ xit('should convert from a string to a number', () => {
53
+ expect(convertByWords('this/is/test/path', ['this', 'is', 'test', 'path'])).toBe('0/1/2/3');
54
+ });
55
+ });
56
+
@@ -0,0 +1,6 @@
1
+ import { Rule, FileEntry } from '@angular-devkit/schematics';
2
+ import { Schema } from '../atomic-component/schema';
3
+ export declare const gpt3: (options: Schema) => Rule;
4
+ export declare function completeToJson(text: string): string[];
5
+ export declare function parseJsonCodeBlock(text: string): string[];
6
+ export declare function parseCodeBlocks(text: string): FileEntry[];
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseCodeBlocks = exports.parseJsonCodeBlock = exports.completeToJson = exports.gpt3 = void 0;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const workspace_1 = require("@schematics/angular/utility/workspace");
6
+ const openai_1 = require("openai");
7
+ const path_1 = require("path");
8
+ const helpers_1 = require("./helpers");
9
+ const config = new openai_1.Configuration({ apiKey: process.env['OPEN_AI_TOKEN'] });
10
+ const openai = new openai_1.OpenAIApi(config);
11
+ const gpt3 = (options) => async (tree) => {
12
+ options.path = (0, path_1.join)(await (0, workspace_1.createDefaultPath)(tree, options.project), options?.path ?? '');
13
+ const files = getFiles(tree.root);
14
+ const path = (0, path_1.join)(tree.root.path, options.path, options.name);
15
+ const estimatedFiles = (0, path_1.parse)(path).ext.length ? [path] : await getPredicatedFiles(files, path);
16
+ for (const file of estimatedFiles) {
17
+ const fileEntries = (0, helpers_1.getEstimateSimilarFilePaths)(file, files).map(file => tree.get(file));
18
+ const fileEntry = await getPredicatedFileEntry(file, fileEntries);
19
+ tree.create(file, fileEntry.content);
20
+ }
21
+ return (0, schematics_1.chain)([]);
22
+ };
23
+ exports.gpt3 = gpt3;
24
+ async function getPredicatedFiles(files, dirPath) {
25
+ const fileStart = dirPath.split('/').slice(-1)[0];
26
+ const prompt = makeDirectoryPrompt(files, (0, path_1.join)(dirPath, fileStart));
27
+ const res = await openai.createCompletion({
28
+ model: 'code-davinci-002',
29
+ prompt,
30
+ temperature: 0,
31
+ max_tokens: 512,
32
+ stop: '\n\`\`\`',
33
+ });
34
+ const results = completeToJson(`${prompt}${res.data.choices?.[0].text}`);
35
+ return results.filter(result => result.startsWith(dirPath));
36
+ }
37
+ async function getPredicatedFileEntry(path, fileEntries = []) {
38
+ const prompt = makeFilePrompt(fileEntries, path);
39
+ const res = await openai.createCompletion({
40
+ model: 'code-davinci-002',
41
+ prompt,
42
+ temperature: 0,
43
+ max_tokens: 256,
44
+ stop: '\n\`\`\`',
45
+ });
46
+ const entries = parseCodeBlocks(`${prompt}${res.data.choices?.[0].text}`);
47
+ return entries.find(entry => entry.path === path);
48
+ }
49
+ function makeDirectoryPrompt(files, name) {
50
+ return `\n\`\`\`tree.json\n[\n${files.map(file => `\t\"${file}\",`).join('\n')}\n\t\"${name}`;
51
+ }
52
+ function makeFilePrompt(files, path) {
53
+ return `${makeFileCodeBlocks(files)}\n\n\`\`\`${path}\n`;
54
+ }
55
+ function makeFileCodeBlocks(files) {
56
+ return files.map(file => makeFileCodeBlock(file.path, file.content.toString())).join('\n\n');
57
+ }
58
+ function makeFileCodeBlock(name, content) {
59
+ return `\`\`\`${name}\n${content}\n\`\`\``;
60
+ }
61
+ function completeToJson(text) {
62
+ while (text.length) {
63
+ let suffixes = ['"]\n```', ']\n```', '\n```', '```', '``', '`', ''];
64
+ for (const suffix of suffixes) {
65
+ try {
66
+ return parseJsonCodeBlock(text + suffix);
67
+ }
68
+ catch { }
69
+ }
70
+ text = text.slice(0, -1);
71
+ }
72
+ }
73
+ exports.completeToJson = completeToJson;
74
+ function parseJsonCodeBlock(text) {
75
+ const code = getCodeBlocks(text);
76
+ return JSON.parse(code);
77
+ }
78
+ exports.parseJsonCodeBlock = parseJsonCodeBlock;
79
+ function getCodeBlocks(text) {
80
+ return text.match(/\`\`\`tree\.json\n([\s\S]*)\`\`\`/)?.[1];
81
+ }
82
+ function parseCodeBlocks(text) {
83
+ return text.split('```').filter((_, i) => i % 2).map(code => {
84
+ const [path, ...lines] = code.split('\n');
85
+ return { path, content: Buffer.from(lines.join('\n')) };
86
+ });
87
+ }
88
+ exports.parseCodeBlocks = parseCodeBlocks;
89
+ function getFiles(dir) {
90
+ const files = [];
91
+ walkDir(dir, (path, entry) => entry.subfiles.forEach(file => files.push(`${path}/${file}`)));
92
+ return files;
93
+ }
94
+ function walkDir(dir, callback, parent = '/') {
95
+ dir.subdirs.forEach(path => {
96
+ const entry = dir.dir(path);
97
+ callback((0, path_1.join)(parent, path), entry);
98
+ walkDir(entry, callback, (0, path_1.join)(parent, path));
99
+ });
100
+ }
101
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/schematics/src/gpt3/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
2
+ import path from 'path';
3
+ import { createWorkspace } from '../_testing';
4
+ import { parseJsonCodeBlock, parseCodeBlocks } from './index';
5
+
6
+ jest.setTimeout(300 * 1000);
7
+
8
+ const COLLECTION_PATH = path.join(__dirname, '../../collection.json');
9
+
10
+ describe('Gpt Schematics', () => {
11
+ const runner = new SchematicTestRunner('@ng-atomic/schematics', COLLECTION_PATH);
12
+ let tree: UnitTestTree;
13
+
14
+ describe('Angular Workspace', () => {
15
+ beforeEach(async () => {
16
+ tree = await createWorkspace(runner, tree);
17
+ tree = await runner.runSchematicAsync('atomic-component', {
18
+ project: 'app', path: '_shared/components', name: 'example'
19
+ }, tree).toPromise();
20
+
21
+ tree = await runner.runSchematicAsync('atomic-component', {
22
+ project: 'app', path: '_shared/components', name: 'test'
23
+ }, tree).toPromise();
24
+
25
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.module.ts');
26
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.component.html');
27
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.component.scss');
28
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.component.spec.ts');
29
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.component.ts');
30
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/example.stories.ts');
31
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/example/index.ts');
32
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.module.ts');
33
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.component.html');
34
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.component.scss');
35
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.component.spec.ts');
36
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.component.ts');
37
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/test.stories.ts');
38
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/test/index.ts');
39
+ });
40
+
41
+ xit('should create atomic component files', async () => {
42
+ tree = await runner.runSchematicAsync('gpt3', {
43
+ project: 'app', path: '_shared/components', name: 'expected'
44
+ }, tree).toPromise();
45
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.module.ts');
46
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.component.html');
47
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.component.scss');
48
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.component.spec.ts');
49
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.component.ts');
50
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.stories.ts');
51
+ // expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/index.ts');
52
+ });
53
+
54
+ xit('should create atomic component files', async () => {
55
+ tree = await runner.runSchematicAsync('gpt3', {
56
+ project: 'app', path: '_shared/components/', name: 'expected/expected.module.ts'
57
+ }, tree).toPromise();
58
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.module.ts');
59
+ });
60
+
61
+ it('should create atomic component files', async () => {
62
+ tree = await runner.runSchematicAsync('gpt3', {
63
+ project: 'app', path: '', name: '_shared/components/expected/expected.module.ts'
64
+ }, tree).toPromise();
65
+ expect(tree.files).toContain('/projects/app/src/app/_shared/components/expected/expected.module.ts');
66
+ });
67
+ });
68
+ });
69
+
70
+
71
+ const TEST = `
72
+ \`\`\`tree.json
73
+ []
74
+ \`\`\`
75
+ `;
76
+
77
+ // describe('completeToJson', () => {
78
+ // xit('should convert to json', () => {
79
+ // expect(completeToJson(TEST)).toBeTruthy();
80
+ // });
81
+ // });
82
+
83
+ describe('parseJsonCodeBlock', () => {
84
+ it('should parse json code block', () => {
85
+ expect(parseJsonCodeBlock(TEST)).toBeTruthy();
86
+ });
87
+ });
88
+
89
+
90
+ const CODE_BLOCKS = `
91
+ \`\`\`/projects/app/src/app/_shared/components/test/test.component.ts
92
+ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
93
+
94
+ @Component({
95
+ selector: 'undefineds-test',
96
+ templateUrl: './test.component.html',
97
+ styleUrls: ['./test.component.scss'],
98
+ changeDetection: ChangeDetectionStrategy.OnPush
99
+ })
100
+ export class TestComponent implements OnInit {
101
+
102
+ constructor() { }
103
+
104
+ ngOnInit(): void {
105
+ }
106
+
107
+ }
108
+
109
+ \`\`\`
110
+
111
+ \`\`\`/projects/app/src/app/_shared/components/example/example.component.ts
112
+ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
113
+
114
+ @Component({
115
+ selector: 'undefineds-example',
116
+ templateUrl: './example.component.html',
117
+ styleUrls: ['./example.component.scss'],
118
+ changeDetection: ChangeDetectionStrategy.OnPush
119
+ })
120
+ export class ExampleComponent implements OnInit {
121
+
122
+ constructor() { }
123
+
124
+ ngOnInit(): void {
125
+ }
126
+
127
+ }
128
+
129
+ \`\`\`
130
+
131
+ \`\`\`/projects/app/src/app/_shared/components/expected/expected.component.ts
132
+ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
133
+
134
+ @Component({
135
+ selector: 'undefineds-expected',
136
+ templateUrl: './expected.component.html',
137
+ styleUrls: ['./expected.component.scss'],
138
+ changeDetection: ChangeDetectionStrategy.OnPush
139
+ })
140
+ export class ExpectedComponent implements OnInit {
141
+
142
+ constructor() { }
143
+
144
+ ngOnInit(): void {
145
+ }
146
+
147
+ }
148
+
149
+ \`\`\`
150
+ `;
151
+
152
+ describe('parseCodeBlocks', () => {
153
+ it('should parse code blocks', () => {
154
+ expect(parseCodeBlocks(CODE_BLOCKS)).toBeTruthy();
155
+ });
156
+ });
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "ng-atomic-schematics-gpt3",
4
+ "title": "Angular Atomic Schematics GPT3",
5
+ "type": "object",
6
+ "properties": {
7
+ "path": {
8
+ "type": "string",
9
+ "format": "path",
10
+ "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
11
+ "visible": false
12
+ },
13
+ "project": {
14
+ "type": "string",
15
+ "description": "The name of the project.",
16
+ "$default": {
17
+ "$source": "projectName"
18
+ }
19
+ },
20
+ "name": {
21
+ "type": "string",
22
+ "description": "The name of the anything.",
23
+ "$default": {
24
+ "$source": "argv",
25
+ "index": 0
26
+ },
27
+ "x-prompt": "What name would you like to generate?"
28
+ }
29
+ },
30
+ "required": []
31
+ }