Skip to content
This repository was archived by the owner on Dec 30, 2023. It is now read-only.

Commit 2a474e0

Browse files
authored
feat(runtime): ✨ Improve snippets (#55)
1 parent edbf1d2 commit 2a474e0

File tree

12 files changed

+198
-63
lines changed

12 files changed

+198
-63
lines changed

.changeset/smart-fireants-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@terminal-nerds/snippets-runtime": minor
3+
---
4+
5+
🔥 Remove `inContinuousIntegration()` and `inTest()` in favour of `isIn(scopeName)`

.changeset/twelve-cougars-obey.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@terminal-nerds/snippets-runtime": minor
3+
---
4+
5+
✨ Add `isIn()`

.changeset/twelve-mails-fly.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@terminal-nerds/snippets-runtime": minor
3+
---
4+
5+
✨ Improve return type for the snippet `getEnvironmentVariable()`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { z } from "zod";
2+
3+
export const CI_CD_ENVIRONMENT_VARIABLES = ["CI", "CONTINUOUS_INTEGRATION"] as const;
4+
export type CICDEnvironmentVariable = (typeof CI_CD_ENVIRONMENT_VARIABLES)[number];
5+
export const CI_CD_ENVIRONMENT_VARIABLE_SCHEMA = z.enum(CI_CD_ENVIRONMENT_VARIABLES);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { IN_NODE } from "../../environment/environment.ts";
2+
import { RuntimeError } from "../../error/error.ts";
3+
import { getEnvironmentVariable } from "../../variable/variable.ts";
4+
import type { ScopeOptions } from "../shared.ts";
5+
6+
export function inDevelopment(options: ScopeOptions = {}): boolean {
7+
return isNodeEnvironment("development", options);
8+
}
9+
10+
export function inProduction(options: ScopeOptions = {}): boolean {
11+
return isNodeEnvironment("production", options);
12+
}
13+
14+
export type NodeEnvironment = "development" | "production";
15+
16+
export function isNodeEnvironment(value: NodeEnvironment, options: ScopeOptions = {}): boolean {
17+
const { strict = false } = options;
18+
19+
/* prettier-ignore */
20+
return IN_NODE
21+
? getEnvironmentVariable("NODE_ENV", { strict: true }) === value
22+
: handleNonNodeRuntime(strict);
23+
}
24+
25+
function handleNonNodeRuntime(strict: boolean) {
26+
if (strict) throw new RuntimeError(`Currently you can check only inside the Node.js runtime environment.`);
27+
else return false;
28+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { z } from "zod";
2+
3+
export const STORYBOOK_ENVIRONMENT_VARIABLES = ["STORYBOOK"] as const;
4+
export type StorybookEnvironmentVariable = (typeof STORYBOOK_ENVIRONMENT_VARIABLES)[number];
5+
export const STORYBOOK_ENVIRONMENT_VARIABLE_SCHEMA = z.enum(STORYBOOK_ENVIRONMENT_VARIABLES);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { z } from "zod";
2+
3+
export const TEST_ENVIRONMENT_VARIABLES = ["JEST", "VITEST"] as const;
4+
export type TestEnvironmentVariable = (typeof TEST_ENVIRONMENT_VARIABLES)[number];
5+
export const TEST_ENVIRONMENT_VARIABLE_SCHEMA = z.enum(TEST_ENVIRONMENT_VARIABLES);
Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,114 @@
11
import { returns } from "@terminal-nerds/snippets-test/unit";
22
import { describe, expect, it } from "vitest";
33

4-
import { deleteEnvironmentVariable, setEnvironmentVariable } from "../variable/variable.ts";
5-
import { CI_CD_ENVIRONMENT_VARIABLES, inContinuousIntegration, inTest, TEST_ENVIRONMENT_VARIABLES } from "./scope.ts";
4+
import { deleteEnvironmentVariable, getEnvironmentVariable, setEnvironmentVariable } from "../variable/variable.ts";
5+
import {
6+
CI_CD_ENVIRONMENT_VARIABLES,
7+
inDevelopment,
8+
inProduction,
9+
isIn,
10+
type ScopeName,
11+
STORYBOOK_ENVIRONMENT_VARIABLES,
12+
TEST_ENVIRONMENT_VARIABLES,
13+
} from "./scope.ts";
14+
15+
describe(`isIn("continuousIntegration", options?)`, () => {
16+
const scopeName: ScopeName = "continuousIntegration";
617

7-
describe("inContinuousIntegration()", () => {
818
it(returns(false).on(`non-existing environment variables`).samples(CI_CD_ENVIRONMENT_VARIABLES), () => {
919
// NOTE: This is for the CI & CD - test
1020
for (const variable of CI_CD_ENVIRONMENT_VARIABLES) {
1121
deleteEnvironmentVariable(variable);
1222
}
1323

14-
expect(inContinuousIntegration()).toBe(false);
24+
expect(isIn(scopeName)).toBe(false);
1525
});
1626

1727
it(returns(true).on(`existing environment variables`).samples(CI_CD_ENVIRONMENT_VARIABLES), () => {
1828
for (const variable of CI_CD_ENVIRONMENT_VARIABLES) {
1929
setEnvironmentVariable(variable, "true");
20-
expect(inContinuousIntegration()).toBe(true);
30+
expect(isIn(scopeName)).toBe(true);
31+
deleteEnvironmentVariable(variable);
32+
}
33+
});
34+
});
35+
36+
describe("inStorybook()", () => {
37+
const scopeName: ScopeName = "storybook";
38+
39+
it(returns(false).on(`non-existing environment variables`).samples(TEST_ENVIRONMENT_VARIABLES), () => {
40+
expect(isIn(scopeName)).toBe(false);
41+
});
42+
43+
it(returns(true).on(`existing environment variables`).samples(STORYBOOK_ENVIRONMENT_VARIABLES), () => {
44+
for (const variable of STORYBOOK_ENVIRONMENT_VARIABLES) {
45+
setEnvironmentVariable(variable, "true");
46+
expect(isIn(scopeName)).toBe(true);
2147
deleteEnvironmentVariable(variable);
2248
}
2349
});
2450
});
2551

2652
describe("inTest()", () => {
53+
const scopeName: ScopeName = "test";
54+
2755
it(returns(false).on(`non-existing environment variables`).samples(TEST_ENVIRONMENT_VARIABLES), () => {
2856
// NOTE: This is for the test
2957
for (const variable of TEST_ENVIRONMENT_VARIABLES) {
3058
deleteEnvironmentVariable(variable);
3159
}
32-
expect(inTest()).toBe(false);
60+
expect(isIn(scopeName)).toBe(false);
3361
});
3462

3563
it(returns(true).on(`existing environment variables`).samples(TEST_ENVIRONMENT_VARIABLES), () => {
3664
for (const variable of TEST_ENVIRONMENT_VARIABLES) {
3765
setEnvironmentVariable(variable, "true");
38-
expect(inTest()).toBe(true);
66+
expect(isIn(scopeName)).toBe(true);
3967
deleteEnvironmentVariable(variable);
4068
}
4169
});
4270
});
71+
72+
describe("inDevelopment()", () => {
73+
const variable = "NODE_ENV";
74+
const production = "production";
75+
const development = "development";
76+
77+
it(returns(true).on(`"${variable}" set to`).sample(development), () => {
78+
const cached = getEnvironmentVariable(variable);
79+
80+
setEnvironmentVariable(variable, development);
81+
expect(inDevelopment()).toBe(true);
82+
setEnvironmentVariable(variable, cached ?? development);
83+
});
84+
85+
it(returns(false).on(`"${variable}" set to`).sample(production), () => {
86+
const cached = getEnvironmentVariable(variable);
87+
88+
setEnvironmentVariable(variable, production);
89+
expect(inDevelopment()).toBe(false);
90+
setEnvironmentVariable(variable, cached ?? development);
91+
});
92+
});
93+
94+
describe("inProduction()", () => {
95+
const variable = "NODE_ENV";
96+
const production = "production";
97+
const development = "development";
98+
99+
it(returns(true).on(`"${variable}" set to`).sample(production), () => {
100+
const cached = getEnvironmentVariable(variable);
101+
102+
setEnvironmentVariable(variable, production);
103+
expect(inProduction()).toBe(true);
104+
setEnvironmentVariable(variable, cached ?? development);
105+
});
106+
107+
it(returns(false).on(`"${variable}" set to`).sample(development), () => {
108+
const cached = getEnvironmentVariable(variable);
109+
110+
setEnvironmentVariable(variable, development);
111+
expect(inProduction()).toBe(false);
112+
setEnvironmentVariable(variable, cached ?? development);
113+
});
114+
});
Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,39 @@
1-
import { z } from "zod";
2-
31
import { IN_BROWSER } from "../environment/environment.ts";
42
import { RuntimeError } from "../error/error.ts";
53
import { getEnvironmentVariable } from "../variable/variable.ts";
6-
7-
export const CI_CD_ENVIRONMENT_VARIABLES = ["CI", "CONTINUOUS_INTEGRATION"] as const;
8-
export type CICDEnvironmentVariable = (typeof CI_CD_ENVIRONMENT_VARIABLES)[number];
9-
export const CI_CD_ENVIRONMENT_VARIABLE_SCHEMA = z.enum(CI_CD_ENVIRONMENT_VARIABLES);
10-
11-
export const TEST_ENVIRONMENT_VARIABLES = ["JEST", "VITEST"] as const;
12-
export type TestEnvironmentVariable = (typeof TEST_ENVIRONMENT_VARIABLES)[number];
13-
export const TEST_ENVIRONMENT_VARIABLE_SCHEMA = z.enum(TEST_ENVIRONMENT_VARIABLES);
14-
15-
interface ScopeOptions {
16-
/**
17-
* Checks if it's being run in the JavaScript environment where continuous integration can be run.
18-
*
19-
* @defaultValue `false`
20-
*/
21-
strict?: boolean;
22-
}
23-
24-
export function inContinuousIntegration(options: ScopeOptions = {}): boolean {
4+
import { CI_CD_ENVIRONMENT_VARIABLES } from "./groups/continuous-integration.ts";
5+
import { STORYBOOK_ENVIRONMENT_VARIABLES } from "./groups/storybook.ts";
6+
import { TEST_ENVIRONMENT_VARIABLES } from "./groups/test.ts";
7+
import type { ScopeOptions } from "./shared.ts";
8+
9+
export * from "./groups/continuous-integration.ts";
10+
export * from "./groups/node.ts";
11+
export * from "./groups/storybook.ts";
12+
export * from "./groups/test.ts";
13+
14+
export const SCOPE_NAMES = ["continuousIntegration", "storybook", "test"] as const;
15+
export type ScopeName = (typeof SCOPE_NAMES)[number];
16+
export const SCOPE_VARIABLES = {
17+
continuousIntegration: CI_CD_ENVIRONMENT_VARIABLES,
18+
storybook: STORYBOOK_ENVIRONMENT_VARIABLES,
19+
test: TEST_ENVIRONMENT_VARIABLES,
20+
} as const;
21+
22+
export function isIn(scopeName: ScopeName, options: ScopeOptions = {}): boolean {
2523
const { strict = false } = options;
2624

27-
if (IN_BROWSER) {
28-
if (strict) throw new RuntimeError(`CI & CD cannot be run in browsers.`);
29-
else return false;
30-
} else {
31-
for (const variable of CI_CD_ENVIRONMENT_VARIABLES) {
32-
if (getEnvironmentVariable(variable)) return true;
33-
}
34-
35-
return false;
36-
}
25+
return IN_BROWSER ? handleBrowserRuntime(strict) : isAnyVariableDefined(SCOPE_VARIABLES[scopeName]);
3726
}
3827

39-
export function inTest(options: ScopeOptions = {}): boolean {
40-
const { strict = false } = options;
41-
42-
if (IN_BROWSER) {
43-
if (strict) throw new RuntimeError(`Test frameworks cannot be run in browsers.`);
44-
else return false;
45-
} else {
46-
for (const variable of TEST_ENVIRONMENT_VARIABLES) {
47-
if (getEnvironmentVariable(variable)) return true;
48-
}
28+
function handleBrowserRuntime(strict: boolean): boolean {
29+
if (strict) throw new RuntimeError(`You cannot use this snippet in the browser.`);
30+
else return false;
31+
}
4932

50-
return false;
33+
function isAnyVariableDefined(names: readonly string[]): boolean {
34+
for (const variable of names) {
35+
if (getEnvironmentVariable(variable)) return true;
5136
}
37+
38+
return false;
5239
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface ScopeOptions {
2+
/**
3+
* Checks if it's being run in the JavaScript environment where continuous integration can be run.
4+
*
5+
* @defaultValue `false`
6+
*/
7+
strict?: boolean;
8+
}

0 commit comments

Comments
 (0)