rps-flagforge 1.1.0 ā 1.1.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/dist/bin/mergeSchema.js
CHANGED
|
@@ -148,7 +148,9 @@ async function main() {
|
|
|
148
148
|
enumDiffs.push(import_chalk.default.green(`+ New enum: ${name}`));
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
const extensionComment = "\n\n// ------------------------------\n// FlagsForge Schema Extensions\n// ------------------------------\n\n";
|
|
152
|
+
let mergedContent = appContent.trim() + extensionComment;
|
|
153
|
+
mergedContent = applyMergedBlocks(mergedContent, mergedModels, "model");
|
|
152
154
|
mergedContent = applyMergedBlocks(mergedContent, mergedEnums, "enum");
|
|
153
155
|
if (isDryRun) {
|
|
154
156
|
console.log(import_chalk.default.gray("----- FULL MERGE DIFF -----\n"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../bin/mergeSchema.ts"],"sourcesContent":["#!/usr/bin/env node\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport chalk from \"chalk\";\r\nimport prompts from \"prompts\";\r\n\r\n// -----------------------------\r\n// CLI Flags\r\n// -----------------------------\r\nconst args = process.argv.slice(2);\r\nconst isDryRun = args.includes(\"--dry-run\");\r\nconst isForce = args.includes(\"--force\");\r\n\r\n// -----------------------------\r\n// Paths\r\n// -----------------------------\r\nconst appSchema = path.resolve(process.cwd(), \"prisma/schema.prisma\");\r\nconst packageSchema = path.resolve(__dirname, \"../../prisma/schema.prisma\");\r\n\r\n// -----------------------------\r\n// Helpers\r\n// -----------------------------\r\nfunction extractBlocks(schema: string, type: \"model\" | \"enum\"): string[] {\r\n const regex = new RegExp(`${type}\\\\s+\\\\w+\\\\s+{[\\\\s\\\\S]*?}\\\\n?`, \"g\");\r\n return schema.match(regex) || [];\r\n}\r\n\r\nfunction parseBlockFields(block: string) {\r\n return block\r\n .split(\"\\n\")\r\n .map(l => l.trim())\r\n .filter(\r\n l =>\r\n l &&\r\n !l.startsWith(\"//\") &&\r\n !l.startsWith(\"model\") &&\r\n !l.startsWith(\"enum\") &&\r\n !l.startsWith(\"{\") &&\r\n !l.startsWith(\"}\")\r\n );\r\n}\r\n\r\nfunction mergeModelFields(existing: string, incoming: string) {\r\n const existingFields = parseBlockFields(existing);\r\n const incomingFields = parseBlockFields(incoming);\r\n\r\n const mergedFields: string[] = [...existingFields];\r\n const diff: string[] = [];\r\n\r\n const map = new Map(existingFields.map(f => [f.split(\" \")[0], f]));\r\n\r\n for (const field of incomingFields) {\r\n const name = field.split(\" \")[0];\r\n if (!map.has(name)) {\r\n mergedFields.push(field);\r\n diff.push(chalk.green(`+ ${field}`));\r\n } else if (map.get(name) !== field) {\r\n const idx = mergedFields.findIndex(f => f.split(\" \")[0] === name);\r\n mergedFields[idx] = field;\r\n diff.push(chalk.yellow(`~ ${field}`));\r\n }\r\n }\r\n\r\n const mergedBlock = existing.replace(/\\{[\\s\\S]*\\}/, `{ \\n ${mergedFields.join(\"\\n \")} \\n}`);\r\n return { mergedBlock, diff };\r\n}\r\n\r\nfunction mergeEnumValues(existing: string, incoming: string) {\r\n const existingValues = parseBlockFields(existing);\r\n const incomingValues = parseBlockFields(incoming);\r\n\r\n const mergedValues = [...existingValues];\r\n const diff: string[] = [];\r\n\r\n for (const v of incomingValues) {\r\n if (!existingValues.includes(v)) {\r\n mergedValues.push(v);\r\n diff.push(chalk.green(`+ ${v}`));\r\n }\r\n }\r\n\r\n const mergedBlock = existing.replace(/\\{[\\s\\S]*\\}/, `{ \\n ${mergedValues.join(\"\\n \")} \\n}`);\r\n return { mergedBlock, diff };\r\n}\r\n\r\n// Replace blocks in schema (update existing, append only new)\r\nfunction applyMergedBlocks(original: string, blocks: string[], type: \"model\" | \"enum\") {\r\n let content = original;\r\n for (const block of blocks) {\r\n const match = block.match(new RegExp(`${type}\\\\s+(\\\\w+)\\\\s+{`));\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const regex = new RegExp(`${type}\\\\s+${name}\\\\s+{[\\\\s\\\\S]*?}`, \"g\");\r\n if (regex.test(content)) {\r\n content = content.replace(regex, block); // update existing\r\n } else {\r\n content += `\\n\\n${block}`; // append new\r\n }\r\n }\r\n return content;\r\n}\r\n\r\n// -----------------------------\r\n// Main\r\n// -----------------------------\r\nasync function main() {\r\n console.log(chalk.blueBright.bold(\"\\nā” FlagsForge Prisma Schema Smart Merger\\n\"));\r\n\r\n if (isDryRun) console.log(chalk.cyan(\"š Dry run: preview all changes\\n\"));\r\n if (isForce) console.log(chalk.yellow(\"ā ļø Force mode enabled (skipping backup prompts)\\n\"));\r\n\r\n if (!fs.existsSync(appSchema)) {\r\n console.error(chalk.red(\"ā App schema not found at prisma/schema.prisma\"));\r\n process.exit(1);\r\n }\r\n if (!fs.existsSync(packageSchema)) {\r\n console.error(chalk.red(\"ā Package Prisma models not found\"));\r\n process.exit(1);\r\n }\r\n\r\n const appContent = fs.readFileSync(appSchema, \"utf-8\");\r\n const packageRaw = fs.readFileSync(packageSchema, \"utf-8\");\r\n const packageContent = packageRaw.replace(/generator\\s+\\w+\\s+{[\\s\\S]*?}\\n?/g, \"\").replace(/datasource\\s+\\w+\\s+{[\\s\\S]*?}\\n?/g, \"\");\r\n\r\n const appModels = extractBlocks(appContent, \"model\");\r\n const appEnums = extractBlocks(appContent, \"enum\");\r\n const packageModels = extractBlocks(packageContent, \"model\");\r\n const packageEnums = extractBlocks(packageContent, \"enum\");\r\n\r\n // Merge models\r\n const mergedModels: string[] = [];\r\n const modelDiffs: string[] = [];\r\n for (const pModel of packageModels) {\r\n const match = pModel.match(/model\\s+(\\w+)\\s+{/);\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const existing = appModels.find(m => m.match(new RegExp(`model\\\\s+${name}\\\\s+{`)));\r\n if (existing) {\r\n const { mergedBlock, diff } = mergeModelFields(existing, pModel);\r\n mergedModels.push(mergedBlock);\r\n modelDiffs.push(...diff);\r\n } else {\r\n mergedModels.push(pModel);\r\n modelDiffs.push(chalk.green(`+ New model: ${name}`));\r\n }\r\n }\r\n\r\n // Merge enums\r\n const mergedEnums: string[] = [];\r\n const enumDiffs: string[] = [];\r\n for (const pEnum of packageEnums) {\r\n const match = pEnum.match(/enum\\s+(\\w+)\\s+{/);\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const existing = appEnums.find(e => e.match(new RegExp(`enum\\\\s+${name}\\\\s+{`)));\r\n if (existing) {\r\n const { mergedBlock, diff } = mergeEnumValues(existing, pEnum);\r\n mergedEnums.push(mergedBlock);\r\n enumDiffs.push(...diff);\r\n } else {\r\n mergedEnums.push(pEnum);\r\n enumDiffs.push(chalk.green(`+ New enum: ${name}`));\r\n }\r\n }\r\n\r\n // Apply merged blocks in-place\r\n let mergedContent = applyMergedBlocks(appContent, mergedModels, \"model\");\r\n mergedContent = applyMergedBlocks(mergedContent, mergedEnums, \"enum\");\r\n\r\n // Dry-run preview\r\n if (isDryRun) {\r\n console.log(chalk.gray(\"----- FULL MERGE DIFF -----\\n\"));\r\n [...enumDiffs, ...modelDiffs].forEach(line => console.log(line));\r\n console.log(chalk.gray(\"\\n------------------------------\"));\r\n console.log(chalk.cyan(\"⨠Dry run complete. No changes were made.\\n\"));\r\n process.exit(0);\r\n }\r\n\r\n // Backup prompt\r\n let shouldBackup = true;\r\n if (!isForce) {\r\n const response = await prompts({\r\n type: \"confirm\",\r\n name: \"backup\",\r\n message: \"Create a backup of your current schema?\",\r\n initial: true,\r\n });\r\n shouldBackup = response.backup;\r\n }\r\n\r\n if (shouldBackup) {\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\r\n const backupPath = `${appSchema}.bak-${timestamp}`;\r\n fs.copyFileSync(appSchema, backupPath);\r\n console.log(chalk.green(`ā
Backup created: ${backupPath}\\n`));\r\n }\r\n\r\n fs.writeFileSync(appSchema, mergedContent);\r\n console.log(chalk.green.bold(\"ā
Prisma schema merged successfully!\"));\r\n console.log(chalk.yellow(\"Run `npx prisma generate` to update your client.\\n\"));\r\n}\r\n\r\nmain().catch(err => {\r\n console.error(chalk.red(\"ā Error merging schemas:\"), err);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":["path","chalk","fs","prompts"]}
|
|
1
|
+
{"version":3,"sources":["../../bin/mergeSchema.ts"],"sourcesContent":["#!/usr/bin/env node\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport chalk from \"chalk\";\r\nimport prompts from \"prompts\";\r\n\r\n// -----------------------------\r\n// CLI Flags\r\n// -----------------------------\r\nconst args = process.argv.slice(2);\r\nconst isDryRun = args.includes(\"--dry-run\");\r\nconst isForce = args.includes(\"--force\");\r\n\r\n// -----------------------------\r\n// Paths\r\n// -----------------------------\r\nconst appSchema = path.resolve(process.cwd(), \"prisma/schema.prisma\");\r\nconst packageSchema = path.resolve(__dirname, \"../../prisma/schema.prisma\");\r\n\r\n// -----------------------------\r\n// Helpers\r\n// -----------------------------\r\nfunction extractBlocks(schema: string, type: \"model\" | \"enum\"): string[] {\r\n const regex = new RegExp(`${type}\\\\s+\\\\w+\\\\s+{[\\\\s\\\\S]*?}\\\\n?`, \"g\");\r\n return schema.match(regex) || [];\r\n}\r\n\r\nfunction parseBlockFields(block: string) {\r\n return block\r\n .split(\"\\n\")\r\n .map(l => l.trim())\r\n .filter(\r\n l =>\r\n l &&\r\n !l.startsWith(\"//\") &&\r\n !l.startsWith(\"model\") &&\r\n !l.startsWith(\"enum\") &&\r\n !l.startsWith(\"{\") &&\r\n !l.startsWith(\"}\")\r\n );\r\n}\r\n\r\nfunction mergeModelFields(existing: string, incoming: string) {\r\n const existingFields = parseBlockFields(existing);\r\n const incomingFields = parseBlockFields(incoming);\r\n\r\n const mergedFields: string[] = [...existingFields];\r\n const diff: string[] = [];\r\n\r\n const map = new Map(existingFields.map(f => [f.split(\" \")[0], f]));\r\n\r\n for (const field of incomingFields) {\r\n const name = field.split(\" \")[0];\r\n if (!map.has(name)) {\r\n mergedFields.push(field);\r\n diff.push(chalk.green(`+ ${field}`));\r\n } else if (map.get(name) !== field) {\r\n const idx = mergedFields.findIndex(f => f.split(\" \")[0] === name);\r\n mergedFields[idx] = field;\r\n diff.push(chalk.yellow(`~ ${field}`));\r\n }\r\n }\r\n\r\n const mergedBlock = existing.replace(/\\{[\\s\\S]*\\}/, `{ \\n ${mergedFields.join(\"\\n \")} \\n}`);\r\n return { mergedBlock, diff };\r\n}\r\n\r\nfunction mergeEnumValues(existing: string, incoming: string) {\r\n const existingValues = parseBlockFields(existing);\r\n const incomingValues = parseBlockFields(incoming);\r\n\r\n const mergedValues = [...existingValues];\r\n const diff: string[] = [];\r\n\r\n for (const v of incomingValues) {\r\n if (!existingValues.includes(v)) {\r\n mergedValues.push(v);\r\n diff.push(chalk.green(`+ ${v}`));\r\n }\r\n }\r\n\r\n const mergedBlock = existing.replace(/\\{[\\s\\S]*\\}/, `{ \\n ${mergedValues.join(\"\\n \")} \\n}`);\r\n return { mergedBlock, diff };\r\n}\r\n\r\n// Replace blocks in schema (update existing, append only new)\r\nfunction applyMergedBlocks(original: string, blocks: string[], type: \"model\" | \"enum\") {\r\n let content = original;\r\n for (const block of blocks) {\r\n const match = block.match(new RegExp(`${type}\\\\s+(\\\\w+)\\\\s+{`));\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const regex = new RegExp(`${type}\\\\s+${name}\\\\s+{[\\\\s\\\\S]*?}`, \"g\");\r\n if (regex.test(content)) {\r\n content = content.replace(regex, block); // update existing\r\n } else {\r\n content += `\\n\\n${block}`; // append new\r\n }\r\n }\r\n return content;\r\n}\r\n\r\n// -----------------------------\r\n// Main\r\n// -----------------------------\r\nasync function main() {\r\n console.log(chalk.blueBright.bold(\"\\nā” FlagsForge Prisma Schema Smart Merger\\n\"));\r\n\r\n if (isDryRun) console.log(chalk.cyan(\"š Dry run: preview all changes\\n\"));\r\n if (isForce) console.log(chalk.yellow(\"ā ļø Force mode enabled (skipping backup prompts)\\n\"));\r\n\r\n if (!fs.existsSync(appSchema)) {\r\n console.error(chalk.red(\"ā App schema not found at prisma/schema.prisma\"));\r\n process.exit(1);\r\n }\r\n if (!fs.existsSync(packageSchema)) {\r\n console.error(chalk.red(\"ā Package Prisma models not found\"));\r\n process.exit(1);\r\n }\r\n\r\n const appContent = fs.readFileSync(appSchema, \"utf-8\");\r\n const packageRaw = fs.readFileSync(packageSchema, \"utf-8\");\r\n const packageContent = packageRaw.replace(/generator\\s+\\w+\\s+{[\\s\\S]*?}\\n?/g, \"\").replace(/datasource\\s+\\w+\\s+{[\\s\\S]*?}\\n?/g, \"\");\r\n\r\n const appModels = extractBlocks(appContent, \"model\");\r\n const appEnums = extractBlocks(appContent, \"enum\");\r\n const packageModels = extractBlocks(packageContent, \"model\");\r\n const packageEnums = extractBlocks(packageContent, \"enum\");\r\n\r\n // Merge models\r\n const mergedModels: string[] = [];\r\n const modelDiffs: string[] = [];\r\n for (const pModel of packageModels) {\r\n const match = pModel.match(/model\\s+(\\w+)\\s+{/);\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const existing = appModels.find(m => m.match(new RegExp(`model\\\\s+${name}\\\\s+{`)));\r\n if (existing) {\r\n const { mergedBlock, diff } = mergeModelFields(existing, pModel);\r\n mergedModels.push(mergedBlock);\r\n modelDiffs.push(...diff);\r\n } else {\r\n mergedModels.push(pModel);\r\n modelDiffs.push(chalk.green(`+ New model: ${name}`));\r\n }\r\n }\r\n\r\n // Merge enums\r\n const mergedEnums: string[] = [];\r\n const enumDiffs: string[] = [];\r\n for (const pEnum of packageEnums) {\r\n const match = pEnum.match(/enum\\s+(\\w+)\\s+{/);\r\n if (!match) continue;\r\n const name = match[1];\r\n\r\n const existing = appEnums.find(e => e.match(new RegExp(`enum\\\\s+${name}\\\\s+{`)));\r\n if (existing) {\r\n const { mergedBlock, diff } = mergeEnumValues(existing, pEnum);\r\n mergedEnums.push(mergedBlock);\r\n enumDiffs.push(...diff);\r\n } else {\r\n mergedEnums.push(pEnum);\r\n enumDiffs.push(chalk.green(`+ New enum: ${name}`));\r\n }\r\n }\r\n\r\n // ------------------------------\r\n // Prepend the FlagsForge Schema comment\r\n // ------------------------------\r\n const extensionComment = \"\\n\\n// ------------------------------\\n\" +\r\n \"// FlagsForge Schema Extensions\\n\" +\r\n \"// ------------------------------\\n\\n\";\r\n\r\n let mergedContent = appContent.trim() + extensionComment;\r\n mergedContent = applyMergedBlocks(mergedContent, mergedModels, \"model\");\r\n mergedContent = applyMergedBlocks(mergedContent, mergedEnums, \"enum\");\r\n\r\n // Dry-run preview\r\n if (isDryRun) {\r\n console.log(chalk.gray(\"----- FULL MERGE DIFF -----\\n\"));\r\n [...enumDiffs, ...modelDiffs].forEach(line => console.log(line));\r\n console.log(chalk.gray(\"\\n------------------------------\"));\r\n console.log(chalk.cyan(\"⨠Dry run complete. No changes were made.\\n\"));\r\n process.exit(0);\r\n }\r\n\r\n // Backup prompt\r\n let shouldBackup = true;\r\n if (!isForce) {\r\n const response = await prompts({\r\n type: \"confirm\",\r\n name: \"backup\",\r\n message: \"Create a backup of your current schema?\",\r\n initial: true,\r\n });\r\n shouldBackup = response.backup;\r\n }\r\n\r\n if (shouldBackup) {\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\r\n const backupPath = `${appSchema}.bak-${timestamp}`;\r\n fs.copyFileSync(appSchema, backupPath);\r\n console.log(chalk.green(`ā
Backup created: ${backupPath}\\n`));\r\n }\r\n\r\n fs.writeFileSync(appSchema, mergedContent);\r\n console.log(chalk.green.bold(\"ā
Prisma schema merged successfully!\"));\r\n console.log(chalk.yellow(\"Run `npx prisma generate` to update your client.\\n\"));\r\n}\r\n\r\nmain().catch(err => {\r\n console.error(chalk.red(\"ā Error merging schemas:\"), err);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":["path","chalk","fs","prompts"]}
|