@fgv/repo-template 5.1.0-10

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.
Files changed (81) hide show
  1. package/.rush/temp/9cc3c12fcd90dc622d9e260e68873bfe822f80a1.tar.log +61 -0
  2. package/.rush/temp/chunked-rush-logs/repo-template.build.chunks.jsonl +6 -0
  3. package/.rush/temp/operation/build/all.log +6 -0
  4. package/.rush/temp/operation/build/log-chunks.jsonl +6 -0
  5. package/.rush/temp/operation/build/state.json +3 -0
  6. package/.rush/temp/shrinkwrap-deps.json +576 -0
  7. package/README.md +216 -0
  8. package/bin/repo-template.js +18 -0
  9. package/config/rig.json +4 -0
  10. package/lib/cli.d.ts +14 -0
  11. package/lib/cli.d.ts.map +1 -0
  12. package/lib/cli.js +167 -0
  13. package/lib/cli.js.map +1 -0
  14. package/lib/commands/create.d.ts +17 -0
  15. package/lib/commands/create.d.ts.map +1 -0
  16. package/lib/commands/create.js +212 -0
  17. package/lib/commands/create.js.map +1 -0
  18. package/lib/commands/init-library.d.ts +38 -0
  19. package/lib/commands/init-library.d.ts.map +1 -0
  20. package/lib/commands/init-library.js +269 -0
  21. package/lib/commands/init-library.js.map +1 -0
  22. package/lib/commands/link.d.ts +20 -0
  23. package/lib/commands/link.d.ts.map +1 -0
  24. package/lib/commands/link.js +273 -0
  25. package/lib/commands/link.js.map +1 -0
  26. package/lib/commands/patch.d.ts +15 -0
  27. package/lib/commands/patch.d.ts.map +1 -0
  28. package/lib/commands/patch.js +104 -0
  29. package/lib/commands/patch.js.map +1 -0
  30. package/lib/commands/sync.d.ts +11 -0
  31. package/lib/commands/sync.d.ts.map +1 -0
  32. package/lib/commands/sync.js +156 -0
  33. package/lib/commands/sync.js.map +1 -0
  34. package/lib/index.d.ts +15 -0
  35. package/lib/index.d.ts.map +1 -0
  36. package/lib/index.js +33 -0
  37. package/lib/index.js.map +1 -0
  38. package/lib/packlets/fs/index.d.ts +40 -0
  39. package/lib/packlets/fs/index.d.ts.map +1 -0
  40. package/lib/packlets/fs/index.js +142 -0
  41. package/lib/packlets/fs/index.js.map +1 -0
  42. package/lib/packlets/jsonc/index.d.ts +27 -0
  43. package/lib/packlets/jsonc/index.d.ts.map +1 -0
  44. package/lib/packlets/jsonc/index.js +124 -0
  45. package/lib/packlets/jsonc/index.js.map +1 -0
  46. package/lib/packlets/manifest/index.d.ts +15 -0
  47. package/lib/packlets/manifest/index.d.ts.map +1 -0
  48. package/lib/packlets/manifest/index.js +61 -0
  49. package/lib/packlets/manifest/index.js.map +1 -0
  50. package/lib/packlets/manifest/types.d.ts +33 -0
  51. package/lib/packlets/manifest/types.d.ts.map +1 -0
  52. package/lib/packlets/manifest/types.js +6 -0
  53. package/lib/packlets/manifest/types.js.map +1 -0
  54. package/lib/packlets/template/index.d.ts +22 -0
  55. package/lib/packlets/template/index.d.ts.map +1 -0
  56. package/lib/packlets/template/index.js +75 -0
  57. package/lib/packlets/template/index.js.map +1 -0
  58. package/package.json +32 -0
  59. package/rush-logs/repo-template.build.cache.log +5 -0
  60. package/rush-logs/repo-template.build.log +6 -0
  61. package/src/cli.ts +197 -0
  62. package/src/commands/create.ts +216 -0
  63. package/src/commands/init-library.ts +313 -0
  64. package/src/commands/link.ts +299 -0
  65. package/src/commands/patch.ts +84 -0
  66. package/src/commands/sync.ts +137 -0
  67. package/src/index.ts +22 -0
  68. package/src/packlets/fs/index.ts +114 -0
  69. package/src/packlets/jsonc/index.ts +134 -0
  70. package/src/packlets/manifest/index.ts +29 -0
  71. package/src/packlets/manifest/types.ts +36 -0
  72. package/src/packlets/template/index.ts +48 -0
  73. package/sync-manifest.json +222 -0
  74. package/temp/build/typescript/ts_l9Fw4VUO.json +1 -0
  75. package/templates/.gitignore.tmpl +85 -0
  76. package/templates/ACTIVE_DEVELOPMENT.md.tmpl +58 -0
  77. package/templates/CLAUDE.md.tmpl +124 -0
  78. package/templates/command-line.json.tmpl +50 -0
  79. package/templates/package.json.tmpl +5 -0
  80. package/templates/version-policies.json.tmpl +8 -0
  81. package/tsconfig.json +7 -0
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ /**
3
+ * Link/unlink/update-fgv-versions commands — automate cross-repo development
4
+ * between fgv and consumer Rush monorepos.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.runLink = runLink;
41
+ exports.runUnlink = runUnlink;
42
+ exports.runUpdateFgvVersions = runUpdateFgvVersions;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const child_process_1 = require("child_process");
46
+ const jsonc_parser_1 = require("jsonc-parser");
47
+ const jsonc_1 = require("../packlets/jsonc");
48
+ // ── Discovery helpers ──
49
+ /**
50
+ * Read a rush.json and return its project entries.
51
+ */
52
+ function readRushProjects(rushJsonPath) {
53
+ const content = fs.readFileSync(rushJsonPath, 'utf-8');
54
+ const rush = (0, jsonc_parser_1.parse)(content);
55
+ return rush.projects;
56
+ }
57
+ /**
58
+ * Scan a consumer Rush repo and collect all @fgv/* dependencies (excluding workspace:* entries).
59
+ * Returns a map of packageName -> list of project folders that depend on it.
60
+ */
61
+ function discoverFgvDeps(repoDir) {
62
+ var _a;
63
+ const rushJsonPath = path.join(repoDir, 'rush.json');
64
+ if (!fs.existsSync(rushJsonPath)) {
65
+ throw new Error(`rush.json not found at ${rushJsonPath}`);
66
+ }
67
+ const projects = readRushProjects(rushJsonPath);
68
+ const deps = new Map();
69
+ for (const project of projects) {
70
+ const pkgJsonPath = path.join(repoDir, project.projectFolder, 'package.json');
71
+ if (!fs.existsSync(pkgJsonPath)) {
72
+ continue;
73
+ }
74
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
75
+ const allDeps = Object.assign(Object.assign({}, pkgJson.dependencies), pkgJson.devDependencies);
76
+ for (const [name, spec] of Object.entries(allDeps)) {
77
+ if (name.startsWith('@fgv/') && spec !== 'workspace:*') {
78
+ const existing = (_a = deps.get(name)) !== null && _a !== void 0 ? _a : [];
79
+ existing.push(project.projectFolder);
80
+ deps.set(name, existing);
81
+ }
82
+ }
83
+ }
84
+ return deps;
85
+ }
86
+ /**
87
+ * Read the fgv worktree's rush.json and build a map of packageName -> projectFolder.
88
+ */
89
+ function buildFgvPackageMap(fgvDir) {
90
+ const rushJsonPath = path.join(fgvDir, 'rush.json');
91
+ if (!fs.existsSync(rushJsonPath)) {
92
+ throw new Error(`fgv rush.json not found at ${rushJsonPath}`);
93
+ }
94
+ const projects = readRushProjects(rushJsonPath);
95
+ const map = new Map();
96
+ for (const project of projects) {
97
+ map.set(project.packageName, project.projectFolder);
98
+ }
99
+ return map;
100
+ }
101
+ // ── Version helpers ──
102
+ /**
103
+ * Query npm for the latest prerelease version of @fgv/ts-utils and construct a ~X.Y.Z spec.
104
+ */
105
+ function resolveLatestFgvVersion() {
106
+ var _a;
107
+ const output = (0, child_process_1.execSync)('npm view @fgv/ts-utils dist-tags --json', { encoding: 'utf-8' });
108
+ const tags = JSON.parse(output);
109
+ const version = (_a = tags.alpha) !== null && _a !== void 0 ? _a : tags.latest;
110
+ if (!version) {
111
+ throw new Error('Could not determine latest @fgv version from npm dist-tags');
112
+ }
113
+ return `~${version}`;
114
+ }
115
+ /**
116
+ * Update all @fgv/* dependency versions (excluding workspace:*) in a consumer repo's package.json files.
117
+ * Uses jsonc-parser modify() to preserve formatting.
118
+ */
119
+ function updateVersionsInPackageJsons(repoDir, versionSpec) {
120
+ const rushJsonPath = path.join(repoDir, 'rush.json');
121
+ const projects = readRushProjects(rushJsonPath);
122
+ const changed = [];
123
+ for (const project of projects) {
124
+ const pkgJsonPath = path.join(repoDir, project.projectFolder, 'package.json');
125
+ if (!fs.existsSync(pkgJsonPath)) {
126
+ continue;
127
+ }
128
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
129
+ const operations = [];
130
+ for (const depField of ['dependencies', 'devDependencies']) {
131
+ const deps = pkgJson[depField];
132
+ if (!deps)
133
+ continue;
134
+ for (const [name, spec] of Object.entries(deps)) {
135
+ if (name.startsWith('@fgv/') && spec !== 'workspace:*') {
136
+ operations.push({
137
+ type: 'set-json',
138
+ path: `${depField}.${name}`,
139
+ value: JSON.stringify(versionSpec)
140
+ });
141
+ }
142
+ }
143
+ }
144
+ if (operations.length > 0) {
145
+ (0, jsonc_1.patchFile)(pkgJsonPath, operations);
146
+ changed.push(pkgJsonPath);
147
+ }
148
+ }
149
+ return changed;
150
+ }
151
+ // ── Command runners ──
152
+ async function runLink(options) {
153
+ const { fgvDir, repoDir } = options;
154
+ console.log(`==> Linking to local fgv worktree`);
155
+ console.log(` fgv dir: ${fgvDir}`);
156
+ console.log(` repo dir: ${repoDir}`);
157
+ const fgvDeps = discoverFgvDeps(repoDir);
158
+ if (fgvDeps.size === 0) {
159
+ console.log(' No @fgv/* dependencies found in consumer repo.');
160
+ return;
161
+ }
162
+ const fgvPackageMap = buildFgvPackageMap(fgvDir);
163
+ // Compute file: overrides relative to common/temp/
164
+ const commonTempDir = path.join(repoDir, 'common', 'temp');
165
+ const overrides = {};
166
+ const warnings = [];
167
+ for (const packageName of fgvDeps.keys()) {
168
+ const projectFolder = fgvPackageMap.get(packageName);
169
+ if (!projectFolder) {
170
+ warnings.push(` Warning: ${packageName} not found in fgv worktree — skipping`);
171
+ continue;
172
+ }
173
+ const absoluteProjectPath = path.join(fgvDir, projectFolder);
174
+ const relativePath = path.relative(commonTempDir, absoluteProjectPath);
175
+ overrides[packageName] = `file:${relativePath}`;
176
+ }
177
+ for (const w of warnings) {
178
+ console.warn(w);
179
+ }
180
+ // Patch pnpm-config.json
181
+ const pnpmConfigPath = path.join(repoDir, 'common', 'config', 'rush', 'pnpm-config.json');
182
+ if (!fs.existsSync(pnpmConfigPath)) {
183
+ throw new Error(`pnpm-config.json not found at ${pnpmConfigPath}`);
184
+ }
185
+ const patchOps = [
186
+ {
187
+ type: 'set-json',
188
+ path: 'globalOverrides',
189
+ value: JSON.stringify(overrides)
190
+ },
191
+ {
192
+ type: 'set',
193
+ path: 'strictPeerDependencies',
194
+ value: false
195
+ },
196
+ {
197
+ type: 'set-json',
198
+ path: 'globalPeerDependencyRules',
199
+ value: JSON.stringify({ ignoreMissing: ['mustache'], allowAny: ['@fgv/*'] })
200
+ }
201
+ ];
202
+ (0, jsonc_1.patchFile)(pnpmConfigPath, patchOps);
203
+ console.log(`\n Patched: ${pnpmConfigPath}`);
204
+ console.log(` Overrides (${Object.keys(overrides).length} packages):`);
205
+ for (const [name, filePath] of Object.entries(overrides)) {
206
+ console.log(` ${name} -> ${filePath}`);
207
+ }
208
+ console.log(`\n Next: run "rush update --purge" in the consumer repo.`);
209
+ }
210
+ async function runUnlink(options) {
211
+ const { repoDir, version } = options;
212
+ console.log(`==> Unlinking from local fgv worktree`);
213
+ console.log(` repo dir: ${repoDir}`);
214
+ // Restore pnpm-config.json to defaults
215
+ const pnpmConfigPath = path.join(repoDir, 'common', 'config', 'rush', 'pnpm-config.json');
216
+ if (!fs.existsSync(pnpmConfigPath)) {
217
+ throw new Error(`pnpm-config.json not found at ${pnpmConfigPath}`);
218
+ }
219
+ const patchOps = [
220
+ {
221
+ type: 'set-json',
222
+ path: 'globalOverrides',
223
+ value: JSON.stringify({})
224
+ },
225
+ {
226
+ type: 'set',
227
+ path: 'strictPeerDependencies',
228
+ value: true
229
+ },
230
+ {
231
+ type: 'set-json',
232
+ path: 'globalPeerDependencyRules',
233
+ value: JSON.stringify({})
234
+ }
235
+ ];
236
+ (0, jsonc_1.patchFile)(pnpmConfigPath, patchOps);
237
+ console.log(` Patched: ${pnpmConfigPath} (restored defaults)`);
238
+ // Optionally bump versions
239
+ if (version) {
240
+ console.log(`\n Bumping @fgv/* deps to ${version}...`);
241
+ const changed = updateVersionsInPackageJsons(repoDir, version);
242
+ console.log(` Updated ${changed.length} package.json file(s):`);
243
+ for (const f of changed) {
244
+ console.log(` ${f}`);
245
+ }
246
+ }
247
+ console.log(`\n Next: run "rush update --purge" in the consumer repo.`);
248
+ }
249
+ async function runUpdateFgvVersions(options) {
250
+ const { repoDir } = options;
251
+ console.log(`==> Updating @fgv/* version specs`);
252
+ console.log(` repo dir: ${repoDir}`);
253
+ // Resolve version
254
+ let versionSpec;
255
+ if (options.version) {
256
+ versionSpec = options.version;
257
+ console.log(` Using explicit version: ${versionSpec}`);
258
+ }
259
+ else {
260
+ console.log(' Querying npm for latest version...');
261
+ versionSpec = resolveLatestFgvVersion();
262
+ console.log(` Resolved version: ${versionSpec}`);
263
+ }
264
+ const changed = updateVersionsInPackageJsons(repoDir, versionSpec);
265
+ console.log(`\n Updated ${changed.length} package.json file(s):`);
266
+ for (const f of changed) {
267
+ console.log(` ${f}`);
268
+ }
269
+ if (changed.length > 0) {
270
+ console.log(`\n Next: run "rush update --purge" in the consumer repo.`);
271
+ }
272
+ }
273
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Link/unlink/update-fgv-versions commands — automate cross-repo development\n * between fgv and consumer Rush monorepos.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\nimport { parse as parseJsonc } from 'jsonc-parser';\nimport { IPatchOperation, patchFile } from '../packlets/jsonc';\n\n// ── Interfaces ──\n\nexport interface ILinkOptions {\n fgvDir: string;\n repoDir: string;\n}\n\nexport interface IUnlinkOptions {\n repoDir: string;\n version?: string;\n}\n\nexport interface IUpdateFgvVersionsOptions {\n repoDir: string;\n version?: string;\n}\n\ninterface IRushProject {\n packageName: string;\n projectFolder: string;\n}\n\n// ── Discovery helpers ──\n\n/**\n * Read a rush.json and return its project entries.\n */\nfunction readRushProjects(rushJsonPath: string): IRushProject[] {\n const content = fs.readFileSync(rushJsonPath, 'utf-8');\n const rush = parseJsonc(content) as { projects: IRushProject[] };\n return rush.projects;\n}\n\n/**\n * Scan a consumer Rush repo and collect all @fgv/* dependencies (excluding workspace:* entries).\n * Returns a map of packageName -> list of project folders that depend on it.\n */\nfunction discoverFgvDeps(repoDir: string): Map<string, string[]> {\n const rushJsonPath = path.join(repoDir, 'rush.json');\n if (!fs.existsSync(rushJsonPath)) {\n throw new Error(`rush.json not found at ${rushJsonPath}`);\n }\n\n const projects = readRushProjects(rushJsonPath);\n const deps = new Map<string, string[]>();\n\n for (const project of projects) {\n const pkgJsonPath = path.join(repoDir, project.projectFolder, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {\n continue;\n }\n\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n const allDeps: Record<string, string> = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies\n };\n\n for (const [name, spec] of Object.entries(allDeps)) {\n if (name.startsWith('@fgv/') && spec !== 'workspace:*') {\n const existing = deps.get(name) ?? [];\n existing.push(project.projectFolder);\n deps.set(name, existing);\n }\n }\n }\n\n return deps;\n}\n\n/**\n * Read the fgv worktree's rush.json and build a map of packageName -> projectFolder.\n */\nfunction buildFgvPackageMap(fgvDir: string): Map<string, string> {\n const rushJsonPath = path.join(fgvDir, 'rush.json');\n if (!fs.existsSync(rushJsonPath)) {\n throw new Error(`fgv rush.json not found at ${rushJsonPath}`);\n }\n\n const projects = readRushProjects(rushJsonPath);\n const map = new Map<string, string>();\n for (const project of projects) {\n map.set(project.packageName, project.projectFolder);\n }\n return map;\n}\n\n// ── Version helpers ──\n\n/**\n * Query npm for the latest prerelease version of @fgv/ts-utils and construct a ~X.Y.Z spec.\n */\nfunction resolveLatestFgvVersion(): string {\n const output = execSync('npm view @fgv/ts-utils dist-tags --json', { encoding: 'utf-8' });\n const tags = JSON.parse(output) as Record<string, string>;\n const version = tags.alpha ?? tags.latest;\n if (!version) {\n throw new Error('Could not determine latest @fgv version from npm dist-tags');\n }\n return `~${version}`;\n}\n\n/**\n * Update all @fgv/* dependency versions (excluding workspace:*) in a consumer repo's package.json files.\n * Uses jsonc-parser modify() to preserve formatting.\n */\nfunction updateVersionsInPackageJsons(repoDir: string, versionSpec: string): string[] {\n const rushJsonPath = path.join(repoDir, 'rush.json');\n const projects = readRushProjects(rushJsonPath);\n const changed: string[] = [];\n\n for (const project of projects) {\n const pkgJsonPath = path.join(repoDir, project.projectFolder, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {\n continue;\n }\n\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n const operations: IPatchOperation[] = [];\n\n for (const depField of ['dependencies', 'devDependencies'] as const) {\n const deps: Record<string, string> | undefined = pkgJson[depField];\n if (!deps) continue;\n\n for (const [name, spec] of Object.entries(deps)) {\n if (name.startsWith('@fgv/') && spec !== 'workspace:*') {\n operations.push({\n type: 'set-json',\n path: `${depField}.${name}`,\n value: JSON.stringify(versionSpec)\n });\n }\n }\n }\n\n if (operations.length > 0) {\n patchFile(pkgJsonPath, operations);\n changed.push(pkgJsonPath);\n }\n }\n\n return changed;\n}\n\n// ── Command runners ──\n\nexport async function runLink(options: ILinkOptions): Promise<void> {\n const { fgvDir, repoDir } = options;\n\n console.log(`==> Linking to local fgv worktree`);\n console.log(` fgv dir: ${fgvDir}`);\n console.log(` repo dir: ${repoDir}`);\n\n const fgvDeps = discoverFgvDeps(repoDir);\n if (fgvDeps.size === 0) {\n console.log(' No @fgv/* dependencies found in consumer repo.');\n return;\n }\n\n const fgvPackageMap = buildFgvPackageMap(fgvDir);\n\n // Compute file: overrides relative to common/temp/\n const commonTempDir = path.join(repoDir, 'common', 'temp');\n const overrides: Record<string, string> = {};\n const warnings: string[] = [];\n\n for (const packageName of fgvDeps.keys()) {\n const projectFolder = fgvPackageMap.get(packageName);\n if (!projectFolder) {\n warnings.push(` Warning: ${packageName} not found in fgv worktree — skipping`);\n continue;\n }\n const absoluteProjectPath = path.join(fgvDir, projectFolder);\n const relativePath = path.relative(commonTempDir, absoluteProjectPath);\n overrides[packageName] = `file:${relativePath}`;\n }\n\n for (const w of warnings) {\n console.warn(w);\n }\n\n // Patch pnpm-config.json\n const pnpmConfigPath = path.join(repoDir, 'common', 'config', 'rush', 'pnpm-config.json');\n if (!fs.existsSync(pnpmConfigPath)) {\n throw new Error(`pnpm-config.json not found at ${pnpmConfigPath}`);\n }\n\n const patchOps: IPatchOperation[] = [\n {\n type: 'set-json',\n path: 'globalOverrides',\n value: JSON.stringify(overrides)\n },\n {\n type: 'set',\n path: 'strictPeerDependencies',\n value: false\n },\n {\n type: 'set-json',\n path: 'globalPeerDependencyRules',\n value: JSON.stringify({ ignoreMissing: ['mustache'], allowAny: ['@fgv/*'] })\n }\n ];\n\n patchFile(pnpmConfigPath, patchOps);\n\n console.log(`\\n Patched: ${pnpmConfigPath}`);\n console.log(` Overrides (${Object.keys(overrides).length} packages):`);\n for (const [name, filePath] of Object.entries(overrides)) {\n console.log(` ${name} -> ${filePath}`);\n }\n console.log(`\\n Next: run \"rush update --purge\" in the consumer repo.`);\n}\n\nexport async function runUnlink(options: IUnlinkOptions): Promise<void> {\n const { repoDir, version } = options;\n\n console.log(`==> Unlinking from local fgv worktree`);\n console.log(` repo dir: ${repoDir}`);\n\n // Restore pnpm-config.json to defaults\n const pnpmConfigPath = path.join(repoDir, 'common', 'config', 'rush', 'pnpm-config.json');\n if (!fs.existsSync(pnpmConfigPath)) {\n throw new Error(`pnpm-config.json not found at ${pnpmConfigPath}`);\n }\n\n const patchOps: IPatchOperation[] = [\n {\n type: 'set-json',\n path: 'globalOverrides',\n value: JSON.stringify({})\n },\n {\n type: 'set',\n path: 'strictPeerDependencies',\n value: true\n },\n {\n type: 'set-json',\n path: 'globalPeerDependencyRules',\n value: JSON.stringify({})\n }\n ];\n\n patchFile(pnpmConfigPath, patchOps);\n console.log(` Patched: ${pnpmConfigPath} (restored defaults)`);\n\n // Optionally bump versions\n if (version) {\n console.log(`\\n Bumping @fgv/* deps to ${version}...`);\n const changed = updateVersionsInPackageJsons(repoDir, version);\n console.log(` Updated ${changed.length} package.json file(s):`);\n for (const f of changed) {\n console.log(` ${f}`);\n }\n }\n\n console.log(`\\n Next: run \"rush update --purge\" in the consumer repo.`);\n}\n\nexport async function runUpdateFgvVersions(options: IUpdateFgvVersionsOptions): Promise<void> {\n const { repoDir } = options;\n\n console.log(`==> Updating @fgv/* version specs`);\n console.log(` repo dir: ${repoDir}`);\n\n // Resolve version\n let versionSpec: string;\n if (options.version) {\n versionSpec = options.version;\n console.log(` Using explicit version: ${versionSpec}`);\n } else {\n console.log(' Querying npm for latest version...');\n versionSpec = resolveLatestFgvVersion();\n console.log(` Resolved version: ${versionSpec}`);\n }\n\n const changed = updateVersionsInPackageJsons(repoDir, versionSpec);\n console.log(`\\n Updated ${changed.length} package.json file(s):`);\n for (const f of changed) {\n console.log(` ${f}`);\n }\n\n if (changed.length > 0) {\n console.log(`\\n Next: run \"rush update --purge\" in the consumer repo.`);\n }\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Patch command — apply targeted edits to JSONC config files.
3
+ */
4
+ import { IPatchOperation } from '../packlets/jsonc';
5
+ export interface IPatchOptions {
6
+ file: string;
7
+ operations: IPatchOperation[];
8
+ }
9
+ /**
10
+ * Parse CLI arguments for the patch command into operations.
11
+ * Expects pairs like: --set 'path=value', --uncomment 'path', etc.
12
+ */
13
+ export declare function parsePatchArgs(args: string[]): IPatchOperation[];
14
+ export declare function runPatch(options: IPatchOptions): Promise<void>;
15
+ //# sourceMappingURL=patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/commands/patch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAmD,MAAM,mBAAmB,CAAC;AAErG,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CA4ChE;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBpE"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /**
3
+ * Patch command — apply targeted edits to JSONC config files.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.parsePatchArgs = parsePatchArgs;
40
+ exports.runPatch = runPatch;
41
+ const fs = __importStar(require("fs"));
42
+ const jsonc_1 = require("../packlets/jsonc");
43
+ /**
44
+ * Parse CLI arguments for the patch command into operations.
45
+ * Expects pairs like: --set 'path=value', --uncomment 'path', etc.
46
+ */
47
+ function parsePatchArgs(args) {
48
+ const operations = [];
49
+ const validOps = ['set', 'set-json', 'uncomment', 'add-to-array', 'remove'];
50
+ let i = 0;
51
+ while (i < args.length) {
52
+ const arg = args[i];
53
+ if (!arg.startsWith('--')) {
54
+ throw new Error(`Unexpected argument: ${arg}`);
55
+ }
56
+ const opType = arg.slice(2);
57
+ if (!validOps.includes(opType)) {
58
+ throw new Error(`Unknown operation: ${arg}`);
59
+ }
60
+ i++;
61
+ if (i >= args.length) {
62
+ throw new Error(`Missing value for ${arg}`);
63
+ }
64
+ const operand = args[i];
65
+ i++;
66
+ if (opType === 'uncomment' || opType === 'remove') {
67
+ operations.push({ type: opType, path: operand });
68
+ }
69
+ else {
70
+ const eqIndex = operand.indexOf('=');
71
+ if (eqIndex === -1) {
72
+ throw new Error(`Expected path=value for ${arg}, got: ${operand}`);
73
+ }
74
+ const opPath = operand.slice(0, eqIndex);
75
+ const rawValue = operand.slice(eqIndex + 1);
76
+ if (opType === 'set') {
77
+ operations.push({ type: opType, path: opPath, value: (0, jsonc_1.parseValue)(rawValue) });
78
+ }
79
+ else {
80
+ // set-json and add-to-array pass raw JSON string
81
+ operations.push({ type: opType, path: opPath, value: rawValue });
82
+ }
83
+ }
84
+ }
85
+ return operations;
86
+ }
87
+ async function runPatch(options) {
88
+ const { file, operations } = options;
89
+ if (!fs.existsSync(file)) {
90
+ throw new Error(`File not found: ${file}`);
91
+ }
92
+ console.log(`Patching: ${file}`);
93
+ let source = fs.readFileSync(file, 'utf-8');
94
+ for (const op of operations) {
95
+ const desc = op.type === 'uncomment' || op.type === 'remove'
96
+ ? ` ${op.type}: ${op.path}`
97
+ : ` ${op.type}: ${op.path} = ${op.value}`;
98
+ console.log(desc);
99
+ }
100
+ source = (0, jsonc_1.applyOperations)(source, operations);
101
+ fs.writeFileSync(file, source);
102
+ console.log(` Done: ${operations.length} operation(s) applied`);
103
+ }
104
+ //# sourceMappingURL=patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/commands/patch.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcH,wCA4CC;AAED,4BAqBC;AA/ED,uCAAyB;AACzB,6CAAqG;AAOrG;;;GAGG;AACH,SAAgB,cAAc,CAAC,IAAc;IAC3C,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAyB,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;IAElG,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAuB,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,CAAC,EAAE,CAAC;QACJ,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,EAAE,CAAC;QAEJ,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,UAAU,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YAE5C,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAA,kBAAU,EAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,OAAsB;IACnD,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAErC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACjC,IAAI,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE5C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,GACR,EAAE,CAAC,IAAI,KAAK,WAAW,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAC7C,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE;YAC5B,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,GAAG,IAAA,uBAAe,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,MAAM,uBAAuB,CAAC,CAAC;AACnE,CAAC","sourcesContent":["/**\n * Patch command — apply targeted edits to JSONC config files.\n */\n\nimport * as fs from 'fs';\nimport { IPatchOperation, PatchOperationType, applyOperations, parseValue } from '../packlets/jsonc';\n\nexport interface IPatchOptions {\n file: string;\n operations: IPatchOperation[];\n}\n\n/**\n * Parse CLI arguments for the patch command into operations.\n * Expects pairs like: --set 'path=value', --uncomment 'path', etc.\n */\nexport function parsePatchArgs(args: string[]): IPatchOperation[] {\n const operations: IPatchOperation[] = [];\n const validOps: PatchOperationType[] = ['set', 'set-json', 'uncomment', 'add-to-array', 'remove'];\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n if (!arg.startsWith('--')) {\n throw new Error(`Unexpected argument: ${arg}`);\n }\n\n const opType = arg.slice(2) as PatchOperationType;\n if (!validOps.includes(opType)) {\n throw new Error(`Unknown operation: ${arg}`);\n }\n\n i++;\n if (i >= args.length) {\n throw new Error(`Missing value for ${arg}`);\n }\n\n const operand = args[i];\n i++;\n\n if (opType === 'uncomment' || opType === 'remove') {\n operations.push({ type: opType, path: operand });\n } else {\n const eqIndex = operand.indexOf('=');\n if (eqIndex === -1) {\n throw new Error(`Expected path=value for ${arg}, got: ${operand}`);\n }\n const opPath = operand.slice(0, eqIndex);\n const rawValue = operand.slice(eqIndex + 1);\n\n if (opType === 'set') {\n operations.push({ type: opType, path: opPath, value: parseValue(rawValue) });\n } else {\n // set-json and add-to-array pass raw JSON string\n operations.push({ type: opType, path: opPath, value: rawValue });\n }\n }\n }\n\n return operations;\n}\n\nexport async function runPatch(options: IPatchOptions): Promise<void> {\n const { file, operations } = options;\n\n if (!fs.existsSync(file)) {\n throw new Error(`File not found: ${file}`);\n }\n\n console.log(`Patching: ${file}`);\n let source = fs.readFileSync(file, 'utf-8');\n\n for (const op of operations) {\n const desc =\n op.type === 'uncomment' || op.type === 'remove'\n ? ` ${op.type}: ${op.path}`\n : ` ${op.type}: ${op.path} = ${op.value}`;\n console.log(desc);\n }\n\n source = applyOperations(source, operations);\n fs.writeFileSync(file, source);\n console.log(` Done: ${operations.length} operation(s) applied`);\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sync command — updates shared files in a consumer repo from the template source.
3
+ * Templated files are NOT touched — they are owned by the consumer after creation.
4
+ */
5
+ export interface ISyncOptions {
6
+ targetDir: string;
7
+ sourceDir: string;
8
+ dryRun: boolean;
9
+ }
10
+ export declare function runSync(options: ISyncOptions): Promise<void>;
11
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHlE"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ /**
3
+ * Sync command — updates shared files in a consumer repo from the template source.
4
+ * Templated files are NOT touched — they are owned by the consumer after creation.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.runSync = runSync;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const manifest_1 = require("../packlets/manifest");
44
+ const fs_1 = require("../packlets/fs");
45
+ async function runSync(options) {
46
+ const { targetDir, sourceDir, dryRun } = options;
47
+ if (!fs.existsSync(targetDir)) {
48
+ throw new Error(`Target directory does not exist: ${targetDir}`);
49
+ }
50
+ if (!fs.existsSync(path.join(sourceDir, 'rush.json'))) {
51
+ throw new Error(`Source directory is not a Rush repo: ${sourceDir}`);
52
+ }
53
+ const manifestPath = (0, manifest_1.getDefaultManifestPath)();
54
+ const manifest = (0, manifest_1.loadManifest)(manifestPath);
55
+ console.log('Syncing shared files');
56
+ console.log(` Source: ${sourceDir}`);
57
+ console.log(` Target: ${targetDir}`);
58
+ if (dryRun) {
59
+ console.log(' Mode: DRY RUN (no changes will be made)');
60
+ }
61
+ console.log('');
62
+ let copied = 0;
63
+ let skipped = 0;
64
+ let warnings = 0;
65
+ // ── Sync individual shared files ──
66
+ console.log('==> Syncing shared files...');
67
+ for (const file of manifest.shared.files) {
68
+ const srcPath = path.join(sourceDir, file.source);
69
+ const dstPath = path.join(targetDir, file.destination);
70
+ if (!fs.existsSync(srcPath)) {
71
+ console.log(` WARNING: Source not found: ${file.source}`);
72
+ warnings++;
73
+ continue;
74
+ }
75
+ if (dryRun) {
76
+ if (fs.existsSync(dstPath) && (0, fs_1.filesAreEqual)(srcPath, dstPath)) {
77
+ console.log(` [unchanged] ${file.destination}`);
78
+ skipped++;
79
+ }
80
+ else if (fs.existsSync(dstPath)) {
81
+ console.log(` [would update] ${file.destination}`);
82
+ copied++;
83
+ }
84
+ else {
85
+ console.log(` [would create] ${file.destination}`);
86
+ copied++;
87
+ }
88
+ }
89
+ else {
90
+ if (fs.existsSync(dstPath) && (0, fs_1.filesAreEqual)(srcPath, dstPath)) {
91
+ skipped++;
92
+ }
93
+ else {
94
+ (0, fs_1.copyFile)(srcPath, dstPath);
95
+ console.log(` Updated: ${file.destination}`);
96
+ copied++;
97
+ }
98
+ }
99
+ }
100
+ // ── Sync shared packages ──
101
+ console.log('');
102
+ console.log('==> Syncing shared packages...');
103
+ for (const pkg of manifest.sharedPackages.packages) {
104
+ const srcPath = path.join(sourceDir, pkg.source);
105
+ const dstPath = path.join(targetDir, pkg.destination);
106
+ if (!fs.existsSync(srcPath)) {
107
+ console.log(` WARNING: Source directory not found: ${pkg.source}`);
108
+ warnings++;
109
+ continue;
110
+ }
111
+ if (dryRun) {
112
+ console.log(` [would sync] ${pkg.destination}/`);
113
+ copied++;
114
+ }
115
+ else {
116
+ (0, fs_1.copyPackage)(srcPath, dstPath);
117
+ console.log(` Synced package: ${pkg.destination}`);
118
+ copied++;
119
+ }
120
+ }
121
+ // ── Update sync metadata ──
122
+ if (!dryRun) {
123
+ const syncFilePath = path.join(targetDir, '.template-sync');
124
+ if (fs.existsSync(syncFilePath)) {
125
+ try {
126
+ const syncData = JSON.parse(fs.readFileSync(syncFilePath, 'utf-8'));
127
+ syncData.lastSyncedAt = new Date().toISOString();
128
+ syncData.sourceCommit = (0, fs_1.getGitCommit)(sourceDir);
129
+ fs.writeFileSync(syncFilePath, JSON.stringify(syncData, null, 2) + '\n');
130
+ console.log('');
131
+ console.log(' Updated .template-sync');
132
+ }
133
+ catch (_a) {
134
+ console.log(' WARNING: Could not update .template-sync');
135
+ }
136
+ }
137
+ }
138
+ // ── Summary ──
139
+ console.log('');
140
+ console.log('=== Sync complete ===');
141
+ console.log(` Updated: ${copied}`);
142
+ console.log(` Unchanged: ${skipped}`);
143
+ console.log(` Warnings: ${warnings}`);
144
+ if (dryRun) {
145
+ console.log('');
146
+ console.log('This was a dry run. No files were modified.');
147
+ console.log('Run without --dry-run to apply changes.');
148
+ }
149
+ if (!dryRun && copied > 0) {
150
+ console.log('');
151
+ console.log('Next steps:');
152
+ console.log(` 1. Review changes: cd ${targetDir} && git diff`);
153
+ console.log(" 2. Commit: git add -A && git commit -m 'Sync shared files from template'");
154
+ }
155
+ }
156
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Sync command — updates shared files in a consumer repo from the template source.\n * Templated files are NOT touched — they are owned by the consumer after creation.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loadManifest, getDefaultManifestPath } from '../packlets/manifest';\nimport { copyFile, copyPackage, filesAreEqual, getGitCommit } from '../packlets/fs';\n\nexport interface ISyncOptions {\n targetDir: string;\n sourceDir: string;\n dryRun: boolean;\n}\n\nexport async function runSync(options: ISyncOptions): Promise<void> {\n const { targetDir, sourceDir, dryRun } = options;\n\n if (!fs.existsSync(targetDir)) {\n throw new Error(`Target directory does not exist: ${targetDir}`);\n }\n if (!fs.existsSync(path.join(sourceDir, 'rush.json'))) {\n throw new Error(`Source directory is not a Rush repo: ${sourceDir}`);\n }\n\n const manifestPath = getDefaultManifestPath();\n const manifest = loadManifest(manifestPath);\n\n console.log('Syncing shared files');\n console.log(` Source: ${sourceDir}`);\n console.log(` Target: ${targetDir}`);\n if (dryRun) {\n console.log(' Mode: DRY RUN (no changes will be made)');\n }\n console.log('');\n\n let copied = 0;\n let skipped = 0;\n let warnings = 0;\n\n // ── Sync individual shared files ──\n console.log('==> Syncing shared files...');\n\n for (const file of manifest.shared.files) {\n const srcPath = path.join(sourceDir, file.source);\n const dstPath = path.join(targetDir, file.destination);\n\n if (!fs.existsSync(srcPath)) {\n console.log(` WARNING: Source not found: ${file.source}`);\n warnings++;\n continue;\n }\n\n if (dryRun) {\n if (fs.existsSync(dstPath) && filesAreEqual(srcPath, dstPath)) {\n console.log(` [unchanged] ${file.destination}`);\n skipped++;\n } else if (fs.existsSync(dstPath)) {\n console.log(` [would update] ${file.destination}`);\n copied++;\n } else {\n console.log(` [would create] ${file.destination}`);\n copied++;\n }\n } else {\n if (fs.existsSync(dstPath) && filesAreEqual(srcPath, dstPath)) {\n skipped++;\n } else {\n copyFile(srcPath, dstPath);\n console.log(` Updated: ${file.destination}`);\n copied++;\n }\n }\n }\n\n // ── Sync shared packages ──\n console.log('');\n console.log('==> Syncing shared packages...');\n\n for (const pkg of manifest.sharedPackages.packages) {\n const srcPath = path.join(sourceDir, pkg.source);\n const dstPath = path.join(targetDir, pkg.destination);\n\n if (!fs.existsSync(srcPath)) {\n console.log(` WARNING: Source directory not found: ${pkg.source}`);\n warnings++;\n continue;\n }\n\n if (dryRun) {\n console.log(` [would sync] ${pkg.destination}/`);\n copied++;\n } else {\n copyPackage(srcPath, dstPath);\n console.log(` Synced package: ${pkg.destination}`);\n copied++;\n }\n }\n\n // ── Update sync metadata ──\n if (!dryRun) {\n const syncFilePath = path.join(targetDir, '.template-sync');\n if (fs.existsSync(syncFilePath)) {\n try {\n const syncData = JSON.parse(fs.readFileSync(syncFilePath, 'utf-8'));\n syncData.lastSyncedAt = new Date().toISOString();\n syncData.sourceCommit = getGitCommit(sourceDir);\n fs.writeFileSync(syncFilePath, JSON.stringify(syncData, null, 2) + '\\n');\n console.log('');\n console.log(' Updated .template-sync');\n } catch {\n console.log(' WARNING: Could not update .template-sync');\n }\n }\n }\n\n // ── Summary ──\n console.log('');\n console.log('=== Sync complete ===');\n console.log(` Updated: ${copied}`);\n console.log(` Unchanged: ${skipped}`);\n console.log(` Warnings: ${warnings}`);\n\n if (dryRun) {\n console.log('');\n console.log('This was a dry run. No files were modified.');\n console.log('Run without --dry-run to apply changes.');\n }\n\n if (!dryRun && copied > 0) {\n console.log('');\n console.log('Next steps:');\n console.log(` 1. Review changes: cd ${targetDir} && git diff`);\n console.log(\" 2. Commit: git add -A && git commit -m 'Sync shared files from template'\");\n }\n}\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fgv/repo-template — CLI tool for creating and maintaining fgv-derived Rush monorepos.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { RepoTemplateCli } from './cli';
7
+ export { runCreate, ICreateOptions } from './commands/create';
8
+ export { runSync, ISyncOptions } from './commands/sync';
9
+ export { runPatch, IPatchOptions, parsePatchArgs } from './commands/patch';
10
+ export { runInitLibrary, IInitLibraryOptions, RigType, CategoryType } from './commands/init-library';
11
+ export { runLink, runUnlink, runUpdateFgvVersions, ILinkOptions, IUnlinkOptions, IUpdateFgvVersionsOptions } from './commands/link';
12
+ export { applyOperations, applyOperation, patchFile, IPatchOperation } from './packlets/jsonc';
13
+ export { loadManifest, IManifest, ISharedFile, ISharedPackage, ITemplatedFile } from './packlets/manifest';
14
+ export { renderTemplate, renderTemplateFile, ITemplateVars } from './packlets/template';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EACL,OAAO,EACP,SAAS,EACT,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}