jaypie 0.1.0 → 0.1.2
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 +1 -1
- package/package.json +21 -3
- package/src/__tests__/dynamicExport.function.spec.js +110 -0
- package/src/__tests__/mongoose.package.spec.js +81 -0
- package/src/aws.package.js +12 -0
- package/src/dynamicExport.function.js +55 -0
- package/src/index.js +4 -0
- package/src/lambda.package.js +12 -0
- package/src/mongoose.package.js +12 -0
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Does NOT use Kubernetes, Docker, Terraform, or the "Serverless" framework.
|
|
|
34
34
|
|
|
35
35
|
#### Eject Anything ⏏️
|
|
36
36
|
|
|
37
|
-
Jaypie embraces "ejectability," the philosophy that any part of the
|
|
37
|
+
Jaypie embraces "ejectability," the philosophy that any part of the code can be removed (and therefore replaced) without disturbing the whole.
|
|
38
38
|
|
|
39
39
|
#### Mock Everywhere 🎴
|
|
40
40
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaypie",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"author": "Finlayson Studio",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
"lint": "eslint .",
|
|
13
13
|
"new": "hygen jaypie vite",
|
|
14
14
|
"test": "vitest",
|
|
15
|
-
"test:spec:
|
|
15
|
+
"test:spec:dynamicExport.function": "vitest run ./src/__tests__/dynamicExport.function.spec.js",
|
|
16
|
+
"test:spec:index": "vitest run ./src/__tests__/index.spec.js",
|
|
17
|
+
"test:spec:mongoose.package": "vitest run ./src/__tests__/mongoose.package.spec.js"
|
|
16
18
|
},
|
|
17
19
|
"dependencies": {
|
|
18
|
-
"@jaypie/core": "^0.
|
|
20
|
+
"@jaypie/core": "^0.4.0"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
|
21
23
|
"eslint": "^8.57.0",
|
|
@@ -28,5 +30,21 @@
|
|
|
28
30
|
"prettier": "^3.2.5",
|
|
29
31
|
"sort-package-json": "^2.8.0",
|
|
30
32
|
"vitest": "^1.4.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@jaypie/aws": "^0.1.1",
|
|
36
|
+
"@jaypie/lambda": "^0.1.1",
|
|
37
|
+
"@jaypie/mongoose": "^0.1.1"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"@jaypie/aws": {
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
"@jaypie/lambda": {
|
|
44
|
+
"optional": true
|
|
45
|
+
},
|
|
46
|
+
"@jaypie/mongoose": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
31
49
|
}
|
|
32
50
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
afterEach,
|
|
3
|
+
beforeAll,
|
|
4
|
+
beforeEach,
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
it,
|
|
8
|
+
vi,
|
|
9
|
+
} from "vitest";
|
|
10
|
+
|
|
11
|
+
// Subject
|
|
12
|
+
import dynamicExport from "../dynamicExport.function.js";
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
//
|
|
16
|
+
// Mock constants
|
|
17
|
+
//
|
|
18
|
+
|
|
19
|
+
const MOCK = {
|
|
20
|
+
MODULE: "mock-module",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
//
|
|
25
|
+
// Mock environment
|
|
26
|
+
//
|
|
27
|
+
|
|
28
|
+
const DEFAULT_ENV = process.env;
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
process.env = { ...process.env };
|
|
31
|
+
});
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
process.env = DEFAULT_ENV;
|
|
34
|
+
vi.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
//
|
|
39
|
+
// Run tests
|
|
40
|
+
//
|
|
41
|
+
|
|
42
|
+
describe("Dynamic Export Function", () => {
|
|
43
|
+
it("Is a function", () => {
|
|
44
|
+
expect(dynamicExport).toBeFunction();
|
|
45
|
+
});
|
|
46
|
+
describe("Error Handling", () => {
|
|
47
|
+
it("Throws if exports is not an array", () => {
|
|
48
|
+
expect(() => dynamicExport({ exports: "string" })).toThrow();
|
|
49
|
+
});
|
|
50
|
+
it("Throws if exports is an empty array", () => {
|
|
51
|
+
expect(() => dynamicExport({ exports: [] })).toThrow();
|
|
52
|
+
});
|
|
53
|
+
it("Throws if moduleImport is not a string", () => {
|
|
54
|
+
expect(() => dynamicExport({ moduleImport: 123 })).toThrow();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("Happy Path", () => {
|
|
58
|
+
it("Returns an object", () => {
|
|
59
|
+
expect(dynamicExport({ moduleImport: MOCK.MODULE })).toBeObject();
|
|
60
|
+
});
|
|
61
|
+
it("Returns an object with the exports", () => {
|
|
62
|
+
const exports = ["default", "named"];
|
|
63
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
64
|
+
expect(result).toContainKeys(exports);
|
|
65
|
+
});
|
|
66
|
+
it("Returns an object with the exports as functions", () => {
|
|
67
|
+
const exports = ["default", "named"];
|
|
68
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
69
|
+
expect(result.default).toBeFunction();
|
|
70
|
+
expect(result.named).toBeFunction();
|
|
71
|
+
});
|
|
72
|
+
it("Exported functions throw if the real module is not installed", async () => {
|
|
73
|
+
const exports = ["default"];
|
|
74
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
75
|
+
await expect(result.default()).rejects.toThrow();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("Features", () => {
|
|
79
|
+
const mockDefaultFunction = vi.fn();
|
|
80
|
+
const mockNamedFunction = vi.fn();
|
|
81
|
+
const mockScalar = "scalar";
|
|
82
|
+
beforeAll(() => {
|
|
83
|
+
vi.doMock(MOCK.MODULE, () => {
|
|
84
|
+
return {
|
|
85
|
+
default: mockDefaultFunction,
|
|
86
|
+
named: mockNamedFunction,
|
|
87
|
+
scalar: mockScalar,
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it("Calls the default function", async () => {
|
|
92
|
+
const exports = ["default", "named"];
|
|
93
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
94
|
+
await result.default();
|
|
95
|
+
expect(mockDefaultFunction).toHaveBeenCalled();
|
|
96
|
+
});
|
|
97
|
+
it("Calls the named function", async () => {
|
|
98
|
+
const exports = ["default", "named"];
|
|
99
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
100
|
+
await result.named();
|
|
101
|
+
expect(mockNamedFunction).toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
it.todo("Returns the scalar", async () => {
|
|
104
|
+
const exports = ["scalar"];
|
|
105
|
+
const result = dynamicExport({ exports, moduleImport: MOCK.MODULE });
|
|
106
|
+
expect(result.scalar).not.toBeFunction();
|
|
107
|
+
expect(result.scalar).toBe(mockScalar);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
afterEach,
|
|
3
|
+
beforeAll,
|
|
4
|
+
beforeEach,
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
it,
|
|
8
|
+
vi,
|
|
9
|
+
} from "vitest";
|
|
10
|
+
|
|
11
|
+
// Subject
|
|
12
|
+
import { connectFromSecretEnv, disconnect } from "../mongoose.package.js";
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
//
|
|
16
|
+
// Mock constants
|
|
17
|
+
//
|
|
18
|
+
|
|
19
|
+
//
|
|
20
|
+
//
|
|
21
|
+
// Mock modules
|
|
22
|
+
//
|
|
23
|
+
|
|
24
|
+
//
|
|
25
|
+
//
|
|
26
|
+
// Mock environment
|
|
27
|
+
//
|
|
28
|
+
|
|
29
|
+
const DEFAULT_ENV = process.env;
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
process.env = { ...process.env };
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
process.env = DEFAULT_ENV;
|
|
35
|
+
vi.clearAllMocks();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
//
|
|
39
|
+
//
|
|
40
|
+
// Run tests
|
|
41
|
+
//
|
|
42
|
+
|
|
43
|
+
describe("Mongoose Package", () => {
|
|
44
|
+
it("Works", () => {
|
|
45
|
+
expect(connectFromSecretEnv).toBeFunction();
|
|
46
|
+
expect(disconnect).toBeFunction();
|
|
47
|
+
});
|
|
48
|
+
describe("Error Handling", () => {
|
|
49
|
+
it("Throws a configuration error if Mongoose is not installed", async () => {
|
|
50
|
+
try {
|
|
51
|
+
await connectFromSecretEnv();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
expect(error.isProjectError).toBeTrue();
|
|
54
|
+
}
|
|
55
|
+
expect.assertions(1);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("Features", () => {
|
|
59
|
+
const mockConnectFromSecretEnv = vi.fn();
|
|
60
|
+
const mockDisconnect = vi.fn();
|
|
61
|
+
beforeAll(() => {
|
|
62
|
+
vi.doMock("@jaypie/mongoose", () => {
|
|
63
|
+
return {
|
|
64
|
+
connectFromSecretEnv: mockConnectFromSecretEnv,
|
|
65
|
+
disconnect: mockDisconnect,
|
|
66
|
+
mongoose: {
|
|
67
|
+
disconnect: mockDisconnect,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("Calls @jaypie/mongoose for connectFromSecretEnv", async () => {
|
|
73
|
+
await connectFromSecretEnv();
|
|
74
|
+
expect(mockConnectFromSecretEnv).toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
it("Calls @jaypie/mongoose for disconnect", async () => {
|
|
77
|
+
await disconnect();
|
|
78
|
+
expect(mockDisconnect).toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ConfigurationError, JAYPIE, moduleLogger } from "@jaypie/core";
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Helper Functions
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
let _importedModule;
|
|
9
|
+
async function dynamicImport(module) {
|
|
10
|
+
if (!_importedModule) {
|
|
11
|
+
try {
|
|
12
|
+
// eslint-disable-next-line import/no-unresolved
|
|
13
|
+
_importedModule = await import(module);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
moduleLogger
|
|
16
|
+
.with({ lib: JAYPIE.LIB.JAYPIE })
|
|
17
|
+
.error(`[jaypie] ${module} could not be imported`);
|
|
18
|
+
if (process.env.NODE_ENV === "test") {
|
|
19
|
+
if (!_importedModule) {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.warn(
|
|
22
|
+
`[jaypie] Caught error importing ${module} -- Is it installed?`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.error(error);
|
|
27
|
+
}
|
|
28
|
+
throw new ConfigurationError();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return _importedModule;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//
|
|
35
|
+
//
|
|
36
|
+
// Main
|
|
37
|
+
//
|
|
38
|
+
|
|
39
|
+
export default ({ exports = ["default"], moduleImport } = {}) => {
|
|
40
|
+
// Validate
|
|
41
|
+
if (Array.isArray(exports) && !exports.length) {
|
|
42
|
+
throw new ConfigurationError();
|
|
43
|
+
}
|
|
44
|
+
if (!moduleImport || typeof moduleImport !== "string") {
|
|
45
|
+
throw new ConfigurationError();
|
|
46
|
+
}
|
|
47
|
+
// Setup
|
|
48
|
+
return exports.reduce((acc, key) => {
|
|
49
|
+
acc[key] = async () => {
|
|
50
|
+
const imported = await dynamicImport(moduleImport);
|
|
51
|
+
return await imported[key]();
|
|
52
|
+
};
|
|
53
|
+
return acc;
|
|
54
|
+
}, {});
|
|
55
|
+
};
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { JAYPIE } from "@jaypie/core";
|
|
2
|
+
import dynamicExport from "./dynamicExport.function.js";
|
|
3
|
+
|
|
4
|
+
//
|
|
5
|
+
//
|
|
6
|
+
// Export
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
export const { connectFromSecretEnv, disconnect } = dynamicExport({
|
|
10
|
+
exports: ["connectFromSecretEnv", "disconnect"],
|
|
11
|
+
moduleImport: JAYPIE.LIB.MONGOOSE,
|
|
12
|
+
});
|