@neurodevs/meta-node 0.15.0 → 0.16.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.
@@ -0,0 +1,19 @@
1
+ import AbstractModuleTest from '@neurodevs/node-tdd';
2
+ export default class NpmPropagationCoordinatorTest extends AbstractModuleTest {
3
+ private static instance;
4
+ private static readonly packageScope;
5
+ private static readonly packageName;
6
+ private static readonly scopedName;
7
+ private static readonly packageVersion;
8
+ private static readonly repoPath;
9
+ private static readonly repoPaths;
10
+ private static readonly pkgJsons;
11
+ protected static beforeEach(): Promise<void>;
12
+ protected static createsInstance(): Promise<void>;
13
+ protected static propagatesToCorrectRepoPaths(): Promise<void>;
14
+ private static run;
15
+ private static generatePackageJson;
16
+ private static setFakeReadFile;
17
+ private static setFakeReleasePropagator;
18
+ private static NpmPropagationCoordinator;
19
+ }
@@ -0,0 +1,86 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { fakeReadFile, resetCallsToReadFile, setFakeReadFileResult, } from '@neurodevs/fake-node-core';
8
+ import AbstractModuleTest, { test, assert } from '@neurodevs/node-tdd';
9
+ import NpmPropagationCoordinator from '../../impl/NpmPropagationCoordinator.js';
10
+ import NpmReleasePropagator from '../../impl/NpmReleasePropagator.js';
11
+ import FakeReleasePropagator from '../../testDoubles/ReleasePropagator/FakeReleasePropagator.js';
12
+ export default class NpmPropagationCoordinatorTest extends AbstractModuleTest {
13
+ static instance;
14
+ static packageScope = this.generateId();
15
+ static packageName = this.generateId();
16
+ static scopedName = `${this.packageScope}/${this.packageName}`;
17
+ static packageVersion = '7.8.9';
18
+ static repoPath = `${this.generateId()}/${this.packageName}`;
19
+ static repoPaths = [
20
+ this.generateId(),
21
+ this.generateId(),
22
+ this.generateId(),
23
+ this.repoPath,
24
+ ];
25
+ static pkgJsons = [
26
+ this.generatePackageJson({
27
+ dependencies: { [this.scopedName]: '^1.2.3' },
28
+ }),
29
+ this.generatePackageJson({
30
+ devDependencies: { [this.scopedName]: '^4.5.6' },
31
+ }),
32
+ this.generatePackageJson(),
33
+ this.generatePackageJson({ version: this.packageVersion }),
34
+ ];
35
+ static async beforeEach() {
36
+ await super.beforeEach();
37
+ this.setFakeReadFile();
38
+ this.setFakeReleasePropagator();
39
+ this.instance = this.NpmPropagationCoordinator();
40
+ }
41
+ static async createsInstance() {
42
+ assert.isTruthy(this.instance, 'Failed to create instance!');
43
+ }
44
+ static async propagatesToCorrectRepoPaths() {
45
+ await this.run();
46
+ assert.isEqualDeep(FakeReleasePropagator.callsToConstructor[0], {
47
+ packageName: this.scopedName,
48
+ packageVersion: this.packageVersion,
49
+ repoPaths: [this.repoPaths[0], this.repoPaths[1]],
50
+ }, 'Incorrect repo paths propagated to!');
51
+ }
52
+ static async run() {
53
+ await this.instance.run();
54
+ }
55
+ static generatePackageJson(options) {
56
+ return {
57
+ name: this.scopedName,
58
+ version: this.packageVersion,
59
+ dependencies: {},
60
+ devDependencies: {},
61
+ ...options,
62
+ };
63
+ }
64
+ static setFakeReadFile() {
65
+ NpmPropagationCoordinator.readFile =
66
+ fakeReadFile;
67
+ resetCallsToReadFile();
68
+ this.repoPaths.forEach((repoPath, i) => {
69
+ setFakeReadFileResult(`${repoPath}/package.json`, JSON.stringify(this.pkgJsons[i], null, 4));
70
+ });
71
+ }
72
+ static setFakeReleasePropagator() {
73
+ NpmReleasePropagator.Class = FakeReleasePropagator;
74
+ FakeReleasePropagator.resetTestDouble();
75
+ }
76
+ static NpmPropagationCoordinator() {
77
+ return NpmPropagationCoordinator.Create(this.repoPath, this.repoPaths);
78
+ }
79
+ }
80
+ __decorate([
81
+ test()
82
+ ], NpmPropagationCoordinatorTest, "createsInstance", null);
83
+ __decorate([
84
+ test()
85
+ ], NpmPropagationCoordinatorTest, "propagatesToCorrectRepoPaths", null);
86
+ //# sourceMappingURL=NpmPropagationCoordinator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NpmPropagationCoordinator.test.js","sourceRoot":"","sources":["../../../src/__tests__/impl/NpmPropagationCoordinator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ export default class NpmPropagationCoordinator implements PropagationCoordinator {
3
+ static Class?: PropagationCoordinatorConstructor;
4
+ static readFile: typeof readFile;
5
+ private repoPath;
6
+ private repoPaths;
7
+ private pkg;
8
+ private currentRepoPath;
9
+ private currentPkgJson;
10
+ protected constructor(repoPath: string, repoPaths: string[]);
11
+ static Create(repoPath: string, repoPaths: string[]): PropagationCoordinator;
12
+ run(): Promise<void>;
13
+ private loadPackageJson;
14
+ private get packageName();
15
+ private get packageVersion();
16
+ private determineWhereToPropagate;
17
+ private get isDependency();
18
+ private get isDevDependency();
19
+ private loadCurrentPkgJson;
20
+ private get readFile();
21
+ private NpmReleaseCoordinator;
22
+ }
23
+ export interface PropagationCoordinator {
24
+ run(): Promise<void>;
25
+ }
26
+ export type PropagationCoordinatorConstructor = new (repoPath: string, repoPaths: string[]) => PropagationCoordinator;
@@ -0,0 +1,66 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import NpmReleasePropagator from './NpmReleasePropagator.js';
3
+ export default class NpmPropagationCoordinator {
4
+ static Class;
5
+ static readFile = readFile;
6
+ repoPath;
7
+ repoPaths;
8
+ pkg;
9
+ currentRepoPath;
10
+ currentPkgJson;
11
+ constructor(repoPath, repoPaths) {
12
+ this.repoPath = repoPath;
13
+ this.repoPaths = repoPaths;
14
+ }
15
+ static Create(repoPath, repoPaths) {
16
+ return new (this.Class ?? this)(repoPath, repoPaths);
17
+ }
18
+ async run() {
19
+ await this.loadPackageJson();
20
+ const repoPaths = await this.determineWhereToPropagate();
21
+ const propagator = this.NpmReleaseCoordinator({
22
+ packageName: this.packageName,
23
+ packageVersion: this.packageVersion,
24
+ repoPaths,
25
+ });
26
+ await propagator.run();
27
+ }
28
+ async loadPackageJson() {
29
+ const pkgJson = await this.readFile(`${this.repoPath}/package.json`, 'utf-8');
30
+ this.pkg = JSON.parse(pkgJson);
31
+ }
32
+ get packageName() {
33
+ return this.pkg.name;
34
+ }
35
+ get packageVersion() {
36
+ return this.pkg.version;
37
+ }
38
+ async determineWhereToPropagate() {
39
+ const repoPaths = [];
40
+ for (const repoPath of this.repoPaths) {
41
+ this.currentRepoPath = repoPath;
42
+ this.currentPkgJson = await this.loadCurrentPkgJson();
43
+ if (this.isDependency ?? this.isDevDependency) {
44
+ repoPaths.push(repoPath);
45
+ }
46
+ }
47
+ return repoPaths;
48
+ }
49
+ get isDependency() {
50
+ return this.currentPkgJson.dependencies[this.packageName];
51
+ }
52
+ get isDevDependency() {
53
+ return this.currentPkgJson.devDependencies[this.packageName];
54
+ }
55
+ async loadCurrentPkgJson() {
56
+ const pkgJson = await this.readFile(`${this.currentRepoPath}/package.json`, 'utf-8');
57
+ return JSON.parse(pkgJson);
58
+ }
59
+ get readFile() {
60
+ return NpmPropagationCoordinator.readFile;
61
+ }
62
+ NpmReleaseCoordinator(options) {
63
+ return NpmReleasePropagator.Create(options);
64
+ }
65
+ }
66
+ //# sourceMappingURL=NpmPropagationCoordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NpmPropagationCoordinator.js","sourceRoot":"","sources":["../../src/impl/NpmPropagationCoordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,oBAGN,MAAM,2BAA2B,CAAA;AAElC,MAAM,CAAC,OAAO,OAAO,yBAAyB;IACnC,MAAM,CAAC,KAAK,CAAoC;IAChD,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAEzB,QAAQ,CAAQ;IAChB,SAAS,CAAU;IAEnB,GAAG,CAAc;IACjB,eAAe,CAAS;IACxB,cAAc,CAAc;IAEpC,YAAsB,QAAgB,EAAE,SAAmB;QACvD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC9B,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,QAAgB,EAAE,SAAmB;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IACxD,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;QAE5B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAA;QAExD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,SAAS;SACZ,CAAC,CAAA;QAEF,MAAM,UAAU,CAAC,GAAG,EAAE,CAAA;IAC1B,CAAC;IAEO,KAAK,CAAC,eAAe;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC/B,GAAG,IAAI,CAAC,QAAQ,eAAe,EAC/B,OAAO,CACV,CAAA;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAClC,CAAC;IAED,IAAY,WAAW;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAA;IACxB,CAAC;IAED,IAAY,cAAc;QACtB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAA;IAC3B,CAAC;IAEO,KAAK,CAAC,yBAAyB;QACnC,MAAM,SAAS,GAAa,EAAE,CAAA;QAE9B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAA;YAC/B,IAAI,CAAC,cAAc,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAA;YAErD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5C,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC5B,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAA;IACpB,CAAC;IAED,IAAY,YAAY;QACpB,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC7D,CAAC;IAED,IAAY,eAAe;QACvB,OAAO,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChE,CAAC;IAEO,KAAK,CAAC,kBAAkB;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC/B,GAAG,IAAI,CAAC,eAAe,eAAe,EACtC,OAAO,CACV,CAAA;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;IAED,IAAY,QAAQ;QAChB,OAAO,yBAAyB,CAAC,QAAQ,CAAA;IAC7C,CAAC;IAEO,qBAAqB,CAAC,OAAiC;QAC3D,OAAO,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC"}
@@ -35,6 +35,8 @@ export interface ReleasePropagatorOptions {
35
35
  repoPaths: string[];
36
36
  }
