Skip to content

Commit

Permalink
Improving docs and fixing CI
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyxiao committed Sep 17, 2022
1 parent 91e7834 commit 3b3a5de
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 53 deletions.
23 changes: 16 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
# Fully qualified url your venice api used for webhooks and server-side rendering.
# Normally this is $SERVER_HOSTNAME/api. e.g. https://connect.example.com/api
NEXT_PUBLIC_API_URL=""
POSTGRES_URL="" # Primary database used for metadata and user data storage
JWT_SECRET_OR_PUBLIC_KEY="" # Used for validating authenticity of accessToken
int_plaid__clientId="" # <Required> ZodString
int_plaid__secrets__sandbox="" # <Required> ZodString
int_plaid__secrets__development="" # <Required> ZodString
int_plaid__secrets__production="" # <Required> ZodString
int_plaid__clientName="" # <Required> ZodString
# Primary database used for metadata and user data storage
POSTGRES_URL=""
# Used for validating authenticity of accessToken
JWT_SECRET_OR_PUBLIC_KEY=""
# <Required>
int_plaid__clientId=""
# <Required>
int_plaid__secrets__sandbox=""
# <Required>
int_plaid__secrets__development=""
# <Required>
int_plaid__secrets__production=""
# <Required> The name of your application, as it should be displayed in Link.
# Maximum length of 30 characters.
# If a value longer than 30 characters is provided, Link will display "This Application" instead.
int_plaid__clientName=""
2 changes: 1 addition & 1 deletion .github/workflows/validate-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
run: pnpm run typecheck

- name: Run health check
run: node --loader tsx ./bin/ledgerSync health
run: POSTGRES_URL=noop node --loader tsx ./bin/ledgerSync health

- name: Generate assets required for lint
run: pnpm --dir ./apps/next/ run generate:css
Expand Down
20 changes: 10 additions & 10 deletions apps/app-config/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@

# Environment variables

| Name | Description |
| :------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NEXT_PUBLIC_API_URL | Fully qualified url your venice api used for webhooks and server-side rendering.</br>Normally this is $SERVER_HOSTNAME/api. e.g. https://connect.example.com/api |
| POSTGRES_URL | Primary database used for metadata and user data storage |
| JWT_SECRET_OR_PUBLIC_KEY | Used for validating authenticity of accessToken |
| int_plaid__clientId | <Required> ZodString |
| int_plaid__secrets__sandbox | <Required> ZodString |
| int_plaid__secrets__development | <Required> ZodString |
| int_plaid__secrets__production | <Required> ZodString |
| int_plaid__clientName | <Required> ZodString |
| Name | Description |
| :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_API_URL` | Fully qualified url your venice api used for webhooks and server-side rendering.</br>Normally this is $SERVER_HOSTNAME/api. e.g. https://connect.example.com/api |
| `POSTGRES_URL` | Primary database used for metadata and user data storage |
| `JWT_SECRET_OR_PUBLIC_KEY` | Used for validating authenticity of accessToken |
| `int_plaid__clientId` | <Required> |
| `int_plaid__secrets__sandbox` | <Required> |
| `int_plaid__secrets__development` | <Required> |
| `int_plaid__secrets__production` | <Required> |
| `int_plaid__clientName` | <Required> The name of your application, as it should be displayed in Link.</br>Maximum length of 30 characters.</br>If a value longer than 30 characters is provided, Link will display "This Application" instead. |

21 changes: 16 additions & 5 deletions apps/app-config/_generateDocs.bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import * as path from 'node:path'

import tablemark from 'tablemark'

import {compact, R} from '@ledger-sync/util'
import {compact, R, zParser} from '@ledger-sync/util'

import {zAllEnv} from './env'
import {parseIntConfigsFromEnv, zAllEnv} from './env'
import {loadEnv} from './loadEnv.node'

const envList = R.pipe(
zAllEnv.shape,
Expand All @@ -19,13 +20,14 @@ const envList = R.pipe(
)

return {
Name: key,
Name: '`' + key + '`',
Description: cmtLines.join('</br>'),
dotEnvLine: R.pipe(cmtLines.map((c) => `# ${c}`).join('\n'), (cmts) =>
compact([
cmtLines.length > 1 && `${cmts}\n`,
`${cmts}\n`, // cmtLines.length > 1 && `${cmts}\n`,
`${key}=""`,
cmtLines.length <= 1 && ` ${cmts}`,
// comment on same line is not supported by @next/env due to using old version of dotenv.
// cmtLines.length <= 1 && ` ${cmts}`,
]).join(''),
),
}
Expand All @@ -48,3 +50,12 @@ fs.writeFileSync(dotEnvExampleOutPath, dotEnvExample)
console.log(`Wrote ${dotEnvExampleOutPath}`)

