#!/usr/bin/env tsx
//The line above calls the TSX typescript executer as runtime, which extends node.js and supports running typescript
// see: https://www.npmjs.com/package/tsx
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// import babelRegister from '@babel/register';
// babelRegister({extensions: ['.ts', '.tsx']});
import { addCapacitor, buildAll, buildApp, buildPackage, buildUpdated, checkImports, compilePackage, createApp, createComponent, createOntology, createPackage, createSetComponent, createShape, depCheck, depCheckStaged, developPackage, executeCommandForEachPackage, executeCommandForPackage, getLincdPackages, getScriptDir, publishPackage, publishUpdated, register, runMethod, runScript, startServer, upgradePackages, } from './cli-methods.js';
// import {buildMetadata} from './metadata';
import { program } from 'commander';
import fs from 'fs-extra';
import path from 'path';
import 'require-extensions';
program
    .command('create-app')
    .action((name, options) => {
    return createApp(name, process.cwd(), {
        appName: options.appName,
        appPrefix: options.appPrefix,
        appDomain: options.appDomain,
        skipInstall: options.skipInstall,
    });
})
    .description('Creates a new folder with all the required files for a Linked app')
    .argument('<name>', 'the name of your Linked app. To use spaces, wrap the name in double quotes.')
    .option('--app-name <name>', 'Display name for the app (skip interactive prompt)')
    .option('--app-prefix <prefix>', 'Short code prefix for data files (skip interactive prompt)')
    .option('--app-domain <domain>', 'Domain for the app (skip interactive prompt)')
    .option('--skip-install', 'Skip running yarn/npm install after scaffolding');
program
    .command('start')
    .action(() => {
    return startServer();
})
    .option('--env', 'The node environment to use. Default is "development"')
    .description('Start the Linked node.js server. Use --initOnly to start the backend without http server');
program
    .command('call')
    .action((packageName, method, options) => {
    return runMethod(packageName, method, { spawn: options.spawn });
})
    .option('--spawn', 'Start a new server instance instead of using an existing one')
    .option('--env', 'The node environment to use. Default is "development"')
    .description('Start the Linked node.js server but without http server. Instead it immediately calls the specified method of the specified package and exits afterwards')
    .argument('<package>', 'the package of the backend provider that contains this method')
    .argument('<method>', 'the name of the method you want to call');
program
    .command('script')
    .action((scriptName, options) => {
    return runScript(scriptName, { spawn: options.spawn });
})
    .option('--spawn', 'Start a new server instance instead of using an existing one')
    .option('--env', 'The node environment to use. Default is "development"')
    .description('Start the Linked node.js server but without http server. Instead it immediately runs the specified script and exits afterwards')
    .argument('<scriptName>', 'the name of the script file inside the /scripts folder');
program
    .command('create-package')
    .action((name, uriBase) => {
    return createPackage(name, uriBase);
})
    .description('Create a new folder with all the required files for a new Linked package')
    .argument('<name>', 'The name of the package. Will be used as package name in package.json')
    .argument('[uri_base]', 'The base URL used for data of this package. Leave blank to use the URL of your package on lincd.org after you register it');
program
    .command('upgrade-packages')
    .action(() => {
    return upgradePackages();
})
    .description('Upgrade all linked packages in the workspace to ESM/CJS dual packages');
program
    .command('create-shape')
    .action((name, uriBase) => {
    return createShape(name);
})
    .description('Creates a new ShapeClass file for your package. Execute this from your package folder.')
    .argument('<name>', 'The name of the shape. Will be used for the file name and the class name');
program
    .command('create-component')
    .action((name, uriBase) => {
    return createComponent(name);
})
    .description('Creates a new Component file for your package. Execute this from your package folder.')
    .argument('<name>', 'The name of the component. Will be used for the file name and the export name');
program
    .command('create-set-component')
    .action((name, uriBase) => {
    return createSetComponent(name);
})
    .description('Creates a new SetComponent file for your package. Execute this from your package folder.')
    .argument('<name>', 'The name of the component. Will be used for the file name and the export name');
program
    .command('create-ontology')
    .action((prefix, uriBase) => {
    return createOntology(prefix, uriBase);
})
    .description('Creates a new ontology file for your package. Execute this from your package folder.')
    .argument('<suggested-prefix>', 'The suggested prefix for your ontology. Also the shorthand code used for the file name and the exported ontology object')
    .argument('[uribase]', "Optional argument to set the URI base for the URI's of all entities in your ontology. Leave blank to use the URI's provided by lincd.org once you register this package");
program.command('app [action]', { hidden: true }).action(() => {
    register('http://localhost:4101');
});
program.command('register-local', { hidden: true }).action(() => {
    register('http://localhost:4101');
});
program.command('register-dev', { hidden: true }).action(() => {
    register('https://dev-registry.lincd.org');
});
program
    .command('register')
    .action(() => {
    register('https://registry.lincd.org');
})
    .description('Register (a new version of) this package to the Linked registry. If successful your package will appear on linked.cm');
program
    .command('info')
    .action(() => {
    let localDir = getScriptDir();
    let packageJsonPath = path.join(localDir, 'package.json');
    try {
        var ownPackage = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
    }
    catch (e) {
        console.warn('Could not read package.json at ' + packageJsonPath + ': ' + e);
        process.exit();
    }
    console.log(ownPackage.version);
    console.log('Running from: ' + localDir);
})
    .description("Log the version of this tool and the path that it's running from");
program
    .command('build [target] [target2]', { isDefault: true })
    .action((target, target2, options) => {
    buildPackage(target, target2, process.cwd(), !(options === null || options === void 0 ? void 0 : options.silent));
})
    .option('--silent', 'No output to console unless errors occur');