37
37
  export interface PackageJson {
38
- dependencies?: Record<string, string>;
39
- devDependencies?: Record<string, string>;
38
+ name: string;
39
+ version: string;
40
+ dependencies: Record<string, string>;
41
+ devDependencies: Record<string, string>;
40
42
  }
package/build/index.d.ts CHANGED
@@ -22,6 +22,10 @@ export { default as NpmAutopackage } from './impl/NpmAutopackage.js';
22
22
  export * from './impl/NpmAutopackage.js';
23
23
  export { default as FakeAutopackage } from './testDoubles/Autopackage/FakeAutopackage.js';
24
24
  export * from './testDoubles/Autopackage/FakeAutopackage.js';
25
+ export { default as NpmPropagationCoordinator } from './impl/NpmPropagationCoordinator.js';
26
+ export * from './impl/NpmPropagationCoordinator.js';
27
+ export { default as FakePropagationCoordinator } from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js';
28
+ export * from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js';
25
29
  export { default as NpmReleasePropagator } from './impl/NpmReleasePropagator.js';
26
30
  export * from './impl/NpmReleasePropagator.js';
27
31
  export { default as FakeReleasePropagator } from './testDoubles/ReleasePropagator/FakeReleasePropagator.js';
package/build/index.js CHANGED
@@ -27,6 +27,11 @@ export { default as NpmAutopackage } from './impl/NpmAutopackage.js';
27
27
  export * from './impl/NpmAutopackage.js';
