UNPKG

envase

Version:

Type-safe environment variable validation with Standard Schema compliance

84 lines 3.73 kB
/** * Generates markdown documentation from extracted environment variables. */ export const generateMarkdown = async (extractedEnvvars) => { const lines = ['# Environment variables', '']; const envvarsByPath = new Map(); for (const envvar of extractedEnvvars) { const key = envvar.path.length > 0 ? envvar.path.join('.') : ''; const envvars = envvarsByPath.get(key); if (envvars) { envvars.push(envvar); } else { envvarsByPath.set(key, [envvar]); } } for (const [path, envvars] of envvarsByPath.entries()) { if (path !== '') { const pathParts = path.split('.'); const sectionName = pathParts .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) .join(' '); lines.push(`## ${sectionName}`, ''); } for (const envvar of envvars) { const jsonSchemaOptions = { target: 'openapi-3.0', libraryOptions: { unrepresentable: 'any', }, }; const inputSchema = envvar.schema['~standard'].jsonSchema.input(jsonSchemaOptions); const outputSchema = envvar.schema['~standard'].jsonSchema.output(jsonSchemaOptions); const mappedType = Array.isArray(outputSchema.anyOf) ? outputSchema.anyOf.map(({ type }) => type) : (outputSchema.type ?? inputSchema.type); const type = Array.isArray(mappedType) ? mappedType.map((type) => `\`${type}\``).join(' | ') : `\`${mappedType}\``; // inputSchema takes precedence (describes accepted format); outputSchema fills // gaps for fields that only exist post-coercion (e.g. default on stringbool) const schema = { ...outputSchema, ...inputSchema }; const validationResult = await envvar.schema['~standard'].validate(undefined); const isOptional = !validationResult.issues; let line = `- \`${envvar.envName}\` (${isOptional ? 'optional' : 'required'})`; line += ` \n Type: ${type}`; if (schema.description) { line += ` \n Description: ${schema.description}`; } if (Array.isArray(schema.enum)) { const enumValues = schema.enum.map((v) => `\`${v}\``).join(' | '); line += ` \n Supported values: ${enumValues}`; } if (schema.format) { line += ` \n Format: \`${schema.format}\``; } if (schema.pattern) { line += ` \n Pattern: \`${schema.pattern}\``; } if (schema.minimum !== undefined && !(schema.type === 'integer' && schema.minimum === Number.MIN_SAFE_INTEGER)) { line += ` \n Min value: \`${schema.minimum}\``; } if (schema.maximum !== undefined && !(schema.type === 'integer' && schema.maximum === Number.MAX_SAFE_INTEGER)) { line += ` \n Max value: \`${schema.maximum}\``; } if (schema.minLength !== undefined) { line += ` \n Min length: \`${schema.minLength}\``; } if (schema.maxLength !== undefined) { line += ` \n Max length: \`${schema.maxLength}\``; } if (schema.default !== undefined) { line += ` \n Default: \`${schema.default}\``; } lines.push(line, ''); } } return lines.join('\n'); }; //# sourceMappingURL=generate-markdown.js.map