copyAppTemplate method

Future<void> copyAppTemplate()

Copy the main app template to the output directory

Implementation

Future<void> copyAppTemplate() async {
  // arcaneJasprFlutterEmbed is a dual-package template: it ships a Jaspr
  // host (_web) AND a Flutter web guest (_app) under one parent dir.
  // Route the copy through the dedicated helper so each sub-package
  // lands in its own scaffolded directory.
  if (config.template == TemplateType.arcaneJasprFlutterEmbed) {
    await _copyJasprFlutterEmbedTemplate();
    return;
  }

  final Directory templateDir = Directory(
    getTemplatePath(config.template.directoryName),
  );

  // For Jaspr templates, use webPackageName; for others, use appName
  final String targetName = config.template.isJasprApp
      ? config.webPackageName
      : config.appName;
  final Directory targetDir = Directory(p.join(config.outputDir, targetName));

  if (!templateDir.existsSync()) {
    throw Exception('Template not found: ${templateDir.path}');
  }

  info('Copying ${config.template.displayName} template...');

  // Copy template files
  await _copyDirectory(templateDir, targetDir);

  // Process placeholders
  await _replacer.processDirectory(targetDir);

  // Update pubspec with correct package name
  final File pubspecFile = File(p.join(targetDir.path, 'pubspec.yaml'));
  await _replacer.updatePubspec(pubspecFile, targetName);

  // Add models dependency if needed
  if (config.createModels) {
    await _replacer.addModelsDependency(pubspecFile);

    // Pure-Dart targets (Jaspr, Dart CLI) cannot resolve `arcane_models`
    // out of the box because `artifact -> json_compress -> jpatch` pulls in
    // the Flutter SDK via jpatch's pubspec. Vendor a pure-Dart jpatch shim
    // and inject a `dependency_overrides` so the project resolves cleanly.
    if (!config.template.isFlutterApp) {
      await _vendorJpatchOverride(pubspecFile);
    }

    // Jaspr targets (web app + docs) bring in `jaspr_builder` (analyzer
    // ^10.0.0). The published `artifact_gen` and `fire_crud_gen` packages
    // pin `analyzer ^8.0.0`, which makes `pub get` impossible to resolve
    // when both are present. Vendor pure-shim drop-ins for the gen
    // packages so build_runner can satisfy `auto_apply: dependents` in the
    // upstream `artifact` and `fire_crud` `build.yaml` files without
    // dragging analyzer 8 into the resolution. The actual model
    // generation still happens in the dedicated models package (which
    // does NOT depend on jaspr_builder), so the web app only consumes
    // the already-generated `.g.dart` files.
    if (config.template.isJasprApp) {
      await _vendorJasprBuilderShims(pubspecFile);
    }
  }

  if (config.template.isJasprDocs) {
    await _prepareJasprDocsDependencies();
  }

  // Patch jaspr.yaml mode for Jaspr templates so the user's selected
  // render mode (CSR / SSG / SSR / Hybrid) lands in the generated
  // project. Without this, every project would inherit the template's
  // default mode (client) regardless of what the user picked.
  if (config.template.isJasprApp) {
    await _patchJasprYamlMode(targetDir);
  }

  // Emit IntelliJ run configurations (Serve / Build / Killall) for
  // every Jaspr web target so a fresh `oracular` scaffold drops the
  // user straight into a clickable dev loop in IntelliJ /
  // Android Studio. No-op for Flutter/Dart-CLI templates — they have
  // their own (Flutter-native) run configs created by `flutter
  // create`.
  if (config.template.isJasprApp) {
    await TemplateRunConfigWriter.generateJasprPackage(
      packageDir: targetDir.path,
    );
  }

  success('App template copied to: ${targetDir.path}');
}