Skip to content

Commit 8f22c66

Browse files
committed
feat(core): add functions for infisical and improve schema validations
closed COD-213
1 parent 383f50e commit 8f22c66

17 files changed

+487
-50
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const baseConfig = require('../../../../eslint.config.js');
2+
3+
module.exports = [...baseConfig];

libs/shared/util/node/project.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "shared-util-node",
3+
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "libs/shared/util/node/src",
5+
"projectType": "library",
6+
"tags": ["scope:shared", "type:util"],
7+
"// targets": "to see all targets run: nx show project shared-util-node --web",
8+
"targets": {
9+
"build": {
10+
"executor": "@nx/esbuild:esbuild",
11+
"options": {
12+
"format": ["cjs", "esm"]
13+
}
14+
}
15+
}
16+
}

libs/shared/util/node/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { findUpFs } from './lib/find-up-fs';
File renamed without changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"extends": "../../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "commonjs",
5+
"forceConsistentCasingInFileNames": true,
6+
"noImplicitOverride": true,
7+
"noImplicitReturns": true,
8+
"noFallthroughCasesInSwitch": true,
9+
"noPropertyAccessFromIndexSignature": true
10+
},
11+
"files": [],
12+
"include": [],
13+
"references": [
14+
{
15+
"path": "./tsconfig.lib.json"
16+
},
17+
{
18+
"path": "./tsconfig.spec.json"
19+
}
20+
]
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../../../dist/out-tsc",
5+
"declaration": true,
6+
"types": ["node"]
7+
},
8+
"include": ["src/**/*.ts"],
9+
"exclude": [
10+
"vite.config.ts",
11+
"vite.config.mts",
12+
"vitest.config.ts",
13+
"vitest.config.mts",
14+
"src/**/*.test.ts",
15+
"src/**/*.spec.ts",
16+
"src/**/*.test.tsx",
17+
"src/**/*.spec.tsx",
18+
"src/**/*.test.js",
19+
"src/**/*.spec.js",
20+
"src/**/*.test.jsx",
21+
"src/**/*.spec.jsx"
22+
]
23+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../../../dist/out-tsc",
5+
"types": [
6+
"vitest/globals",
7+
"vitest/importMeta",
8+
"vite/client",
9+
"node",
10+
"vitest"
11+
]
12+
},
13+
"include": [
14+
"vite.config.ts",
15+
"vite.config.mts",
16+
"vitest.config.ts",
17+
"vitest.config.mts",
18+
"src/**/*.test.ts",
19+
"src/**/*.spec.ts",
20+
"src/**/*.test.tsx",
21+
"src/**/*.spec.tsx",
22+
"src/**/*.test.js",
23+
"src/**/*.spec.js",
24+
"src/**/*.test.jsx",
25+
"src/**/*.spec.jsx",
26+
"src/**/*.d.ts"
27+
]
28+
}

packages/core/src/lib/secrets/read-infisical-config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { readFile } from 'fs/promises';
22

3-
import { findUpFs } from './find-up-fs';
3+
import { findUpFs } from '@codeware/shared/util/node';
4+
45
import { ConfigSchema } from './infisical.schemas';
56

