@neurodevs/meta-node 0.0.1 → 0.1.0

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 (48) hide show
  1. package/build/__tests__/modules/NodeAutomodule.test.d.ts +20 -0
  2. package/build/__tests__/modules/NodeAutomodule.test.js +166 -0
  3. package/build/__tests__/modules/NodeAutomodule.test.js.map +1 -0
  4. package/build/__tests__/modules/PackageJsonUpdater.test.d.ts +7 -0
  5. package/build/__tests__/modules/PackageJsonUpdater.test.js +63 -0
  6. package/build/__tests__/modules/PackageJsonUpdater.test.js.map +1 -0
  7. package/build/index.d.ts +8 -2
  8. package/build/index.js +17 -6
  9. package/build/index.js.map +1 -1
  10. package/build/modules/GitAutocloner.d.ts +5 -6
  11. package/build/modules/GitAutocloner.js +14 -17
  12. package/build/modules/GitAutocloner.js.map +1 -1
  13. package/build/modules/NodeAutomodule.d.ts +34 -0
  14. package/build/modules/NodeAutomodule.js +102 -0
  15. package/build/modules/NodeAutomodule.js.map +1 -0
  16. package/build/modules/PackageJsonUpdater.d.ts +8 -0
  17. package/build/modules/PackageJsonUpdater.js +10 -0
  18. package/build/modules/PackageJsonUpdater.js.map +1 -0
  19. package/build/modules/pathExists.d.ts +1 -0
  20. package/build/modules/pathExists.js +14 -0
  21. package/build/modules/pathExists.js.map +1 -0
  22. package/build/scripts/runAutomodule.d.ts +1 -0
  23. package/build/scripts/runAutomodule.js +22 -0
  24. package/build/scripts/runAutomodule.js.map +1 -0
  25. package/build/scripts/runAutopackage.js +3 -3
  26. package/build/scripts/runAutopackage.js.map +1 -1
  27. package/build/testDoubles/Automodule/FakeAutomodule.d.ts +8 -0
  28. package/build/testDoubles/Automodule/FakeAutomodule.js +18 -0
  29. package/build/testDoubles/Automodule/FakeAutomodule.js.map +1 -0
  30. package/build/testDoubles/fs/fakePathExists.d.ts +3 -0
  31. package/build/testDoubles/fs/fakePathExists.js +13 -0
  32. package/build/testDoubles/fs/fakePathExists.js.map +1 -0
  33. package/build/testDoubles/fs/fakeWriteFile.d.ts +6 -0
  34. package/build/testDoubles/fs/fakeWriteFile.js +13 -0
  35. package/build/testDoubles/fs/fakeWriteFile.js.map +1 -0
  36. package/package.json +1 -1
  37. package/src/__tests__/modules/NodeAutomodule.test.ts +160 -0
  38. package/src/__tests__/modules/PackageJsonUpdater.test.ts +23 -0
  39. package/src/index.ts +18 -5
  40. package/src/modules/GitAutocloner.ts +18 -22
  41. package/src/modules/NodeAutomodule.ts +136 -0
  42. package/src/modules/PackageJsonUpdater.ts +13 -0
  43. package/src/modules/pathExists.ts +10 -0
  44. package/src/scripts/runAutomodule.ts +22 -0
  45. package/src/scripts/runAutopackage.ts +3 -3
  46. package/src/testDoubles/Automodule/FakeAutomodule.ts +19 -0
  47. package/src/testDoubles/fs/fakePathExists.ts +9 -0
  48. package/src/testDoubles/fs/fakeWriteFile.ts +9 -0
