frontmcp 0.11.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/args.d.ts +2 -0
- package/src/args.js +2 -0
- package/src/args.js.map +1 -1
- package/src/cli.js +2 -0
- package/src/cli.js.map +1 -1
- package/src/commands/create.d.ts +3 -0
- package/src/commands/create.js +282 -201
- package/src/commands/create.js.map +1 -1
- package/src/commands/install/questionnaire.d.ts +1 -1
- package/src/commands/install/questionnaire.js +73 -96
- package/src/commands/install/questionnaire.js.map +1 -1
- package/src/commands/template.js +81 -67
- package/src/commands/template.js.map +1 -1
- package/src/utils/prompts.d.ts +1 -0
- package/src/utils/prompts.js +17 -0
- package/src/utils/prompts.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questionnaire.js","sourceRoot":"","sources":["../../../../src/commands/install/questionnaire.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interactive setup questionnaire runner.\n * Reads manifest setup steps and prompts the user via Node.js readline.\n */\n\nimport * as readline from 'readline';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { c } from '../../colors';\nimport { ManifestSetupStep } from '../build/exec/manifest';\n\nexport interface QuestionnaireResult {\n answers: Record<string, string>;\n envContent: string;\n}\n\n/**\n * Run the interactive questionnaire from manifest setup steps.\n */\nexport async function runQuestionnaire(\n steps: ManifestSetupStep[],\n opts: { silent?: boolean } = {},\n): Promise<QuestionnaireResult> {\n const answers: Record<string, string> = {};\n\n if (opts.silent) {\n return runSilent(steps);\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const ask = (question: string): Promise<string> =>\n new Promise((resolve) => {\n rl.question(question, (answer) => resolve(answer));\n });\n\n let currentIndex = 0;\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n\n try {\n let currentGroup = '';\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n // Check showWhen conditions\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n // Show group header\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n console.log(`\\n${c('bold', `--- ${currentGroup} ---`)}`);\n }\n\n // Determine prompt based on schema type\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n const value = await promptStep(ask, step, defaultValue);\n\n answers[step.id] = value;\n\n // Determine next step\n currentIndex = resolveNextStep(step, value, currentIndex, stepMap, steps.length);\n }\n } finally {\n rl.close();\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nfunction runSilent(steps: ManifestSetupStep[]): QuestionnaireResult {\n const answers: Record<string, string> = {};\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentIndex = 0;\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n if (defaultValue === undefined || defaultValue === '') {\n // Check if the step is required (no default)\n const isOptional =\n step.jsonSchema.default !== undefined || (step.jsonSchema as Record<string, unknown>).nullable === true;\n\n if (!isOptional) {\n throw new Error(\n `Setup step \"${step.id}\" requires input but --yes mode cannot provide a value. ` +\n `Set a default or provide values via environment variables.`,\n );\n }\n }\n\n answers[step.id] = defaultValue ?? '';\n\n currentIndex = resolveNextStep(step, answers[step.id], currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nasync function promptStep(\n ask: (q: string) => Promise<string>,\n step: ManifestSetupStep,\n defaultValue: string | undefined,\n): Promise<string> {\n const schema = step.jsonSchema;\n\n // Enum → numbered select menu\n if (schema.enum && Array.isArray(schema.enum)) {\n return promptEnum(ask, step, schema.enum as string[], defaultValue);\n }\n\n // Boolean → y/n\n if (schema.type === 'boolean') {\n return promptBoolean(ask, step, defaultValue);\n }\n\n // Default → text input\n return promptText(ask, step, defaultValue);\n}\n\nasync function promptEnum(\n ask: (q: string) => Promise<string>,\n step: ManifestSetupStep,\n options: string[],\n defaultValue: string | undefined,\n): Promise<string> {\n if (step.description) {\n console.log(` ${c('gray', step.description)}`);\n }\n\n for (let i = 0; i < options.length; i++) {\n const marker = options[i] === defaultValue ? c('green', '*') : ' ';\n console.log(` ${marker} ${i + 1}) ${options[i]}`);\n }\n\n while (true) {\n const defaultHint = defaultValue ? ` [${defaultValue}]` : '';\n const input = await ask(`${step.prompt}${defaultHint}: `);\n const trimmed = input.trim();\n\n if (!trimmed && defaultValue) return defaultValue;\n\n // Accept number or value\n const num = parseInt(trimmed, 10);\n if (num >= 1 && num <= options.length) return options[num - 1];\n if (options.includes(trimmed)) return trimmed;\n\n console.log(c('red', ` Invalid choice. Enter 1-${options.length} or a value from the list.`));\n }\n}\n\nasync function promptBoolean(\n ask: (q: string) => Promise<string>,\n step: ManifestSetupStep,\n defaultValue: string | undefined,\n): Promise<string> {\n const defaultHint = defaultValue !== undefined ? ` [${defaultValue === 'true' ? 'Y/n' : 'y/N'}]` : ' [y/N]';\n while (true) {\n const input = await ask(`${step.prompt}${defaultHint}: `);\n const trimmed = input.trim().toLowerCase();\n\n if (!trimmed && defaultValue !== undefined) return defaultValue;\n if (trimmed === 'y' || trimmed === 'yes') return 'true';\n if (trimmed === 'n' || trimmed === 'no') return 'false';\n\n console.log(c('red', ' Please enter y or n.'));\n }\n}\n\nasync function promptText(\n ask: (q: string) => Promise<string>,\n step: ManifestSetupStep,\n defaultValue: string | undefined,\n): Promise<string> {\n if (step.description) {\n console.log(` ${c('gray', step.description)}`);\n }\n\n while (true) {\n const defaultHint = defaultValue ? ` [${step.sensitive ? '****' : defaultValue}]` : '';\n const input = await ask(`${step.prompt}${defaultHint}: `);\n const trimmed = input.trim();\n\n if (!trimmed && defaultValue !== undefined) return defaultValue;\n if (!trimmed) {\n // Check if optional\n const schema = step.jsonSchema;\n if (schema.default !== undefined || (schema as Record<string, unknown>).nullable === true) {\n return '';\n }\n console.log(c('red', ' This field is required.'));\n continue;\n }\n\n // Validate against JSON Schema constraints\n const validationError = validateAgainstSchema(trimmed, step.jsonSchema);\n if (validationError) {\n console.log(c('red', ` ${validationError}`));\n continue;\n }\n\n return trimmed;\n }\n}\n\nfunction validateAgainstSchema(value: string, schema: Record<string, unknown>): string | null {\n if (schema.minLength && typeof schema.minLength === 'number' && value.length < schema.minLength) {\n return `Minimum length is ${schema.minLength}`;\n }\n if (schema.maxLength && typeof schema.maxLength === 'number' && value.length > schema.maxLength) {\n return `Maximum length is ${schema.maxLength}`;\n }\n if (schema.pattern && typeof schema.pattern === 'string') {\n let re: RegExp;\n try {\n re = new RegExp(schema.pattern);\n } catch {\n return `Invalid pattern in schema: ${schema.pattern}`;\n }\n if (!re.test(value)) return `Value must match pattern: ${schema.pattern}`;\n }\n if (schema.type === 'number' || schema.type === 'integer') {\n const n = Number(value);\n if (isNaN(n)) return 'Must be a number';\n if (schema.minimum !== undefined && typeof schema.minimum === 'number' && n < schema.minimum) {\n return `Minimum value is ${schema.minimum}`;\n }\n if (schema.maximum !== undefined && typeof schema.maximum === 'number' && n > schema.maximum) {\n return `Maximum value is ${schema.maximum}`;\n }\n }\n if (schema.format === 'uri') {\n try {\n new URL(value);\n } catch {\n return 'Must be a valid URL';\n }\n }\n return null;\n}\n\nfunction evaluateShowWhen(conditions: Record<string, string | string[]>, answers: Record<string, string>): boolean {\n for (const [stepId, expected] of Object.entries(conditions)) {\n const actual = answers[stepId];\n if (actual === undefined) return false;\n\n if (Array.isArray(expected)) {\n if (!expected.includes(actual)) return false;\n } else {\n if (actual !== expected) return false;\n }\n }\n return true;\n}\n\nfunction resolveNextStep(\n step: ManifestSetupStep,\n answer: string,\n currentIndex: number,\n stepMap: Map<string, number>,\n totalSteps: number,\n): number {\n if (!step.next) return currentIndex + 1;\n\n if (typeof step.next === 'string') {\n const idx = stepMap.get(step.next);\n return idx !== undefined ? idx : totalSteps; // end if target not found\n }\n\n // Record-based routing\n const target = step.next[answer];\n if (target) {\n const idx = stepMap.get(target);\n return idx !== undefined ? idx : totalSteps;\n }\n\n return currentIndex + 1;\n}\n\nfunction getDefaultFromSchema(schema: Record<string, unknown>): string | undefined {\n if (schema.default !== undefined) {\n return String(schema.default);\n }\n return undefined;\n}\n\nfunction answersToEnv(answers: Record<string, string>, steps: ManifestSetupStep[]): string {\n const lines: string[] = ['# Generated by frontmcp install'];\n\n let currentGroup = '';\n for (const step of steps) {\n const value = answers[step.id];\n if (value === undefined) continue;\n\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n lines.push(`\\n# ${currentGroup}`);\n }\n\n const envName = step.env;\n // Quote values that contain special characters\n const needsQuotes = /[\\s#\"'\\\\]/.test(value) || value.includes('=');\n const quotedValue = needsQuotes ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value;\n\n lines.push(`${envName}=${quotedValue}`);\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Write .env file for an installed app.\n */\nexport function writeEnvFile(appDir: string, content: string): void {\n const envPath = path.join(appDir, '.env');\n fs.writeFileSync(envPath, content, 'utf-8');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"questionnaire.js","sourceRoot":"","sources":["../../../../src/commands/install/questionnaire.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interactive setup questionnaire runner.\n * Reads manifest setup steps and prompts the user via @clack/prompts.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { c } from '../../colors';\nimport { ManifestSetupStep } from '../build/exec/manifest';\nimport { clack } from '../../utils/prompts';\n\nexport interface QuestionnaireResult {\n answers: Record<string, string>;\n envContent: string;\n}\n\n/**\n * Run the interactive questionnaire from manifest setup steps.\n */\nexport async function runQuestionnaire(\n steps: ManifestSetupStep[],\n opts: { silent?: boolean } = {},\n): Promise<QuestionnaireResult> {\n const answers: Record<string, string> = {};\n\n if (opts.silent) {\n return runSilent(steps);\n }\n\n const p = await clack();\n\n let currentIndex = 0;\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentGroup = '';\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n // Check showWhen conditions\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n // Show group header\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n p.log.step(`--- ${currentGroup} ---`);\n }\n\n // Determine prompt based on schema type\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n const value = await promptStep(step, defaultValue);\n\n answers[step.id] = value;\n\n // Determine next step\n currentIndex = resolveNextStep(step, value, currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nfunction runSilent(steps: ManifestSetupStep[]): QuestionnaireResult {\n const answers: Record<string, string> = {};\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentIndex = 0;\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n if (defaultValue === undefined || defaultValue === '') {\n // Check if the step is required (no default)\n const isOptional =\n step.jsonSchema.default !== undefined || (step.jsonSchema as Record<string, unknown>).nullable === true;\n\n if (!isOptional) {\n throw new Error(\n `Setup step \"${step.id}\" requires input but --yes mode cannot provide a value. ` +\n `Set a default or provide values via environment variables.`,\n );\n }\n }\n\n answers[step.id] = defaultValue ?? '';\n\n currentIndex = resolveNextStep(step, answers[step.id], currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nasync function promptStep(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const schema = step.jsonSchema;\n\n // Enum → select menu\n if (schema.enum && Array.isArray(schema.enum)) {\n return promptEnum(step, schema.enum as string[], defaultValue);\n }\n\n // Boolean → confirm\n if (schema.type === 'boolean') {\n return promptBoolean(step, defaultValue);\n }\n\n // Default → text input\n return promptText(step, defaultValue);\n}\n\nasync function promptEnum(\n step: ManifestSetupStep,\n options: string[],\n defaultValue: string | undefined,\n): Promise<string> {\n const p = await clack();\n\n const message = step.description ? `${step.prompt}\\n${c('gray', step.description)}` : step.prompt;\n\n const result = await p.select({\n message,\n options: options.map((opt) => ({ label: opt, value: opt })),\n initialValue: defaultValue ?? options[0],\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result;\n}\n\nasync function promptBoolean(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const result = await p.confirm({\n message: step.prompt,\n initialValue: defaultValue === undefined ? false : defaultValue === 'true',\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result ? 'true' : 'false';\n}\n\nasync function promptText(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const schema = step.jsonSchema;\n const isOptional = schema.default !== undefined || (schema as Record<string, unknown>).nullable === true;\n\n const result = await p.text({\n message: step.prompt,\n placeholder: step.description || (step.sensitive && defaultValue ? '****' : undefined),\n defaultValue,\n validate: (val) => {\n const trimmed = val.trim();\n if (!trimmed && !defaultValue && !isOptional) {\n return 'This field is required.';\n }\n if (trimmed) {\n const error = validateAgainstSchema(trimmed, step.jsonSchema);\n if (error) return error;\n }\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result.trim() || defaultValue || '';\n}\n\nfunction validateAgainstSchema(value: string, schema: Record<string, unknown>): string | null {\n if (schema.minLength && typeof schema.minLength === 'number' && value.length < schema.minLength) {\n return `Minimum length is ${schema.minLength}`;\n }\n if (schema.maxLength && typeof schema.maxLength === 'number' && value.length > schema.maxLength) {\n return `Maximum length is ${schema.maxLength}`;\n }\n if (schema.pattern && typeof schema.pattern === 'string') {\n let re: RegExp;\n try {\n re = new RegExp(schema.pattern);\n } catch {\n return `Invalid pattern in schema: ${schema.pattern}`;\n }\n if (!re.test(value)) return `Value must match pattern: ${schema.pattern}`;\n }\n if (schema.type === 'number' || schema.type === 'integer') {\n const n = Number(value);\n if (isNaN(n)) return 'Must be a number';\n if (schema.minimum !== undefined && typeof schema.minimum === 'number' && n < schema.minimum) {\n return `Minimum value is ${schema.minimum}`;\n }\n if (schema.maximum !== undefined && typeof schema.maximum === 'number' && n > schema.maximum) {\n return `Maximum value is ${schema.maximum}`;\n }\n }\n if (schema.format === 'uri') {\n try {\n new URL(value);\n } catch {\n return 'Must be a valid URL';\n }\n }\n return null;\n}\n\nfunction evaluateShowWhen(conditions: Record<string, string | string[]>, answers: Record<string, string>): boolean {\n for (const [stepId, expected] of Object.entries(conditions)) {\n const actual = answers[stepId];\n if (actual === undefined) return false;\n\n if (Array.isArray(expected)) {\n if (!expected.includes(actual)) return false;\n } else {\n if (actual !== expected) return false;\n }\n }\n return true;\n}\n\nfunction resolveNextStep(\n step: ManifestSetupStep,\n answer: string,\n currentIndex: number,\n stepMap: Map<string, number>,\n totalSteps: number,\n): number {\n if (!step.next) return currentIndex + 1;\n\n if (typeof step.next === 'string') {\n const idx = stepMap.get(step.next);\n return idx !== undefined ? idx : totalSteps; // end if target not found\n }\n\n // Record-based routing\n const target = step.next[answer];\n if (target) {\n const idx = stepMap.get(target);\n return idx !== undefined ? idx : totalSteps;\n }\n\n return currentIndex + 1;\n}\n\nfunction getDefaultFromSchema(schema: Record<string, unknown>): string | undefined {\n if (schema.default !== undefined) {\n return String(schema.default);\n }\n return undefined;\n}\n\nfunction answersToEnv(answers: Record<string, string>, steps: ManifestSetupStep[]): string {\n const lines: string[] = ['# Generated by frontmcp install'];\n\n let currentGroup = '';\n for (const step of steps) {\n const value = answers[step.id];\n if (value === undefined) continue;\n\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n lines.push(`\\n# ${currentGroup}`);\n }\n\n const envName = step.env;\n // Quote values that contain special characters\n const needsQuotes = /[\\s#\"'\\\\]/.test(value) || value.includes('=');\n const quotedValue = needsQuotes ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value;\n\n lines.push(`${envName}=${quotedValue}`);\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Write .env file for an installed app.\n */\nexport function writeEnvFile(appDir: string, content: string): void {\n const envPath = path.join(appDir, '.env');\n fs.writeFileSync(envPath, content, 'utf-8');\n}\n"]}
|
package/src/commands/template.js
CHANGED
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.runTemplate = runTemplate;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const path = tslib_1.__importStar(require("path"));
|
|
6
|
-
const readline = tslib_1.__importStar(require("readline"));
|
|
7
6
|
const colors_1 = require("../colors");
|
|
8
7
|
const utils_1 = require("@frontmcp/utils");
|
|
9
8
|
const fs_1 = require("../utils/fs");
|
|
9
|
+
const prompts_1 = require("../utils/prompts");
|
|
10
10
|
/**
|
|
11
11
|
* frontmcp template <templateName>
|
|
12
12
|
*
|
|
@@ -25,76 +25,90 @@ async function runTemplate(templateName) {
|
|
|
25
25
|
console.log((0, colors_1.c)('red', 'Template name is required (e.g. 3rd-party-integration).'));
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
else if (available.includes(sanitized)) {
|
|
48
|
-
selected = sanitized;
|
|
49
|
-
if (sanitized !== name) {
|
|
50
|
-
console.log((0, colors_1.c)('yellow', `[template] Template "${name}" not found, using sanitized "${sanitized}"`));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (!selected) {
|
|
54
|
-
console.log((0, colors_1.c)('red', `Template "${name}" not found under ${path.relative(process.cwd(), templatesRoot)}.`));
|
|
55
|
-
console.log((0, colors_1.c)('gray', '\nAvailable templates:'));
|
|
56
|
-
for (const t of available) {
|
|
57
|
-
console.log(' -', t);
|
|
58
|
-
}
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const templateRoot = path.resolve(templatesRoot, selected);
|
|
62
|
-
console.log((0, colors_1.c)('cyan', '[template]') + ` Using template "${selected}" from src/templates/${selected}`);
|
|
63
|
-
// Ask for owner & service
|
|
64
|
-
let owner = await ask(`Third-party owner (e.g. google, github, slack): `);
|
|
65
|
-
if (!owner) {
|
|
66
|
-
console.log((0, colors_1.c)('red', 'Owner is required.'));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
owner = sanitizeSlug(owner);
|
|
70
|
-
let service = await ask(`Third-party service (e.g. gmail, slack-bot): `);
|
|
71
|
-
if (!service) {
|
|
72
|
-
console.log((0, colors_1.c)('red', 'Service is required.'));
|
|
73
|
-
return;
|
|
28
|
+
const p = await (0, prompts_1.clack)();
|
|
29
|
+
const templatesRoot = path.resolve(__dirname, '..', 'templates');
|
|
30
|
+
// 1) Collect available templates up-front
|
|
31
|
+
const available = await listAvailableTemplates(templatesRoot);
|
|
32
|
+
if (!available.length) {
|
|
33
|
+
console.log((0, colors_1.c)('red', `No templates found under ${path.relative(process.cwd(), templatesRoot)}.`));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// 2) Sanitize the name and choose the actual template folder
|
|
37
|
+
const sanitized = sanitizeTemplateName(name);
|
|
38
|
+
let selected = null;
|
|
39
|
+
if (available.includes(name)) {
|
|
40
|
+
selected = name;
|
|
41
|
+
}
|
|
42
|
+
else if (available.includes(sanitized)) {
|
|
43
|
+
selected = sanitized;
|
|
44
|
+
if (sanitized !== name) {
|
|
45
|
+
console.log((0, colors_1.c)('yellow', `[template] Template "${name}" not found, using sanitized "${sanitized}"`));
|
|
74
46
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!['oauth2', 'bearer', 'apiKey'].includes(authType)) {
|
|
82
|
-
console.log((0, colors_1.c)('red', `Invalid auth type: ${authRaw}`));
|
|
83
|
-
return;
|
|
47
|
+
}
|
|
48
|
+
if (!selected) {
|
|
49
|
+
console.log((0, colors_1.c)('red', `Template "${name}" not found under ${path.relative(process.cwd(), templatesRoot)}.`));
|
|
50
|
+
console.log((0, colors_1.c)('gray', '\nAvailable templates:'));
|
|
51
|
+
for (const t of available) {
|
|
52
|
+
console.log(' -', t);
|
|
84
53
|
}
|
|
85
|
-
|
|
86
|
-
const cwd = process.cwd();
|
|
87
|
-
const destRoot = path.resolve(cwd, 'integrations', owner, service);
|
|
88
|
-
await (0, utils_1.ensureDir)(destRoot);
|
|
89
|
-
console.log((0, colors_1.c)('gray', `[template] Scaffolding into ${path.relative(cwd, destRoot)}`));
|
|
90
|
-
await copyTemplateTree(templateRoot, destRoot, ctx);
|
|
91
|
-
console.log('');
|
|
92
|
-
console.log((0, colors_1.c)('green', '✔ Template hydrated into: ') + path.relative(cwd, destRoot));
|
|
93
|
-
console.log((0, colors_1.c)('gray', 'You can now edit or delete the generated example files and create your own tools.'));
|
|
54
|
+
return;
|
|
94
55
|
}
|
|
95
|
-
|
|
96
|
-
|
|
56
|
+
const templateRoot = path.resolve(templatesRoot, selected);
|
|
57
|
+
console.log((0, colors_1.c)('cyan', '[template]') + ` Using template "${selected}" from src/templates/${selected}`);
|
|
58
|
+
// Ask for owner
|
|
59
|
+
const ownerResult = await p.text({
|
|
60
|
+
message: 'Third-party owner',
|
|
61
|
+
placeholder: 'google, github, slack',
|
|
62
|
+
validate: (val) => {
|
|
63
|
+
if (!val.trim())
|
|
64
|
+
return 'Owner is required.';
|
|
65
|
+
return undefined;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
if (p.isCancel(ownerResult)) {
|
|
69
|
+
p.cancel('Cancelled.');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
const owner = sanitizeSlug(ownerResult);
|
|
73
|
+
// Ask for service
|
|
74
|
+
const serviceResult = await p.text({
|
|
75
|
+
message: 'Third-party service',
|
|
76
|
+
placeholder: 'gmail, slack-bot',
|
|
77
|
+
validate: (val) => {
|
|
78
|
+
if (!val.trim())
|
|
79
|
+
return 'Service is required.';
|
|
80
|
+
return undefined;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
if (p.isCancel(serviceResult)) {
|
|
84
|
+
p.cancel('Cancelled.');
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
const service = sanitizeSlug(serviceResult);
|
|
88
|
+
// Auth type — select instead of free-text
|
|
89
|
+
const authResult = await p.select({
|
|
90
|
+
message: 'Default auth type',
|
|
91
|
+
options: [
|
|
92
|
+
{ label: 'OAuth 2.0', value: 'oauth2' },
|
|
93
|
+
{ label: 'Bearer token', value: 'bearer' },
|
|
94
|
+
{ label: 'API key', value: 'apiKey' },
|
|
95
|
+
],
|
|
96
|
+
initialValue: 'oauth2',
|
|
97
|
+
});
|
|
98
|
+
if (p.isCancel(authResult)) {
|
|
99
|
+
p.cancel('Cancelled.');
|
|
100
|
+
process.exit(0);
|
|
97
101
|
}
|
|
102
|
+
const authType = authResult;
|
|
103
|
+
const ctx = { owner, service, authType };
|
|
104
|
+
const cwd = process.cwd();
|
|
105
|
+
const destRoot = path.resolve(cwd, 'integrations', owner, service);
|
|
106
|
+
await (0, utils_1.ensureDir)(destRoot);
|
|
107
|
+
console.log((0, colors_1.c)('gray', `[template] Scaffolding into ${path.relative(cwd, destRoot)}`));
|
|
108
|
+
await copyTemplateTree(templateRoot, destRoot, ctx);
|
|
109
|
+
console.log('');
|
|
110
|
+
console.log((0, colors_1.c)('green', '✔ Template hydrated into: ') + path.relative(cwd, destRoot));
|
|
111
|
+
console.log((0, colors_1.c)('gray', 'You can now edit or delete the generated example files and create your own tools.'));
|
|
98
112
|
}
|
|
99
113
|
/* -------------------------------------------------------------------------- */
|
|
100
114
|
/* Helpers */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/commands/template.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as readline from 'readline';\nimport { c } from '../colors';\nimport { ensureDir, fileExists } from '@frontmcp/utils';\nimport { fsp } from '../utils/fs';\n\ntype AuthType = 'oauth2' | 'bearer' | 'apiKey';\n\ninterface TemplateContext {\n owner: string;\n service: string;\n authType: AuthType;\n}\n\n/**\n * frontmcp template <templateName>\n *\n * Example:\n * npx frontmcp template 3rd-party-integration\n *\n * This will look for templates in:\n * src/templates/<templateName> (built to dist/templates/<templateName>)\n * and copy them into:\n * integrations/<owner>/<service>\n * with __OWNER__, __SERVICE__, __AUTH_TYPE__ replaced.\n */\nexport async function runTemplate(templateName?: string): Promise<void> {\n const name = (templateName || '').trim();\n if (!name) {\n console.log(c('red', 'Template name is required (e.g. 3rd-party-integration).'));\n return;\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const ask = (q: string): Promise<string> => new Promise((resolve) => rl.question(q, (ans) => resolve(ans.trim())));\n\n try {\n const templatesRoot = path.resolve(__dirname, '..', 'templates');\n\n // 1) Collect available templates up-front\n const available = await listAvailableTemplates(templatesRoot);\n if (!available.length) {\n console.log(c('red', `No templates found under ${path.relative(process.cwd(), templatesRoot)}.`));\n return;\n }\n\n // 2) Sanitize the name and choose the actual template folder\n const sanitized = sanitizeTemplateName(name);\n let selected: string | null = null;\n\n if (available.includes(name)) {\n selected = name;\n } else if (available.includes(sanitized)) {\n selected = sanitized;\n if (sanitized !== name) {\n console.log(c('yellow', `[template] Template \"${name}\" not found, using sanitized \"${sanitized}\"`));\n }\n }\n\n if (!selected) {\n console.log(c('red', `Template \"${name}\" not found under ${path.relative(process.cwd(), templatesRoot)}.`));\n console.log(c('gray', '\\nAvailable templates:'));\n for (const t of available) {\n console.log(' -', t);\n }\n return;\n }\n\n const templateRoot = path.resolve(templatesRoot, selected);\n\n console.log(c('cyan', '[template]') + ` Using template \"${selected}\" from src/templates/${selected}`);\n\n // Ask for owner & service\n let owner = await ask(`Third-party owner (e.g. google, github, slack): `);\n if (!owner) {\n console.log(c('red', 'Owner is required.'));\n return;\n }\n owner = sanitizeSlug(owner);\n\n let service = await ask(`Third-party service (e.g. gmail, slack-bot): `);\n if (!service) {\n console.log(c('red', 'Service is required.'));\n return;\n }\n service = sanitizeSlug(service);\n\n // Auth type (for placeholders only – you can use or ignore in templates)\n let authRaw = await ask(`Default auth type (oauth2/bearer/apiKey) [oauth2]: `);\n if (!authRaw) authRaw = 'oauth2';\n const authType = authRaw as AuthType;\n if (!['oauth2', 'bearer', 'apiKey'].includes(authType)) {\n console.log(c('red', `Invalid auth type: ${authRaw}`));\n return;\n }\n\n const ctx: TemplateContext = { owner, service, authType };\n\n const cwd = process.cwd();\n const destRoot = path.resolve(cwd, 'integrations', owner, service);\n await ensureDir(destRoot);\n\n console.log(c('gray', `[template] Scaffolding into ${path.relative(cwd, destRoot)}`));\n\n await copyTemplateTree(templateRoot, destRoot, ctx);\n\n console.log('');\n console.log(c('green', '✔ Template hydrated into: ') + path.relative(cwd, destRoot));\n console.log(c('gray', 'You can now edit or delete the generated example files and create your own tools.'));\n } finally {\n rl.close();\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction sanitizeSlug(val: string): string {\n return (\n val\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'service'\n );\n}\n\n// More permissive for template folder names (allow . _ -)\nfunction sanitizeTemplateName(val: string): string {\n return (\n val\n .trim()\n .replace(/[^a-zA-Z0-9._-]/g, '-') // replace weird chars\n .replace(/-+/g, '-') // collapse multiple dashes\n .replace(/^-|-$/g, '') || 'template'\n );\n}\n\nasync function dirExists(p: string): Promise<boolean> {\n try {\n const st = await fsp.stat(p);\n return st.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function listAvailableTemplates(templatesRoot: string): Promise<string[]> {\n try {\n const entries = await fsp.readdir(templatesRoot, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\n/**\n * Replace placeholders in both filenames and file contents.\n *\n * Supported placeholders:\n * __OWNER__\n * __SERVICE__\n * __AUTH_TYPE__\n */\nfunction applyPlaceholders(input: string, ctx: TemplateContext): string {\n return input\n .replaceAll('__OWNER__', ctx.owner)\n .replaceAll('__SERVICE__', ctx.service)\n .replaceAll('__AUTH_TYPE__', ctx.authType);\n}\n\nasync function copyTemplateTree(templateRoot: string, destRoot: string, ctx: TemplateContext): Promise<void> {\n const walk = async (srcDir: string) => {\n const entries = await fsp.readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(srcDir, entry.name);\n const relFromRoot = path.relative(templateRoot, srcPath);\n\n // Apply placeholders in path segments too\n const relWithPlaceholders = applyPlaceholders(relFromRoot, ctx);\n const destPath = path.join(destRoot, relWithPlaceholders);\n\n if (entry.isDirectory()) {\n await ensureDir(destPath);\n await walk(srcPath);\n } else if (entry.isFile()) {\n // Read template file, apply placeholders, write if not existing\n const content = await fsp.readFile(srcPath, 'utf8');\n const processed = applyPlaceholders(content, ctx);\n\n if (await fileExists(destPath)) {\n console.log(c('gray', `skip: ${path.relative(process.cwd(), destPath)} already exists`));\n continue;\n }\n\n await ensureDir(path.dirname(destPath));\n await fsp.writeFile(destPath, processed, 'utf8');\n console.log(c('green', `✓ created ${path.relative(process.cwd(), destPath)}`));\n }\n }\n };\n\n await walk(templateRoot);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/commands/template.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { c } from '../colors';\nimport { ensureDir, fileExists } from '@frontmcp/utils';\nimport { fsp } from '../utils/fs';\nimport { clack } from '../utils/prompts';\n\ntype AuthType = 'oauth2' | 'bearer' | 'apiKey';\n\ninterface TemplateContext {\n owner: string;\n service: string;\n authType: AuthType;\n}\n\n/**\n * frontmcp template <templateName>\n *\n * Example:\n * npx frontmcp template 3rd-party-integration\n *\n * This will look for templates in:\n * src/templates/<templateName> (built to dist/templates/<templateName>)\n * and copy them into:\n * integrations/<owner>/<service>\n * with __OWNER__, __SERVICE__, __AUTH_TYPE__ replaced.\n */\nexport async function runTemplate(templateName?: string): Promise<void> {\n const name = (templateName || '').trim();\n if (!name) {\n console.log(c('red', 'Template name is required (e.g. 3rd-party-integration).'));\n return;\n }\n\n const p = await clack();\n const templatesRoot = path.resolve(__dirname, '..', 'templates');\n\n // 1) Collect available templates up-front\n const available = await listAvailableTemplates(templatesRoot);\n if (!available.length) {\n console.log(c('red', `No templates found under ${path.relative(process.cwd(), templatesRoot)}.`));\n return;\n }\n\n // 2) Sanitize the name and choose the actual template folder\n const sanitized = sanitizeTemplateName(name);\n let selected: string | null = null;\n\n if (available.includes(name)) {\n selected = name;\n } else if (available.includes(sanitized)) {\n selected = sanitized;\n if (sanitized !== name) {\n console.log(c('yellow', `[template] Template \"${name}\" not found, using sanitized \"${sanitized}\"`));\n }\n }\n\n if (!selected) {\n console.log(c('red', `Template \"${name}\" not found under ${path.relative(process.cwd(), templatesRoot)}.`));\n console.log(c('gray', '\\nAvailable templates:'));\n for (const t of available) {\n console.log(' -', t);\n }\n return;\n }\n\n const templateRoot = path.resolve(templatesRoot, selected);\n\n console.log(c('cyan', '[template]') + ` Using template \"${selected}\" from src/templates/${selected}`);\n\n // Ask for owner\n const ownerResult = await p.text({\n message: 'Third-party owner',\n placeholder: 'google, github, slack',\n validate: (val) => {\n if (!val.trim()) return 'Owner is required.';\n return undefined;\n },\n });\n if (p.isCancel(ownerResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n const owner = sanitizeSlug(ownerResult);\n\n // Ask for service\n const serviceResult = await p.text({\n message: 'Third-party service',\n placeholder: 'gmail, slack-bot',\n validate: (val) => {\n if (!val.trim()) return 'Service is required.';\n return undefined;\n },\n });\n if (p.isCancel(serviceResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n const service = sanitizeSlug(serviceResult);\n\n // Auth type — select instead of free-text\n const authResult = await p.select({\n message: 'Default auth type',\n options: [\n { label: 'OAuth 2.0', value: 'oauth2' as AuthType },\n { label: 'Bearer token', value: 'bearer' as AuthType },\n { label: 'API key', value: 'apiKey' as AuthType },\n ],\n initialValue: 'oauth2' as AuthType,\n });\n if (p.isCancel(authResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n const authType = authResult;\n\n const ctx: TemplateContext = { owner, service, authType };\n\n const cwd = process.cwd();\n const destRoot = path.resolve(cwd, 'integrations', owner, service);\n await ensureDir(destRoot);\n\n console.log(c('gray', `[template] Scaffolding into ${path.relative(cwd, destRoot)}`));\n\n await copyTemplateTree(templateRoot, destRoot, ctx);\n\n console.log('');\n console.log(c('green', '✔ Template hydrated into: ') + path.relative(cwd, destRoot));\n console.log(c('gray', 'You can now edit or delete the generated example files and create your own tools.'));\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction sanitizeSlug(val: string): string {\n return (\n val\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'service'\n );\n}\n\n// More permissive for template folder names (allow . _ -)\nfunction sanitizeTemplateName(val: string): string {\n return (\n val\n .trim()\n .replace(/[^a-zA-Z0-9._-]/g, '-') // replace weird chars\n .replace(/-+/g, '-') // collapse multiple dashes\n .replace(/^-|-$/g, '') || 'template'\n );\n}\n\nasync function dirExists(p: string): Promise<boolean> {\n try {\n const st = await fsp.stat(p);\n return st.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function listAvailableTemplates(templatesRoot: string): Promise<string[]> {\n try {\n const entries = await fsp.readdir(templatesRoot, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\n/**\n * Replace placeholders in both filenames and file contents.\n *\n * Supported placeholders:\n * __OWNER__\n * __SERVICE__\n * __AUTH_TYPE__\n */\nfunction applyPlaceholders(input: string, ctx: TemplateContext): string {\n return input\n .replaceAll('__OWNER__', ctx.owner)\n .replaceAll('__SERVICE__', ctx.service)\n .replaceAll('__AUTH_TYPE__', ctx.authType);\n}\n\nasync function copyTemplateTree(templateRoot: string, destRoot: string, ctx: TemplateContext): Promise<void> {\n const walk = async (srcDir: string) => {\n const entries = await fsp.readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(srcDir, entry.name);\n const relFromRoot = path.relative(templateRoot, srcPath);\n\n // Apply placeholders in path segments too\n const relWithPlaceholders = applyPlaceholders(relFromRoot, ctx);\n const destPath = path.join(destRoot, relWithPlaceholders);\n\n if (entry.isDirectory()) {\n await ensureDir(destPath);\n await walk(srcPath);\n } else if (entry.isFile()) {\n // Read template file, apply placeholders, write if not existing\n const content = await fsp.readFile(srcPath, 'utf8');\n const processed = applyPlaceholders(content, ctx);\n\n if (await fileExists(destPath)) {\n console.log(c('gray', `skip: ${path.relative(process.cwd(), destPath)} already exists`));\n continue;\n }\n\n await ensureDir(path.dirname(destPath));\n await fsp.writeFile(destPath, processed, 'utf8');\n console.log(c('green', `✓ created ${path.relative(process.cwd(), destPath)}`));\n }\n }\n };\n\n await walk(templateRoot);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function clack(): Promise<typeof import('@clack/prompts')>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clack = clack;
|
|
4
|
+
/**
|
|
5
|
+
* Lazy-loader for @clack/prompts (ESM-only package).
|
|
6
|
+
*
|
|
7
|
+
* The CLI compiles as CJS, so a static `import` would compile to `require()`
|
|
8
|
+
* and fail at runtime. This helper uses a dynamic `await import()` and caches
|
|
9
|
+
* the module after first load.
|
|
10
|
+
*/
|
|
11
|
+
let _p;
|
|
12
|
+
async function clack() {
|
|
13
|
+
if (!_p)
|
|
14
|
+
_p = await import('@clack/prompts');
|
|
15
|
+
return _p;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/utils/prompts.ts"],"names":[],"mappings":";;AASA,sBAGC;AAZD;;;;;;GAMG;AACH,IAAI,EAA+C,CAAC;AAE7C,KAAK,UAAU,KAAK;IACzB,IAAI,CAAC,EAAE;QAAE,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC7C,OAAO,EAAE,CAAC;AACZ,CAAC","sourcesContent":["/**\n * Lazy-loader for @clack/prompts (ESM-only package).\n *\n * The CLI compiles as CJS, so a static `import` would compile to `require()`\n * and fail at runtime. This helper uses a dynamic `await import()` and caches\n * the module after first load.\n */\nlet _p: typeof import('@clack/prompts') | undefined;\n\nexport async function clack(): Promise<typeof import('@clack/prompts')> {\n if (!_p) _p = await import('@clack/prompts');\n return _p;\n}\n"]}
|