@authrim/setup 0.1.63 → 0.1.64
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/__tests__/migrate.test.d.ts +5 -0
- package/dist/__tests__/migrate.test.d.ts.map +1 -0
- package/dist/__tests__/migrate.test.js +273 -0
- package/dist/__tests__/migrate.test.js.map +1 -0
- package/dist/__tests__/paths.test.d.ts +2 -0
- package/dist/__tests__/paths.test.d.ts.map +1 -0
- package/dist/__tests__/paths.test.js +257 -0
- package/dist/__tests__/paths.test.js.map +1 -0
- package/dist/cli/commands/config.d.ts +1 -0
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +41 -7
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +1 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/deploy.js +181 -19
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +267 -82
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/migrate.d.ts +21 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +166 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/core/admin.d.ts +18 -1
- package/dist/core/admin.d.ts.map +1 -1
- package/dist/core/admin.js +36 -7
- package/dist/core/admin.js.map +1 -1
- package/dist/core/config.d.ts +10 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +6 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/keys.d.ts +55 -4
- package/dist/core/keys.d.ts.map +1 -1
- package/dist/core/keys.js +104 -12
- package/dist/core/keys.js.map +1 -1
- package/dist/core/lock.d.ts +60 -3
- package/dist/core/lock.d.ts.map +1 -1
- package/dist/core/lock.js +108 -4
- package/dist/core/lock.js.map +1 -1
- package/dist/core/migrate.d.ts +95 -0
- package/dist/core/migrate.d.ts.map +1 -0
- package/dist/core/migrate.js +549 -0
- package/dist/core/migrate.js.map +1 -0
- package/dist/core/paths.d.ts +171 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +319 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/wrangler-sync.d.ts +88 -0
- package/dist/core/wrangler-sync.d.ts.map +1 -0
- package/dist/core/wrangler-sync.js +242 -0
- package/dist/core/wrangler-sync.js.map +1 -0
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/web/api.d.ts.map +1 -1
- package/dist/web/api.js +102 -28
- package/dist/web/api.js.map +1 -1
- package/dist/web/ui.d.ts.map +1 -1
- package/dist/web/ui.js +831 -273
- package/dist/web/ui.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,18 +6,17 @@
|
|
|
6
6
|
import { input, select, confirm, password } from '@inquirer/prompts';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import ora from 'ora';
|
|
9
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
9
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
10
10
|
import { existsSync } from 'node:fs';
|
|
11
11
|
import { join, resolve } from 'node:path';
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
13
|
import { execa } from 'execa';
|
|
14
14
|
import { createDefaultConfig, parseConfig } from '../../core/config.js';
|
|
15
15
|
import { generateAllSecrets, saveKeysToDirectory, generateKeyId, keysExistForEnvironment, } from '../../core/keys.js';
|
|
16
|
-
import { generateWranglerConfig, toToml } from '../../core/wrangler.js';
|
|
17
|
-
import { CORE_WORKER_COMPONENTS, } from '../../core/naming.js';
|
|
18
16
|
import { isWranglerInstalled, checkAuth, provisionResources, toResourceIds, getAccountId, detectEnvironments, getWorkersSubdomain, } from '../../core/cloudflare.js';
|
|
19
|
-
import { createLockFile, saveLockFile, loadLockFile
|
|
20
|
-
import {
|
|
17
|
+
import { createLockFile, saveLockFile, loadLockFile } from '../../core/lock.js';
|
|
18
|
+
import { getEnvironmentPaths, getRelativeKeysPath, AUTHRIM_DIR, } from '../../core/paths.js';
|
|
19
|
+
import { downloadSource, verifySourceStructure, checkForUpdate } from '../../core/source.js';
|
|
21
20
|
// =============================================================================
|
|
22
21
|
// Version
|
|
23
22
|
// =============================================================================
|
|
@@ -293,15 +292,12 @@ async function updateExistingSource(sourceDir, gitRef) {
|
|
|
293
292
|
const spinner = ora('Updating source code...').start();
|
|
294
293
|
try {
|
|
295
294
|
// Backup existing configuration files
|
|
296
|
-
|
|
295
|
+
// Support both legacy (authrim-*.json, .keys/) and new (.authrim/) structures
|
|
296
|
+
const configFiles = ['authrim-config.json', 'authrim-lock.json'];
|
|
297
297
|
const backups = [];
|
|
298
298
|
for (const file of configFiles) {
|
|
299
299
|
const filePath = join(sourceDir, file);
|
|
300
300
|
if (existsSync(filePath)) {
|
|
301
|
-
if (file === '.keys') {
|
|
302
|
-
// Skip backing up .keys - will be preserved
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
301
|
const { readFile: rf } = await import('node:fs/promises');
|
|
306
302
|
const content = await rf(filePath, 'utf-8');
|
|
307
303
|
backups.push({ file, content });
|
|
@@ -318,7 +314,13 @@ async function updateExistingSource(sourceDir, gitRef) {
|
|
|
318
314
|
spinner.text = msg;
|
|
319
315
|
},
|
|
320
316
|
});
|
|
321
|
-
// Preserve .
|
|
317
|
+
// Preserve .authrim directory if it exists (new structure)
|
|
318
|
+
const authrimDir = join(sourceDir, AUTHRIM_DIR);
|
|
319
|
+
const tempAuthrimDir = join(tempDir, AUTHRIM_DIR);
|
|
320
|
+
if (existsSync(authrimDir)) {
|
|
321
|
+
await cp(authrimDir, tempAuthrimDir, { recursive: true });
|
|
322
|
+
}
|
|
323
|
+
// Preserve .keys directory if it exists (legacy structure)
|
|
322
324
|
const keysDir = join(sourceDir, '.keys');
|
|
323
325
|
const tempKeysDir = join(tempDir, '.keys');
|
|
324
326
|
if (existsSync(keysDir)) {
|
|
@@ -586,42 +588,175 @@ async function runLoadConfig() {
|
|
|
586
588
|
console.log(chalk.bold('📂 Load Existing Configuration'));
|
|
587
589
|
console.log(chalk.blue('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
588
590
|
console.log('');
|
|
589
|
-
// Check for config
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
591
|
+
// Check for config files in both new and legacy structures
|
|
592
|
+
const baseDir = process.cwd();
|
|
593
|
+
// Detect existing environments
|
|
594
|
+
const { listEnvironments } = await import('../../core/paths.js');
|
|
595
|
+
const environments = listEnvironments(baseDir);
|
|
596
|
+
// Build list of found configs
|
|
597
|
+
const foundConfigs = [];
|
|
598
|
+
// Check new structure (.authrim/{env}/config.json)
|
|
599
|
+
for (const env of environments) {
|
|
600
|
+
const newPaths = getEnvironmentPaths({ baseDir, env });
|
|
601
|
+
if (existsSync(newPaths.config)) {
|
|
602
|
+
foundConfigs.push({ path: newPaths.config, env, type: 'new' });
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// Check legacy structure (authrim-config.json)
|
|
606
|
+
const legacyConfigPath = './authrim-config.json';
|
|
607
|
+
if (existsSync(legacyConfigPath) && !foundConfigs.some((c) => c.type === 'legacy')) {
|
|
608
|
+
// Try to read env from legacy config
|
|
609
|
+
try {
|
|
610
|
+
const legacyContent = await readFile(legacyConfigPath, 'utf-8');
|
|
611
|
+
const legacyConfig = JSON.parse(legacyContent);
|
|
612
|
+
const legacyEnv = legacyConfig.environment?.prefix || 'unknown';
|
|
613
|
+
foundConfigs.push({ path: legacyConfigPath, env: legacyEnv, type: 'legacy' });
|
|
614
|
+
}
|
|
615
|
+
catch {
|
|
616
|
+
foundConfigs.push({ path: legacyConfigPath, env: 'unknown', type: 'legacy' });
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
let configPath;
|
|
620
|
+
if (foundConfigs.length > 0) {
|
|
621
|
+
console.log(chalk.green(`✓ Found ${foundConfigs.length} configuration(s):`));
|
|
622
|
+
for (const cfg of foundConfigs) {
|
|
623
|
+
const typeLabel = cfg.type === 'new' ? chalk.blue('(new)') : chalk.yellow('(legacy)');
|
|
624
|
+
console.log(` • ${cfg.path} ${typeLabel} - env: ${cfg.env}`);
|
|
625
|
+
}
|
|
595
626
|
console.log('');
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
627
|
+
// Check if there are legacy configs that could be migrated
|
|
628
|
+
const legacyConfigs = foundConfigs.filter((c) => c.type === 'legacy');
|
|
629
|
+
if (legacyConfigs.length > 0) {
|
|
630
|
+
console.log(chalk.yellow('━━━ Legacy Structure Detected ━━━'));
|
|
631
|
+
console.log(chalk.gray('Legacy files:'));
|
|
632
|
+
console.log(chalk.gray(' • authrim-config.json'));
|
|
633
|
+
console.log(chalk.gray(' • authrim-lock.json'));
|
|
634
|
+
console.log(chalk.gray(' • .keys/{env}/'));
|
|
635
|
+
console.log('');
|
|
636
|
+
console.log(chalk.gray('New structure benefits:'));
|
|
637
|
+
console.log(chalk.gray(' • Environment portability (zip .authrim/prod/)'));
|
|
638
|
+
console.log(chalk.gray(' • Version tracking per environment'));
|
|
639
|
+
console.log(chalk.gray(' • Cleaner project structure'));
|
|
640
|
+
console.log('');
|
|
641
|
+
const migrateAction = await select({
|
|
642
|
+
message: 'Would you like to migrate to the new structure?',
|
|
643
|
+
choices: [
|
|
644
|
+
{ value: 'migrate', name: '🔄 Migrate to new structure (.authrim/{env}/)' },
|
|
645
|
+
{ value: 'continue', name: '📂 Continue with legacy structure' },
|
|
646
|
+
{ value: 'back', name: '← Back to Main Menu' },
|
|
647
|
+
],
|
|
648
|
+
});
|
|
649
|
+
if (migrateAction === 'back') {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
if (migrateAction === 'migrate') {
|
|
653
|
+
const { migrateToNewStructure, validateMigration } = await import('../../core/migrate.js');
|
|
654
|
+
console.log('');
|
|
655
|
+
const envToMigrate = legacyConfigs[0].env;
|
|
656
|
+
const result = await migrateToNewStructure({
|
|
657
|
+
baseDir,
|
|
658
|
+
env: envToMigrate,
|
|
659
|
+
onProgress: (msg) => console.log(msg),
|
|
660
|
+
});
|
|
661
|
+
if (result.success) {
|
|
662
|
+
console.log('');
|
|
663
|
+
console.log(chalk.green('✓ Migration completed successfully!'));
|
|
664
|
+
// Validate
|
|
665
|
+
const validation = await validateMigration(baseDir, envToMigrate);
|
|
666
|
+
if (validation.valid) {
|
|
667
|
+
console.log(chalk.green('✓ Validation passed'));
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
console.log(chalk.yellow('⚠ Validation issues:'));
|
|
671
|
+
for (const issue of validation.issues) {
|
|
672
|
+
console.log(chalk.yellow(` • ${issue}`));
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
console.log('');
|
|
676
|
+
console.log(chalk.cyan('New configuration location:'));
|
|
677
|
+
console.log(chalk.cyan(` .authrim/${envToMigrate}/config.json`));
|
|
678
|
+
console.log('');
|
|
679
|
+
// Update foundConfigs to use new path
|
|
680
|
+
const newPaths = getEnvironmentPaths({ baseDir, env: envToMigrate });
|
|
681
|
+
foundConfigs.length = 0;
|
|
682
|
+
foundConfigs.push({ path: newPaths.config, env: envToMigrate, type: 'new' });
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
console.log('');
|
|
686
|
+
console.log(chalk.red('✗ Migration failed:'));
|
|
687
|
+
for (const error of result.errors) {
|
|
688
|
+
console.log(chalk.red(` • ${error}`));
|
|
689
|
+
}
|
|
690
|
+
console.log('');
|
|
691
|
+
console.log(chalk.yellow('Continuing with legacy structure...'));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
606
694
|
}
|
|
607
|
-
if (
|
|
608
|
-
configPath =
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
695
|
+
if (foundConfigs.length === 1) {
|
|
696
|
+
configPath = foundConfigs[0].path;
|
|
697
|
+
const action = await select({
|
|
698
|
+
message: 'What would you like to do?',
|
|
699
|
+
choices: [
|
|
700
|
+
{ value: 'load', name: '📂 Load this configuration' },
|
|
701
|
+
{ value: 'other', name: '📁 Specify different file' },
|
|
702
|
+
{ value: 'back', name: '← Back to Main Menu' },
|
|
703
|
+
],
|
|
704
|
+
});
|
|
705
|
+
if (action === 'back') {
|
|
706
|
+
return false; // Return to main menu
|
|
707
|
+
}
|
|
708
|
+
if (action === 'other') {
|
|
709
|
+
configPath = await input({
|
|
710
|
+
message: 'Enter configuration file path',
|
|
711
|
+
validate: (value) => {
|
|
712
|
+
if (!value)
|
|
713
|
+
return 'Please enter a path';
|
|
714
|
+
if (!existsSync(value))
|
|
715
|
+
return `File not found: ${value}`;
|
|
716
|
+
return true;
|
|
717
|
+
},
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// Multiple configs found - let user select
|
|
723
|
+
const choices = [
|
|
724
|
+
...foundConfigs.map((cfg) => ({
|
|
725
|
+
value: cfg.path,
|
|
726
|
+
name: `📂 ${cfg.env} (${cfg.path}) ${cfg.type === 'legacy' ? chalk.yellow('legacy') : ''}`,
|
|
727
|
+
})),
|
|
728
|
+
{ value: '__other__', name: '📁 Specify different file' },
|
|
729
|
+
{ value: '__back__', name: '← Back to Main Menu' },
|
|
730
|
+
];
|
|
731
|
+
const selected = await select({
|
|
732
|
+
message: 'Select configuration to load',
|
|
733
|
+
choices,
|
|
617
734
|
});
|
|
735
|
+
if (selected === '__back__') {
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
if (selected === '__other__') {
|
|
739
|
+
configPath = await input({
|
|
740
|
+
message: 'Enter configuration file path',
|
|
741
|
+
validate: (value) => {
|
|
742
|
+
if (!value)
|
|
743
|
+
return 'Please enter a path';
|
|
744
|
+
if (!existsSync(value))
|
|
745
|
+
return `File not found: ${value}`;
|
|
746
|
+
return true;
|
|
747
|
+
},
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
configPath = selected;
|
|
752
|
+
}
|
|
618
753
|
}
|
|
619
754
|
}
|
|
620
755
|
else {
|
|
621
|
-
console.log(chalk.yellow('No
|
|
756
|
+
console.log(chalk.yellow('No configuration found in current directory.'));
|
|
622
757
|
console.log('');
|
|
623
758
|
console.log(chalk.gray('💡 Tip: You can specify a config file with:'));
|
|
624
|
-
console.log(chalk.cyan(' npx @authrim/setup --config /path/to/
|
|
759
|
+
console.log(chalk.cyan(' npx @authrim/setup --config /path/to/.authrim/{env}/config.json'));
|
|
625
760
|
console.log('');
|
|
626
761
|
const action = await select({
|
|
627
762
|
message: 'What would you like to do?',
|
|
@@ -893,11 +1028,13 @@ async function runQuickSetup(options) {
|
|
|
893
1028
|
}
|
|
894
1029
|
// Save email secrets if configured
|
|
895
1030
|
if (emailConfig.provider === 'resend' && emailConfig.apiKey) {
|
|
896
|
-
|
|
1031
|
+
// Use new structure for fresh setups
|
|
1032
|
+
const paths = getEnvironmentPaths({ baseDir: process.cwd(), env: envPrefix });
|
|
1033
|
+
const keysDir = paths.keys;
|
|
897
1034
|
await import('node:fs/promises').then(async (fs) => {
|
|
898
1035
|
await fs.mkdir(keysDir, { recursive: true });
|
|
899
|
-
await fs.writeFile(
|
|
900
|
-
await fs.writeFile(
|
|
1036
|
+
await fs.writeFile(paths.keyFiles.resendApiKey, emailConfig.apiKey.trim());
|
|
1037
|
+
await fs.writeFile(paths.keyFiles.emailFrom, emailConfig.fromAddress.trim());
|
|
901
1038
|
if (emailConfig.fromName) {
|
|
902
1039
|
await fs.writeFile(`${keysDir}/email_from_name.txt`, emailConfig.fromName.trim());
|
|
903
1040
|
}
|
|
@@ -1476,11 +1613,13 @@ async function runNormalSetup(options) {
|
|
|
1476
1613
|
}
|
|
1477
1614
|
// Save email secrets if configured
|
|
1478
1615
|
if (emailConfigNormal.provider === 'resend' && emailConfigNormal.apiKey) {
|
|
1479
|
-
|
|
1616
|
+
// Use new structure for fresh setups
|
|
1617
|
+
const paths = getEnvironmentPaths({ baseDir: process.cwd(), env: envPrefix });
|
|
1618
|
+
const keysDir = paths.keys;
|
|
1480
1619
|
await import('node:fs/promises').then(async (fs) => {
|
|
1481
1620
|
await fs.mkdir(keysDir, { recursive: true });
|
|
1482
|
-
await fs.writeFile(
|
|
1483
|
-
await fs.writeFile(
|
|
1621
|
+
await fs.writeFile(paths.keyFiles.resendApiKey, emailConfigNormal.apiKey.trim());
|
|
1622
|
+
await fs.writeFile(paths.keyFiles.emailFrom, emailConfigNormal.fromAddress.trim());
|
|
1484
1623
|
if (emailConfigNormal.fromName) {
|
|
1485
1624
|
await fs.writeFile(`${keysDir}/email_from_name.txt`, emailConfigNormal.fromName.trim());
|
|
1486
1625
|
}
|
|
@@ -1549,17 +1688,16 @@ async function executeSetup(config, cfApiToken, keepPath) {
|
|
|
1549
1688
|
try {
|
|
1550
1689
|
const keyId = generateKeyId(env);
|
|
1551
1690
|
secrets = generateAllSecrets(keyId);
|
|
1552
|
-
// Save to
|
|
1553
|
-
const
|
|
1554
|
-
await saveKeysToDirectory(secrets,
|
|
1555
|
-
const keysDir = join(keysBaseDir, env);
|
|
1691
|
+
// Save to new structure: .authrim/{env}/keys/
|
|
1692
|
+
const envPaths = getEnvironmentPaths({ baseDir: outputDir, env });
|
|
1693
|
+
await saveKeysToDirectory(secrets, { baseDir: outputDir, env });
|
|
1556
1694
|
config.keys = {
|
|
1557
1695
|
keyId: secrets.keyPair.keyId,
|
|
1558
1696
|
publicKeyJwk: secrets.keyPair.publicKeyJwk,
|
|
1559
|
-
secretsPath:
|
|
1697
|
+
secretsPath: getRelativeKeysPath(), // './keys/' (relative from config location)
|
|
1560
1698
|
includeSecrets: false,
|
|
1561
1699
|
};
|
|
1562
|
-
keysSpinner.succeed(`Keys generated (${
|
|
1700
|
+
keysSpinner.succeed(`Keys generated (${envPaths.keys})`);
|
|
1563
1701
|
}
|
|
1564
1702
|
catch (error) {
|
|
1565
1703
|
keysSpinner.fail('Failed to generate keys');
|
|
@@ -1595,53 +1733,89 @@ async function executeSetup(config, cfApiToken, keepPath) {
|
|
|
1595
1733
|
// Create empty resources
|
|
1596
1734
|
provisionedResources = { d1: [], kv: [], queues: [], r2: [] };
|
|
1597
1735
|
}
|
|
1598
|
-
// Step 3: Create lock file
|
|
1599
|
-
const
|
|
1736
|
+
// Step 3: Create lock file (save to new structure: .authrim/{env}/lock.json)
|
|
1737
|
+
const envPaths = getEnvironmentPaths({ baseDir: outputDir, env });
|
|
1738
|
+
const lockSpinner = ora('Generating lock file...').start();
|
|
1600
1739
|
try {
|
|
1601
1740
|
const lockFile = createLockFile(env, provisionedResources);
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
lockSpinner.succeed(`authrim-lock.json saved (${lockPath})`);
|
|
1741
|
+
await saveLockFile(lockFile, { baseDir: outputDir, env });
|
|
1742
|
+
lockSpinner.succeed(`Lock file saved (${envPaths.lock})`);
|
|
1605
1743
|
}
|
|
1606
1744
|
catch (error) {
|
|
1607
|
-
lockSpinner.fail('
|
|
1745
|
+
lockSpinner.fail('Lock file save failed');
|
|
1608
1746
|
console.error(error);
|
|
1609
1747
|
}
|
|
1610
|
-
// Step 4: Save configuration
|
|
1748
|
+
// Step 4: Save configuration (save to new structure: .authrim/{env}/config.json)
|
|
1611
1749
|
const configSpinner = ora('Saving configuration...').start();
|
|
1612
1750
|
try {
|
|
1613
|
-
|
|
1751
|
+
// Ensure environment directory exists
|
|
1752
|
+
await mkdir(envPaths.root, { recursive: true });
|
|
1753
|
+
const configPath = envPaths.config;
|
|
1614
1754
|
config.updatedAt = new Date().toISOString();
|
|
1615
1755
|
await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
1756
|
+
// Also save version.txt
|
|
1757
|
+
const setupVersion = getVersion();
|
|
1758
|
+
await writeFile(envPaths.version, setupVersion, 'utf-8');
|
|
1616
1759
|
configSpinner.succeed(`Configuration saved (${configPath})`);
|
|
1617
1760
|
}
|
|
1618
1761
|
catch (error) {
|
|
1619
1762
|
configSpinner.fail('Configuration save failed');
|
|
1620
1763
|
throw error;
|
|
1621
1764
|
}
|
|
1622
|
-
// Step 5: Generate wrangler.toml files
|
|
1765
|
+
// Step 5: Generate wrangler.toml files
|
|
1623
1766
|
const resourceIds = toResourceIds(provisionedResources);
|
|
1624
1767
|
const packagesDir = join(outputDir, 'packages');
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1768
|
+
const baseDir = process.cwd();
|
|
1769
|
+
// Step 5a: Save master wrangler configs to .authrim/{env}/wrangler/
|
|
1770
|
+
const wranglerSpinner = ora('Saving wrangler.toml master configs...').start();
|
|
1771
|
+
try {
|
|
1772
|
+
const { saveMasterWranglerConfigs, syncWranglerConfigs } = await import('../../core/wrangler-sync.js');
|
|
1773
|
+
const masterResult = await saveMasterWranglerConfigs(config, resourceIds, {
|
|
1774
|
+
baseDir,
|
|
1775
|
+
env,
|
|
1776
|
+
dryRun: false,
|
|
1777
|
+
onProgress: (msg) => {
|
|
1778
|
+
wranglerSpinner.text = msg;
|
|
1779
|
+
},
|
|
1780
|
+
});
|
|
1781
|
+
if (masterResult.success) {
|
|
1782
|
+
wranglerSpinner.succeed(`Saved ${masterResult.files.length} wrangler.toml master configs`);
|
|
1783
|
+
}
|
|
1784
|
+
else {
|
|
1785
|
+
wranglerSpinner.warn('Some wrangler configs failed to save');
|
|
1786
|
+
for (const error of masterResult.errors) {
|
|
1787
|
+
console.log(chalk.yellow(` • ${error}`));
|
|
1637
1788
|
}
|
|
1638
|
-
wranglerSpinner.succeed('wrangler.toml files generated');
|
|
1639
1789
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1790
|
+
// Step 5b: Sync to deployment locations (if packages directory exists)
|
|
1791
|
+
if (existsSync(packagesDir)) {
|
|
1792
|
+
const syncSpinner = ora('Syncing wrangler configs to packages...').start();
|
|
1793
|
+
const syncResult = await syncWranglerConfigs({
|
|
1794
|
+
baseDir,
|
|
1795
|
+
env,
|
|
1796
|
+
packagesDir,
|
|
1797
|
+
force: true, // First time setup, always overwrite
|
|
1798
|
+
dryRun: false,
|
|
1799
|
+
onProgress: (msg) => {
|
|
1800
|
+
syncSpinner.text = msg;
|
|
1801
|
+
},
|
|
1802
|
+
}, undefined // No manual edit callback for init
|
|
1803
|
+
);
|
|
1804
|
+
if (syncResult.success) {
|
|
1805
|
+
syncSpinner.succeed(`Synced wrangler configs to ${syncResult.synced.length} components`);
|
|
1806
|
+
}
|
|
1807
|
+
else {
|
|
1808
|
+
syncSpinner.fail('wrangler config sync failed');
|
|
1809
|
+
for (const error of syncResult.errors) {
|
|
1810
|
+
console.log(chalk.red(` • ${error}`));
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1643
1813
|
}
|
|
1644
1814
|
}
|
|
1815
|
+
catch (error) {
|
|
1816
|
+
wranglerSpinner.fail('wrangler.toml generation failed');
|
|
1817
|
+
console.error(error);
|
|
1818
|
+
}
|
|
1645
1819
|
// Summary
|
|
1646
1820
|
console.log('');
|
|
1647
1821
|
console.log(chalk.green('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
@@ -1667,9 +1841,10 @@ async function executeSetup(config, cfApiToken, keepPath) {
|
|
|
1667
1841
|
console.log('');
|
|
1668
1842
|
}
|
|
1669
1843
|
console.log(chalk.bold('📁 Generated Files:'));
|
|
1670
|
-
console.log(` - ${
|
|
1671
|
-
console.log(` - ${
|
|
1672
|
-
console.log(` - ${
|
|
1844
|
+
console.log(` - ${envPaths.config}`);
|
|
1845
|
+
console.log(` - ${envPaths.lock}`);
|
|
1846
|
+
console.log(` - ${envPaths.version}`);
|
|
1847
|
+
console.log(` - ${envPaths.keys}/ ${chalk.gray('(private keys - add .authrim/ to .gitignore)')}`);
|
|
1673
1848
|
console.log('');
|
|
1674
1849
|
// Show URLs
|
|
1675
1850
|
console.log(chalk.bold('🌐 Endpoints:'));
|
|
@@ -1747,7 +1922,17 @@ async function handleExistingConfig(configPath) {
|
|
|
1747
1922
|
// =============================================================================
|
|
1748
1923
|
async function handleRedeploy(config, configPath) {
|
|
1749
1924
|
const env = config.environment.prefix;
|
|
1750
|
-
|
|
1925
|
+
// Determine lock file path based on config file structure
|
|
1926
|
+
// New structure: .authrim/{env}/config.json -> .authrim/{env}/lock.json
|
|
1927
|
+
// Legacy structure: authrim-config.json -> authrim-lock.json
|
|
1928
|
+
let lockPath;
|
|
1929
|
+
const isNewStructure = configPath.includes(`${AUTHRIM_DIR}/`) && configPath.endsWith('/config.json');
|
|
1930
|
+
if (isNewStructure) {
|
|
1931
|
+
lockPath = configPath.replace('/config.json', '/lock.json');
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
lockPath = configPath.replace('authrim-config.json', 'authrim-lock.json');
|
|
1935
|
+
}
|
|
1751
1936
|
console.log('');
|
|
1752
1937
|
console.log(chalk.blue('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
1753
1938
|
console.log(chalk.bold('🚀 Redeploy'));
|
|
@@ -1789,7 +1974,7 @@ async function handleRedeploy(config, configPath) {
|
|
|
1789
1974
|
const lock = await loadLockFile(lockPath);
|
|
1790
1975
|
const hasLock = lock !== null;
|
|
1791
1976
|
if (!hasLock) {
|
|
1792
|
-
console.log(chalk.yellow(
|
|
1977
|
+
console.log(chalk.yellow(`\n⚠️ Lock file not found (${lockPath})`));
|
|
1793
1978
|
const createResources = await confirm({
|
|
1794
1979
|
message: 'Create new Cloudflare resources?',
|
|
1795
1980
|
default: true,
|
|
@@ -1815,7 +2000,7 @@ async function handleRedeploy(config, configPath) {
|
|
|
1815
2000
|
// Create and save lock file
|
|
1816
2001
|
const newLock = createLockFile(env, provisionedResources);
|
|
1817
2002
|
await saveLockFile(newLock, lockPath);
|
|
1818
|
-
console.log(chalk.green(`\n✓
|
|
2003
|
+
console.log(chalk.green(`\n✓ Lock file saved (${lockPath})`));
|
|
1819
2004
|
}
|
|
1820
2005
|
catch (error) {
|
|
1821
2006
|
console.log(chalk.red(' ✗ Failed to create resources'));
|