@@ -0,0 +1,22 @@
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
+ const NodeAutomodule_1 = __importDefault(require("../modules/NodeAutomodule"));
7
+ async function main() {
8
+ console.log('\nRunning automodule...');
9
+ const instance = NodeAutomodule_1.default.Create({
10
+ testSaveDir: '/Users/ericthecurious/dev/meta-node/src/__tests__/modules',
11
+ moduleSaveDir: '/Users/ericthecurious/dev/meta-node/src/modules',
12
+ interfaceName: 'Autocomponent',
13
+ implName: 'ReactAutocomponent',
14
+ });
15
+ await instance.run();
16
+ console.log('Finished running automodule!\n');
17
+ }
18
+ main().catch((err) => {
19
+ console.error(err);
20
+ process.exit(1);
21
+ });
22
+ //# sourceMappingURL=runAutomodule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runAutomodule.js","sourceRoot":"","sources":["../../src/scripts/runAutomodule.ts"],"names":[],"mappings":";;;;;AAAA,+EAAsD;AAEtD,KAAK,UAAU,IAAI;IACf,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;IAEtC,MAAM,QAAQ,GAAG,wBAAc,CAAC,MAAM,CAAC;QACnC,WAAW,EACP,2DAA2D;QAC/D,aAAa,EAAE,iDAAiD;QAChE,aAAa,EAAE,eAAe;QAC9B,QAAQ,EAAE,oBAAoB;KACjC,CAAC,CAAA;IAEF,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAA;IAEpB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC,CAAC,CAAA"}
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const child_process_1 = require("child_process");
7
7
  const NpmAutopackage_1 = __importDefault(require("../modules/NpmAutopackage"));