28
28
  export { default as FakeAutopackage } from './testDoubles/Autopackage/FakeAutopackage.js';
29
29
  export * from './testDoubles/Autopackage/FakeAutopackage.js';
30
+ // PropagationCoordinator
31
+ export { default as NpmPropagationCoordinator } from './impl/NpmPropagationCoordinator.js';
32
+ export * from './impl/NpmPropagationCoordinator.js';
33
+ export { default as FakePropagationCoordinator } from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js';
34
+ export * from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js';
30
35
  // ReleasePropagator
31
36
  export { default as NpmReleasePropagator } from './impl/NpmReleasePropagator.js';
32
37
  export * from './impl/NpmReleasePropagator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAClE,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAClE,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,iBAAiB;AAEjB,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAClF,cAAc,iCAAiC,CAAA;AAE/C,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,oDAAoD,CAAA;AAClG,cAAc,oDAAoD,CAAA;AAElE,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAC5E,cAAc,8BAA8B,CAAA;AAE5C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,cAAc,0BAA0B,CAAA;AAExC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAChE,cAAc,wBAAwB,CAAA;AAEtC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,cAAc;AAEd,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,cAAc,0BAA0B,CAAA;AAExC,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,8CAA8C,CAAA;AACzF,cAAc,8CAA8C,CAAA;AAE5D,oBAAoB;AAEpB,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAChF,cAAc,gCAAgC,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0DAA0D,CAAA;AAC3G,cAAc,0DAA0D,CAAA;AAExE,mBAAmB;AAEnB,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AACpF,cAAc,kCAAkC,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wDAAwD,CAAA;AACxG,cAAc,wDAAwD,CAAA;AAEtE,eAAe;AAEf,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,uCAAuC,CAAA;AAC9F,cAAc,uCAAuC,CAAA;AAErD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AAC5F,cAAc,gDAAgD,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAClE,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAClE,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,iBAAiB;AAEjB,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAClF,cAAc,iCAAiC,CAAA;AAE/C,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,oDAAoD,CAAA;AAClG,cAAc,oDAAoD,CAAA;AAElE,aAAa;AAEb,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAC5E,cAAc,8BAA8B,CAAA;AAE5C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,cAAc,0BAA0B,CAAA;AAExC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAChE,cAAc,wBAAwB,CAAA;AAEtC,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,cAAc,4CAA4C,CAAA;AAE1D,cAAc;AAEd,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACpE,cAAc,0BAA0B,CAAA;AAExC,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,8CAA8C,CAAA;AACzF,cAAc,8CAA8C,CAAA;AAE5D,yBAAyB;AAEzB,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qCAAqC,CAAA;AAC1F,cAAc,qCAAqC,CAAA;AAEnD,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,oEAAoE,CAAA;AAC1H,cAAc,oEAAoE,CAAA;AAElF,oBAAoB;AAEpB,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAChF,cAAc,gCAAgC,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0DAA0D,CAAA;AAC3G,cAAc,0DAA0D,CAAA;AAExE,mBAAmB;AAEnB,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AACpF,cAAc,kCAAkC,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wDAAwD,CAAA;AACxG,cAAc,wDAAwD,CAAA;AAEtE,eAAe;AAEf,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,uCAAuC,CAAA;AAC9F,cAAc,uCAAuC,CAAA;AAErD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AAC5F,cAAc,gDAAgD,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { PropagationCoordinator } from '../../impl/NpmPropagationCoordinator.js';