67
/**

packages/core/src/lib/secrets/with-infisical.ts

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InfisicalSDK } from '@infisical/sdk';
1+
import { InfisicalSDK, ListSecretsResult } from '@infisical/sdk';
22

33
import { ClientSchema, type Environment } from './infisical.schemas';
44
import { readInfisicalConfig } from './read-infisical-config';
@@ -35,14 +35,11 @@ type Options<TEnv> = {
3535
*/
3636
filter?: Filter;
3737
/**
38-
* The action to perform when the client is authenticated.
38+
* Whether to inject the secrets into the `process.env` object.
3939
*
40-
* **`inject`**
41-
*
42-
* Get the secrets from your project and inject them into the `process.env` object.
43-
* Use early in your application to ensure that the secrets are available as soon as possible.
40+
* Defaults to `false`.
4441
*/
45-
onConnect?: 'inject';
42+
injectEnv?: boolean;
4643
/**
4744
* The project ID to get the secrets from.
4845
*
@@ -63,6 +60,13 @@ type Options<TEnv> = {
6360
site?: 'eu' | 'us';
6461
};
6562

63+
/**
64+
* Helper type to determine return type based on silent option
65+
*/
66+
type Response<TSilent extends boolean | undefined> = TSilent extends true
67+
? ListSecretsResult['secrets'] | null
68+
: ListSecretsResult['secrets'];
69+
6670
/**
6771
* Utility function to connect and authenticate to Infisical.
6872
*
@@ -71,25 +75,27 @@ type Options<TEnv> = {
7175
* - `INFISICAL_CLIENT_ID` and `INFISICAL_CLIENT_SECRET` must be available in the environment variables.
7276
* - A project ID, either from `options` or the Infisical configuration file `.infisical.json`.
7377
*
74-
* @returns The authenticated Infisical SDK client
78+
* @returns The secrets from the Infisical project
7579
* @throws An error if the environment variables are invalid or the client fails to authenticate
7680
*/
77-
export const withInfisical = async <TEnv = Environment>(
78-
options?: Options<TEnv>
79-
): Promise<InfisicalSDK | null> => {
81+
export const withInfisical = async <
82+
TEnv = Environment,
83+
TSilent extends boolean | undefined = undefined
84+
>(
85+
options?: Options<TEnv> & { silent?: TSilent }
86+
): Promise<Response<TSilent>> => {
8087
const { success, data, error } = ClientSchema.safeParse(process.env);
8188

8289
if (!success) {
83-
const msg = 'Could not resolve client credentials';
90+
const msg = 'Could not resolve Infisical client credentials';
8491
if (!options?.silent) {
8592
throw new Error(msg, {
8693
cause: error.flatten().fieldErrors
8794
});
8895
}
8996

90-
console.warn(msg);
91-
console.warn(JSON.stringify(error.flatten().fieldErrors, null, 2));
92-
return null;
97+
console.info(msg);
98+
return null as Response<TSilent>;
9399
}
94100

95101
const {
@@ -112,39 +118,34 @@ export const withInfisical = async <TEnv = Environment>(
112118
});
113119

114120
// Connect to Infisical
115-
const ref = await client.auth().universalAuth.login({
121+
await client.auth().universalAuth.login({
116122
clientId,
117123
clientSecret
118124
});
119125

120-
console.log('[Infisical] connected successfully');
121-
122-
// Action to perform when the client is authenticated
123-
switch (options?.onConnect) {
124-
case 'inject': {
125-
const { secrets } = await client.secrets().listSecrets({
126-
environment,
127-
projectId,
128-
expandSecretReferences: true,
129-
recursive: options?.filter?.recurse ?? false,
130-
secretPath: options?.filter?.path,
131-
tagSlugs: options?.filter?.tags
132-
});
133-
console.log(
134-
`[Infisical] inject ${secrets.length} secrets into process.env`
135-
);
136-
for (const { secretKey, secretValue } of secrets) {
137-
process.env[secretKey] = secretValue;
138-
console.log(`[Infisical] injected '${secretKey}'`);
139-
}
140-
console.log('process.env', process.env);
141-
break;
126+
console.log('[Infisical] connected successfully, load secrets');
127+
128+
const { secrets } = await client.secrets().listSecrets({
129+
environment,
130+
projectId,
131+
expandSecretReferences: true,
132+
recursive: options?.filter?.recurse ?? false,
133+
secretPath: options?.filter?.path,
134+
tagSlugs: options?.filter?.tags
135+
});
136+
137+
// Post-actions to perform after the secrets are retrieved
138+
if (options?.injectEnv) {
139+
console.log(
140+
`[Infisical] inject ${secrets.length} secrets into process.env`
141+
);
142+
for (const { secretKey, secretValue } of secrets) {
143+
process.env[secretKey] = secretValue;
144+
console.log(`[Infisical] injected '${secretKey}'`);
142145
}
143-
default:
144-
break;
145146
}
146147

147-
return ref;
148+
return secrets;
148149
} catch (error) {
149150
if (!options?.silent) {
150151
throw error;
@@ -155,10 +156,10 @@ export const withInfisical = async <TEnv = Environment>(
155156
if (error instanceof Error) {
156157
console.error(error.message);
157158
if (error.cause) {
158-
console.error(error.cause);
159+
console.info(error.cause);
159160
}
160161
}
161162

162-
return null;
163+
return null as Response<TSilent>;
163164
}
164165
};

packages/core/src/lib/zod/with-camel-case.transformer.spec.ts renamed to packages/core/src/lib/zod/with-camel-case.preprocess.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { z } from 'zod';
22

3-
import { withCamelCase } from './with-camel-case.transformer';
3+
import { withCamelCase } from './with-camel-case.preprocess';
44

55
describe('withCamelCase', () => {
66
it('should handle empty objects', () => {

0 commit comments

Comments
 (0)