@intrig/core 0.0.15-15 → 0.0.15-16
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/main.js +191 -38
- package/package.json +2 -1
package/main.js
CHANGED
|
@@ -901,6 +901,10 @@ class SpecManagementService {
|
|
|
901
901
|
external_fs_namespaceObject.mkdirSync(this.specsDir, {
|
|
902
902
|
recursive: true
|
|
903
903
|
});
|
|
904
|
+
// Create the file if it doesn't exist (proper-lockfile requires the file to exist)
|
|
905
|
+
if (!external_fs_namespaceObject.existsSync(filePath)) {
|
|
906
|
+
external_fs_namespaceObject.writeFileSync(filePath, '', 'utf-8');
|
|
907
|
+
}
|
|
904
908
|
// Acquire lock for the file
|
|
905
909
|
release = await external_proper_lockfile_namespaceObject.lock(filePath, {
|
|
906
910
|
retries: {
|
|
@@ -984,6 +988,10 @@ class SpecManagementService {
|
|
|
984
988
|
if (external_fs_namespaceObject.existsSync(specPath)) {
|
|
985
989
|
try {
|
|
986
990
|
const content = external_fs_namespaceObject.readFileSync(specPath, 'utf-8');
|
|
991
|
+
// Handle empty files (created for locking purposes)
|
|
992
|
+
if (!content || content.trim() === '') {
|
|
993
|
+
return undefined;
|
|
994
|
+
}
|
|
987
995
|
return JSON.parse(content);
|
|
988
996
|
} catch (error) {
|
|
989
997
|
this.logger.error(`Failed to parse JSON for ${apiName}: ${error.message}`);
|
|
@@ -5296,6 +5304,9 @@ class SourcesAddCommand extends external_nest_commander_namespaceObject.CommandR
|
|
|
5296
5304
|
constructor(pm, httpService, lazyPluginService, configService){
|
|
5297
5305
|
super(), this.pm = pm, this.httpService = httpService, this.lazyPluginService = lazyPluginService, this.configService = configService;
|
|
5298
5306
|
}
|
|
5307
|
+
parseIdOption(val) {
|
|
5308
|
+
return val;
|
|
5309
|
+
}
|
|
5299
5310
|
async run(passedParams, options) {
|
|
5300
5311
|
const metadata = await this.pm.getMetadata();
|
|
5301
5312
|
if (!metadata) {
|
|
@@ -5327,15 +5338,27 @@ class SourcesAddCommand extends external_nest_commander_namespaceObject.CommandR
|
|
|
5327
5338
|
console.log(external_chalk_default().bold.cyan('\nSource details:'));
|
|
5328
5339
|
console.log(`${external_chalk_default().green('Name:')} ${external_chalk_default().white(source.name ?? 'N/A')}`);
|
|
5329
5340
|
console.log(`${external_chalk_default().green('Spec:')} ${external_chalk_default().white(source.specUrl ?? 'N/A')}`);
|
|
5330
|
-
// 6)
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5341
|
+
// 6) Get ID from option or prompt
|
|
5342
|
+
let id;
|
|
5343
|
+
if (options?.id) {
|
|
5344
|
+
// Validate the provided ID
|
|
5345
|
+
if (!/^[\w-]+$/.test(options.id)) {
|
|
5346
|
+
console.error(external_chalk_default().red.bold('Error:'), external_chalk_default().red('ID must contain only letters, numbers, hyphens, or underscores'));
|
|
5347
|
+
process.exit(1);
|
|
5337
5348
|
}
|
|
5338
|
-
|
|
5349
|
+
id = options.id;
|
|
5350
|
+
console.log(external_chalk_default().blue(`ℹ️ Using provided ID: ${id}`));
|
|
5351
|
+
} else {
|
|
5352
|
+
const { id: promptedId } = await external_inquirer_default().prompt([
|
|
5353
|
+
{
|
|
5354
|
+
type: 'input',
|
|
5355
|
+
name: 'id',
|
|
5356
|
+
message: external_chalk_default().yellow('Enter an ID for this source (letters/numbers/-/_):'),
|
|
5357
|
+
validate: (v)=>/^[\w-]+$/.test(v) || 'ID must contain only letters, numbers, hyphens, or underscores'
|
|
5358
|
+
}
|
|
5359
|
+
]);
|
|
5360
|
+
id = promptedId;
|
|
5361
|
+
}
|
|
5339
5362
|
source.id = id;
|
|
5340
5363
|
// 7) Add endpoint
|
|
5341
5364
|
const addUrl = `${metadata.url}/api/config/sources/add`;
|
|
@@ -5368,6 +5391,17 @@ class SourcesAddCommand extends external_nest_commander_namespaceObject.CommandR
|
|
|
5368
5391
|
}
|
|
5369
5392
|
}
|
|
5370
5393
|
}
|
|
5394
|
+
sources_command_ts_decorate([
|
|
5395
|
+
(0,external_nest_commander_namespaceObject.Option)({
|
|
5396
|
+
flags: '--id <id>',
|
|
5397
|
+
description: 'Specify source ID directly (letters/numbers/-/_)'
|
|
5398
|
+
}),
|
|
5399
|
+
sources_command_ts_metadata("design:type", Function),
|
|
5400
|
+
sources_command_ts_metadata("design:paramtypes", [
|
|
5401
|
+
String
|
|
5402
|
+
]),
|
|
5403
|
+
sources_command_ts_metadata("design:returntype", String)
|
|
5404
|
+
], SourcesAddCommand.prototype, "parseIdOption", null);
|
|
5371
5405
|
SourcesAddCommand = sources_command_ts_decorate([
|
|
5372
5406
|
(0,external_nest_commander_namespaceObject.SubCommand)({
|
|
5373
5407
|
name: 'add',
|
|
@@ -5426,6 +5460,12 @@ class SourceRemoveCommand extends external_nest_commander_namespaceObject.Comman
|
|
|
5426
5460
|
constructor(pm, httpService, lazyPluginService, configService){
|
|
5427
5461
|
super(), this.pm = pm, this.httpService = httpService, this.lazyPluginService = lazyPluginService, this.configService = configService;
|
|
5428
5462
|
}
|
|
5463
|
+
parseIdOption(val) {
|
|
5464
|
+
return val;
|
|
5465
|
+
}
|
|
5466
|
+
parseYesOption() {
|
|
5467
|
+
return true;
|
|
5468
|
+
}
|
|
5429
5469
|
async run(passedParams, options) {
|
|
5430
5470
|
// 1) fetch metadata
|
|
5431
5471
|
const metadata = await this.pm.getMetadata();
|
|
@@ -5444,33 +5484,54 @@ class SourceRemoveCommand extends external_nest_commander_namespaceObject.Comman
|
|
|
5444
5484
|
console.log(external_chalk_default().yellow('No sources found.'));
|
|
5445
5485
|
return;
|
|
5446
5486
|
}
|
|
5447
|
-
// 3)
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5487
|
+
// 3) Get source ID from option or prompt
|
|
5488
|
+
let id;
|
|
5489
|
+
if (options?.id) {
|
|
5490
|
+
// Validate the ID exists in sources
|
|
5491
|
+
const sourceExists = sources.some((src)=>src.id === options.id);
|
|
5492
|
+
if (!sourceExists) {
|
|
5493
|
+
console.error(external_chalk_default().red.bold('Error:'), external_chalk_default().red(`Source with ID "${options.id}" not found.`));
|
|
5494
|
+
console.log(external_chalk_default().yellow('Available sources:'));
|
|
5495
|
+
sources.forEach((src)=>{
|
|
5496
|
+
console.log(` - ${src.id}`);
|
|
5497
|
+
});
|
|
5498
|
+
process.exit(1);
|
|
5458
5499
|
}
|
|
5459
|
-
|
|
5500
|
+
id = options.id;
|
|
5501
|
+
console.log(external_chalk_default().blue(`ℹ️ Using provided ID: ${id}`));
|
|
5502
|
+
} else {
|
|
5503
|
+
const choices = sources.map((src)=>({
|
|
5504
|
+
name: `${src.id} — ${src.name ?? 'N/A'} (${src.specUrl})`,
|
|
5505
|
+
value: src.id
|
|
5506
|
+
}));
|
|
5507
|
+
const { id: promptedId } = await external_inquirer_default().prompt([
|
|
5508
|
+
{
|
|
5509
|
+
type: 'list',
|
|
5510
|
+
name: 'id',
|
|
5511
|
+
message: external_chalk_default().yellow('Select a source to remove:'),
|
|
5512
|
+
choices
|
|
5513
|
+
}
|
|
5514
|
+
]);
|
|
5515
|
+
id = promptedId;
|
|
5516
|
+
}
|
|
5460
5517
|
// Store the source details before deletion for lifecycle method
|
|
5461
5518
|
const selectedSource = sources.find((src)=>src.id === id);
|
|
5462
|
-
// 4)
|
|
5463
|
-
|
|
5464
|
-
{
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5519
|
+
// 4) Confirm deletion (skip if --yes flag is set)
|
|
5520
|
+
if (!options?.yes) {
|
|
5521
|
+
const { confirm } = await external_inquirer_default().prompt([
|
|
5522
|
+
{
|
|
5523
|
+
type: 'confirm',
|
|
5524
|
+
name: 'confirm',
|
|
5525
|
+
message: external_chalk_default().red(`Are you sure you want to delete "${id}"?`),
|
|
5526
|
+
default: false
|
|
5527
|
+
}
|
|
5528
|
+
]);
|
|
5529
|
+
if (!confirm) {
|
|
5530
|
+
console.log(external_chalk_default().gray('Aborted.'));
|
|
5531
|
+
return;
|
|
5469
5532
|
}
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
console.log(external_chalk_default().gray('Aborted.'));
|
|
5473
|
-
return;
|
|
5533
|
+
} else {
|
|
5534
|
+
console.log(external_chalk_default().blue(`ℹ️ Skipping confirmation (--yes flag set)`));
|
|
5474
5535
|
}
|
|
5475
5536
|
// 5) call DELETE /remove/:id
|
|
5476
5537
|
const removeUrl = `${metadata.url}/api/config/sources/remove/${encodeURIComponent(id)}`;
|
|
@@ -5497,6 +5558,26 @@ class SourceRemoveCommand extends external_nest_commander_namespaceObject.Comman
|
|
|
5497
5558
|
}
|
|
5498
5559
|
}
|
|
5499
5560
|
}
|
|
5561
|
+
sources_command_ts_decorate([
|
|
5562
|
+
(0,external_nest_commander_namespaceObject.Option)({
|
|
5563
|
+
flags: '--id <id>',
|
|
5564
|
+
description: 'Specify source ID to remove directly'
|
|
5565
|
+
}),
|
|
5566
|
+
sources_command_ts_metadata("design:type", Function),
|
|
5567
|
+
sources_command_ts_metadata("design:paramtypes", [
|
|
5568
|
+
String
|
|
5569
|
+
]),
|
|
5570
|
+
sources_command_ts_metadata("design:returntype", String)
|
|
5571
|
+
], SourceRemoveCommand.prototype, "parseIdOption", null);
|
|
5572
|
+
sources_command_ts_decorate([
|
|
5573
|
+
(0,external_nest_commander_namespaceObject.Option)({
|
|
5574
|
+
flags: '-y, --yes',
|
|
5575
|
+
description: 'Skip confirmation prompt'
|
|
5576
|
+
}),
|
|
5577
|
+
sources_command_ts_metadata("design:type", Function),
|
|
5578
|
+
sources_command_ts_metadata("design:paramtypes", []),
|
|
5579
|
+
sources_command_ts_metadata("design:returntype", Boolean)
|
|
5580
|
+
], SourceRemoveCommand.prototype, "parseYesOption", null);
|
|
5500
5581
|
SourceRemoveCommand = sources_command_ts_decorate([
|
|
5501
5582
|
(0,external_nest_commander_namespaceObject.SubCommand)({
|
|
5502
5583
|
name: 'rm',
|
|
@@ -8118,6 +8199,9 @@ function init_command_ts_decorate(decorators, target, key, desc) {
|
|
|
8118
8199
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
8119
8200
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8120
8201
|
}
|
|
8202
|
+
function init_command_ts_metadata(k, v) {
|
|
8203
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
8204
|
+
}
|
|
8121
8205
|
|
|
8122
8206
|
|
|
8123
8207
|
|
|
@@ -8129,6 +8213,12 @@ function init_command_ts_decorate(decorators, target, key, desc) {
|
|
|
8129
8213
|
|
|
8130
8214
|
|
|
8131
8215
|
class InitCommand extends external_nest_commander_namespaceObject.CommandRunner {
|
|
8216
|
+
parsePluginOption(val) {
|
|
8217
|
+
return val;
|
|
8218
|
+
}
|
|
8219
|
+
parseYesOption() {
|
|
8220
|
+
return true;
|
|
8221
|
+
}
|
|
8132
8222
|
async run(passedParams, options) {
|
|
8133
8223
|
console.log(external_chalk_default().blue('🚀 Initializing Intrig setup...'));
|
|
8134
8224
|
const rootDir = process.cwd();
|
|
@@ -8143,17 +8233,49 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8143
8233
|
// Check for existing plugin dependency matching the plugin regex format
|
|
8144
8234
|
const existingPlugin = this.checkForExistingPlugin(packageJson);
|
|
8145
8235
|
let selectedPlugin;
|
|
8146
|
-
|
|
8236
|
+
// Priority: 1. CLI --plugin option, 2. Existing plugin in package.json, 3. Interactive prompt (or best match with --yes)
|
|
8237
|
+
if (options?.plugin) {
|
|
8238
|
+
console.log(external_chalk_default().blue(`ℹ️ Using plugin from CLI option: ${options.plugin}`));
|
|
8239
|
+
selectedPlugin = {
|
|
8240
|
+
type: 'generator',
|
|
8241
|
+
generator: 'custom',
|
|
8242
|
+
name: options.plugin,
|
|
8243
|
+
compat: {
|
|
8244
|
+
latest: {
|
|
8245
|
+
dependencies: {}
|
|
8246
|
+
}
|
|
8247
|
+
}
|
|
8248
|
+
};
|
|
8249
|
+
} else if (existingPlugin) {
|
|
8147
8250
|
console.log(external_chalk_default().green(`✅ Found existing plugin dependency: ${existingPlugin.name}`));
|
|
8148
8251
|
selectedPlugin = existingPlugin;
|
|
8149
8252
|
} else {
|
|
8150
8253
|
// Fetch approved plugins from GitHub
|
|
8151
8254
|
const approvedPlugins = await this.fetchApprovedPlugins();
|
|
8152
|
-
//
|
|
8153
|
-
|
|
8255
|
+
// If --yes flag is set, use the best matching plugin automatically
|
|
8256
|
+
if (options?.yes) {
|
|
8257
|
+
const projectDependencies = {
|
|
8258
|
+
...packageJson.dependencies,
|
|
8259
|
+
...packageJson.devDependencies
|
|
8260
|
+
};
|
|
8261
|
+
const pluginsWithScores = approvedPlugins.map((plugin)=>({
|
|
8262
|
+
plugin,
|
|
8263
|
+
score: this.calculateCompatibilityScore(plugin, projectDependencies)
|
|
8264
|
+
})).sort((a, b)=>b.score - a.score);
|
|
8265
|
+
const bestMatch = pluginsWithScores[0]?.plugin;
|
|
8266
|
+
if (bestMatch) {
|
|
8267
|
+
console.log(external_chalk_default().blue(`ℹ️ Auto-selecting best matching plugin: ${bestMatch.name} (score: ${pluginsWithScores[0].score})`));
|
|
8268
|
+
selectedPlugin = bestMatch;
|
|
8269
|
+
} else {
|
|
8270
|
+
throw new Error('No plugins available and --yes flag was set. Please specify a plugin with --plugin option.');
|
|
8271
|
+
}
|
|
8272
|
+
} else {
|
|
8273
|
+
// Prompt user to select plugin (show all plugins with best match as default)
|
|
8274
|
+
selectedPlugin = await this.promptUserForPlugin(approvedPlugins, packageJson);
|
|
8275
|
+
}
|
|
8154
8276
|
}
|
|
8155
8277
|
// Load and initialize the selected plugin
|
|
8156
|
-
const { pluginInstance, generatorOptions, postInitFunction } = await this.loadAndInitializePlugin(selectedPlugin);
|
|
8278
|
+
const { pluginInstance, generatorOptions, postInitFunction } = await this.loadAndInitializePlugin(selectedPlugin, options?.yes);
|
|
8157
8279
|
// Check if plugin loading failed
|
|
8158
8280
|
if (!pluginInstance) {
|
|
8159
8281
|
throw new Error(`Failed to load and initialize plugin ${selectedPlugin.name}. Please check the plugin installation and try again.`);
|
|
@@ -8352,7 +8474,7 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8352
8474
|
}
|
|
8353
8475
|
return selectedPlugin;
|
|
8354
8476
|
}
|
|
8355
|
-
async loadAndInitializePlugin(plugin) {
|
|
8477
|
+
async loadAndInitializePlugin(plugin, skipPrompts) {
|
|
8356
8478
|
const installSpinner = external_ora_default()(`Installing plugin: ${plugin.name}`).start();
|
|
8357
8479
|
try {
|
|
8358
8480
|
const rootDir = process.cwd();
|
|
@@ -8397,7 +8519,7 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8397
8519
|
loadSpinner.text = 'Collecting generator configuration...';
|
|
8398
8520
|
// Stop the spinner before collecting interactive input to prevent interference
|
|
8399
8521
|
loadSpinner.stop();
|
|
8400
|
-
generatorOptions = await this.collectGeneratorOptions(pluginInstance.$generatorSchema, plugin.name);
|
|
8522
|
+
generatorOptions = await this.collectGeneratorOptions(pluginInstance.$generatorSchema, plugin.name, skipPrompts);
|
|
8401
8523
|
console.log("Generator options", generatorOptions);
|
|
8402
8524
|
// Restart the spinner if we have more work to do
|
|
8403
8525
|
loadSpinner.start();
|
|
@@ -8460,7 +8582,7 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8460
8582
|
throw new Error(`Plugin "${pluginName}" does not export a factory function. ` + `Expected "createPlugin()" or a default function export. ` + `Available exports: ${Object.keys(mod || {}).join(', ')}`);
|
|
8461
8583
|
}
|
|
8462
8584
|
}
|
|
8463
|
-
async collectGeneratorOptions(generatorSchema, pluginName) {
|
|
8585
|
+
async collectGeneratorOptions(generatorSchema, pluginName, skipPrompts) {
|
|
8464
8586
|
const options = {};
|
|
8465
8587
|
if (!generatorSchema.properties) {
|
|
8466
8588
|
return options;
|
|
@@ -8468,6 +8590,17 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8468
8590
|
// Use schinquirer to generate questions from schema
|
|
8469
8591
|
if (generatorSchema.properties && Object.keys(generatorSchema.properties).length > 0) {
|
|
8470
8592
|
try {
|
|
8593
|
+
// If --yes flag is set, use defaults from schema
|
|
8594
|
+
if (skipPrompts) {
|
|
8595
|
+
console.log(external_chalk_default().blue(`ℹ️ Using default generator options (--yes flag set)`));
|
|
8596
|
+
for (const [key, prop] of Object.entries(generatorSchema.properties)){
|
|
8597
|
+
if (prop.default !== undefined) {
|
|
8598
|
+
options[key] = prop.default;
|
|
8599
|
+
}
|
|
8600
|
+
}
|
|
8601
|
+
console.log(external_chalk_default().blue(`ℹ️ You can configure generator options later in intrig.config.json`));
|
|
8602
|
+
return options;
|
|
8603
|
+
}
|
|
8471
8604
|
// Check if we're in a non-interactive environment
|
|
8472
8605
|
if (!process.stdin.isTTY) {
|
|
8473
8606
|
console.log(external_chalk_default().yellow(`⚠️ Non-interactive environment detected. Skipping generator configuration for plugin ${pluginName}.`));
|
|
@@ -8535,6 +8668,26 @@ class InitCommand extends external_nest_commander_namespaceObject.CommandRunner
|
|
|
8535
8668
|
}
|
|
8536
8669
|
}
|
|
8537
8670
|
}
|
|
8671
|
+
init_command_ts_decorate([
|
|
8672
|
+
(0,external_nest_commander_namespaceObject.Option)({
|
|
8673
|
+
flags: '-p, --plugin <plugin>',
|
|
8674
|
+
description: 'Specify plugin name directly (e.g., @intrig/plugin-react)'
|
|
8675
|
+
}),
|
|
8676
|
+
init_command_ts_metadata("design:type", Function),
|
|
8677
|
+
init_command_ts_metadata("design:paramtypes", [
|
|
8678
|
+
String
|
|
8679
|
+
]),
|
|
8680
|
+
init_command_ts_metadata("design:returntype", String)
|
|
8681
|
+
], InitCommand.prototype, "parsePluginOption", null);
|
|
8682
|
+
init_command_ts_decorate([
|
|
8683
|
+
(0,external_nest_commander_namespaceObject.Option)({
|
|
8684
|
+
flags: '-y, --yes',
|
|
8685
|
+
description: 'Accept defaults and skip interactive prompts'
|
|
8686
|
+
}),
|
|
8687
|
+
init_command_ts_metadata("design:type", Function),
|
|
8688
|
+
init_command_ts_metadata("design:paramtypes", []),
|
|
8689
|
+
init_command_ts_metadata("design:returntype", Boolean)
|
|
8690
|
+
], InitCommand.prototype, "parseYesOption", null);
|
|
8538
8691
|
InitCommand = init_command_ts_decorate([
|
|
8539
8692
|
(0,external_nest_commander_namespaceObject.Command)({
|
|
8540
8693
|
name: 'init',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intrig/core",
|
|
3
|
-
"version": "0.0.15-
|
|
3
|
+
"version": "0.0.15-16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@apidevtools/json-schema-ref-parser": "12.0.2",
|
|
14
|
+
"@intrig/plugin-sdk": "^0.0.15-16",
|
|
14
15
|
"@nestjs/axios": "4.0.1",
|
|
15
16
|
"@nestjs/common": "10.4.20",
|
|
16
17
|
"@nestjs/config": "4.0.2",
|