2
+ export default class FakePropagationCoordinator implements PropagationCoordinator {
3
+ static callsToConstructor: {
4
+ repoPath?: string;
5
+ repoPaths?: string[];
6
+ }[];
7
+ static numCallsToRun: number;
8
+ constructor(repoPath?: string, repoPaths?: string[]);
9
+ run(): Promise<void>;
10
+ static resetTestDouble(): void;
11
+ }
@@ -0,0 +1,18 @@
1
+ export default class FakePropagationCoordinator {
2
+ static callsToConstructor = [];
3
+ static numCallsToRun = 0;
4
+ constructor(repoPath, repoPaths) {
5
+ FakePropagationCoordinator.callsToConstructor.push({
6
+ repoPath,
7
+ repoPaths,
8
+ });
9
+ }
10
+ async run() {
11
+ FakePropagationCoordinator.numCallsToRun += 1;
12
+ }
13
+ static resetTestDouble() {
14
+ FakePropagationCoordinator.callsToConstructor = [];
15
+ FakePropagationCoordinator.numCallsToRun = 0;
16
+ }
17
+ }
18
+ //# sourceMappingURL=FakePropagationCoordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FakePropagationCoordinator.js","sourceRoot":"","sources":["../../../src/testDoubles/PropagationCoordinator/FakePropagationCoordinator.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,0BAA0B;IACpC,MAAM,CAAC,kBAAkB,GAG1B,EAAE,CAAA;IAED,MAAM,CAAC,aAAa,GAAG,CAAC,CAAA;IAE/B,YAAmB,QAAiB,EAAE,SAAoB;QACtD,0BAA0B,CAAC,kBAAkB,CAAC,IAAI,CAAC;YAC/C,QAAQ;YACR,SAAS;SACZ,CAAC,CAAA;IACN,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,0BAA0B,CAAC,aAAa,IAAI,CAAC,CAAA;IACjD,CAAC;IAEM,MAAM,CAAC,eAAe;QACzB,0BAA0B,CAAC,kBAAkB,GAAG,EAAE,CAAA;QAClD,0BAA0B,CAAC,aAAa,GAAG,CAAC,CAAA;IAChD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neurodevs/meta-node",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "Meta-layer utilities for maintaining Node.js package ecosystems.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -0,0 +1,109 @@
1
+ import { readFile } from 'node:fs/promises'
2
+
3
+ import {
4
+ fakeReadFile,
5
+ resetCallsToReadFile,
6
+ setFakeReadFileResult,
7
+ } from '@neurodevs/fake-node-core'
8
+ import AbstractModuleTest, { test, assert } from '@neurodevs/node-tdd'
9
+
10
+ import NpmPropagationCoordinator, {
11
+ PropagationCoordinator,
12
+ } from '../../impl/NpmPropagationCoordinator.js'
13
+ import NpmReleasePropagator, {
14
+ PackageJson,
15
+ } from '../../impl/NpmReleasePropagator.js'
16
+ import FakeReleasePropagator from '../../testDoubles/ReleasePropagator/FakeReleasePropagator.js'
17
+
18
+ export default class NpmPropagationCoordinatorTest extends AbstractModuleTest {
19
+ private static instance: PropagationCoordinator
20
+
21
+ private static readonly packageScope = this.generateId()
22
+ private static readonly packageName = this.generateId()
23
+ private static readonly scopedName = `${this.packageScope}/${this.packageName}`
24
+ private static readonly packageVersion = '7.8.9'
25
+ private static readonly repoPath = `${this.generateId()}/${this.packageName}`
26
+
27
+ private static readonly repoPaths = [
28
+ this.generateId(),
29
+ this.generateId(),
30
+ this.generateId(),
31
+ this.repoPath,
32
+ ]
33
+
34
+ private static readonly pkgJsons = [
35
+ this.generatePackageJson({
36
+ dependencies: { [this.scopedName]: '^1.2.3' },
37
+ }),
38
+ this.generatePackageJson({
39
+ devDependencies: { [this.scopedName]: '^4.5.6' },
40
+ }),
41
+ this.generatePackageJson(),
42
+ this.generatePackageJson({ version: this.packageVersion }),
43
+ ]
44
+
45
+ protected static async beforeEach() {
46
+ await super.beforeEach()
47
+
48
+ this.setFakeReadFile()
49
+ this.setFakeReleasePropagator()
50
+
51
+ this.instance = this.NpmPropagationCoordinator()
52
+ }
53
+
54
+ @test()
55
+ protected static async createsInstance() {
56
+ assert.isTruthy(this.instance, 'Failed to create instance!')
57
+ }
58
+
59
+ @test()
60
+ protected static async propagatesToCorrectRepoPaths() {
61
+ await this.run()
62
+
63
+ assert.isEqualDeep(
64
+ FakeReleasePropagator.callsToConstructor[0],
65
+ {
66
+ packageName: this.scopedName,
67
+ packageVersion: this.packageVersion,
68
+ repoPaths: [this.repoPaths[0], this.repoPaths[1]],
69
+ },
70
+ 'Incorrect repo paths propagated to!'
71
+ )
72
+ }
73
+
74
+ private static async run() {
75
+ await this.instance.run()
76
+ }
77
+
78
+ private static generatePackageJson(options?: Partial<PackageJson>) {
79
+ return {
80
+ name: this.scopedName,
81
+ version: this.packageVersion,
82
+ dependencies: {},
83
+ devDependencies: {},
84
+ ...options,
85
+ }
86
+ }
87
+
88
+ private static setFakeReadFile() {
89
+ NpmPropagationCoordinator.readFile =
90
+ fakeReadFile as unknown as typeof readFile
91
+ resetCallsToReadFile()
92
+
93
+ this.repoPaths.forEach((repoPath, i) => {
94
+ setFakeReadFileResult(
95
+ `${repoPath}/package.json`,
96
+ JSON.stringify(this.pkgJsons[i], null, 4)
97
+ )
98
+ })
99
+ }
100
+
101
+ private static setFakeReleasePropagator() {
102
+ NpmReleasePropagator.Class = FakeReleasePropagator
103
+ FakeReleasePropagator.resetTestDouble()
104
+ }
105
+
106
+ private static NpmPropagationCoordinator() {
107
+ return NpmPropagationCoordinator.Create(this.repoPath, this.repoPaths)
108
+ }
109
+ }
@@ -0,0 +1,104 @@
1
+ import { readFile } from 'node:fs/promises'
2
+
3
+ import NpmReleasePropagator, {
4
+ PackageJson,
5
+ ReleasePropagatorOptions,
6
+ } from './NpmReleasePropagator.js'
7
+
8
+ export default class NpmPropagationCoordinator implements PropagationCoordinator {
9
+ public static Class?: PropagationCoordinatorConstructor
10
+ public static readFile = readFile
11
+
12
+ private repoPath: string
13
+ private repoPaths: string[]
14
+
15
+ private pkg!: PackageJson
16
+ private currentRepoPath!: string
17
+ private currentPkgJson!: PackageJson
18
+
19
+ protected constructor(repoPath: string, repoPaths: string[]) {
20
+ this.repoPath = repoPath
21
+ this.repoPaths = repoPaths
22
+ }
23
+
24
+ public static Create(repoPath: string, repoPaths: string[]) {
25
+ return new (this.Class ?? this)(repoPath, repoPaths)
26
+ }
27
+
28
+ public async run() {
29
+ await this.loadPackageJson()
30
+
31
+ const repoPaths = await this.determineWhereToPropagate()
32
+
33
+ const propagator = this.NpmReleaseCoordinator({
34
+ packageName: this.packageName,
35
+ packageVersion: this.packageVersion,
36
+ repoPaths,
37
+ })
38
+
39
+ await propagator.run()
40
+ }
41
+
42
+ private async loadPackageJson() {
43
+ const pkgJson = await this.readFile(
44
+ `${this.repoPath}/package.json`,
45
+ 'utf-8'
46
+ )
47
+ this.pkg = JSON.parse(pkgJson)
48
+ }
49
+
50
+ private get packageName() {
51
+ return this.pkg.name
52
+ }
53
+
54
+ private get packageVersion() {
55
+ return this.pkg.version
56
+ }
57
+
58
+ private async determineWhereToPropagate() {
59
+ const repoPaths: string[] = []
60
+
61
+ for (const repoPath of this.repoPaths) {
62
+ this.currentRepoPath = repoPath
63
+ this.currentPkgJson = await this.loadCurrentPkgJson()
64
+
65
+ if (this.isDependency ?? this.isDevDependency) {
66
+ repoPaths.push(repoPath)
67
+ }
68
+ }
69
+ return repoPaths
70
+ }
71
+
72
+ private get isDependency() {
73
+ return this.currentPkgJson.dependencies[this.packageName]
74
+ }
75
+
76
+ private get isDevDependency() {
77
+ return this.currentPkgJson.devDependencies[this.packageName]
78
+ }
79
+
80
+ private async loadCurrentPkgJson() {
81
+ const pkgJson = await this.readFile(
82
+ `${this.currentRepoPath}/package.json`,
83
+ 'utf-8'
84
+ )
85
+ return JSON.parse(pkgJson)
86
+ }
87
+
88
+ private get readFile() {
89
+ return NpmPropagationCoordinator.readFile
90
+ }
91
+
92
+ private NpmReleaseCoordinator(options: ReleasePropagatorOptions) {
93
+ return NpmReleasePropagator.Create(options)
94
+ }
95
+ }
96
+
97
+ export interface PropagationCoordinator {
98
+ run(): Promise<void>
99
+ }
100
+
101
+ export type PropagationCoordinatorConstructor = new (
102
+ repoPath: string,
103
+ repoPaths: string[]
104
+ ) => PropagationCoordinator
@@ -129,6 +129,8 @@ export interface ReleasePropagatorOptions {
129
129
  }
