creatium 0.0.4 → 0.0.6

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/README.md CHANGED
@@ -28,7 +28,7 @@ Build your create-bins quickly and easily
28
28
  - [Api documentation](#api-documentation)
29
29
  - [Classes](#classes)
30
30
  - [Creatium](#creatium)
31
- - [CreatiumPrompt\<C\>](#creatiumpromptc)
31
+ - [CreatiumCore\<C\>](#creatiumcorec)
32
32
  - [Type Aliases](#type-aliases)
33
33
  - [CliOpts](#cliopts)
34
34
  - [Config](#config)
@@ -186,22 +186,25 @@ Class of `Creatium` for create project templates (CLI and Library).
186
186
  ##### Example
187
187
 
188
188
  ```ts
189
- // ./main.js
190
- export const core = new CreatiumPrompt({
189
+ //////////////// core.js ///////////////////
190
+
191
+ import { Creatium } from 'creatium'
192
+ export const core = new Creatium({
191
193
  name: 'My Project',
192
194
  version: '1.0.0',
193
- prompts: {
195
+ templates: {
194
196
  ...
195
197
  },
196
- ...
197
198
  })
198
199
 
199
- // ./bin.js
200
- import { core } from './main.js'
200
+ //////////////// bin.js ///////////////////
201
+
202
+ import { core } from './core.js'
201
203
  core.cli()
202
204
 
203
- // ./lib.js
204
- import { core } from './main.js'
205
+ //////////////// lib.js ///////////////////
206
+
207
+ import { core } from './core.js'
205
208
  export const create = core.build
206
209
  ```
207
210
 
@@ -268,7 +271,7 @@ new Creatium(options: {
268
271
  ```ts
269
272
  build(values?: {
270
273
  input: string;
271
- install: PkgManager;
274
+ install: Installer;
272
275
  name: string;
273
276
  openEditor: TextEditor;
274
277
  output: string;
@@ -289,7 +292,7 @@ A simplified version of the `build` method from the main class.
289
292
  | ------ | ------ | ------ |
290
293
  | `values`? | `object` | The values to override the CLI prompts. If not set, the CLI prompts will be executed. |
291
294
  | `values.input`? | `string` | Set the input path or the template key |
292
- | `values.install`? | `PkgManager` | Set the installer |
295
+ | `values.install`? | `Installer` | Set the installer |
293
296
  | `values.name`? | `string` | Set the name of the template |
294
297
  | `values.openEditor`? | `TextEditor` | Open editor |
295
298
  | `values.output`? | `string` | Set the output path |
@@ -382,16 +385,16 @@ await core.cli( { args : process.argv.slice(4), hideBin : false } )
382
385
 
383
386
  ***
384
387
 
385
- #### CreatiumPrompt\<C\>
388
+ #### CreatiumCore\<C\>
386
389
 
387
390
  Customizable class of `Creatium` for create project templates (CLI and Library).
388
391
 
389
392
  ##### Example
390
393
 
391
394
  ```ts
392
- //////////////// main.js ///////////////////
395
+ //////////////// core.js ///////////////////
393
396
 
394
- const core = new CreatiumPrompt({
397
+ export const core = new CreatiumCore({
395
398
  name: 'My Project',
396
399
  version: '1.0.0',
397
400
  prompts: {
@@ -402,14 +405,14 @@ const core = new CreatiumPrompt({
402
405
 
403
406
  //////////////// bin.js ///////////////////
404
407
 
405
- import { core } from './main.js'
408
+ import { core } from './core.js'
406
409
  const res = await core.cli()
407
410
  // do something with res...
408
411
  await core.createTemplate( res )
409
412
 
410
413
  //////////////// lib.js ///////////////////
411
414
 
412
- import { core } from './main.js'
415
+ import { core } from './core.js'
413
416
  export const create = async (args) => {
414
417
  const res = await core.build( args )
415
418
  // do something with res...
@@ -447,10 +450,10 @@ Force debug mode
447
450
 
448
451
  ##### Constructors
449
452
 
450
- ###### new CreatiumPrompt()
453
+ ###### new CreatiumCore()
451
454
 
452
455
  ```ts
453
- new CreatiumPrompt<C>(config: C): CreatiumPrompt<C>
456
+ new CreatiumCore<C>(config: C): CreatiumCore<C>
454
457
  ```
455
458
 
456
459
  ###### Parameters
@@ -461,7 +464,7 @@ new CreatiumPrompt<C>(config: C): CreatiumPrompt<C>
461
464
 
462
465
  ###### Returns
463
466
 
464
- [`CreatiumPrompt`](index.md#creatiumpromptc)\<`C`\>
467
+ [`CreatiumCore`](index.md#creatiumcorec)\<`C`\>
465
468
 
466
469
  ##### Methods
467
470
 
@@ -486,6 +489,16 @@ Initialize the CLI and executes the callback function passed in the config.
486
489
 
487
490
  The result of the callback function.
488
491
 
492
+ ###### cancel()
493
+
494
+ ```ts
495
+ cancel(): Promise<void>
496
+ ```
497
+
498
+ ###### Returns
499
+
500
+ `Promise`\<`void`\>
501
+
489
502
  ###### cli()
490
503
 
491
504
  ```ts
@@ -518,6 +531,23 @@ await core.cli()
518
531
  await core.cli( { args : process.argv.slice( 4), hideBin : false } )
519
532
  ```
520
533
 
534
+ ###### copyDir()
535
+
536
+ ```ts
537
+ copyDir(input: string, output: string): Promise<void>
538
+ ```
539
+
540
+ ###### Parameters
541
+
542
+ | Parameter | Type |
543
+ | ------ | ------ |
544
+ | `input` | `string` |
545
+ | `output` | `string` |
546
+
547
+ ###### Returns
548
+
549
+ `Promise`\<`void`\>
550
+
521
551
  ###### createTemplate()
522
552
 
523
553
  ```ts
@@ -559,6 +589,103 @@ await core.createTemplate( {
559
589
  } )
560
590
  ```
561
591
 
592
+ ###### getTemplateInput()
593
+
594
+ ```ts
595
+ getTemplateInput(input?: string): Promise<undefined | string>
596
+ ```
597
+
598
+ ###### Parameters
599
+
600
+ | Parameter | Type |
601
+ | ------ | ------ |
602
+ | `input`? | `string` |
603
+
604
+ ###### Returns
605
+
606
+ `Promise`\<`undefined` \| `string`\>
607
+
608
+ ###### install()
609
+
610
+ ```ts
611
+ install(installer?: Installer, output?: string): Promise<void>
612
+ ```
613
+
614
+ ###### Parameters
615
+
616
+ | Parameter | Type |
617
+ | ------ | ------ |
618
+ | `installer`? | `Installer` |
619
+ | `output`? | `string` |
620
+
621
+ ###### Returns
622
+
623
+ `Promise`\<`void`\>
624
+
625
+ ###### intro()
626
+
627
+ ```ts
628
+ intro(): Promise<void>
629
+ ```
630
+
631
+ ###### Returns
632
+
633
+ `Promise`\<`void`\>
634
+
635
+ ###### openEditor()
636
+
637
+ ```ts
638
+ openEditor(editor?: TextEditor, output?: string): Promise<void>
639
+ ```
640
+
641
+ ###### Parameters
642
+
643
+ | Parameter | Type |
644
+ | ------ | ------ |
645
+ | `editor`? | `TextEditor` |
646
+ | `output`? | `string` |
647
+
648
+ ###### Returns
649
+
650
+ `Promise`\<`void`\>
651
+
652
+ ###### outro()
653
+
654
+ ```ts
655
+ outro(): Promise<void>
656
+ ```
657
+
658
+ ###### Returns
659
+
660
+ `Promise`\<`void`\>
661
+
662
+ ###### replacePlaceholders()
663
+
664
+ ```ts
665
+ replacePlaceholders(input: string, params: Params): Promise<void>
666
+ ```
667
+
668
+ ###### Parameters
669
+
670
+ | Parameter | Type |
671
+ | ------ | ------ |
672
+ | `input` | `string` |
673
+ | `params` | `Params` |
674
+
675
+ ###### Returns
676
+
677
+ `Promise`\<`void`\>
678
+
679
+ ###### updateNotify()
680
+
681
+ ```ts
682
+ updateNotify(): Promise<void>
683
+ ```
684
+
685
+ ###### Returns
686
+
687
+ `Promise`\<`void`\>
688
+
562
689
  ##### Properties
563
690
 
564
691
  | Property | Type |
@@ -645,7 +772,7 @@ type CreateOpts: CliOpts & {
645
772
  type CreateTemplateOpts: {
646
773
  consts: Record<string, string>;
647
774
  input: string;
648
- install: PkgManager;
775
+ install: Installer;
649
776
  name: string;
650
777
  openEditor: TextEditor;
651
778
  output: string;
@@ -658,7 +785,7 @@ type CreateTemplateOpts: {
658
785
  | ------ | ------ | ------ |
659
786
  | `consts`? | `Record`\<`string`, `string`\> | Add consts to use in your templates. |
660
787
  | `input`? | `string` | Set the input path or the template key |
661
- | `install`? | `PkgManager` | Set the installer |
788
+ | `install`? | `Installer` | Set the installer |
662
789
  | `name`? | `string` | Set the name of the template |
663
790
  | `openEditor`? | `TextEditor` | Open editor |
664
791
  | `output`? | `string` | Set the output path |
package/dist/main.d.mts CHANGED
@@ -819,12 +819,12 @@ declare const INSTALLER: {
819
819
  readonly PNPM: "pnpm";
820
820
  readonly YARN: "yarn";
821
821
  };
822
- type PkgManager = ObjectValues<typeof INSTALLER>;
823
- type OptionInstall = SelectBaseOptions<PkgManager>;
824
- declare class Install extends Select<PkgManager> {
822
+ type Installer = ObjectValues<typeof INSTALLER>;
823
+ type OptionInstall = SelectBaseOptions<Installer>;
824
+ declare class Install extends Select<Installer> {
825
825
  constructor(config: OptionInstall);
826
- validateInitialValue(): Promise<PkgManager | undefined>;
827
- prompt(): Promise<PkgManager>;
826
+ validateInitialValue(): Promise<Installer | undefined>;
827
+ prompt(): Promise<Installer>;
828
828
  }
829
829
 
830
830
  /** Object of the CREATIUM types */
@@ -1044,7 +1044,7 @@ type CreateTemplateOpts = {
1044
1044
  /** Set the name of the template */
1045
1045
  name?: string;
1046
1046
  /** Set the installer */
1047
- install?: PkgManager;
1047
+ install?: Installer;
1048
1048
  /**
1049
1049
  * Open editor
1050
1050
  */
@@ -1137,6 +1137,69 @@ type CreateOpts = CliOpts & {
1137
1137
  activeCli?: boolean;
1138
1138
  };
1139
1139
 
1140
+ type ParamFn = (arg: string) => Promise<string>;
1141
+ type ParamsValue = string | number | Record<string, unknown> | unknown[] | unknown;
1142
+ type Params = Record<string, ParamsValue>;
1143
+ type Props = {
1144
+ /** Content to be replaced */
1145
+ content: string;
1146
+ /**
1147
+ * Parameters
1148
+ * @example
1149
+ * const params = {
1150
+ * name: 'Antonio',
1151
+ * lastName : 'Resines'
1152
+ * }
1153
+ */
1154
+ params: Params;
1155
+ /**
1156
+ * Transform parameters insde placeholders.
1157
+ * @example
1158
+ * const transform = async ( param: string ) => {
1159
+ * if ( param === 'url' ) return 'https://pigeonposse.com',
1160
+ * else if ( param === 'http://pigeonposse.com' ) return 'https://pigeonposse.com'
1161
+ * return param
1162
+ * }
1163
+ */
1164
+ transform?: ParamFn;
1165
+ /** Options */
1166
+ opts?: {
1167
+ /**
1168
+ * Throw an error if a placeholder is not found.
1169
+ * @default false
1170
+ */
1171
+ throw?: boolean;
1172
+ /**
1173
+ * Throw an error if a parameter is not found.
1174
+ * @default
1175
+ * {
1176
+ * prefix : '{{',
1177
+ * suffix : '}}',
1178
+ * }
1179
+ */
1180
+ mark?: {
1181
+ prefix: string;
1182
+ suffix: string;
1183
+ };
1184
+ };
1185
+ };
1186
+ /**
1187
+ * Replace placeholders in a string with their corresponding values.
1188
+ *
1189
+ * The function takes a string with placeholders, an object with parameter values,
1190
+ * and an optional custom parameter function.
1191
+ *
1192
+ * The function returns a Promise that resolves to the string with all placeholders
1193
+ * replaced.
1194
+ * @param {Props} props - Props for the function.
1195
+ * @param {Props['content']} props.content - The string with placeholders.
1196
+ * @param {Props['params']} props.params - An object with parameter values.
1197
+ * @param {Props['transform']} [props.transform] - An optional custom parameter function.
1198
+ * @param {Props['opts']} [props.opts] - Options to customize the behavior of the function.
1199
+ * @returns {Promise<string>} - A Promise that resolves to the string with all placeholders replaced.
1200
+ */
1201
+ declare const replacePlaceholders: (props: Props) => Promise<string>;
1202
+
1140
1203
  type GetPromptValues<C extends Config> = Prettify<{
1141
1204
  [K in keyof C['prompt']]?: Prettify<(C['prompt'][K] extends {
1142
1205
  type: infer T;
@@ -1147,9 +1210,9 @@ type GetPromptValues<C extends Config> = Prettify<{
1147
1210
  * Customizable class of `Creatium` for create project templates (CLI and Library).
1148
1211
  * @template C
1149
1212
  * @example
1150
- * //////////////// main.js ///////////////////
1213
+ * //////////////// core.js ///////////////////
1151
1214
  *
1152
- * const core = new CreatiumPrompt({
1215
+ * export const core = new CreatiumCore({
1153
1216
  * name: 'My Project',
1154
1217
  * version: '1.0.0',
1155
1218
  * prompts: {
@@ -1160,27 +1223,36 @@ type GetPromptValues<C extends Config> = Prettify<{
1160
1223
  *
1161
1224
  * //////////////// bin.js ///////////////////
1162
1225
  *
1163
- * import { core } from './main.js'
1226
+ * import { core } from './core.js'
1164
1227
  * const res = await core.cli()
1165
1228
  * // do something with res...
1166
1229
  * await core.createTemplate( res )
1167
1230
  *
1168
1231
  * //////////////// lib.js ///////////////////
1169
1232
  *
1170
- * import { core } from './main.js'
1233
+ * import { core } from './core.js'
1171
1234
  * export const create = async (args) => {
1172
1235
  * const res = await core.build( args )
1173
1236
  * // do something with res...
1174
1237
  * await core.createTemplate( res )
1175
1238
  * }
1176
1239
  */
1177
- declare class CreatiumPrompt<C extends Config = Config> {
1240
+ declare class CreatiumCore<C extends Config = Config> {
1178
1241
  #private;
1179
1242
  utils: typeof ___shared_utils;
1180
1243
  config: C;
1181
1244
  constructor(config: C);
1182
1245
  /** Force debug mode */
1183
1246
  set debugMode(value: boolean);
1247
+ updateNotify(): Promise<void>;
1248
+ cancel(): Promise<void>;
1249
+ intro(): Promise<void>;
1250
+ outro(): Promise<void>;
1251
+ copyDir(input: string, output: string): Promise<void>;
1252
+ install(installer?: Installer, output?: string): Promise<void>;
1253
+ openEditor(editor?: TextEditor, output?: string): Promise<void>;
1254
+ replacePlaceholders(input: string, params: Parameters<typeof replacePlaceholders>[0]['params']): Promise<void>;
1255
+ getTemplateInput(input?: string): Promise<string | undefined>;
1184
1256
  /**
1185
1257
  * Create a new project template.
1186
1258
  * @param {CreateTemplateOpts} values - The values to create the template.
@@ -1242,22 +1314,25 @@ declare class CreatiumPrompt<C extends Config = Config> {
1242
1314
  /**
1243
1315
  * Class of `Creatium` for create project templates (CLI and Library).
1244
1316
  * @example
1245
- * // ./main.js
1246
- * export const core = new CreatiumPrompt({
1317
+ * //////////////// core.js ///////////////////
1318
+ *
1319
+ * import { Creatium } from 'creatium'
1320
+ * export const core = new Creatium({
1247
1321
  * name: 'My Project',
1248
1322
  * version: '1.0.0',
1249
- * prompts: {
1323
+ * templates: {
1250
1324
  * ...
1251
1325
  * },
1252
- * ...
1253
1326
  * })
1254
1327
  *
1255
- * // ./bin.js
1256
- * import { core } from './main.js'
1328
+ * //////////////// bin.js ///////////////////
1329
+ *
1330
+ * import { core } from './core.js'
1257
1331
  * core.cli()
1258
1332
  *
1259
- * // ./lib.js
1260
- * import { core } from './main.js'
1333
+ * //////////////// lib.js ///////////////////
1334
+ *
1335
+ * import { core } from './core.js'
1261
1336
  * export const create = core.build
1262
1337
  */
1263
1338
  declare class Creatium {
@@ -1339,4 +1414,4 @@ declare class Creatium {
1339
1414
  }>;
1340
1415
  }
1341
1416
 
1342
- export { type CliOpts, type Config, type CreateOpts, type CreateTemplateOpts, Creatium, CreatiumPrompt, IDE, INSTALLER, OPTION, env, prompt, style, sys };
1417
+ export { type CliOpts, type Config, type CreateOpts, type CreateTemplateOpts, Creatium, CreatiumCore, IDE, INSTALLER, OPTION, env, prompt, style, sys };
package/dist/main.d.ts CHANGED
@@ -819,12 +819,12 @@ declare const INSTALLER: {
819
819
  readonly PNPM: "pnpm";
820
820
  readonly YARN: "yarn";
821
821
  };
822
- type PkgManager = ObjectValues<typeof INSTALLER>;
823
- type OptionInstall = SelectBaseOptions<PkgManager>;
824
- declare class Install extends Select<PkgManager> {
822
+ type Installer = ObjectValues<typeof INSTALLER>;
823
+ type OptionInstall = SelectBaseOptions<Installer>;
824
+ declare class Install extends Select<Installer> {
825
825
  constructor(config: OptionInstall);
826
- validateInitialValue(): Promise<PkgManager | undefined>;
827
- prompt(): Promise<PkgManager>;
826
+ validateInitialValue(): Promise<Installer | undefined>;
827
+ prompt(): Promise<Installer>;
828
828
  }
829
829
 
830
830
  /** Object of the CREATIUM types */
@@ -1044,7 +1044,7 @@ type CreateTemplateOpts = {
1044
1044
  /** Set the name of the template */
1045
1045
  name?: string;
1046
1046
  /** Set the installer */
1047
- install?: PkgManager;
1047
+ install?: Installer;
1048
1048
  /**
1049
1049
  * Open editor
1050
1050
  */
@@ -1137,6 +1137,69 @@ type CreateOpts = CliOpts & {
1137
1137
  activeCli?: boolean;
1138
1138
  };
1139
1139
 
1140
+ type ParamFn = (arg: string) => Promise<string>;
1141
+ type ParamsValue = string | number | Record<string, unknown> | unknown[] | unknown;
1142
+ type Params = Record<string, ParamsValue>;
1143
+ type Props = {
1144
+ /** Content to be replaced */
1145
+ content: string;
1146
+ /**
1147
+ * Parameters
1148
+ * @example
1149
+ * const params = {
1150
+ * name: 'Antonio',
1151
+ * lastName : 'Resines'
1152
+ * }
1153
+ */
1154
+ params: Params;
1155
+ /**
1156
+ * Transform parameters insde placeholders.
1157
+ * @example
1158
+ * const transform = async ( param: string ) => {
1159
+ * if ( param === 'url' ) return 'https://pigeonposse.com',
1160
+ * else if ( param === 'http://pigeonposse.com' ) return 'https://pigeonposse.com'
1161
+ * return param
1162
+ * }
1163
+ */
1164
+ transform?: ParamFn;
1165
+ /** Options */
1166
+ opts?: {
1167
+ /**
1168
+ * Throw an error if a placeholder is not found.
1169
+ * @default false
1170
+ */
1171
+ throw?: boolean;
1172
+ /**
1173
+ * Throw an error if a parameter is not found.
1174
+ * @default
1175
+ * {
1176
+ * prefix : '{{',
1177
+ * suffix : '}}',
1178
+ * }
1179
+ */
1180
+ mark?: {
1181
+ prefix: string;
1182
+ suffix: string;
1183
+ };
1184
+ };
1185
+ };
1186
+ /**
1187
+ * Replace placeholders in a string with their corresponding values.
1188
+ *
1189
+ * The function takes a string with placeholders, an object with parameter values,
1190
+ * and an optional custom parameter function.
1191
+ *
1192
+ * The function returns a Promise that resolves to the string with all placeholders
1193
+ * replaced.
1194
+ * @param {Props} props - Props for the function.
1195
+ * @param {Props['content']} props.content - The string with placeholders.
1196
+ * @param {Props['params']} props.params - An object with parameter values.
1197
+ * @param {Props['transform']} [props.transform] - An optional custom parameter function.
1198
+ * @param {Props['opts']} [props.opts] - Options to customize the behavior of the function.
1199
+ * @returns {Promise<string>} - A Promise that resolves to the string with all placeholders replaced.
1200
+ */
1201
+ declare const replacePlaceholders: (props: Props) => Promise<string>;
1202
+
1140
1203
  type GetPromptValues<C extends Config> = Prettify<{
1141
1204
  [K in keyof C['prompt']]?: Prettify<(C['prompt'][K] extends {
1142
1205
  type: infer T;
@@ -1147,9 +1210,9 @@ type GetPromptValues<C extends Config> = Prettify<{
1147
1210
  * Customizable class of `Creatium` for create project templates (CLI and Library).
1148
1211
  * @template C
1149
1212
  * @example
1150
- * //////////////// main.js ///////////////////
1213
+ * //////////////// core.js ///////////////////
1151
1214
  *
1152
- * const core = new CreatiumPrompt({
1215
+ * export const core = new CreatiumCore({
1153
1216
  * name: 'My Project',
1154
1217
  * version: '1.0.0',
1155
1218
  * prompts: {
@@ -1160,27 +1223,36 @@ type GetPromptValues<C extends Config> = Prettify<{
1160
1223
  *
1161
1224
  * //////////////// bin.js ///////////////////
1162
1225
  *
1163
- * import { core } from './main.js'
1226
+ * import { core } from './core.js'
1164
1227
  * const res = await core.cli()
1165
1228
  * // do something with res...
1166
1229
  * await core.createTemplate( res )
1167
1230
  *
1168
1231
  * //////////////// lib.js ///////////////////
1169
1232
  *
1170
- * import { core } from './main.js'
1233
+ * import { core } from './core.js'
1171
1234
  * export const create = async (args) => {
1172
1235
  * const res = await core.build( args )
1173
1236
  * // do something with res...
1174
1237
  * await core.createTemplate( res )
1175
1238
  * }
1176
1239
  */
1177
- declare class CreatiumPrompt<C extends Config = Config> {
1240
+ declare class CreatiumCore<C extends Config = Config> {
1178
1241
  #private;
1179
1242
  utils: typeof ___shared_utils;
1180
1243
  config: C;
1181
1244
  constructor(config: C);
1182
1245
  /** Force debug mode */
1183
1246
  set debugMode(value: boolean);
1247
+ updateNotify(): Promise<void>;
1248
+ cancel(): Promise<void>;
1249
+ intro(): Promise<void>;
1250
+ outro(): Promise<void>;
1251
+ copyDir(input: string, output: string): Promise<void>;
1252
+ install(installer?: Installer, output?: string): Promise<void>;
1253
+ openEditor(editor?: TextEditor, output?: string): Promise<void>;
1254
+ replacePlaceholders(input: string, params: Parameters<typeof replacePlaceholders>[0]['params']): Promise<void>;
1255
+ getTemplateInput(input?: string): Promise<string | undefined>;
1184
1256
  /**
1185
1257
  * Create a new project template.
1186
1258
  * @param {CreateTemplateOpts} values - The values to create the template.
@@ -1242,22 +1314,25 @@ declare class CreatiumPrompt<C extends Config = Config> {
1242
1314
  /**
1243
1315
  * Class of `Creatium` for create project templates (CLI and Library).
1244
1316
  * @example
1245
- * // ./main.js
1246
- * export const core = new CreatiumPrompt({
1317
+ * //////////////// core.js ///////////////////
1318
+ *
1319
+ * import { Creatium } from 'creatium'
1320
+ * export const core = new Creatium({
1247
1321
  * name: 'My Project',
1248
1322
  * version: '1.0.0',
1249
- * prompts: {
1323
+ * templates: {
1250
1324
  * ...
1251
1325
  * },
1252
- * ...
1253
1326
  * })
1254
1327
  *
1255
- * // ./bin.js
1256
- * import { core } from './main.js'
1328
+ * //////////////// bin.js ///////////////////
1329
+ *
1330
+ * import { core } from './core.js'
1257
1331
  * core.cli()
1258
1332
  *
1259
- * // ./lib.js
1260
- * import { core } from './main.js'
1333
+ * //////////////// lib.js ///////////////////
1334
+ *
1335
+ * import { core } from './core.js'
1261
1336
  * export const create = core.build
1262
1337
  */
1263
1338
  declare class Creatium {
@@ -1339,4 +1414,4 @@ declare class Creatium {
1339
1414
  }>;
1340
1415
  }
1341
1416
 
1342
- export { type CliOpts, type Config, type CreateOpts, type CreateTemplateOpts, Creatium, CreatiumPrompt, IDE, INSTALLER, OPTION, env, prompt, style, sys };
1417
+ export { type CliOpts, type Config, type CreateOpts, type CreateTemplateOpts, Creatium, CreatiumCore, IDE, INSTALLER, OPTION, env, prompt, style, sys };
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { deepmerge, deepmergeCustom } from 'deepmerge-ts';
1
+ import { deepmergeCustom, deepmerge } from 'deepmerge-ts';
2
2
  import process$1 from 'node:process';
3
3
  import { spawn } from 'node:child_process';
4
4
  import yargs from 'yargs';
@@ -18,20 +18,6 @@ import { resolve, relative, extname, dirname, basename, isAbsolute, normalize, j
18
18
  import { fileURLToPath } from 'node:url';
19
19
  import Conf from 'conf';
20
20
 
21
- const SELECT_BASE_OPTS = { NONE: "none" };
22
- const mergeSelectBaseOptions = (config, defaultOptions) => {
23
- const options = deepmerge(defaultOptions || {}, config.options || {});
24
- const filteredOptions = config.onlyOptions && config.onlyOptions.length > 1 ? Object.entries(options).reduce((acc, [key, value]) => {
25
- if (key === SELECT_BASE_OPTS.NONE || config.onlyOptions.includes(key))
26
- acc[key] = value;
27
- return acc;
28
- }, {}) : options;
29
- return {
30
- ...config,
31
- options: Object.keys(filteredOptions).length > 1 ? filteredOptions : options
32
- };
33
- };
34
-
35
21
  const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
36
22
  const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
37
23
  const isWebWorker = typeof self === "object" && self.constructor && self.constructor.name === "DedicatedWorkerGlobalScope";
@@ -254,6 +240,57 @@ const corePromptLine = {
254
240
  ...printOptions
255
241
  };
256
242
 
243
+ const replacePlaceholders = async (props) => {
244
+ const { content, params, transform, opts } = props;
245
+ const { prefix, suffix } = opts?.mark || {
246
+ prefix: "{{",
247
+ suffix: "}}"
248
+ };
249
+ const escapeRegExp = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
250
+ const regex = new RegExp(
251
+ `${escapeRegExp(prefix)}\\s*([^}]+?)\\s*${escapeRegExp(suffix)}`,
252
+ "g"
253
+ );
254
+ const getValue = (obj, path) => {
255
+ const parts = path.split(".");
256
+ let result2 = obj;
257
+ for (const part of parts) {
258
+ if (result2 === void 0)
259
+ return void 0;
260
+ if (part.includes("[") && part.includes("]")) {
261
+ const [arrayName, indexStr] = part.split("[");
262
+ const index = parseInt(indexStr.replace("]", ""), 10);
263
+ result2 = result2[arrayName]?.[index];
264
+ } else {
265
+ result2 = result2[part];
266
+ }
267
+ }
268
+ return result2;
269
+ };
270
+ const replaceAsync = async (match, key) => {
271
+ if (transform) {
272
+ const transformed = await transform(key);
273
+ if (transformed !== key)
274
+ return transformed;
275
+ }
276
+ const value = getValue(params, key);
277
+ if (value === void 0) {
278
+ if (opts?.throw)
279
+ throw new Error(`Placeholder ${key} not found`);
280
+ return match;
281
+ }
282
+ return String(value);
283
+ };
284
+ let result = content;
285
+ const matches = [...content.matchAll(regex)];
286
+ for (const match of matches) {
287
+ const [fullMatch, key] = match;
288
+ const replacement = await replaceAsync(fullMatch, key);
289
+ result = result.replace(fullMatch, replacement);
290
+ }
291
+ return result;
292
+ };
293
+
257
294
  const resolvePath = resolve;
258
295
  const relativePath = relative;
259
296
  const getExtName = extname;
@@ -615,6 +652,20 @@ const _sys = {
615
652
  writeFileContent: writeFileContent
616
653
  };
617
654
 
655
+ const SELECT_BASE_OPTS = { NONE: "none" };
656
+ const mergeSelectBaseOptions = (config, defaultOptions) => {
657
+ const options = deepmerge(defaultOptions || {}, config.options || {});
658
+ const filteredOptions = config.onlyOptions && config.onlyOptions.length > 1 ? Object.entries(options).reduce((acc, [key, value]) => {
659
+ if (key === SELECT_BASE_OPTS.NONE || config.onlyOptions.includes(key))
660
+ acc[key] = value;
661
+ return acc;
662
+ }, {}) : options;
663
+ return {
664
+ ...config,
665
+ options: Object.keys(filteredOptions).length > 1 ? filteredOptions : options
666
+ };
667
+ };
668
+
618
669
  const sys = _sys;
619
670
  const prompt = corePromptLine;
620
671
  const env = env$1;
@@ -842,57 +893,6 @@ const OPTION = {
842
893
  path: "path"
843
894
  };
844
895
 
845
- const replacePlaceholders = async (props) => {
846
- const { content, params, transform, opts } = props;
847
- const { prefix, suffix } = opts?.mark || {
848
- prefix: "{{",
849
- suffix: "}}"
850
- };
851
- const escapeRegExp = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
852
- const regex = new RegExp(
853
- `${escapeRegExp(prefix)}\\s*([^}]+?)\\s*${escapeRegExp(suffix)}`,
854
- "g"
855
- );
856
- const getValue = (obj, path) => {
857
- const parts = path.split(".");
858
- let result2 = obj;
859
- for (const part of parts) {
860
- if (result2 === void 0)
861
- return void 0;
862
- if (part.includes("[") && part.includes("]")) {
863
- const [arrayName, indexStr] = part.split("[");
864
- const index = parseInt(indexStr.replace("]", ""), 10);
865
- result2 = result2[arrayName]?.[index];
866
- } else {
867
- result2 = result2[part];
868
- }
869
- }
870
- return result2;
871
- };
872
- const replaceAsync = async (match, key) => {
873
- if (transform) {
874
- const transformed = await transform(key);
875
- if (transformed !== key)
876
- return transformed;
877
- }
878
- const value = getValue(params, key);
879
- if (value === void 0) {
880
- if (opts?.throw)
881
- throw new Error(`Placeholder ${key} not found`);
882
- return match;
883
- }
884
- return String(value);
885
- };
886
- let result = content;
887
- const matches = [...content.matchAll(regex)];
888
- for (const match of matches) {
889
- const [fullMatch, key] = match;
890
- const replacement = await replaceAsync(fullMatch, key);
891
- result = result.replace(fullMatch, replacement);
892
- }
893
- return result;
894
- };
895
-
896
896
  var __accessCheck$4 = (obj, member, msg) => {
897
897
  if (!member.has(obj))
898
898
  throw TypeError("Cannot " + msg);
@@ -1420,7 +1420,7 @@ getCache_fn = async function() {
1420
1420
  return;
1421
1421
  return await cache({
1422
1422
  projectName: this.projectName,
1423
- id: "prompts",
1423
+ id: "create-prompts",
1424
1424
  values: resetObjectValues(this.config)
1425
1425
  });
1426
1426
  };
@@ -1471,10 +1471,9 @@ var __privateMethod = (obj, member, method) => {
1471
1471
  __accessCheck$1(obj, member, "access private method");
1472
1472
  return method;
1473
1473
  };
1474
- var _core$1, _data, _updateNotify, updateNotify_fn, _exec, exec_fn, _getCliArgs, getCliArgs_fn, _initCli, initCli_fn, _createTemplate, createTemplate_fn;
1475
- class CreatiumPrompt {
1474
+ var _core$1, _data, _style, _exec, exec_fn, _getCliArgs, getCliArgs_fn, _initCli, initCli_fn, _createTemplate, createTemplate_fn;
1475
+ class CreatiumCore {
1476
1476
  constructor(config) {
1477
- __privateAdd$1(this, _updateNotify);
1478
1477
  __privateAdd$1(this, _exec);
1479
1478
  __privateAdd$1(this, _getCliArgs);
1480
1479
  __privateAdd$1(this, _initCli);
@@ -1483,17 +1482,132 @@ class CreatiumPrompt {
1483
1482
  __privateAdd$1(this, _data, void 0);
1484
1483
  __publicField$1(this, "utils");
1485
1484
  __publicField$1(this, "config");
1485
+ __privateAdd$1(this, _style, void 0);
1486
1486
  __privateSet$1(this, _core$1, new Core(config.prompt));
1487
1487
  this.config = config;
1488
1488
  this.utils = __privateGet$1(this, _core$1).utils;
1489
1489
  __privateGet$1(this, _core$1).cache = this.config.cache === void 0 ? true : this.config.cache;
1490
1490
  __privateGet$1(this, _core$1).projectName = this.config.name;
1491
1491
  this.debugMode = false;
1492
+ __privateSet$1(this, _style, { tick: this.utils.style.color.green.dim("\u2713") });
1492
1493
  }
1493
1494
  /** Force debug mode */
1494
1495
  set debugMode(value) {
1495
1496
  __privateGet$1(this, _core$1).debugMode = value;
1496
1497
  }
1498
+ async updateNotify() {
1499
+ const { default: up } = await import('update-notifier');
1500
+ const updater = up({ pkg: {
1501
+ name: this.config.name,
1502
+ version: this.config.version
1503
+ } });
1504
+ updater.notify();
1505
+ }
1506
+ async cancel() {
1507
+ if (this.config.onCancel && __privateGet$1(this, _data))
1508
+ await this.config.onCancel(__privateGet$1(this, _data));
1509
+ else if (this.config.onCancel === void 0) {
1510
+ this.utils.prompt.log.step("");
1511
+ this.utils.prompt.cancel("Canceled \u{1F494}");
1512
+ process$1.exit(0);
1513
+ }
1514
+ }
1515
+ async intro() {
1516
+ if (typeof this.config.intro === "function")
1517
+ await this.config.intro(__privateGet$1(this, _data) || {});
1518
+ else if (this.config.intro === void 0) {
1519
+ console.log();
1520
+ this.utils.prompt.intro(this.utils.style.color.cyan.inverse(` ${this.config.name} `));
1521
+ this.utils.prompt.log.step("");
1522
+ }
1523
+ }
1524
+ async outro() {
1525
+ if (typeof this.config.outro === "function" && __privateGet$1(this, _data))
1526
+ await this.config.outro(__privateGet$1(this, _data));
1527
+ else if (this.config.outro === void 0)
1528
+ this.utils.prompt.outro("Succesfully finished \u{1F308}");
1529
+ }
1530
+ async copyDir(input, output) {
1531
+ return await copyDir({
1532
+ input,
1533
+ output
1534
+ });
1535
+ }
1536
+ async install(installer, output) {
1537
+ if (!installer || installer === "none")
1538
+ return;
1539
+ const s = this.utils.prompt.spinner();
1540
+ const command = {
1541
+ [INSTALLER.PNPM]: !output ? "pnpm i" : `pnpm i --dir ${output}`,
1542
+ [INSTALLER.NPM]: !output ? "npm install" : `npm install --prefix ${output}`,
1543
+ [INSTALLER.YARN]: !output ? "yarn install" : `yarn install --cwd ${output}`,
1544
+ [INSTALLER.DENO]: !output ? "deno install" : `deno install --root ${output}`,
1545
+ [INSTALLER.BUN]: !output ? "bun install" : `bun install --cwd ${output}`
1546
+ };
1547
+ try {
1548
+ s.start(`Installing with ${installer}`);
1549
+ await execChild(command[installer]);
1550
+ s.stop(__privateGet$1(this, _style).tick + " Package installed successfully");
1551
+ } catch (_e) {
1552
+ if (this.debugMode)
1553
+ s.stop(`Error in installation with [${installer}]: ${_e?.toString()}`);
1554
+ else
1555
+ s.stop(`Error in installation with [${installer}]`);
1556
+ }
1557
+ }
1558
+ async openEditor(editor, output) {
1559
+ if (!editor || editor === "none")
1560
+ return;
1561
+ const s = this.utils.prompt.spinner();
1562
+ try {
1563
+ s.start(`Opening in ${editor}`);
1564
+ await execChild(`${editor} ${output}`);
1565
+ s.stop(__privateGet$1(this, _style).tick + " IDE opened successfully");
1566
+ } catch (_e) {
1567
+ if (this.debugMode)
1568
+ s.stop(`Error opening in [${editor}]: ${_e?.toString()}`);
1569
+ else
1570
+ s.stop("Error opening IDE");
1571
+ }
1572
+ }
1573
+ async replacePlaceholders(input, params) {
1574
+ if (!input || !params)
1575
+ throw new Error('Missing parameters "output" and "params" for replace placeholders');
1576
+ const getContent = async (filePath) => {
1577
+ try {
1578
+ const content = await readFile(filePath, "utf-8");
1579
+ return typeof content === "string" && content.trim().length > 0 ? content : void 0;
1580
+ } catch (_e) {
1581
+ return void 0;
1582
+ }
1583
+ };
1584
+ const paths = await getPaths([input], { onlyFiles: true });
1585
+ console.debug({ templatePaths: paths });
1586
+ for (const path of paths) {
1587
+ const content = await getContent(path);
1588
+ if (!content)
1589
+ continue;
1590
+ const res = await replacePlaceholders({
1591
+ content,
1592
+ params
1593
+ });
1594
+ await writeFile(path, res, "utf-8");
1595
+ }
1596
+ }
1597
+ async getTemplateInput(input) {
1598
+ const templates = Object.entries(this.config.prompt).reduce((acc, [_key, value]) => {
1599
+ if (value.type === OPTION.template && value.options)
1600
+ Object.assign(acc, value.options);
1601
+ return acc;
1602
+ }, {});
1603
+ console.debug({ templates });
1604
+ if (input && templates[input].input)
1605
+ return templates[input].input;
1606
+ if (input && await existsDir(input))
1607
+ return input;
1608
+ this.utils.prompt.log.error(`Error creating Template: template input "${input}" not found`);
1609
+ return;
1610
+ }
1497
1611
  /**
1498
1612
  * Create a new project template.
1499
1613
  * @param {CreateTemplateOpts} values - The values to create the template.
@@ -1555,38 +1669,16 @@ ${error}
1555
1669
  }
1556
1670
  _core$1 = new WeakMap();
1557
1671
  _data = new WeakMap();
1558
- _updateNotify = new WeakSet();
1559
- updateNotify_fn = async function() {
1560
- const { default: up } = await import('update-notifier');
1561
- const updater = up({ pkg: {
1562
- name: this.config.name,
1563
- version: this.config.version
1564
- } });
1565
- updater.notify();
1566
- };
1672
+ _style = new WeakMap();
1567
1673
  _exec = new WeakSet();
1568
1674
  exec_fn = async function(values) {
1569
1675
  __privateSet$1(this, _data, { values });
1570
1676
  console.debug({ data: __privateGet$1(this, _data) });
1571
- __privateGet$1(this, _core$1).onCancel = async () => {
1572
- if (this.config.onCancel && __privateGet$1(this, _data))
1573
- await this.config.onCancel(__privateGet$1(this, _data));
1574
- else if (this.config.onCancel === void 0) {
1575
- this.utils.prompt.log.step("");
1576
- this.utils.prompt.cancel("Canceled \u{1F494}");
1577
- process$1.exit(0);
1578
- }
1579
- };
1677
+ __privateGet$1(this, _core$1).onCancel = async () => await this.cancel();
1580
1678
  if (this.config.hooks?.beforePrompt)
1581
1679
  await this.config.hooks.beforePrompt(__privateGet$1(this, _data));
1582
1680
  console.debug({ beforePrompt: __privateGet$1(this, _data) });
1583
- if (typeof this.config.intro === "function")
1584
- await this.config.intro(__privateGet$1(this, _data));
1585
- else if (this.config.intro === void 0) {
1586
- console.log();
1587
- this.utils.prompt.intro(this.utils.style.color.cyan.inverse(` ${this.config.name} `));
1588
- this.utils.prompt.log.step("");
1589
- }
1681
+ await this.intro();
1590
1682
  const prompts = await __privateGet$1(this, _core$1).getPrompts();
1591
1683
  const answers = await this.utils.prompt.group(prompts, { onCancel: __privateGet$1(this, _core$1).onCancel });
1592
1684
  __privateGet$1(this, _data).values = answers;
@@ -1603,7 +1695,7 @@ getCliArgs_fn = function(props) {
1603
1695
  _initCli = new WeakSet();
1604
1696
  initCli_fn = async function(props) {
1605
1697
  if (this.config.updater)
1606
- await __privateMethod(this, _updateNotify, updateNotify_fn).call(this);
1698
+ await this.updateNotify();
1607
1699
  const args = __privateMethod(this, _getCliArgs, getCliArgs_fn).call(this, props);
1608
1700
  const instance = await createCli({
1609
1701
  args,
@@ -1638,109 +1730,29 @@ createTemplate_fn = async function(values) {
1638
1730
  openEditor,
1639
1731
  input,
1640
1732
  output,
1641
- install
1733
+ install,
1734
+ consts,
1735
+ ...prompt
1642
1736
  } = values;
1643
- const templates = Object.entries(this.config.prompt).reduce((acc, [_key, value]) => {
1644
- if (value.type === OPTION.template && value.options)
1645
- Object.assign(acc, value.options);
1646
- return acc;
1647
- }, {});
1648
- const getTemplate = async () => {
1649
- if (input && templates[input].input)
1650
- return templates[input].input;
1651
- if (input && await existsDir(input))
1652
- return input;
1653
- this.utils.prompt.log.error(`Error creating Template: template input "${input}" not found`);
1654
- return;
1655
- };
1656
1737
  const data = {
1657
- input: await getTemplate(),
1738
+ input: await this.getTemplateInput(input),
1658
1739
  output: output ? resolvePath(output) : void 0
1659
1740
  };
1660
- console.debug({
1661
- templates,
1662
- templateData: data
1663
- });
1664
- const open = async () => {
1665
- if (!openEditor || openEditor === "none")
1666
- return;
1667
- const s = this.utils.prompt.spinner();
1668
- try {
1669
- s.start(`Opening in ${openEditor}`);
1670
- await execChild(`${openEditor} ${output}`);
1671
- s.stop(tick + " IDE opened successfully");
1672
- } catch (_e) {
1673
- if (this.debugMode)
1674
- s.stop(`Error opening in [${openEditor}]: ${_e?.toString()}`);
1675
- else
1676
- s.stop("Error opening IDE");
1677
- }
1678
- };
1679
- const tick = this.utils.style.color.green.dim("\u2713");
1680
- const installation = async () => {
1681
- if (!install || install === "none")
1682
- return;
1683
- const s = this.utils.prompt.spinner();
1684
- const command = {
1685
- [INSTALLER.PNPM]: `pnpm i --dir ${output}`,
1686
- [INSTALLER.NPM]: `npm install --prefix ${output}`,
1687
- [INSTALLER.YARN]: `yarn install --cwd ${output}`,
1688
- [INSTALLER.DENO]: `deno install --root ${output}`,
1689
- [INSTALLER.BUN]: `bun install --cwd ${output}`
1690
- };
1691
- try {
1692
- s.start(`Installing with ${install}`);
1693
- await execChild(command[install]);
1694
- s.stop(tick + " Package installed successfully");
1695
- } catch (_e) {
1696
- if (this.debugMode)
1697
- s.stop(`Error in installation with [${install}]: ${_e?.toString()}`);
1698
- else
1699
- s.stop(`Error in installation with [${install}]`);
1700
- }
1701
- };
1702
- const getContent = async (filePath) => {
1703
- try {
1704
- const content = await readFile(filePath, "utf-8");
1705
- return typeof content === "string" && content.trim().length > 0 ? content : void 0;
1706
- } catch (_e) {
1707
- return void 0;
1708
- }
1709
- };
1741
+ console.debug({ templateData: data });
1710
1742
  this.utils.prompt.log.step("");
1711
1743
  if (!(data.input && data.output))
1712
1744
  throw new Error("Invalid input or output template");
1713
- await copyDir(data);
1714
- const paths = await getPaths([data.output], { onlyFiles: true });
1715
- console.debug({ templatePaths: paths });
1716
- for (const path of paths) {
1717
- const content = await getContent(path);
1718
- if (!content)
1719
- continue;
1720
- const {
1721
- consts,
1722
- ...prompt
1723
- } = values;
1724
- if (!prompt.name)
1725
- prompt.name = getBaseName(data.output);
1726
- const res = await replacePlaceholders({
1727
- content,
1728
- params: {
1729
- name: this.config.name,
1730
- version: this.config.version,
1731
- consts,
1732
- prompt
1733
- }
1734
- });
1735
- await writeFile(path, res, "utf-8");
1736
- }
1737
- await installation();
1738
- await open();
1745
+ await this.copyDir(data.input, data.output);
1746
+ await this.replacePlaceholders(data.output, {
1747
+ name: this.config.name,
1748
+ version: this.config.version,
1749
+ consts,
1750
+ prompt
1751
+ });
1752
+ await this.install(install, data.output);
1753
+ await this.openEditor(openEditor, data.output);
1739
1754
  this.utils.prompt.log.step("");
1740
- if (typeof this.config.outro === "function" && __privateGet$1(this, _data))
1741
- await this.config.outro(__privateGet$1(this, _data));
1742
- else if (this.config.outro === void 0)
1743
- this.utils.prompt.outro("Succesfully finished \u{1F308}");
1755
+ await this.outro();
1744
1756
  };
1745
1757
 
1746
1758
  var __defProp = Object.defineProperty;
@@ -1799,7 +1811,7 @@ class Creatium {
1799
1811
  } } : {}
1800
1812
  }
1801
1813
  };
1802
- __privateSet(this, _core, new CreatiumPrompt(this.config));
1814
+ __privateSet(this, _core, new CreatiumCore(this.config));
1803
1815
  }
1804
1816
  /**
1805
1817
  * A simplified version of the `build` method from the main class.
@@ -1844,4 +1856,4 @@ class Creatium {
1844
1856
  }
1845
1857
  _core = new WeakMap();
1846
1858
 
1847
- export { Creatium, CreatiumPrompt, IDE, INSTALLER, OPTION, env, prompt, style, sys };
1859
+ export { Creatium, CreatiumCore, IDE, INSTALLER, OPTION, env, prompt, style, sys };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creatium",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Build your create-bins quickly and easily",
5
5
  "bugs": {
6
6
  "url": "https://github.com/pigeonposse/creatium/issues",
@@ -47,7 +47,7 @@
47
47
  "@types/columnify": "1.5.4",
48
48
  "@types/update-notifier": "6.0.8",
49
49
  "@types/yargs": "17.0.33",
50
- "@creatium/repo-config": "0.0.4"
50
+ "@creatium/repo-config": "0.0.6"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public",