Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for rendering the prompt-screen's settings - EA #998

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 42 additions & 5 deletions src/context/directory/handlers/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import { ensureDirSync, writeFileSync } from 'fs-extra';
import { constants, loadFileAndReplaceKeywords } from '../../../tools';
import { dumpJSON, existsMustBeDir, isFile, loadJSON } from '../../../utils';
import { getFiles, dumpJSON, existsMustBeDir, isFile, loadJSON } from '../../../utils';
import { DirectoryHandler } from '.';
import DirectoryContext from '..';
import { ParsedAsset } from '../../../types';
Expand All @@ -15,6 +15,7 @@ import {
Prompts,
PromptSettings,
ScreenConfig,
ScreenRenderer,
} from '../../../tools/auth0/handlers/prompts';

type ParsedPrompts = ParsedAsset<'prompts', Prompts>;
Expand All @@ -29,6 +30,9 @@ const getCustomTextFile = (promptsDirectory: string) =>

const getPartialsFile = (promptsDirectory: string) => path.join(promptsDirectory, 'partials.json');

const getScreenRenderSettingsDir = (promptsDirectory: string) =>
path.join(promptsDirectory, 'screenRenderSettings');

function parse(context: DirectoryContext): ParsedPrompts {
const promptsDirectory = getPromptsDirectory(context.filePath);
if (!existsMustBeDir(promptsDirectory)) return { prompts: null }; // Skip
Expand Down Expand Up @@ -68,9 +72,9 @@ function parse(context: DirectoryContext): ParsedPrompts {
const templateFilePath = path.join(promptsDirectory, template);
insertionAcc[name] = isFile(templateFilePath)
? loadFileAndReplaceKeywords(templateFilePath, {
mappings: context.mappings,
disableKeywordReplacement: context.disableKeywordReplacement,
}).trim()
mappings: context.mappings,
disableKeywordReplacement: context.disableKeywordReplacement,
}).trim()
: '';
return insertionAcc;
},
Expand All @@ -84,11 +88,31 @@ function parse(context: DirectoryContext): ParsedPrompts {
}, {} as Record<CustomPartialsPromptTypes, Record<CustomPartialsScreenTypes, Record<string, string>>>);
})();

const screenRenderers = (() => {
const screenRenderSettingsDir = getScreenRenderSettingsDir(promptsDirectory);
if (!existsMustBeDir(screenRenderSettingsDir)) return [];

const screenSettingsFiles = getFiles(screenRenderSettingsDir, ['.json']);

const renderSettings: ScreenRenderer[] = screenSettingsFiles.map((f) => {
const renderSetting = {
...loadJSON(f, {
mappings: context.mappings,
disableKeywordReplacement: context.disableKeywordReplacement,
}),
};
return renderSetting as ScreenRenderer;
});

return renderSettings as ScreenRenderer[];
})();

return {
prompts: {
...promptsSettings,
customText,
partials,
screenRenderers,
},
};
}
Expand All @@ -98,7 +122,7 @@ async function dump(context: DirectoryContext): Promise<void> {

if (!prompts) return;

const { customText, partials, ...promptsSettings } = prompts;
const { customText, partials, screenRenderers, ...promptsSettings } = prompts;

const promptsDirectory = getPromptsDirectory(context.filePath);
ensureDirSync(promptsDirectory);
Expand Down Expand Up @@ -144,6 +168,19 @@ async function dump(context: DirectoryContext): Promise<void> {
}, {} as CustomPartialsConfig);

dumpJSON(partialsFile, transformedPartials);

if (!screenRenderers) return;
const screenRenderSettingsDir = getScreenRenderSettingsDir(promptsDirectory);
ensureDirSync(screenRenderSettingsDir);

for (let index = 0; index < screenRenderers.length; index++) {
const screenRenderersSetting = screenRenderers[index];
delete screenRenderersSetting.tenant;
const fileName = `${screenRenderersSetting.prompt}_${screenRenderersSetting.screen}.json`;
const screenSettingsFilePath = path.join(screenRenderSettingsDir, fileName);

dumpJSON(screenSettingsFilePath, screenRenderersSetting);
}
}