130
130
 
131
131
  export interface PackageJson {
132
- dependencies?: Record<string, string>
133
- devDependencies?: Record<string, string>
132
+ name: string
133
+ version: string
134
+ dependencies: Record<string, string>
135
+ devDependencies: Record<string, string>
134
136
  }
package/src/index.ts CHANGED
@@ -44,6 +44,14 @@ export * from './impl/NpmAutopackage.js'
44
44
  export { default as FakeAutopackage } from './testDoubles/Autopackage/FakeAutopackage.js'
45
45
  export * from './testDoubles/Autopackage/FakeAutopackage.js'
46
46
 
47
+ // PropagationCoordinator
48
+
49
+ export { default as NpmPropagationCoordinator } from './impl/NpmPropagationCoordinator.js'
50
+ export * from './impl/NpmPropagationCoordinator.js'
51
+
52
+ export { default as FakePropagationCoordinator } from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js'
53
+ export * from './testDoubles/PropagationCoordinator/FakePropagationCoordinator.js'
54
+
47
55
  // ReleasePropagator
48
56
 
49
57
  export { default as NpmReleasePropagator } from './impl/NpmReleasePropagator.js'
@@ -0,0 +1,26 @@
1
+ import { PropagationCoordinator } from '../../impl/NpmPropagationCoordinator.js'
2
+
3
+ export default class FakePropagationCoordinator implements PropagationCoordinator {
4
+ public static callsToConstructor: {
5
+ repoPath?: string
6
+ repoPaths?: string[]
7
+ }[] = []
8
+
9
+ public static numCallsToRun = 0
10
+
11
+ public constructor(repoPath?: string, repoPaths?: string[]) {
12
+ FakePropagationCoordinator.callsToConstructor.push({
13
+ repoPath,
14
+ repoPaths,
15
+ })
16
+ }
17
+
18
+ public async run() {
19
+ FakePropagationCoordinator.numCallsToRun += 1
20
+ }
21
+
22
+ public static resetTestDouble() {
23
+ FakePropagationCoordinator.callsToConstructor = []
24
+ FakePropagationCoordinator.numCallsToRun = 0
25
+ }
26
+ }