// console.log(dotEnvExample)

if (process.env.NODE_ENV !== 'production') {
console.log('Test out loading env vars')
loadEnv()
const env = zParser(zAllEnv).parseUnknown(process.env)
const configs = parseIntConfigsFromEnv(env)
console.log('Parsed env', env)
console.log('Parsed intConfigs', configs)
}
37 changes: 11 additions & 26 deletions apps/app-config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ export const PROVIDERS = [
postgresProvider,
] as const

export const zFlatConfigByProvider = R.mapToObj(DOCUMENTED_PROVIDERS, (p) => [
p.name,
zFlatten(p.def.integrationConfig ?? z.unknown()),
])

// MARK: - Env vars

export const zCommonEnv = zEnvVars({
Expand All @@ -81,14 +76,18 @@ export const zBackendEnv = zEnvVars({
.describe('Used for validating authenticity of accessToken'),
})

export const zFlatConfigByIntId = R.mapToObj(DOCUMENTED_PROVIDERS, (p) => [
`int_${p.name}`,
zFlatten(p.def.integrationConfig ?? z.unknown()),
])

export const zIntegrationEnv = zEnvVars(
R.pipe(
zFlatConfigByProvider,
zFlatConfigByIntId,
R.toPairs,
// R.map((p) => flattenZObject(p.def.integrationConfig, [`int_${p.name}`])),
R.map(([name, schema]) =>
R.map(([intId, schema]) =>
R.mapKeys(schema.innerType().shape, (k) =>
compact([`int_${name}`, k]).join('__'),
compact([intId, k]).join('__'),
),
),
R.mergeAll,
Expand All @@ -103,10 +102,10 @@ export function parseIntConfigsFromEnv(
env: Record<string, string | undefined>,
) {
return R.pipe(
R.mapValues(zFlatConfigByProvider, (zFlatConfig, name) => {
R.mapValues(zFlatConfigByIntId, (zFlatConfig, intId) => {
try {
const subEnv = R.pipe(
filterObject(env, (key) => key.startsWith(`int_${name}`)),
filterObject(env, (key) => key.startsWith(intId)),
R.mapKeys((key) => key.split('__').slice(1).join('__')),
(sEnv) => (Object.keys(sEnv).length ? sEnv : undefined),
)
Expand All @@ -120,7 +119,7 @@ export function parseIntConfigsFromEnv(
// const msg = issue.code === 'invalid_type' && issue.message === 'Required' ? ``
throw new Error(
`Failed to configure "${name}" provider due to invalid env var "${[
`int_${name}`,
intId,
...issue.path,
].join('__')}": ${issue.message} [${issue.code}]`,
)
Expand All @@ -130,17 +129,3 @@ export function parseIntConfigsFromEnv(
(configMap) => filterObject(configMap, (_, val) => val !== undefined),
)
}

// loadEnv()
// const env = zParser(zAllEnv).parseUnknown(process.env)
// const configs = parseIntConfigs(env)
// console.log(env, configs)
// beancount: undefined,
// onebrick: getEnv('ONEBRICK_CREDENTIALS'),
// alka: {
// baseDir: './data',
// // serviceAccountJson: safeJSONParse(
// // process.env['FIREBASE_SERVICE_ACCOUNT_STAGING'],
// // ),
// // envName: 'staging',
// },
9 changes: 8 additions & 1 deletion packages/@integrations/integration-plaid/PlaidProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ const _def = makeSyncProvider.def({
name: z.literal('plaid'),
// There is a mixing of cases here... Unfortunately...
integrationConfig: zPlaidClientConfig.extend({
clientName: z.string().max(30),
clientName: z
.string()
.max(30)
.describe(
`The name of your application, as it should be displayed in Link.
Maximum length of 30 characters.
If a value longer than 30 characters is provided, Link will display "This Application" instead.`,
),
}),
connectionSettings: z.object({
itemId: z.string().nullish(),
Expand Down
6 changes: 3 additions & 3 deletions packages/@utils/util/env-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ function flattenZObject<T extends z.ZodTypeAny>(
// console.log('schema def', prefixes, schema._def)

return {
[prefixes.join('__')]: z
[prefixes.join(separator)]: z
.string()
.optional()
.describe(
`${schema.isOptional() ? '[Optional]' : '<Required>'} ${
(schema._def ).typeName ?? ''
} ${schema.description ?? ''}`,
schema.description ?? ''
}`,
),
}
}
Expand Down

0 comments on commit 3b3a5de

Please sign in to comment.