mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): refactor the code editor type definition (#5516)
* refactor(console): refactor the code editor type definition refactor the code editor type definition * refactor(console): extract type definition gen process extract the type definition gen step to the build time. As typescript is not available at run time. * fix(console): add generate to console build script add generate to console build script * fix(console): add prettier format add prettier format
This commit is contained in:
parent
23bc5cdc8e
commit
08acdf73e3
16 changed files with 251 additions and 62 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -35,3 +35,6 @@ dump.rdb
|
|||
|
||||
# connectors
|
||||
/packages/core/connectors
|
||||
|
||||
# console auto generated files
|
||||
/packages/console/src/consts/jwt-customizer-type-definition.ts
|
||||
|
|
12
packages/console/generate.sh
Executable file
12
packages/console/generate.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Clean up
|
||||
rm -rf scripts-js/
|
||||
# build the jwt-customizer-type-definition generate script
|
||||
pnpm exec tsc -p tsconfig.scripts.gen.json
|
||||
# clean up the existing generated jwt-customizer-type-definition file
|
||||
rm -f src/consts/jwt-customizer-type-definition.ts
|
||||
# run script
|
||||
node scripts-js/generate-jwt-customizer-type-definition.js
|
||||
# Clean up
|
||||
rm -rf scripts-js/
|
|
@ -11,11 +11,13 @@
|
|||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"prepack": "pnpm generate",
|
||||
"generate": "./generate.sh",
|
||||
"precommit": "lint-staged",
|
||||
"start": "parcel src/index.html",
|
||||
"dev": "cross-env PORT=5002 parcel src/index.html --public-url ${CONSOLE_PUBLIC_URL:-/console} --no-cache --hmr-port 6002",
|
||||
"check": "tsc --noEmit",
|
||||
"build": "pnpm check && rm -rf dist && parcel build src/index.html --no-autoinstall --no-cache --public-url ${CONSOLE_PUBLIC_URL:-/console}",
|
||||
"build": "pnpm generate && pnpm check && rm -rf dist && parcel build src/index.html --no-autoinstall --no-cache --public-url ${CONSOLE_PUBLIC_URL:-/console}",
|
||||
"lint": "eslint --ext .ts --ext .tsx src",
|
||||
"lint:report": "pnpm lint --format json --output-file report.json",
|
||||
"stylelint": "stylelint \"src/**/*.scss\"",
|
||||
|
@ -121,7 +123,8 @@
|
|||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.3.3",
|
||||
"zod": "^3.22.4"
|
||||
"zod": "^3.22.4",
|
||||
"zod-to-ts": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.9.0"
|
||||
|
@ -141,6 +144,12 @@
|
|||
},
|
||||
"eslintConfig": {
|
||||
"extends": "@silverhand/react",
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"./tsconfig.json",
|
||||
"./tsconfig.scripts.gen.json"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
"react/function-component-definition": [
|
||||
"error",
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import fs from 'node:fs';
|
||||
|
||||
import {
|
||||
jwtCustomizerUserContextGuard,
|
||||
accessTokenPayloadGuard,
|
||||
clientCredentialsPayloadGuard,
|
||||
} from '@logto/schemas';
|
||||
import prettier from 'prettier';
|
||||
import { type ZodTypeAny } from 'zod';
|
||||
import { zodToTs, printNode } from 'zod-to-ts';
|
||||
|
||||
const filePath = 'src/consts/jwt-customizer-type-definition.ts';
|
||||
|
||||
const typeIdentifiers = `export enum JwtCustomizerTypeDefinitionKey {
|
||||
JwtCustomizerUserContext = 'JwtCustomizerUserContext',
|
||||
AccessTokenPayload = 'AccessTokenPayload',
|
||||
ClientCredentialsPayload = 'ClientCredentialsPayload',
|
||||
EnvironmentVariables = 'EnvironmentVariables',
|
||||
};`;
|
||||
|
||||
const inferTsDefinitionFromZod = (zodSchema: ZodTypeAny, identifier: string): string => {
|
||||
const { node } = zodToTs(zodSchema, identifier);
|
||||
const typeDefinition = printNode(node);
|
||||
|
||||
return `type ${identifier} = ${typeDefinition};`;
|
||||
};
|
||||
|
||||
// Create the jwt-customizer-type-definition.ts file
|
||||
const createJwtCustomizerTypeDefinitions = async () => {
|
||||
const jwtCustomizerUserContextTypeDefinition = inferTsDefinitionFromZod(
|
||||
jwtCustomizerUserContextGuard,
|
||||
'JwtCustomizerUserContext'
|
||||
);
|
||||
|
||||
const accessTokenPayloadTypeDefinition = inferTsDefinitionFromZod(
|
||||
accessTokenPayloadGuard,
|
||||
'AccessTokenPayload'
|
||||
);
|
||||
|
||||
const clientCredentialsPayloadTypeDefinition = inferTsDefinitionFromZod(
|
||||
clientCredentialsPayloadGuard,
|
||||
'ClientCredentialsPayload'
|
||||
);
|
||||
|
||||
const fileContent = `/* This file is auto-generated. Do not modify it manually. */
|
||||
${typeIdentifiers}
|
||||
|
||||
export const jwtCustomizerUserContextTypeDefinition = \`${jwtCustomizerUserContextTypeDefinition}\`;
|
||||
|
||||
export const accessTokenPayloadTypeDefinition = \`${accessTokenPayloadTypeDefinition}\`;
|
||||
|
||||
export const clientCredentialsPayloadTypeDefinition = \`${clientCredentialsPayloadTypeDefinition}\`;
|
||||
`;
|
||||
|
||||
const formattedFileContent = await prettier.format(fileContent, {
|
||||
parser: 'typescript',
|
||||
tabWidth: 2,
|
||||
singleQuote: true,
|
||||
});
|
||||
|
||||
fs.writeFileSync(filePath, formattedFileContent);
|
||||
};
|
||||
|
||||
void createJwtCustomizerTypeDefinitions();
|
|
@ -17,7 +17,11 @@ import ScriptSection from './ScriptSection';
|
|||
import SettingsSection from './SettingsSection';
|
||||
import * as styles from './index.module.scss';
|
||||
import { type JwtClaimsFormType } from './type';
|
||||
import { formatResponseDataToFormData, formatFormDataToRequestData, getApiPath } from './utils';
|
||||
import {
|
||||
formatResponseDataToFormData,
|
||||
formatFormDataToRequestData,
|
||||
getApiPath,
|
||||
} from './utils/format';
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
|
@ -100,7 +104,7 @@ function Main({
|
|||
onDiscard={reset}
|
||||
onSubmit={onSubmitHandler}
|
||||
/>
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={isDirty && !isSubmitting} />
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={isDirty && !isSubmitting} onConfirm={reset} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type Props = {
|
|||
activeModelName?: string;
|
||||
setActiveModel?: (name: string) => void;
|
||||
value?: string;
|
||||
environmentVariablesDefinition?: string;
|
||||
onChange?: (value: string | undefined) => void;
|
||||
onMountHandler?: (editor: IStandaloneCodeEditor) => void;
|
||||
};
|
||||
|
@ -37,6 +38,7 @@ type Props = {
|
|||
* @param {(name: string) => void} prop.setActiveModel - The callback function to set the active model. Used to switch between tabs.
|
||||
* @param {string} prop.value - The value of the code editor for the current active model.
|
||||
* @param {(value: string | undefined) => void} prop.onChange - The callback function to handle the value change of the code editor.
|
||||
* @param {string} [prop.environmentVariablesDefinition] - The environment variables type definition for the script section.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
|
@ -46,6 +48,7 @@ function MonacoCodeEditor({
|
|||
models,
|
||||
activeModelName,
|
||||
value,
|
||||
environmentVariablesDefinition,
|
||||
setActiveModel,
|
||||
onChange,
|
||||
onMountHandler,
|
||||
|
@ -71,19 +74,28 @@ function MonacoCodeEditor({
|
|||
|
||||
// Set the global declarations for the active model
|
||||
// @see {@link https://microsoft.github.io/monaco-editor/typedoc/interfaces/languages.typescript.LanguageServiceDefaults.html#setExtraLibs}
|
||||
if (activeModel.globalDeclarations) {
|
||||
monaco.languages.typescript.typescriptDefaults.setExtraLibs([
|
||||
{
|
||||
content: activeModel.globalDeclarations,
|
||||
filePath: `file:///global.d.ts`,
|
||||
},
|
||||
]);
|
||||
if (activeModel.extraLibs) {
|
||||
monaco.languages.typescript.typescriptDefaults.setExtraLibs(activeModel.extraLibs);
|
||||
}
|
||||
}, [activeModel, monaco]);
|
||||
|
||||
// Set the environment variables type definition for the active model
|
||||
if (environmentVariablesDefinition) {
|
||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||
environmentVariablesDefinition,
|
||||
'environmentVariables.d.ts'
|
||||
);
|
||||
}
|
||||
}, [activeModel, monaco, environmentVariablesDefinition]);
|
||||
|
||||
const handleEditorWillMount = useCallback<BeforeMount>((monaco) => {
|
||||
// Register the new logto theme
|
||||
monaco.editor.defineTheme('logto-dark', logtoDarkTheme);
|
||||
|
||||
// Set the typescript compiler options
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
||||
allowNonTsExtensions: true,
|
||||
strictNullChecks: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleEditorDidMount = useCallback<OnMount>(
|
||||
|
|
|
@ -4,6 +4,11 @@ export type IStandaloneThemeData = Parameters<Monaco['editor']['defineTheme']>[1
|
|||
|
||||
export type IStandaloneCodeEditor = Parameters<OnMount>[0];
|
||||
|
||||
type ExtraLibrary = {
|
||||
content: string;
|
||||
filePath: string;
|
||||
};
|
||||
|
||||
export type ModelSettings = {
|
||||
/** Used as the unique key for the monaco editor model @see {@link https://github.com/suren-atoyan/monaco-react?tab=readme-ov-file#multi-model-editor} */
|
||||
name: string;
|
||||
|
@ -19,7 +24,7 @@ export type ModelSettings = {
|
|||
* @see {@link https://microsoft.github.io/monaco-editor/typedoc/interfaces/languages.typescript.LanguageServiceDefaults.html#setExtraLibs}
|
||||
* We use this to load the global type declarations for the active model
|
||||
*/
|
||||
globalDeclarations?: string;
|
||||
extraLibs?: ExtraLibrary[];
|
||||
};
|
||||
|
||||
export type ModelControl = {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
/* Code Editor for the custom JWT claims script. */
|
||||
import { LogtoJwtTokenPath } from '@logto/schemas';
|
||||
import { useMemo, useContext, useCallback } from 'react';
|
||||
import { useFormContext, Controller } from 'react-hook-form';
|
||||
import { useFormContext, Controller, useWatch } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Card from '@/ds-components/Card';
|
||||
|
||||
import { CodeEditorLoadingContext } from './CodeEditorLoadingContext';
|
||||
import MonacoCodeEditor, { type ModelSettings } from './MonacoCodeEditor';
|
||||
import { userJwtFile, machineToMachineJwtFile } from './config';
|
||||
import * as styles from './index.module.scss';
|
||||
import { type JwtClaimsFormType } from './type';
|
||||
import { accessTokenJwtCustomizerModel, clientCredentialsModel } from './utils/config';
|
||||
import { buildEnvironmentVariablesTypeDefinition } from './utils/type-definitions';
|
||||
|
||||
const titlePhrases = Object.freeze({
|
||||
[LogtoJwtTokenPath.AccessToken]: 'user_jwt',
|
||||
|
@ -21,12 +22,28 @@ function ScriptSection() {
|
|||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
const { watch, control } = useFormContext<JwtClaimsFormType>();
|
||||
|
||||
const tokenType = watch('tokenType');
|
||||
|
||||
// Need to use useWatch hook to subscribe the mutation of the environmentVariables field
|
||||
// Otherwise, the default watch function's return value won't mutate when the environmentVariables field changes
|
||||
const envVariables = useWatch({
|
||||
control,
|
||||
name: 'environmentVariables',
|
||||
});
|
||||
|
||||
const environmentVariablesTypeDefinition = useMemo(
|
||||
() => buildEnvironmentVariablesTypeDefinition(envVariables),
|
||||
[envVariables]
|
||||
);
|
||||
|
||||
const { setIsMonacoLoaded } = useContext(CodeEditorLoadingContext);
|
||||
|
||||
const activeModel = useMemo<ModelSettings>(
|
||||
() => (tokenType === LogtoJwtTokenPath.AccessToken ? userJwtFile : machineToMachineJwtFile),
|
||||
() =>
|
||||
tokenType === LogtoJwtTokenPath.AccessToken
|
||||
? accessTokenJwtCustomizerModel
|
||||
: clientCredentialsModel,
|
||||
[tokenType]
|
||||
);
|
||||
|
||||
|
@ -54,6 +71,7 @@ function ScriptSection() {
|
|||
models={[activeModel]}
|
||||
activeModelName={activeModel.name}
|
||||
value={value}
|
||||
environmentVariablesDefinition={environmentVariablesTypeDefinition}
|
||||
onChange={(newValue) => {
|
||||
// If the value is the same as the default code and the original form script value is undefined, reset the value to undefined as well
|
||||
if (newValue === activeModel.defaultValue && !defaultValues?.script) {
|
||||
|
|
|
@ -7,13 +7,13 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import Table from '@/ds-components/Table';
|
||||
|
||||
import { type JwtClaimsFormType } from '../type';
|
||||
import {
|
||||
userDataDescription,
|
||||
tokenDataDescription,
|
||||
fetchExternalDataEditorOptions,
|
||||
fetchExternalDataCodeExample,
|
||||
} from '../config';
|
||||
import { type JwtClaimsFormType } from '../type';
|
||||
} from '../utils/config';
|
||||
|
||||
import EnvironmentVariablesField from './EnvironmentVariablesField';
|
||||
import GuideCard, { CardType } from './GuideCard';
|
||||
|
|
|
@ -8,12 +8,12 @@ import Button from '@/ds-components/Button';
|
|||
import Card from '@/ds-components/Card';
|
||||
|
||||
import MonacoCodeEditor, { type ModelControl } from '../MonacoCodeEditor/index.js';
|
||||
import { type JwtClaimsFormType } from '../type.js';
|
||||
import {
|
||||
userTokenPayloadTestModel,
|
||||
machineToMachineTokenPayloadTestModel,
|
||||
userTokenContextTestModel,
|
||||
} from '../config.js';
|
||||
import { type JwtClaimsFormType } from '../type.js';
|
||||
} from '../utils/config.js';
|
||||
|
||||
import TestResult, { type TestResultData } from './TestResult.js';
|
||||
import * as styles from './index.module.scss';
|
||||
|
|
|
@ -11,7 +11,7 @@ import useApi from '@/hooks/use-api';
|
|||
import useSwrFetcher from '@/hooks/use-swr-fetcher';
|
||||
import { shouldRetryOnError } from '@/utils/request';
|
||||
|
||||
import { getApiPath } from './utils';
|
||||
import { getApiPath } from './utils/format';
|
||||
|
||||
function useJwtCustomizer() {
|
||||
const fetchApi = useApi({ hideErrorToast: true });
|
||||
|
|
|
@ -3,52 +3,40 @@ import { type EditorProps } from '@monaco-editor/react';
|
|||
import TokenFileIcon from '@/assets/icons/token-file-icon.svg';
|
||||
import UserFileIcon from '@/assets/icons/user-file-icon.svg';
|
||||
|
||||
import type { ModelSettings } from './MonacoCodeEditor/type.js';
|
||||
import type { ModelSettings } from '../MonacoCodeEditor/type.js';
|
||||
|
||||
import {
|
||||
JwtCustomizerTypeDefinitionKey,
|
||||
buildAccessTokenJwtCustomizerContextTsDefinition,
|
||||
buildClientCredentialsJwtCustomizerContextTsDefinition,
|
||||
} from './type-definitions.js';
|
||||
|
||||
/**
|
||||
* JWT token code editor configuration
|
||||
*/
|
||||
const userJwtGlobalDeclarations = `
|
||||
const accessTokenJwtCustomizerDefinition = `
|
||||
declare global {
|
||||
export interface CustomJwtClaims extends Record<string, any> {}
|
||||
|
||||
/** The user info associated with the token.
|
||||
*
|
||||
* @param {string} id - The user id
|
||||
* @param {string} [primaryEmail] - The user email
|
||||
* @param {string} [primaryPhone] - The user phone
|
||||
* @param {string} [username] - The user username
|
||||
* @param {string} [name] - The user name
|
||||
* @param {string} [avatar] - The user avatar
|
||||
*
|
||||
*/
|
||||
export type User = {
|
||||
id: string;
|
||||
primaryEmail?: string;
|
||||
primaryPhone?: string;
|
||||
username?: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
}
|
||||
|
||||
/** Logto internal data that can be used to pass additional information
|
||||
* @param {User} user - The user info associated with the token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.JwtCustomizerUserContext}} user - The user info associated with the token.
|
||||
*/
|
||||
export type Data = {
|
||||
user: User;
|
||||
user: ${JwtCustomizerTypeDefinitionKey.JwtCustomizerUserContext};
|
||||
}
|
||||
|
||||
export interface Exports {
|
||||
/**
|
||||
* This function is called to get custom claims for the JWT token.
|
||||
*
|
||||
* @param {string} token -The JWT token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.AccessTokenPayload}} token -The JWT token.
|
||||
* @param {Data} data - Logto internal data that can be used to pass additional information
|
||||
* @param {User} data.user - The user info associated with the token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.JwtCustomizerUserContext}} data.user - The user info associated with the token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.EnvironmentVariables}} envVariables - The environment variables.
|
||||
*
|
||||
* @returns The custom claims.
|
||||
*/
|
||||
getCustomJwtClaims: (token: string, data: Data) => Promise<CustomJwtClaims>;
|
||||
getCustomJwtClaims: (token: ${JwtCustomizerTypeDefinitionKey.AccessTokenPayload}, data: Data, envVariables: ${JwtCustomizerTypeDefinitionKey.EnvironmentVariables}) => Promise<CustomJwtClaims>;
|
||||
}
|
||||
|
||||
const exports: Exports;
|
||||
|
@ -57,7 +45,7 @@ declare global {
|
|||
export { exports as default };
|
||||
`;
|
||||
|
||||
const machineToMachineJwtGlobalDeclarations = `
|
||||
const clientCredentialsJwtCustomizerDefinition = `
|
||||
declare global {
|
||||
export interface CustomJwtClaims extends Record<string, any> {}
|
||||
|
||||
|
@ -65,11 +53,11 @@ declare global {
|
|||
/**
|
||||
* This function is called to get custom claims for the JWT token.
|
||||
*
|
||||
* @param {string} token -The JWT token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.ClientCredentialsPayload}} token -The JWT token.
|
||||
*
|
||||
* @returns The custom claims.
|
||||
*/
|
||||
getCustomJwtClaims: (token: string) => Promise<CustomJwtClaims>;
|
||||
getCustomJwtClaims: (token: ${JwtCustomizerTypeDefinitionKey.ClientCredentialsPayload}, envVariables: ${JwtCustomizerTypeDefinitionKey.EnvironmentVariables}) => Promise<CustomJwtClaims>;
|
||||
}
|
||||
|
||||
const exports: Exports;
|
||||
|
@ -78,12 +66,13 @@ declare global {
|
|||
export { exports as default };
|
||||
`;
|
||||
|
||||
const defaultUserJwtClaimsCode = `/**
|
||||
const defaultAccessTokenJwtCustomizerCode = `/**
|
||||
* This function is called to get custom claims for the JWT token.
|
||||
*
|
||||
* @param {string} token -The JWT token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.AccessTokenPayload}} token -The JWT token.
|
||||
* @param {Data} data - Logto internal data that can be used to pass additional information
|
||||
* @param {User} data.user - The user info associated with the token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.JwtCustomizerUserContext}} data.user - The user info associated with the token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.EnvironmentVariables}} [envVariables] - The environment variables.
|
||||
*
|
||||
* @returns The custom claims.
|
||||
*/
|
||||
|
@ -92,10 +81,11 @@ exports.getCustomJwtClaims = async (token, data) => {
|
|||
return {};
|
||||
}`;
|
||||
|
||||
const defaultMachineToMachineJwtClaimsCode = `/**
|
||||
const defaultClientCredentialsJwtCustomizerCode = `/**
|
||||
* This function is called to get custom claims for the JWT token.
|
||||
*
|
||||
* @param {string} token -The JWT token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.ClientCredentialsPayload}} token -The JWT token.
|
||||
* @param {${JwtCustomizerTypeDefinitionKey.EnvironmentVariables}} [envVariables] - The environment variables.
|
||||
*
|
||||
* @returns The custom claims.
|
||||
*/
|
||||
|
@ -104,20 +94,38 @@ exports.getCustomJwtClaims = async (token) => {
|
|||
return {};
|
||||
}`;
|
||||
|
||||
export const userJwtFile: ModelSettings = {
|
||||
export const accessTokenJwtCustomizerModel: ModelSettings = {
|
||||
name: 'user-jwt.ts',
|
||||
title: 'TypeScript',
|
||||
language: 'typescript',
|
||||
defaultValue: defaultUserJwtClaimsCode,
|
||||
globalDeclarations: userJwtGlobalDeclarations,
|
||||
defaultValue: defaultAccessTokenJwtCustomizerCode,
|
||||
extraLibs: [
|
||||
{
|
||||
content: accessTokenJwtCustomizerDefinition,
|
||||
filePath: `file:///logto-jwt-customizer.d.ts`,
|
||||
},
|
||||
{
|
||||
content: buildAccessTokenJwtCustomizerContextTsDefinition(),
|
||||
filePath: `file:///logto-jwt-customizer-context.d.ts`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const machineToMachineJwtFile: ModelSettings = {
|
||||
export const clientCredentialsModel: ModelSettings = {
|
||||
name: 'machine-to-machine-jwt.ts',
|
||||
title: 'TypeScript',
|
||||
language: 'typescript',
|
||||
defaultValue: defaultMachineToMachineJwtClaimsCode,
|
||||
globalDeclarations: machineToMachineJwtGlobalDeclarations,
|
||||
defaultValue: defaultClientCredentialsJwtCustomizerCode,
|
||||
extraLibs: [
|
||||
{
|
||||
content: clientCredentialsJwtCustomizerDefinition,
|
||||
filePath: `file:///logto-jwt-customizer.d.ts`,
|
||||
},
|
||||
{
|
||||
content: buildClientCredentialsJwtCustomizerContextTsDefinition(),
|
||||
filePath: `file:///logto-jwt-customizer-context.d.ts`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
|
@ -4,7 +4,7 @@ import {
|
|||
type ClientCredentialsJwtCustomizer,
|
||||
} from '@logto/schemas';
|
||||
|
||||
import type { JwtClaimsFormType } from './type';
|
||||
import type { JwtClaimsFormType } from '../type';
|
||||
|
||||
const formatEnvVariablesResponseToFormData = (
|
||||
enVariables?: AccessTokenJwtCustomizer['envVars']
|
|
@ -0,0 +1,34 @@
|
|||
import {
|
||||
JwtCustomizerTypeDefinitionKey,
|
||||
accessTokenPayloadTypeDefinition,
|
||||
jwtCustomizerUserContextTypeDefinition,
|
||||
clientCredentialsPayloadTypeDefinition,
|
||||
} from '@/consts/jwt-customizer-type-definition';
|
||||
|
||||
import { type JwtClaimsFormType } from '../type';
|
||||
|
||||
export { JwtCustomizerTypeDefinitionKey } from '@/consts/jwt-customizer-type-definition';
|
||||
|
||||
export const buildAccessTokenJwtCustomizerContextTsDefinition = () => {
|
||||
return `declare ${jwtCustomizerUserContextTypeDefinition}
|
||||
|
||||
declare ${accessTokenPayloadTypeDefinition}`;
|
||||
};
|
||||
|
||||
export const buildClientCredentialsJwtCustomizerContextTsDefinition = () =>
|
||||
`declare ${clientCredentialsPayloadTypeDefinition}`;
|
||||
|
||||
export const buildEnvironmentVariablesTypeDefinition = (
|
||||
envVariables?: JwtClaimsFormType['environmentVariables']
|
||||
) => {
|
||||
const typeDefinition = envVariables
|
||||
? `{
|
||||
${envVariables
|
||||
.filter(({ key }) => Boolean(key))
|
||||
.map(({ key }) => `${key}: string`)
|
||||
.join(';\n')}
|
||||
}`
|
||||
: 'undefined';
|
||||
|
||||
return `declare type ${JwtCustomizerTypeDefinitionKey.EnvironmentVariables} = ${typeDefinition}`;
|
||||
};
|
7
packages/console/tsconfig.scripts.gen.json
Normal file
7
packages/console/tsconfig.scripts.gen.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "@silverhand/ts-config/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"outDir": "scripts-js"
|
||||
},
|
||||
"include": ["scripts"]
|
||||
}
|
|
@ -3200,6 +3200,9 @@ importers:
|
|||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
zod-to-ts:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(typescript@5.3.3)(zod@3.22.4)
|
||||
|
||||
packages/core:
|
||||
dependencies:
|
||||
|
@ -21483,6 +21486,16 @@ packages:
|
|||
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
/zod-to-ts@1.2.0(typescript@5.3.3)(zod@3.22.4):
|
||||
resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==}
|
||||
peerDependencies:
|
||||
typescript: ^4.9.4 || ^5.0.2
|
||||
zod: ^3
|
||||
dependencies:
|
||||
typescript: 5.3.3
|
||||
zod: 3.22.4
|
||||
dev: true
|
||||
|
||||
/zod@3.22.4:
|
||||
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
|
||||
requiresBuild: true
|
||||
|
|
Loading…
Reference in a new issue