program
    .command('compile-only')
    .action(() => {
    compilePackage();
})
    .description('Compile the package without other build steps. Run this command from the package folder');
program.command('build-metadata').action(() => {
    console.log('Needs to be reimplemented');
    // buildMetadata();
});
program
    .command('build-app')
    .action(() => {
    buildApp();
})
    .option('--env', 'The node environment to use. Default is "development"')
    .description('Start the Linked node.js server. Use --initOnly to start the backend without http server');
program.command('publish-updated').action(() => {
    return publishUpdated();
});
program.command('publish [version]').action((version) => {
    publishPackage(null, false, null, version);
});
program.command('status').action(() => {
    //log which packages need to be published
    return publishUpdated(true).then(() => {
        //log which packages need to be build
        return buildUpdated(undefined, '', '', true);
    });
});
program
    .command('build-updated [target] [target2]')
    .action((target, target2, options) => {
    const { useGit } = options;
    return buildUpdated(1, target, target2, useGit || false);
})
    .option('--use-git', 'Use git commit timestamps to check which packages have been updated since the last build');
program
    .command('build-updated-since [num-commits-back] [target] [target2]')
    .action((back, target, target2) => {
    return buildUpdated(back, target, target2);
});
program
    .command('build-all')
    .action((options) => {
    buildAll(options);
})
    .option('--sync', 'build each package 1 by 1 - use this if you have build issues due to low available RAM memory')
    .option('--from <char>', 'start from a specific package');
program
    .command('build-workspace')
    .description('Build all linked packages in the current workspace in dependency order')
    .option('-u, --updated', 'Only build updated packages')
    .option('--use-git', 'Use git commit timestamps to determine which packages need updating')
    .action((options) => __awaiter(void 0, void 0, void 0, function* () {
    if (options.updated) {
        return buildUpdated(1, undefined, undefined, !!options.useGit);
    }
    return buildAll(options);
}));
program
    .command('build-package <filepath>')
    .description('Given a file path, find its package.json and rebuild that package. Use for editor save hooks.')
    .action((filepath) => __awaiter(void 0, void 0, void 0, function* () {
    const { buildPackageByPath } = yield import('./commands/build-package.js');
    return buildPackageByPath(filepath);
}));
program
    .command('yarn')
    .description("Run yarn at the workspace root while preserving nested repositories' yarn.lock files. Forwards all extra args to yarn.")
    .allowUnknownOption(true)
    .action(() => __awaiter(void 0, void 0, void 0, function* () {
    const yarnArgs = program.args.slice(1); // drop 'yarn' itself
    const { safeYarn } = yield import('./commands/safe-yarn.js');
    return safeYarn(yarnArgs);
}));
program
    .command('setup-publish')
    .description('Set up a changesets publish workflow in the current package repo. Writes GitHub Actions workflows, changesets config, .gitignore entries, and patches package.json.')
    .option('--configure-github', 'Also configure GitHub branch protection on main (requires gh CLI installed and authenticated).')
    .option('--dual-branch', 'Use dual-branch (main + dev) flow with @next prereleases on dev. Default is single-branch (main only).')
    .option('--scope <scope>', 'Which NPM secret to reference in the publish workflow: "core" uses NPM_AUTH_TOKEN, "community" uses NPM_AUTH_TOKEN_CM. Defaults to "core".', 'core')
    .option('--grant-team <slug>', 'GitHub team slug to grant push access on the repo. Requires gh CLI.')
    .action((options) => __awaiter(void 0, void 0, void 0, function* () {
    const { setupPublish } = yield import('./commands/setup-publish.js');
    yield setupPublish({
        configureGithub: !!options.configureGithub,
        dualBranch: !!options.dualBranch,
        scope: options.scope === 'community' ? 'community' : 'core',
        grantTeam: options.grantTeam,
    });
}));
program
    .command('all [action] [filter] [filter-value]')
    .action((command, filter, filterValue) => {
    executeCommandForEachPackage(getLincdPackages(), command, filter, filterValue);
});
// program.command('all-except [excludedSpaces] [action]').action((excludedSpaces, command) => {
//   executeCommandForEachModule(getLincdModules(), command, null, excludedSpaces);
// });
program.command('dev [target] [mode]').action((target, mode) => {
    developPackage(target, mode);
});
program.command('depcheck').action((target, mode) => {
    depCheck();
});
program.command('depcheck-staged').action((target, mode) => {
    depCheckStaged();
});
program.command('check-imports').action((target, mode) => {
    checkImports();
});
program
    .command('package')
    .action((name, command, args) => {
    let fullCommand = command
        ? command +
            ' ' +
            args
                .slice(0, 3)
                .filter((a) => a && true)
                .join(' ')
        : null;
    //TODO: call
    // let pkgName = process.argv[1];
    // console.log(pkgName);
    // let restArgs = process.argv.slice(2)
    // program.parse([],{from:'user'});
    // program.parse(['--port', '80'], { from: 'user' })
    executeCommandForPackage(name, fullCommand);
})
    .alias('p')
    .alias('pkg')
    .alias('m')
    .alias('module')
    .description('Searches for a package in this workspace with a partially matching name and executes a command for that package (without needing to execute it from the folder of the package)')
    .argument('<name>', 'the name of the package. Can be a part of the name.')
    .argument('[command]', 'the lincd command you want to execute. Like dev or build')
    .argument('[args...]', 'the additional arguments of that command');
program.command('enable-capacitor').action(() => {
    addCapacitor();
});
program.parse(process.argv);
//# sourceMappingURL=cli.js.map