const promptsHandler: DirectoryHandler<ParsedPrompts> = {
Expand Down
117 changes: 114 additions & 3 deletions src/context/yaml/handlers/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,134 @@
import path from 'path';
import { ensureDirSync } from 'fs-extra';
import fs from 'fs';
import { GetRendering200Response } from 'auth0';
import { YAMLHandler } from '.';
import YAMLContext from '..';
import { constants } from '../../../tools';
import { ParsedAsset } from '../../../types';
import { Prompts } from '../../../tools/auth0/handlers/prompts';
import { existsMustBeDir } from '../../../utils';

const getPromptsDirectory = (filePath: string) => path.join(filePath, constants.PROMPTS_DIRECTORY);

type ParsedPrompts = ParsedAsset<'prompts', Prompts>;

async function parseAndDump(context: YAMLContext): Promise<ParsedPrompts> {
// Type for the screen render array
type ScreenRenderArray = Array<{
kushalshit27 marked this conversation as resolved.
Show resolved Hide resolved
[prompt: string]: {
[screen: string]: string // filename
}
}>;

const loadScreenRenderers = (screenRenderArray: ScreenRenderArray, inputDir: string): GetRendering200Response[] => {
// Array to store loaded renderers
const loadedRenderers: GetRendering200Response[] = [];

// Iterate through each entry in the ScreenRenderArray
screenRenderArray.forEach(promptEntry => {
// Get the prompt (there will be only one key in each entry)
const prompt = Object.keys(promptEntry)[0];

// Get the screens for this prompt
const screens = promptEntry[prompt];

// Iterate through each screen for this prompt
Object.entries(screens).forEach(([, fileName]) => {
// Construct full file path
const filePath = fileName;

try {
// Read and parse the JSON file
const fileContent = fs.readFileSync(filePath, 'utf8');
const rendererData = JSON.parse(fileContent);

// Add to the loadedRenderers array
loadedRenderers.push(rendererData);
} catch (error) {
console.error(`Error loading file ${fileName}:`, error);
}
});
});

return loadedRenderers;
};

async function parse(context: YAMLContext): Promise<ParsedPrompts> {
const { prompts } = context.assets;
if (!prompts) return { prompts: null };

const promptsDirectory = getPromptsDirectory(context.basePath);
const renderSettingsDir = path.join(promptsDirectory, 'renderSettings');

if (!existsMustBeDir(renderSettingsDir)) {
prompts.screenRenderers = [];
return { prompts: null };
} // Skip

const a = prompts.screenRenderers as ScreenRenderArray;
console.log(a);

prompts.screenRenderers = loadScreenRenderers(a,renderSettingsDir);

return {
prompts,
};
}

const processScreenRenderers = (screenRenderers: any[], outputDir: string) => {
kushalshit27 marked this conversation as resolved.
Show resolved Hide resolved
// Resulting ScreenRenderArray to be returned
const screenRenderArray: ScreenRenderArray = [];

console.log(outputDir);
kushalshit27 marked this conversation as resolved.
Show resolved Hide resolved

// Process each renderer
screenRenderers.forEach(renderer => {
// Create filename in the format: promptName_screenName.json
const fileName = `${renderer.prompt}_${renderer.screen}.json`;
const filePath = path.join(outputDir, fileName);

// Write individual file
fs.writeFileSync(filePath, JSON.stringify(renderer, null, 2));

// Find or create entry for this prompt in the screenRenderArray
let promptEntry = screenRenderArray.find(entry => entry[renderer.prompt]);

if (!promptEntry) {
// If no entry exists for this prompt, create a new one
promptEntry = { [renderer.prompt]: {} };
screenRenderArray.push(promptEntry);
}

// Add screen to the prompt entry
promptEntry[renderer.prompt][renderer.screen] = filePath;
});

return screenRenderArray;
};

async function dump(context: YAMLContext): Promise<ParsedPrompts> {
const { prompts } = context.assets;

if (!prompts) return { prompts: null };

const promptsDirectory = getPromptsDirectory(context.basePath);
ensureDirSync(promptsDirectory);

// Create the directory for render settings if it doesn't exist
const renderSettingsDir = path.join(promptsDirectory, 'renderSettings');
ensureDirSync(renderSettingsDir);

// @ts-ignore
prompts.screenRenderers = processScreenRenderers(prompts.screenRenderers,renderSettingsDir);

return {
prompts,
};
}

const promptsHandler: YAMLHandler<ParsedPrompts> = {
parse: parseAndDump,
dump: parseAndDump,
parse,
dump,
};

export default promptsHandler;
Loading
Loading