8
- async function run() {
9
- console.log('Running...');
8
+ async function main() {
9
+ console.log('Running autopackage...');
10
10
  await NpmAutopackage_1.default.Create({
11
11
  name: 'node-xyz',
12
12
  description: 'XYZ, yo',
@@ -19,7 +19,7 @@ async function run() {
19
19
  console.log('Done!');
20
20
  process.exit(0);
21
21
  }
22
- run().catch((err) => {
22
+ main().catch((err) => {
23
23
  console.error(err);
24
24
  process.exit(1);
25
25
  });
@@ -1 +1 @@
1
- {"version":3,"file":"runAutopackage.js","sourceRoot":"","sources":["../../src/scripts/runAutopackage.ts"],"names":[],"mappings":";;;;;AAAA,iDAAwC;AACxC,+EAAsD;AAEtD,KAAK,UAAU,GAAG;IACd,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAEzB,MAAM,wBAAc,CAAC,MAAM,CAAC;QACxB,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,SAAS;QACtB,YAAY,EAAE,WAAW;QACzB,YAAY,EAAE,WAAW;QACzB,UAAU,EAAE,2BAA2B;KAC1C,CAAC,CAAA;IAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;IACnC,IAAA,wBAAQ,EAAC,QAAQ,CAAC,CAAA;IAClB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAEpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"runAutopackage.js","sourceRoot":"","sources":["../../src/scripts/runAutopackage.ts"],"names":[],"mappings":";;;;;AAAA,iDAAwC;AACxC,+EAAsD;AAEtD,KAAK,UAAU,IAAI;IACf,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;IAErC,MAAM,wBAAc,CAAC,MAAM,CAAC;QACxB,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,SAAS;QACtB,YAAY,EAAE,WAAW;QACzB,YAAY,EAAE,WAAW;QACzB,UAAU,EAAE,2BAA2B;KAC1C,CAAC,CAAA;IAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;IACnC,IAAA,wBAAQ,EAAC,QAAQ,CAAC,CAAA;IAClB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAEpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { Automodule, AutomoduleOptions } from '../../modules/NodeAutomodule';
2
+ export default class FakeAutomodule implements Automodule {
3
+ static callsToConstructor: AutomoduleOptions[];
4
+ static numCallsToRun: number;
5
+ constructor(options: AutomoduleOptions);
6
+ run(): Promise<void>;
7
+ static resetTestDouble(): void;
8
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class FakeAutomodule {
4
+ constructor(options) {
5
+ FakeAutomodule.callsToConstructor.push(options);
6
+ }
7
+ async run() {
8
+ FakeAutomodule.numCallsToRun++;
9
+ }
10
+ static resetTestDouble() {
11
+ this.callsToConstructor = [];
12
+ this.numCallsToRun = 0;
13
+ }
14
+ }
15
+ FakeAutomodule.callsToConstructor = [];
16
+ FakeAutomodule.numCallsToRun = 0;
17
+ exports.default = FakeAutomodule;
18
+ //# sourceMappingURL=FakeAutomodule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FakeAutomodule.js","sourceRoot":"","sources":["../../../src/testDoubles/Automodule/FakeAutomodule.ts"],"names":[],"mappings":";;AAEA,MAAqB,cAAc;IAI/B,YAAmB,OAA0B;QACzC,cAAc,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACnD,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,cAAc,CAAC,aAAa,EAAE,CAAA;IAClC,CAAC;IAEM,MAAM,CAAC,eAAe;QACzB,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAA;QAC5B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAA;IAC1B,CAAC;;AAda,iCAAkB,GAAwB,EAAE,CAAA;AAC5C,4BAAa,GAAG,CAAC,CAAA;kBAFd,cAAc"}
@@ -0,0 +1,3 @@
1
+ export declare let pathShouldExist: Record<string, boolean>;
2
+ export declare function setPathShouldExist(path: string, shouldExist: boolean): void;
3
+ export default function fakePathExists(path: string): Promise<boolean>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pathShouldExist = void 0;
4
+ exports.setPathShouldExist = setPathShouldExist;
5
+ exports.default = fakePathExists;
6
+ exports.pathShouldExist = {};
7
+ function setPathShouldExist(path, shouldExist) {
8
+ exports.pathShouldExist[path] = shouldExist;
9
+ }
10
+ async function fakePathExists(path) {
11
+ return exports.pathShouldExist[path];
12
+ }
13
+ //# sourceMappingURL=fakePathExists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fakePathExists.js","sourceRoot":"","sources":["../../../src/testDoubles/fs/fakePathExists.ts"],"names":[],"mappings":";;;AAEA,gDAEC;AAED,iCAEC;AARU,QAAA,eAAe,GAA4B,EAAE,CAAA;AAExD,SAAgB,kBAAkB,CAAC,IAAY,EAAE,WAAoB;IACjE,uBAAe,CAAC,IAAI,CAAC,GAAG,WAAW,CAAA;AACvC,CAAC;AAEc,KAAK,UAAU,cAAc,CAAC,IAAY;IACrD,OAAO,uBAAe,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare let callsToWriteFile: {
2
+ file: string;
3
+ data: string;
4
+ }[];
5
+ export declare function resetCallsToWriteFile(): void;
6
+ export default function fakeWriteFile(file: string, data: string): Promise<void>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.callsToWriteFile = void 0;
4
+ exports.resetCallsToWriteFile = resetCallsToWriteFile;
5
+ exports.default = fakeWriteFile;
6
+ exports.callsToWriteFile = [];
7
+ function resetCallsToWriteFile() {
8
+ exports.callsToWriteFile = [];
9
+ }
10
+ async function fakeWriteFile(file, data) {
11
+ exports.callsToWriteFile.push({ file, data });
12
+ }
13
+ //# sourceMappingURL=fakeWriteFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fakeWriteFile.js","sourceRoot":"","sources":["../../../src/testDoubles/fs/fakeWriteFile.ts"],"names":[],"mappings":";;;AAEA,sDAEC;AAED,gCAEC;AARU,QAAA,gBAAgB,GAAqC,EAAE,CAAA;AAElE,SAAgB,qBAAqB;IACjC,wBAAgB,GAAG,EAAE,CAAA;AACzB,CAAC;AAEc,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,IAAY;IAClE,wBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neurodevs/meta-node",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Meta-layer utilities for maintaining Node.js package ecosystems.",
5
5
  "repository": "https://github.com/neurodevs/meta-node.git",
6
6
  "main": "build/index.js",
@@ -0,0 +1,160 @@
1
+ import { writeFile } from 'fs/promises'
2
+ import AbstractSpruceTest, {
3
+ test,
4
+ assert,
5
+ generateId,
6
+ } from '@sprucelabs/test-utils'
7
+ import NodeAutomodule, { Automodule } from '../../modules/NodeAutomodule'
8
+ import fakePathExists, {
9
+ setPathShouldExist,
10
+ } from '../../testDoubles/fs/fakePathExists'
11
+ import fakeWriteFile, {
12
+ callsToWriteFile,
13
+ resetCallsToWriteFile,
14
+ } from '../../testDoubles/fs/fakeWriteFile'
15
+
16
+ export default class NodeAutomoduleTest extends AbstractSpruceTest {
17
+ private static instance: Automodule
18
+
19
+ protected static async beforeEach() {
20
+ await super.beforeEach()
21
+
22
+ this.setFakePathExists()
23
+ this.setFakeWriteFile()
24
+
25
+ this.instance = this.NodeAutomodule()
26
+ }
27
+
28
+ @test()
29
+ protected static async createsInstance() {
30
+ assert.isTruthy(this.instance, 'Failed to create instance!')
31
+ }
32
+
33
+ @test()
34
+ protected static async runThrowsIfTestSaveDirMissing() {
35
+ setPathShouldExist(this.testSaveDir, false)
36
+
37
+ const err = await assert.doesThrowAsync(async () => await this.run())
38
+
39
+ assert.isEqual(
40
+ err.message,
41
+ `testSaveDir does not exist: ${this.testSaveDir}!`,
42
+ 'Did not receive the expected error!'
43
+ )
44
+ }
45
+
46
+ @test()
47
+ protected static async runThrowsIfModuleSaveDirMissing() {
48
+ setPathShouldExist(this.moduleSaveDir, false)
49
+
50
+ const err = await assert.doesThrowAsync(async () => await this.run())
51
+
52
+ assert.isEqual(
53
+ err.message,
54
+ `moduleSaveDir does not exist: ${this.moduleSaveDir}!`,
55
+ 'Did not receive the expected error!'
56
+ )
57
+ }
58
+
59
+ @test()
60
+ protected static async createsTestFileAsExpected() {
61
+ await this.run()
62
+
63
+ assert.isEqualDeep(
64
+ callsToWriteFile[0],
65
+ {
66
+ file: `${this.testSaveDir}/${this.implName}.test.ts`,
67
+ data: this.testFilePattern,
68
+ },
69
+ 'Did not write expected test file!'
70
+ )
71
+ }
72
+
73
+ @test()
74
+ protected static async createsModuleFileAsExpected() {
75
+ await this.run()
76
+
77
+ assert.isEqualDeep(
78
+ callsToWriteFile[1],
79
+ {
80
+ file: `${this.moduleSaveDir}/${this.implName}.ts`,
81
+ data: this.moduleFilePattern,
82
+ },
83
+ 'Did not write expected module file!'
84
+ )
85
+ }
86
+
87
+ private static async run() {
88
+ return await this.instance.run()
89
+ }
90
+
91
+ private static setFakePathExists() {
92
+ NodeAutomodule.pathExists = fakePathExists
93
+
94
+ setPathShouldExist(this.testSaveDir, true)
95
+ setPathShouldExist(this.moduleSaveDir, true)
96
+ }
97
+
98
+ private static setFakeWriteFile() {
99
+ NodeAutomodule.writeFile = fakeWriteFile as typeof writeFile
100
+ resetCallsToWriteFile()
101
+ }
102
+
103
+ private static readonly testSaveDir = generateId()
104
+ private static readonly moduleSaveDir = generateId()
105
+ private static readonly interfaceName = generateId()
106
+ private static readonly implName = generateId()
107
+
108
+ private static get testFilePattern() {
109
+ return `
110
+ import AbstractSpruceTest, { test, assert } from '@sprucelabs/test-utils'
111
+ import ${this.implName}, { ${this.interfaceName} } from '../../modules/${this.implName}'
112
+
113
+ export default class ${this.implName}Test extends AbstractSpruceTest {
114
+ private static instance: ${this.interfaceName}
115
+
116
+ protected static async beforeEach() {
117
+ await super.beforeEach()
118
+
119
+ this.instance = this.${this.implName}()
120
+ }
121
+
122
+ @test()
123
+ protected static async createsInstance() {
124
+ assert.isTruthy(this.instance, 'Failed to create instance!')
125
+ }
126
+
127
+ private static ${this.implName}() {
128
+ return ${this.implName}.Create()
129
+ }
130
+ }
131
+ `
132
+ }
133
+
134
+ private static get moduleFilePattern() {
135
+ return `
136
+ export default class ${this.implName} implements ${this.interfaceName} {
137
+ public static Class?: ${this.interfaceName}Constructor
138
+
139
+ protected constructor() {}
140
+
141
+ public static Create() {
142
+ return new (this.Class ?? this)()
143
+ }
144
+ }
145
+
146
+ export interface ${this.interfaceName} {}
147
+
148
+ export type ${this.interfaceName}Constructor = new () => ${this.interfaceName}
149
+ `
150
+ }
151
+
152
+ private static NodeAutomodule() {
153
+ return NodeAutomodule.Create({
154
+ testSaveDir: this.testSaveDir,
155
+ moduleSaveDir: this.moduleSaveDir,
156
+ interfaceName: this.interfaceName,
157
+ implName: this.implName,
158
+ })
159
+ }
160
+ }
@@ -0,0 +1,23 @@
1
+ import AbstractSpruceTest, { test, assert } from '@sprucelabs/test-utils'
2
+ import PackageJsonUpdater, {
3
+ JsonUpdater,
4
+ } from '../../modules/PackageJsonUpdater'
5
+
6
+ export default class PackageJsonUpdaterTest extends AbstractSpruceTest {
7
+ private static instance: JsonUpdater
8
+
9
+ protected static async beforeEach() {
10
+ await super.beforeEach()
11
+
12
+ this.instance = this.PackageJsonUpdater()
13
+ }
14
+
15
+ @test()
16
+ protected static async createsInstance() {
17
+ assert.isTruthy(this.instance, 'Failed to create instance!')
18
+ }
19
+
20
+ private static PackageJsonUpdater() {
21
+ return PackageJsonUpdater.Create()
22
+ }
23
+ }
package/src/index.ts CHANGED
@@ -1,8 +1,3 @@
1
- // Autopackage
2
-
3
- export { default as NpmAutopackage } from './modules/NpmAutopackage'
4
- export * from './modules/NpmAutopackage'
5
-
6
1
  // Autocloner
7
2
 
8
3
  export { default as GitAutocloner } from './modules/GitAutocloner'
@@ -10,3 +5,21 @@ export * from './modules/GitAutocloner'
10
5
 
11
6
  export { default as FakeAutocloner } from './testDoubles/Autocloner/FakeAutocloner'
12
7
  export * from './testDoubles/Autocloner/FakeAutocloner'
8
+
9
+ // Automodule
10
+
11
+ export { default as NodeAutomodule } from './modules/NodeAutomodule'
12
+ export * from './modules/NodeAutomodule'
13
+
14
+ export { default as FakeAutomodule } from './testDoubles/Automodule/FakeAutomodule'
15
+ export * from './testDoubles/Automodule/FakeAutomodule'
16
+
17
+ // Autopackage
18
+
19
+ export { default as NpmAutopackage } from './modules/NpmAutopackage'
20
+ export * from './modules/NpmAutopackage'
21
+
22
+ // PackageJsonUpdater
23
+
24
+ export { default as PackageJsonUpdater } from './modules/PackageJsonUpdater'
25
+ export * from './modules/PackageJsonUpdater'
@@ -32,12 +32,16 @@ export default class GitAutocloner implements Autocloner {
32
32
 
33
33
  private throwIfDirPathDoesNotExist() {
34
34
  if (!this.dirPathExists) {
35
- throw new Error(this.dirPathDoesNotExistMessage)
35
+ this.throwDirPathDoesNotExist()
36
36
  }
37
37
  }
38
38
 
39
- private get dirPathDoesNotExistMessage() {
40
- return `dirPath does not exist: ${this.dirPath}!`
39
+ private get dirPathExists() {
40
+ return this.existsSync(this.dirPath)
41
+ }
42
+
43
+ private throwDirPathDoesNotExist() {
44
+ throw new Error(`dirPath does not exist: ${this.dirPath}!`)
41
45
  }
42
46
 
43
47
  private changeDirectoryToDirPath() {
@@ -55,10 +59,20 @@ export default class GitAutocloner implements Autocloner {
55
59
  if (!this.currentRepoExists) {
56
60
  this.tryToCloneRepo()
57
61
  } else {
58
- this.log.info(this.repoExistsMessage)
62
+ this.log.info(`Repo exists, skipping: ${this.currentRepoName}!`)
59
63
  }
60
64
  }
61
65
 
66
+ private get currentRepoExists() {
67
+ return this.existsSync(this.currentRepoName)
68
+ }
69
+
70
+ private get currentRepoName() {
71
+ return this.currentUrl.match(this.regexForRepoName)![1]
72
+ }
73
+
74
+ private readonly regexForRepoName = /\/([a-zA-Z0-9_.-]+)\.git/
75
+
62
76
  private tryToCloneRepo() {
63
77
  try {
64
78
  this.execSync(`git clone ${this.currentUrl}`)
@@ -76,22 +90,6 @@ export default class GitAutocloner implements Autocloner {
76
90
  return `Git clone failed for repo: ${this.currentUrl}!\n\n${this.currentError}\n\n`
77
91
  }
78
92
 
79
- private get dirPathExists() {
80
- return this.existsSync(this.dirPath)
81
- }
82
-
83
- private get currentRepoName() {
84
- return this.currentUrl.match(this.regex)![1]
85
- }
86
-
87
- private get currentRepoExists() {
88
- return this.existsSync(this.currentRepoName)
89
- }
90
-
91
- private get repoExistsMessage() {
92
- return `Repo already exists, skipping: ${this.currentRepoName}!`
93
- }
94
-
95
93
  private get existsSync() {
96
94
  return GitAutocloner.existsSync
97
95
  }
@@ -99,8 +97,6 @@ export default class GitAutocloner implements Autocloner {
99
97
  private get execSync() {
100
98
  return GitAutocloner.execSync
101
99
  }
102
-
103
- private readonly regex = /\/([a-zA-Z0-9_.-]+)\.git/
104
100
  }
105
101
 
106
102
  export interface Autocloner {
@@ -0,0 +1,136 @@
1
+ import { writeFile } from 'fs/promises'
2
+ import path from 'path'
3
+ import pathExists from './pathExists'
4
+
5
+ export default class NodeAutomodule implements Automodule {
6
+ public static Class?: AutomoduleConstructor
7
+ public static pathExists = pathExists
8
+ public static writeFile = writeFile
9
+
10
+ private testSaveDir: string
11
+ private moduleSaveDir: string
12
+ private interfaceName: string
13
+ private implName: string
14
+
15
+ protected constructor(options: AutomoduleOptions) {
16
+ const { testSaveDir, moduleSaveDir, interfaceName, implName } = options
17
+
18
+ this.testSaveDir = testSaveDir
19
+ this.moduleSaveDir = moduleSaveDir
20
+ this.interfaceName = interfaceName
21
+ this.implName = implName
22
+ }
23
+
24
+ public static Create(options: AutomoduleOptions) {
25
+ return new (this.Class ?? this)(options)
26
+ }
27
+
28
+ public async run() {
29
+ await this.throwIfTestDirDoesNotExist()
30
+ await this.throwIfModuleDirDoesNotExist()
31
+
32
+ await this.createTestFile()
33
+ await this.createModuleFile()
34
+ }
35
+
36
+ private async throwIfTestDirDoesNotExist() {
37
+ const testDirExists = await this.pathExists(this.testSaveDir)
38
+
39
+ if (!testDirExists) {
40
+ throw new Error(`testSaveDir does not exist: ${this.testSaveDir}!`)
41
+ }
42
+ }
43
+
44
+ private async throwIfModuleDirDoesNotExist() {
45
+ const moduleDirExists = await this.pathExists(this.moduleSaveDir)
46
+
47
+ if (!moduleDirExists) {
48
+ throw new Error(
49
+ `moduleSaveDir does not exist: ${this.moduleSaveDir}!`
50
+ )
51
+ }
52
+ }
53
+
54
+ private async createTestFile() {
55
+ await this.writeFile(this.testFileName, this.testFilePattern)
56
+ }
57
+
58
+ private get testFileName() {
59
+ return path.join(this.testSaveDir, `${this.implName}.test.ts`)
60
+ }
61
+
62
+ private async createModuleFile() {
63
+ await this.writeFile(this.moduleFileName, this.moduleFilePattern)
64
+ }
65
+
66
+ private get moduleFileName() {
67
+ return path.join(this.moduleSaveDir, `${this.implName}.ts`)
68
+ }
69
+
70
+ private get pathExists() {
71
+ return NodeAutomodule.pathExists
72
+ }
73
+
74
+ private get writeFile() {
75
+ return NodeAutomodule.writeFile
76
+ }
77
+
78
+ private get testFilePattern() {
79
+ return `
80
+ import AbstractSpruceTest, { test, assert } from '@sprucelabs/test-utils'
81
+ import ${this.implName}, { ${this.interfaceName} } from '../../modules/${this.implName}'
82
+
83
+ export default class ${this.implName}Test extends AbstractSpruceTest {
84
+ private static instance: ${this.interfaceName}
85
+
86
+ protected static async beforeEach() {
87
+ await super.beforeEach()
88
+
89
+ this.instance = this.${this.implName}()
90
+ }
91
+
92
+ @test()
93
+ protected static async createsInstance() {
94
+ assert.isTruthy(this.instance, 'Failed to create instance!')
95
+ }
96
+
97
+ private static ${this.implName}() {
98
+ return ${this.implName}.Create()
99
+ }
100
+ }
101
+ `
102
+ }
103
+
104
+ private get moduleFilePattern() {
105
+ return `
106
+ export default class ${this.implName} implements ${this.interfaceName} {
107
+ public static Class?: ${this.interfaceName}Constructor
108
+
109
+ protected constructor() {}
110
+
111
+ public static Create() {
112
+ return new (this.Class ?? this)()
113
+ }
114
+ }
115
+
116
+ export interface ${this.interfaceName} {}
117
+
118
+ export type ${this.interfaceName}Constructor = new () => ${this.interfaceName}
119
+ `
120
+ }
121
+ }
122
+
123
+ export interface Automodule {
124
+ run(): Promise<void>
125
+ }
126
+
127
+ export type AutomoduleConstructor = new (
128
+ options: AutomoduleOptions
129
+ ) => Automodule
130
+
131
+ export interface AutomoduleOptions {
132
+ testSaveDir: string
133
+ moduleSaveDir: string
134
+ interfaceName: string
135
+ implName: string
136
+ }
@@ -0,0 +1,13 @@
1
+ export default class PackageJsonUpdater implements JsonUpdater {
2
+ public static Class?: JsonUpdateConstructor
3
+
4
+ protected constructor() {}
5
+
6
+ public static Create() {
7
+ return new (this.Class ?? this)()
8
+ }
9
+ }
10
+
11
+ export interface JsonUpdater {}
12
+
13
+ export type JsonUpdateConstructor = new () => JsonUpdater
@@ -0,0 +1,10 @@
1
+ import { access } from 'fs/promises'
2
+
3
+ export default async function pathExists(path: string) {
4
+ try {
5
+ await access(path)
6
+ return true
7
+ } catch {
8
+ return false
9
+ }
10
+ }
@@ -0,0 +1,22 @@
1
+ import NodeAutomodule from '../modules/NodeAutomodule'
2
+
3
+ async function main() {
4
+ console.log('\nRunning automodule...')
5
+
6
+ const instance = NodeAutomodule.Create({
7
+ testSaveDir:
8
+ '/Users/ericthecurious/dev/meta-node/src/__tests__/modules',
9
+ moduleSaveDir: '/Users/ericthecurious/dev/meta-node/src/modules',
10
+ interfaceName: 'Autocomponent',
11
+ implName: 'ReactAutocomponent',
12
+ })
13
+
14
+ await instance.run()
15
+
16
+ console.log('Finished running automodule!\n')
17
+ }
18
+
19
+ main().catch((err) => {
20
+ console.error(err)
21
+ process.exit(1)
22
+ })
@@ -1,8 +1,8 @@
1
1
  import { execSync } from 'child_process'
2
2
  import NpmAutopackage from '../modules/NpmAutopackage'
3
3
 
4
- async function run() {
5
- console.log('Running...')
4
+ async function main() {
5
+ console.log('Running autopackage...')
6
6
 
7
7
  await NpmAutopackage.Create({
8
8
  name: 'node-xyz',
@@ -19,7 +19,7 @@ async function run() {
19
19
  process.exit(0)
20
20
  }
21
21
 
22
- run().catch((err) => {
22
+ main().catch((err) => {
23
23
  console.error(err)
24
24
  process.exit(1)
25
25
  })
@@ -0,0 +1,19 @@
1
+ import { Automodule, AutomoduleOptions } from '../../modules/NodeAutomodule'
2
+
3
+ export default class FakeAutomodule implements Automodule {
4
+ public static callsToConstructor: AutomoduleOptions[] = []
5
+ public static numCallsToRun = 0
6
+
7
+ public constructor(options: AutomoduleOptions) {
8
+ FakeAutomodule.callsToConstructor.push(options)
9
+ }
10
+
11
+ public async run() {
12
+ FakeAutomodule.numCallsToRun++
13
+ }
14
+
15
+ public static resetTestDouble() {
16
+ this.callsToConstructor = []
17
+ this.numCallsToRun = 0
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ export let pathShouldExist: Record<string, boolean> = {}
2
+
3
+ export function setPathShouldExist(path: string, shouldExist: boolean) {
4
+ pathShouldExist[path] = shouldExist
5
+ }
6
+
7
+ export default async function fakePathExists(path: string) {
8
+ return pathShouldExist[path]
9
+ }