173 Commits

Author SHA1 Message Date
github-actions[bot]
70886c28f0 chore(main): release 1.3.2 (#143)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-31 09:25:13 -05:00
Duro
53ca446a38 fix: make tsconfig work with comments/trailing commas (#142) 2024-07-31 18:24:04 +05:30
github-actions[bot]
dac05ab7ce chore(main): release 1.3.1 (#141)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-27 11:09:00 -05:00
Jacob Nguyen
2bb169f600 chore: release 1.3.1
Release-As: 1.3.1
2024-07-27 11:06:37 -05:00
Jacob Nguyen
89302d62c4 oops 2024-07-27 11:04:26 -05:00
github-actions[bot]
a63192ab10 chore(main): release 1.3.0 (#140)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-27 10:55:38 -05:00
Jacob Nguyen
20364fa20d feat: plugin, no prompt, bug fixes (#139)
* high hopes

* s

* plugin calling

* add

* eol

* more progress

* fmt

* step 1

* refactor out

* /internal route

* prg

* write handler

* consolidate

* fix version gen

* prototype

* out

* fix merge

* bundle presence and event modules

* extrapolate into plugin

* pluginify and simplify

* fix up typing gen for process env and watch mode

* watch

* add nonpromptable plugins install

* fix regression and clean up publish script

* ea
2024-07-27 10:45:53 -05:00
Duro
d581142f08 fix: fix publish command for bun & pnpm (#137)
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2024-06-03 11:34:58 -05:00
Jacob Nguyen
fe2e8ff0c0 fix config fn defai;lt 2024-05-27 11:34:28 -05:00
Jacob Nguyen
41046ebd37 fix config fn unresolved name 2024-05-26 14:03:32 -05:00
renovate[bot]
fc5e974f9b chore(deps): update actions/setup-node digest to 1a4442c (#124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-24 23:05:00 -05:00
Jacob Nguyen
5fbb15f385 remove plugin 2024-04-11 18:29:49 -05:00
Jacob Nguyen
c90003e411 remove deprecated application id option for publish 2024-04-11 18:27:34 -05:00
Jacob Nguyen
d94d5de520 user install works (#135)
user install work?
2024-04-11 10:14:52 -05:00
Jacob Nguyen
44e5dd3845 the readme was kinda vague (#133) 2024-03-19 12:41:41 -05:00
github-actions[bot]
9f9a2aaca7 chore(main): release 1.2.1 (#132)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-07 22:09:32 -06:00
Jacob Nguyen
d1832e44ce fix: better error messages for publish 2024-02-07 22:04:05 -06:00
Jacob Nguyen
e55ceedadd refactor: error json inspecter 2024-02-07 21:49:09 -06:00
github-actions[bot]
6bb212a3be chore(main): release 1.2.0 (#131)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-29 00:38:02 -06:00
Jacob Nguyen
2d6e65a1e6 feat: make application id optional, thanks @trueharuu (#130)
make application id optional, thanks @trueharuu
2024-01-29 09:56:24 +05:30
github-actions[bot]
eb53ecb638 chore(main): release 1.1.0 (#129)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-27 23:50:17 -06:00
Jacob Nguyen
303ac0280c feat: command clear (#128) 2024-01-28 10:59:37 +05:30
github-actions[bot]
3f994d6948 chore(main): release 1.0.3 (#127)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-12-25 19:26:01 -06:00
Jacob Nguyen
a5cb66828e fix: intellisense for esm build ts (#126)
* fix: broken link and refactor
2023-12-25 11:47:46 -06:00
github-actions[bot]
667d0c1b89 chore(main): release 1.0.2 (#125)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-11-04 16:20:29 -05:00
Jacob Nguyen
5dbf2a87dc fix: better error handling 2023-11-04 16:14:00 -05:00
a309c085e9 chore: build docs rephrasing (#118)
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2023-10-18 13:39:58 -05:00
f1d7d6c911 fix: build mkdir errors (#122)
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2023-10-18 13:27:58 -05:00
Jacob Nguyen
4ec96dbe17 Update continuous-integration.yml 2023-10-18 13:18:29 -05:00
Peter-MJ-Parker
3970cc6911 chore: fix grammar in error message (#123) 2023-10-13 22:53:19 +05:30
github-actions[bot]
9045e1a03f chore(main): release 1.0.1 (#120)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-05 12:21:23 +05:30
Jacob Nguyen
d9ca5ff3ff fix: multiple bugs (#119) 2023-10-05 12:18:08 +05:30
github-actions[bot]
5a68916479 chore(main): release 1.0.0 (#116)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-06 10:56:59 +05:30
EvolutionX
e8c4764a9e style: pretty pretty 2023-09-05 09:02:18 +05:30
Jacob Nguyen
c785d49fa5 feat(plugins)!: new method to obtain plugins (#114)
BREAKING CHANGE: older versions of cli does not have plugins command functional
2023-09-05 08:58:08 +05:30
40829267c4 fix(extra): dockerfile errors and tsc fallback (#101) 2023-09-01 22:05:21 +05:30
renovate[bot]
1fc69b0a6e chore(deps): lock file maintenance (#104)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 10:05:31 +05:30
renovate[bot]
d01e4cb2f1 chore(deps): update all non-major dependencies (#107)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 09:59:07 +05:30
Evo
5fd2a7b4c4 feat: list subcommand (#113)
* chore: progress

* chore: blaming regex.

permalink: http://whatthecommit.com/7eaa73b94ca6e8f964d99b6f2db6e9e4

* chore:

permalink:

* chore: lol

* chore: accidental commit

permalink: http://whatthecommit.com/7c6c9323d8c243d10cd93c8bbbc55d09

* fix syntx

* fix list not showing up

* prety

* chore: refresh lockfile

* chore: progress

* fix list not showing up

* refactor: cleanup some mess

* Update preprocessor.ts

---------

Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2023-08-31 15:07:16 -05:00
EvolutionX
42bd528756 chore: for the statistics only
permalink: http://whatthecommit.com/f6cb5f952917639c9e28f94ae495bd59
2023-08-31 10:47:45 +05:30
EvolutionX
c218065a04 chore: refresh lockfile 2023-08-31 10:45:34 +05:30
Jacob Nguyen
2ece63cb8b fix preprocessor.ts dependencies intellisense 2023-08-28 10:57:19 -05:00
Jacob Nguyen
88e2bbf6c8 feat: build app (#112)
* chore: start publish work

* chore: more debug... who overwrote!

permalink: http://whatthecommit.com/2e6bbd4fd1a21e16039ce52216c3c0b4

* update node version requirement (#106)

* update node version requirement

* publish progress

* progress on publish

* style: pretty pretty

* chore: some progress i guess?

* more progress on publish command

* chore: remove magicast

* more progress on command data

* fix: adding extra fields to json output

* fix: stringify again

* rest field cli

* style: run prettier

* chore: friday 5pm

permalink: http://whatthecommit.com/502256b954264d50f29967e1fef8394b

* prettier and more progress on publish

* progress on publishing

* config can be function and publishing seems to be working correctly

* fix, made mistakes

* fix guild command publishing

* fix guild ids not publishing correctly

* edit correctly

* upgrade fire readiers

* refactor and separate some stuff

* ^

* add default_member_permissions

* refator

* refactors

* publish functionality done

* seems like attachment loading works correctly

* extrapolate

* code splitting and faster startup

* fix up bugs

* forgot to merge prompts/plugin

* remove unneeded esbuild plugin for simple define

* build auto generate typings

* fix: template dir after switching commands to dynamic imports

* update preprocessor

* fix: add experimental warning to publish and build

* fix vulnerability

* oops, false alarm

* better sern.build.js config support

* chore: remove pnpm lock

* cleaner build and also some cli options

* fix regression

* add more cli options

* optimize

* no any

---------

Co-authored-by: EvolutionX <evolutionx9777@gmail.com>
2023-08-28 09:46:29 -05:00
EvolutionX
913ff4dc15 docs(readme): update some outdated info 2023-08-17 13:20:06 +05:30
EvolutionX
30179d1ea9 docs(readme): update to latest help 2023-08-17 13:18:35 +05:30
Jacob Nguyen
3f74658b16 fix: credentials precedence (#111)
Co-authored-by: Evo <85353424+EvolutionX-10@users.noreply.github.com>
2023-08-10 18:23:18 +00:00
EvolutionX
0a3fedd1d8 chore: git stash changelog.md license.md readme.md dist node_modules package-lock.json package.json renovate.json src templates tsconfig.json tsup.config.ts
permalink: http://whatthecommit.com/7ad7c71289d30791e2f20c54465142aa
2023-08-10 11:14:55 +05:30
github-actions[bot]
f12d541dfe chore(main): release 0.6.0 (#110)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-09 23:00:36 +05:30
EvolutionX
642bf11608 chore: release 0.6.0
Release-As: 0.6.0
2023-08-09 22:14:55 +05:30
Evo
827ffb7ad9 feat: publish command (#105)
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
Co-authored-by: jacob <jacoobes@sern.dev>
2023-08-09 22:06:50 +05:30
Gary
2348e3e9ab fix: change file path for sern/extras (#109)
Co-authored-by: gary <gary@mini-hoster.thetechgurus.xyz>
2023-08-06 20:37:35 +05:30
Jacob Nguyen
14df4a9b65 chore: Update package.json 2023-06-29 22:57:54 -05:00
renovate[bot]
4bc7d1b081 chore(deps): lock file maintenance (#94)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-26 08:09:42 +05:30
EvolutionX
acbec3e733 chore: bless seren 2023-06-19 16:57:46 +05:30
github-actions[bot]
dbc3154101 chore(main): release 0.5.1 (#103)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-06-16 10:38:09 +05:30
EvolutionX
7252c533bc chore: remove yarn 2023-06-16 10:35:39 +05:30
Evo
dce78c0945 feat(init): deprecate init and bump deps (#102)
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2023-06-16 10:32:56 +05:30
Jacob Nguyen
58fa3253f6 feat: version injector (#90) 2023-03-21 18:47:40 +05:30
renovate[bot]
1421136181 chore(deps): lock file maintenance (#71)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:33:28 -06:00
renovate[bot]
f29c7881fe chore(deps): update actions/setup-node digest to 64ed1c7 (#81)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
2023-03-11 23:29:39 -06:00
renovate[bot]
0d37da5689 chore(deps): update actions/checkout digest to ac59398 (#86)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:28:27 -06:00
renovate[bot]
504d36729e chore(deps): update dependency @favware/npm-deprecate to v1.0.7 (#88)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:26:34 -06:00
renovate[bot]
e391fddf20 chore(deps): update dependency @types/prompts to v2.4.3 (#83)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:23:16 -06:00
renovate[bot]
e5d6de4841 chore(deps): update dependency prettier to v2.8.4 (#87)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:19:00 -06:00
renovate[bot]
fc47847eeb chore(deps): update dependency typescript to v4.9.5 (#78)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 23:13:48 -06:00
Jacob Nguyen
386b30aedd chore: update discord link 2023-02-16 11:43:11 -06:00
Duro
f2531a6f9b docs: fix yarn installation step in readme (#84) 2022-10-11 16:59:23 +05:30
69287ab1bd fix: git not installed errors during init (#79)
Co-authored-by: EvolutionX <evolutionx9777@gmail.com>
2022-09-22 12:38:49 +05:30
Evo
aa398a871c chore: i hate you github 2022-09-16 12:16:22 +05:30
Evo
0855abfea3 chore: ffs github 2022-09-16 12:13:07 +05:30
github-actions[bot]
6212fb3588 chore(main): release 0.5.0 (#77)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-09-16 12:10:23 +05:30
EvolutionX
2018c4381e chore: release 0.5.0
Release-As: 0.5.0
2022-09-16 12:06:24 +05:30
EvolutionX
5b0214a073 chore: for real.
permalink: http://whatthecommit.com/2466dab665a386b7b29018ac71f45033
2022-09-16 12:00:57 +05:30
Jacob Nguyen
6e6ed3136d docs(readme): add banner (#75) 2022-09-16 06:10:42 +05:30
EvolutionX
c302e1e4be chore: cmon github bruh 2022-09-13 10:31:15 +05:30
EvolutionX
e60fb42e3e chore: cmon github 2022-09-13 10:29:22 +05:30
EvolutionX
5e48f27584 chore: update help 2022-09-13 10:26:50 +05:30
EvolutionX
276b9656b8 ci: update to auto deprecate 2022-09-13 10:22:43 +05:30
EvolutionX
75dff367f5 ci: update testing 2.0 2022-09-13 10:10:24 +05:30
EvolutionX
90429523c3 ci: update testing 2022-09-13 10:06:46 +05:30
Tofix.js
bed31c1f49 feat!: re-write to TypeScript
Co-authored-by: Evo <85353424+EvolutionX-10@users.noreply.github.com>
2022-09-13 10:05:02 +05:30
Jacob Nguyen
9271da3076 feat: adds the esm template option + refactors (#73)
* feat: inline gimmeChoices returned value

* feat: add esm option

* feat: add config support for javascript-esm

* feat: add fromCwd.js util

* feat: transform repetitive paths to fromCwd

* feat: remove conditional branch in favor of transform

* refactor: extract condition into function

* style: prettier
2022-08-13 23:15:44 +05:30
Jacob Nguyen
2009d1fdca feat: add engine for node version & remove manual version check (#72)
cheers
2022-08-12 12:01:35 +05:30
Evo
f9aa2c3d20 chore: oops 2022-08-12 11:01:25 +05:30
Evo
3fa93bd903 ci: update again 2022-08-12 11:01:02 +05:30
Evo
e7c50c4d32 ci: update publish.yml 2022-08-12 10:53:09 +05:30
Evo
b1190efee3 chore: update description 2022-08-07 23:24:22 +05:30
renovate[bot]
55b1fff28e chore(deps): lock file maintenance (#69)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-01 08:51:46 +05:30
renovate[bot]
7bcbf55fb5 chore(deps): update dependency @favware/npm-deprecate to v1.0.5 (#68)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-31 10:32:16 +05:30
github-actions[bot]
ebc688022e chore(main): release 0.4.2 (#66)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-28 12:33:13 +05:30
renovate[bot]
810763837c chore(deps): lock file maintenance (#65)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-25 13:26:49 +05:30
renovate[bot]
fa331ae0c0 chore(deps): lock file maintenance (#64)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-25 08:37:41 +05:30
Evo
6c034a568f refactor(init): improve node version check (#63) 2022-07-22 19:22:54 +05:30
EvolutionX
9158e66bb4 chore(init): update naming of variable 2022-07-21 23:15:27 +05:30
renovate[bot]
af593bf84a chore(deps): update actions/setup-node digest to 2fddd88 (#60)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 09:39:56 +05:30
renovate[bot]
f84e7ac8f5 chore(deps): lock file maintenance (#61)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 09:24:27 +05:30
renovate[bot]
08b8a13d16 chore(deps): lock file maintenance (#59) 2022-07-11 15:28:32 +05:30
Evo
c4f8e45bdc feat: switch to undici (#58) 2022-07-10 11:09:22 +05:30
EvolutionX
83e841a341 chore: update scripts 2022-07-07 23:05:47 +05:30
EvolutionX
ab2f8016b6 chore: remove standard-version 2022-07-07 23:05:00 +05:30
github-actions[bot]
93ef62bc9d chore(main): release 0.4.1 (#57)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-07 22:49:09 +05:30
EvolutionX
e454ddaaab chore: stuff 2022-07-07 22:45:42 +05:30
EvolutionX
e3ee6d5428 chore: stuff 2022-07-07 22:43:39 +05:30
EvolutionX
02eec5f926 chore: stuff 2022-07-07 22:39:04 +05:30
EvolutionX
aa1e11b24a chore: stuff 2022-07-07 22:37:36 +05:30
EvolutionX
39817e6b4f chore: stuff 2022-07-07 22:36:06 +05:30
github-actions[bot]
a0d5890ea7 chore(main): release 0.4.0 (#56)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-07 22:34:55 +05:30
EvolutionX
2fa5a360ef chore: fix workflow 2022-07-07 22:33:24 +05:30
EvolutionX
1e07b5f1c8 chore: revert versions 2022-07-07 22:29:55 +05:30
EvolutionX
c312ca794c ci: update workflows 2022-07-07 22:24:45 +05:30
EvolutionX
eee3bb8db6 docs(changelog): update changelog 2022-07-07 22:04:43 +05:30
github-actions[bot]
d9ea304fa6 chore(main): release 0.3.0 (#55)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-07 21:53:27 +05:30
EvolutionX
52725ea7f6 ci: remove sign off 2022-07-07 21:50:26 +05:30
Evo
b24a053d1c feat(init): add --sync flag (#53) 2022-07-07 10:52:49 -05:00
EvolutionX
419b7bce22 chore: add .gitattributes to npmignore 2022-07-07 21:13:08 +05:30
EvolutionX
5a24ae4819 ci: new workflow release 2022-07-07 21:12:08 +05:30
EvolutionX
8f6b1c690f ci: rename release to publish 2022-07-07 21:03:26 +05:30
xxDeveloper
46ec745b88 docs(README): Remove stats (#52) 2022-07-07 20:26:46 +05:30
Evo
6472683c19 chore: add website as homepage 2022-07-06 09:14:15 +05:30
EvolutionX
2b260eb1bc chore(release): 0.2.2 2022-07-05 18:56:15 +05:30
EvolutionX
428b87ee1f chore(release): 0.2.1 2022-07-05 18:52:58 +05:30
renovate[bot]
493189772f chore(deps): lock file maintenance (#46)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-05 18:50:47 +05:30
renovate[bot]
dff1481e19 chore(deps): update dependency eslint to v8.19.0 (#51)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-05 13:18:29 +00:00
renovate[bot]
9264dde532 chore(deps): pin dependencies (#48)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-05 18:47:18 +05:30
renovate[bot]
ffc1e6f3eb chore(deps): update dependency cz-conventional-changelog to v3.3.0 (#41)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-05 18:44:50 +05:30
EvolutionX
95c20a3edf chore: update name and add npmignore 2022-07-03 09:36:31 +05:30
EvolutionX
c351bd5c0b chore: no 2022-06-29 13:12:58 +05:30
EvolutionX
f218e6524b ci: deprecations should now work 2022-06-29 13:10:10 +05:30
EvolutionX
afd0b46ffc ci: final final final update 2022-06-29 12:56:25 +05:30
EvolutionX
c730986264 ci: final final update 2022-06-29 12:52:30 +05:30
EvolutionX
03dddd4384 ci: final update 2022-06-29 12:49:16 +05:30
EvolutionX
177766e357 ci: update cd 2022-06-29 12:45:40 +05:30
EvolutionX
7cbde33af2 ci: update cd 2022-06-29 12:36:15 +05:30
EvolutionX
58922bf69e ci: update cd 2022-06-29 12:32:14 +05:30
EvolutionX
92b713e476 ci: update workflows 2022-06-29 12:24:27 +05:30
EvolutionX
94757d67cb chore(release): 0.2.1 2022-06-29 12:23:47 +05:30
EvolutionX
6253571095 ci: update stuff 2022-06-29 11:59:57 +05:30
EvolutionX
c4c9b11bc2 ci: npm version stuff 2022-06-29 11:50:10 +05:30
EvolutionX
e06ae29fa1 ci: update workflows 2022-06-29 11:32:25 +05:30
EvolutionX
d455a9ef30 ci: update delivery workflow 2022-06-29 11:14:55 +05:30
Jacob Nguyen
9bd2b0f38b feat: making sern help message look better, adding ascii art (#50) 2022-06-29 10:17:07 +05:30
Jacob Nguyen
330b2ee92d docs: add better instructions for readme (#49) 2022-06-28 23:05:45 +05:30
Evo
8c45327094 fix: avoid crashing of cli when no plugin found (#47) 2022-06-22 11:53:42 -05:00
EvolutionX
361e6451a7 ci: damn it 2022-06-22 13:02:44 +05:30
EvolutionX
81eabff53e ci: finally done 2022-06-22 12:58:06 +05:30
EvolutionX
d78c20a491 ci: testing npm 3x 2022-06-22 12:49:07 +05:30
EvolutionX
a97bfdf9ee ci: testing npm 2x 2022-06-22 12:42:03 +05:30
EvolutionX
7276c2cb21 ci: testing npm 2022-06-22 12:40:17 +05:30
EvolutionX
0ba16b494c chore(release): 0.2.0 2022-06-22 12:25:51 +05:30
EvolutionX
d35cb828fb ci: add cd, closes #37 2022-06-22 12:24:27 +05:30
EvolutionX
ae3725587d ci: nvm 2022-06-22 12:04:09 +05:30
EvolutionX
885045a041 style: pretty 2022-06-22 12:02:44 +05:30
EvolutionX
54a3e6e42c ci: update workflow 2022-06-22 12:02:37 +05:30
EvolutionX
eb85a7a8f2 feat: add basic type checking 2022-06-22 11:58:30 +05:30
EvolutionX
e86e3a7e67 chore: update exitoverride 2022-06-22 11:24:49 +05:30
EvolutionX
e3a7d1a28c ci: update workflow 2022-06-22 11:19:06 +05:30
EvolutionX
82dd9e7141 ci: update workflow 2022-06-22 09:23:20 +05:30
EvolutionX
055da6c24d refactor: remove prefix question 2022-06-22 09:16:34 +05:30
EvolutionX
3bd262739f chore: add verbose messages 2022-06-22 09:05:46 +05:30
renovate[bot]
805543e1a3 chore(deps): update dependency eslint to v8.18.0 (#42)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-06-21 20:30:37 +05:30
renovate[bot]
7e65f3e5c3 chore(deps): pin dependency cz-conventional-changelog to v (#39)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-06-19 19:30:45 +05:30
renovate[bot]
93e17be8c7 chore(deps): update actions/setup-node digest to eeb10cf (#40)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-06-19 19:29:54 +05:30
renovate[bot]
514a56fde4 chore(deps): update dependency prettier to v2.7.1 (#44)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-06-19 19:27:43 +05:30
Evo
895a48910e feat: plugin command!!! (#45) 2022-06-18 23:05:34 +05:30
Evo
7cf62c0308 feat: enable extra command & jsdockerfile (#43) 2022-06-18 01:47:26 -05:00
Evo
3eb63835d9 feat: add sern.config.json (#38) 2022-06-17 22:09:13 +05:30
EvolutionX
e78cb552da ci: update branch names 2022-06-14 08:44:52 +05:30
EvolutionX
f650171030 refactor: remove degit 2022-06-14 08:43:14 +05:30
Jacob Nguyen
b2e6236dde feat: add commander and start plugins installer (#36)
Co-authored-by: EvolutionX
2022-06-11 09:33:44 +05:30
EvolutionX
09a9b68b65 ci: fix workflows 2022-06-10 22:43:16 +05:30
EvolutionX
67a0efd1c2 chore(release): 0.1.3 2022-06-10 22:40:32 +05:30
EvolutionX
310c82f24e chore(release): 0.1.2 2022-06-10 22:37:57 +05:30
Allyedge
b1a8683373 feat: create typescript dockerfile and the extra command (#28)
Co-authored-by: EvolutionX
2022-05-29 23:26:06 +05:30
65 changed files with 6762 additions and 767 deletions

1
.github/CODEOWNERS vendored
View File

@@ -1,2 +1 @@
* @Allyedge
* @EvolutionX-10

32
.github/workflows/auto-deprecate.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: NPM Auto Deprecate
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
auto-deprecate:
name: NPM Auto Deprecate
runs-on: ubuntu-latest
steps:
- name: Checkout Project
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
- name: Use Node.js
uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3
with:
node-version: 17
registry-url: 'https://registry.npmjs.org/'
- name: Install Node.js dependencies
run: npm i
- name: Deprecate dev versions
run: npx npm-deprecate --name "*dev*" --package "@sern/cli" --message "This is a deprecated version of @sern/cli@dev. Please use the latest dev version."
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Deprecate pr versions
run: npx npm-deprecate --name "*pr*" --package "@sern/cli" --message "This is a deprecated version of @sern/cli. Please use the latest version."
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -1,35 +0,0 @@
name: "CodeQL Go"
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "40 13 * * 2"
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["go"]
steps:
- name: Checkout repository
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

65
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,65 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '40 13 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@@ -0,0 +1,40 @@
name: Continuous Delivery
on:
push:
branches:
- main
paths:
- 'src/**'
- 'package.json'
jobs:
Publish:
name: Publishing Dev
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
- name: Set up Node.js
uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3
with:
node-version: 17
registry-url: 'https://registry.npmjs.org'
- name: Install Node.js dependencies
run: npm i && npm run build
- name: Link Project
run: npm link
- name: Test Sern
run: sern
- name: Publish to npm
run: |
npm version premajor --preid "dev.$(git rev-parse --verify --short HEAD)" --git-tag-version=false
npm publish --tag dev
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -0,0 +1,54 @@
name: Continuous Integration
on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main
pull_request_target:
branches:
- main
jobs:
# Lint:
# name: Linting
# runs-on: ubuntu-latest
# steps:
# - name: Check out Git repository
# uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
# - name: Set up Node.js
# uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3
# with:
# node-version: 17
# Prettier must be in `package.json`
# - name: Install Node.js dependencies
# run: npm i
# - name: Run Prettier
# run: npm run format
Test:
name: Testing
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
- name: Set up Node.js
uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3
with:
node-version: 17
- name: Install Node.js dependencies
run: npm i && npm run build
- name: Link Project
run: npm link
- name: Test sern
run: sern

40
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Publish
on:
workflow_dispatch:
inputs:
prNumber:
description: The number of the PR that is being deployed
required: true
jobs:
Publish:
name: Publishing
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
- name: Set up Node.js
uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3
with:
node-version: 17
registry-url: 'https://registry.npmjs.org'
- name: Install Node.js dependencies
run: npm i && npm run build
- name: Link Project
run: npm link
- name: Test sern
run: sern
- name: Publish to npm
run: |
TAG=$(echo 'pr-${{ github.event.inputs.prNumber }}')
npm version premajor --preid "${TAG}.$(git rev-parse --verify --short HEAD)" --git-tag-version=false
npm publish --tag ${TAG}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

32
.github/workflows/release-please.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Release
on:
workflow_dispatch:
jobs:
Release:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v3
id: release
with:
release-type: node
bump-patch-for-minor-pre-major: true
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
if: ${{ steps.release.outputs.release_created }}
- uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3
with:
node-version: 17
registry-url: 'https://registry.npmjs.org'
if: ${{ steps.release.outputs.release_created }}
- run: npm i && npm run build
if: ${{ steps.release.outputs.release_created }}
- run: npm link
if: ${{ steps.release.outputs.release_created }}
- run: sern
if: ${{ steps.release.outputs.release_created }}
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
if: ${{ steps.release.outputs.release_created }}

View File

@@ -1,35 +0,0 @@
name: goreleaser
on:
push:
tags:
- "*"
permissions:
contents: write
packages: write
issues: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --force --tags
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
id: go
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

118
.gitignore vendored
View File

@@ -1 +1,117 @@
node_modules
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Editor Files
.vscode
.idea
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.development.local
.env.development
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Extras
.vscode/
# Yarn files
.yarn/install-state.gz
.yarn/build-state.yml

View File

@@ -1,9 +0,0 @@
builds:
- binary: sern
goos:
- windows
- darwin
- linux
goarch:
- amd64
main: ./cmd

6
.npmignore Normal file
View File

@@ -0,0 +1,6 @@
renovate.json
tsconfig.json
.prettierignore
.prettierrc
.gitattributes
.github/

3
.prettierignore Normal file
View File

@@ -0,0 +1,3 @@
.github/
CHANGELOG.md
dist/

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"useTabs": false,
"singleQuote": true,
"printWidth": 140
}

View File

@@ -1,23 +1,258 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
All notable changes to this project will be documented in this file.
## 0.1.1 (2022-06-02)
## [1.3.2](https://github.com/sern-handler/cli/compare/v1.3.1...v1.3.2) (2024-07-31)
The `go-npm` package was replaced by one of its forks, `@gzuidhof/go-npm`.
`@gzuidhof/go-npm` has updated dependencies, and it uses `esbuild`, which is great.
### Bug Fixes
### Changes
* make tsconfig work with comments/trailing commas ([#142](https://github.com/sern-handler/cli/issues/142)) ([53ca446](https://github.com/sern-handler/cli/commit/53ca446a38076ed7b165dbbb41f346f028b7e394))
- Replace `go-npm` with `@gzuidhof/go-npm`.
## [1.3.1](https://github.com/sern-handler/cli/compare/v1.3.0...v1.3.1) (2024-07-27)
## 0.1.0 (2022-06-02)
This is the CLI's initial release.
### Miscellaneous Chores
* release 1.3.1 ([2bb169f](https://github.com/sern-handler/cli/commit/2bb169f600172af8c8316b6c9420684a4de34e0d))
## [1.3.0](https://github.com/sern-handler/cli/compare/v1.2.1...v1.3.0) (2024-07-27)
### Features
- `init` command
- `help` command
- `version` command
* plugin, no prompt, bug fixes ([#139](https://github.com/sern-handler/cli/issues/139)) ([20364fa](https://github.com/sern-handler/cli/commit/20364fa20d1f3bf70a1c0cfefbc1d6c9365a4925))
### Bug Fixes
* fix publish command for bun & pnpm ([#137](https://github.com/sern-handler/cli/issues/137)) ([d581142](https://github.com/sern-handler/cli/commit/d581142f082ed888036e58aa33e9d88d84d34c2f))
## [1.2.1](https://github.com/sern-handler/cli/compare/v1.2.0...v1.2.1) (2024-02-08)
### Bug Fixes
* better error messages for publish ([d1832e4](https://github.com/sern-handler/cli/commit/d1832e44ce1b10aeb5b9dc902b7d35ab51c41ff3))
## [1.2.0](https://github.com/sern-handler/cli/compare/v1.1.0...v1.2.0) (2024-01-29)
### Features
* make application id optional, thanks [@trueharuu](https://github.com/trueharuu) ([#130](https://github.com/sern-handler/cli/issues/130)) ([2d6e65a](https://github.com/sern-handler/cli/commit/2d6e65a1e6073f605aab192b8cea33037a04af2c))
## [1.1.0](https://github.com/sern-handler/cli/compare/v1.0.3...v1.1.0) (2024-01-28)
### Features
* command clear ([#128](https://github.com/sern-handler/cli/issues/128)) ([303ac02](https://github.com/sern-handler/cli/commit/303ac0280c7c7c55f2670d49c9685b911670bc05))
## [1.0.3](https://github.com/sern-handler/cli/compare/v1.0.2...v1.0.3) (2023-12-25)
### Bug Fixes
* intellisense for esm build ts ([#126](https://github.com/sern-handler/cli/issues/126)) ([a5cb668](https://github.com/sern-handler/cli/commit/a5cb66828eae47d3eac5b86c7e67c01dbed500d5))
## [1.0.2](https://github.com/sern-handler/cli/compare/v1.0.1...v1.0.2) (2023-11-04)
### Bug Fixes
* better error handling ([5dbf2a8](https://github.com/sern-handler/cli/commit/5dbf2a87dcb0001993fe126d9002bc82c8108e24))
* build mkdir errors ([#122](https://github.com/sern-handler/cli/issues/122)) ([f1d7d6c](https://github.com/sern-handler/cli/commit/f1d7d6c911bc54ed3ca3e39eefbc7de6ee33b10d))
## [1.0.1](https://github.com/sern-handler/cli/compare/v1.0.0...v1.0.1) (2023-10-05)
### Bug Fixes
* multiple bugs ([#119](https://github.com/sern-handler/cli/issues/119)) ([d9ca5ff](https://github.com/sern-handler/cli/commit/d9ca5ff3ff2f304a6d75f2b7a296bd900431d41f))
## [1.0.0](https://github.com/sern-handler/cli/compare/v0.6.0...v1.0.0) (2023-09-05)
### ⚠ BREAKING CHANGES
* **plugins:** older versions of cli does not have plugins command functional
### Features
* build app ([#112](https://github.com/sern-handler/cli/issues/112)) ([88e2bbf](https://github.com/sern-handler/cli/commit/88e2bbf6c84e3841370a4288181e8ec721ef1925))
* list subcommand ([#113](https://github.com/sern-handler/cli/issues/113)) ([5fd2a7b](https://github.com/sern-handler/cli/commit/5fd2a7b4c4bc92467fbaa26005d261d4ed8b2a13))
* **plugins:** new method to obtain plugins ([#114](https://github.com/sern-handler/cli/issues/114)) ([c785d49](https://github.com/sern-handler/cli/commit/c785d49fa5c0d98261de7d7b0c39f85c21316156))
### Bug Fixes
* credentials precedence ([#111](https://github.com/sern-handler/cli/issues/111)) ([3f74658](https://github.com/sern-handler/cli/commit/3f74658b16b2697df11c7e33172c09c30b7543a8))
* **extra:** dockerfile errors and tsc fallback ([#101](https://github.com/sern-handler/cli/issues/101)) ([4082926](https://github.com/sern-handler/cli/commit/40829267c4e77b316a60604c63bad79124713b89))
## [0.6.0](https://github.com/sern-handler/cli/compare/v0.5.1...v0.6.0) (2023-08-09)
### Features
* publish command ([#105](https://github.com/sern-handler/cli/issues/105)) ([827ffb7](https://github.com/sern-handler/cli/commit/827ffb7ad9252e3cda257bed1febdca2da03e253))
### Bug Fixes
* change file path for sern/extras ([#109](https://github.com/sern-handler/cli/issues/109)) ([2348e3e](https://github.com/sern-handler/cli/commit/2348e3e9ab055fddab3f44d574af79fd7ccd4485))
### Miscellaneous Chores
* release 0.6.0 ([642bf11](https://github.com/sern-handler/cli/commit/642bf11608cf5d9b4256999e3bdb48e762ca88ee))
## [0.5.1](https://github.com/sern-handler/cli/compare/v0.5.0...v0.5.1) (2023-06-16)
### Features
* **init:** deprecate init and bump deps ([#102](https://github.com/sern-handler/cli/issues/102)) ([dce78c0](https://github.com/sern-handler/cli/commit/dce78c0945de6da79bf1e268f29651da0c44c1eb))
* version injector ([#90](https://github.com/sern-handler/cli/issues/90)) ([58fa325](https://github.com/sern-handler/cli/commit/58fa3253f62da9fb66d1b2ae901b568367f065d0))
### Bug Fixes
* git not installed errors during init ([#79](https://github.com/sern-handler/cli/issues/79)) ([69287ab](https://github.com/sern-handler/cli/commit/69287ab1bd0c4960384144f90fea8ebded3b0cc5))
## [0.5.0](https://github.com/sern-handler/cli/compare/v0.4.2...v0.5.0) (2022-09-16)
### ⚠ BREAKING CHANGES
* re-write to TypeScript
### Features
* add engine for node version & remove manual version check ([#72](https://github.com/sern-handler/cli/issues/72)) ([2009d1f](https://github.com/sern-handler/cli/commit/2009d1fdca9a383d219304fd3cb48a622355b7dc))
* adds the esm template option + refactors ([#73](https://github.com/sern-handler/cli/issues/73)) ([9271da3](https://github.com/sern-handler/cli/commit/9271da30764f86225385e8ae6448b99d66687294))
* re-write to TypeScript ([bed31c1](https://github.com/sern-handler/cli/commit/bed31c1f4995bbf7d8d0a483f562788172e29919))
### Miscellaneous Chores
* release 0.5.0 ([2018c43](https://github.com/sern-handler/cli/commit/2018c4381e665b9b0c5e70a203aa0dfd9fdd3cef))
## [0.4.2](https://github.com/sern-handler/cli/compare/v0.4.1...v0.4.2) (2022-07-28)
### Features
* switch to undici ([#58](https://github.com/sern-handler/cli/issues/58)) ([c4f8e45](https://github.com/sern-handler/cli/commit/c4f8e45bdc0af5a3bbd394d2b9f852f4a946114c))
## [0.4.1](https://github.com/sern-handler/cli/compare/v0.4.0...v0.4.1) (2022-07-07)
### Features
* add `sern.config.json` ([#38](https://github.com/sern-handler/cli/issues/38)) ([3eb6383](https://github.com/sern-handler/cli/commit/3eb63835d9f6ff3f3426e017ea87344c00bb13a4))
* add basic type checking ([eb85a7a](https://github.com/sern-handler/cli/commit/eb85a7a8f2f6252f719fd396d42cded2d9eb0918))
* add commander and start plugins installer ([#36](https://github.com/sern-handler/cli/issues/36)) ([b2e6236](https://github.com/sern-handler/cli/commit/b2e6236dde6f4848dde6fc23a6222415824bb294))
* add default settings for the -y flag ([#19](https://github.com/sern-handler/cli/issues/19)) ([e5f607e](https://github.com/sern-handler/cli/commit/e5f607e99875e105cbb148cab3ed1bbc3771ae35))
* added actions and formatting stuff ([b302a8b](https://github.com/sern-handler/cli/commit/b302a8b362257fb2cea72b7e1fc66bea351c511f))
* added help command ([ca23d17](https://github.com/sern-handler/cli/commit/ca23d17670663b62e23849e2350deef208bfc100))
* Added version command & created readme ([#25](https://github.com/sern-handler/cli/issues/25)) ([7535a5e](https://github.com/sern-handler/cli/commit/7535a5e0267c9e682b7bc8470206c0597f5ba9a1))
* bump all files to GitHub 🎉 ([01b39ad](https://github.com/sern-handler/cli/commit/01b39ad9b78f0a67e23ba66c10262082675eeed5))
* cli is now functional ([65f38f3](https://github.com/sern-handler/cli/commit/65f38f3eb2b4e8e2bd136b9bd8f37f1966be1661))
* cli is now functional ([5021d28](https://github.com/sern-handler/cli/commit/5021d28bca6ebe1cb4a548f5e595b1220f222c98))
* create typescript dockerfile and the extra command ([#28](https://github.com/sern-handler/cli/issues/28)) ([b1a8683](https://github.com/sern-handler/cli/commit/b1a86833734258e0a22da18c2c780133c199d5cd))
* enable extra command & jsdockerfile ([#43](https://github.com/sern-handler/cli/issues/43)) ([7cf62c0](https://github.com/sern-handler/cli/commit/7cf62c03083b8ebbb8a6a63fd8efe592344d5230))
* **init:** add --sync flag ([#53](https://github.com/sern-handler/cli/issues/53)) ([b24a053](https://github.com/sern-handler/cli/commit/b24a053d1cb8c00d49a96b6d536dd17205b9fa0e))
* making sern help message look better, adding ascii art ([#50](https://github.com/sern-handler/cli/issues/50)) ([9bd2b0f](https://github.com/sern-handler/cli/commit/9bd2b0f38be835a31fceeabdf60487a1424cdf7e))
* more questions, better handling, better ui ([f931802](https://github.com/sern-handler/cli/commit/f9318024bb4c62cee1a7ddfc6af4117c22ca6020))
* now edits the directories as per user's choice ([fec1c8e](https://github.com/sern-handler/cli/commit/fec1c8e24c5ca7752f9e74b0fc3a32716bb42299))
* plugin command!!! ([#45](https://github.com/sern-handler/cli/issues/45)) ([895a489](https://github.com/sern-handler/cli/commit/895a48910e32813f8aa25f57302a4123fc631c2c))
* rebase changes ([cae3c59](https://github.com/sern-handler/cli/commit/cae3c597c3da6aa836fb9c70b8555814e8fc5db0))
* refactored code and added custom handling of commands ([0e97b7d](https://github.com/sern-handler/cli/commit/0e97b7db8afed7f625eeb0a43aa992441ab49b39))
* **skip:** option to skip package manager selection ([#20](https://github.com/sern-handler/cli/issues/20)) ([7b1d535](https://github.com/sern-handler/cli/commit/7b1d53520f0aa35e48b72d61d2f1a85ffdfdfec8))
* using degit to clone the templates ([ddb0285](https://github.com/sern-handler/cli/commit/ddb02850f2096d8c9ec36e766ea74e10d2efce3f))
### Bug Fixes
* avoid crashing of cli when no plugin found ([#47](https://github.com/sern-handler/cli/issues/47)) ([8c45327](https://github.com/sern-handler/cli/commit/8c45327094b2560f7b5c813a1c1925920bd46038))
* fix degit erroring when there's no cache ([fc01554](https://github.com/sern-handler/cli/commit/fc01554fae2726f4ebd39a66ef1cb634a421dd9f))
* **install.js:** fix mistyped. cached -> cache ([fa68936](https://github.com/sern-handler/cli/commit/fa689360ce054c63dab77e8b8f0b794b3b8736e4))
* no more crashing cli if yarn isnt present ([#24](https://github.com/sern-handler/cli/issues/24)) ([88893a3](https://github.com/sern-handler/cli/commit/88893a35cd1144867713de32c5bf52c2dc702450))
* no more error when selecting js ([cc410bd](https://github.com/sern-handler/cli/commit/cc410bd370a751833dbc5fc04030bfa53a6c1fd2))
* prettier things ([1265224](https://github.com/sern-handler/cli/commit/1265224bb9f93cb104915be50c1c2ea1e3924955))
* removed useless line ([f268b1c](https://github.com/sern-handler/cli/commit/f268b1c62fd4d5823d483a33cfef2e2d7f7b127c))
### Performance Improvements
* **init.js:** string.match -> regex.test for node version ([f760dbc](https://github.com/sern-handler/cli/commit/f760dbc6e39e098496f25a5c4ee90855a2bb3bd5))
### [0.2.2](https://github.com/sern-handler/cli/compare/v0.2.1...v0.2.2) (2022-07-05)
### [0.2.1](https://github.com/sern-handler/cli/compare/v0.2.0...v0.2.1) (2022-07-05)
### Features
* making sern help message look better, adding ascii art ([#50](https://github.com/sern-handler/cli/issues/50)) ([9bd2b0f](https://github.com/sern-handler/cli/commit/9bd2b0f38be835a31fceeabdf60487a1424cdf7e))
### Bug Fixes
* avoid crashing of cli when no plugin found ([#47](https://github.com/sern-handler/cli/issues/47)) ([8c45327](https://github.com/sern-handler/cli/commit/8c45327094b2560f7b5c813a1c1925920bd46038))
## [0.2.0](https://github.com/sern-handler/cli/compare/v0.1.3...v0.2.0) (2022-06-22)
### Features
* add `sern.config.json` ([#38](https://github.com/sern-handler/cli/issues/38)) ([3eb6383](https://github.com/sern-handler/cli/commit/3eb63835d9f6ff3f3426e017ea87344c00bb13a4))
* add basic type checking ([eb85a7a](https://github.com/sern-handler/cli/commit/eb85a7a8f2f6252f719fd396d42cded2d9eb0918))
* add commander and start plugins installer ([#36](https://github.com/sern-handler/cli/issues/36)) ([b2e6236](https://github.com/sern-handler/cli/commit/b2e6236dde6f4848dde6fc23a6222415824bb294))
* enable extra command & jsdockerfile ([#43](https://github.com/sern-handler/cli/issues/43)) ([7cf62c0](https://github.com/sern-handler/cli/commit/7cf62c03083b8ebbb8a6a63fd8efe592344d5230))
* plugin command!!! ([#45](https://github.com/sern-handler/cli/issues/45)) ([895a489](https://github.com/sern-handler/cli/commit/895a48910e32813f8aa25f57302a4123fc631c2c))
### [0.1.3](https://github.com/sern-handler/cli/compare/v0.1.2...v0.1.3) (2022-06-10)
### Features
* add default settings for the -y flag ([#19](https://github.com/sern-handler/cli/issues/19)) ([e5f607e](https://github.com/sern-handler/cli/commit/e5f607e99875e105cbb148cab3ed1bbc3771ae35))
* Added version command & created readme ([#25](https://github.com/sern-handler/cli/issues/25)) ([7535a5e](https://github.com/sern-handler/cli/commit/7535a5e0267c9e682b7bc8470206c0597f5ba9a1))
* create typescript dockerfile and the extra command ([#28](https://github.com/sern-handler/cli/issues/28)) ([b1a8683](https://github.com/sern-handler/cli/commit/b1a86833734258e0a22da18c2c780133c199d5cd))
* now edits the directories as per user's choice ([fec1c8e](https://github.com/sern-handler/cli/commit/fec1c8e24c5ca7752f9e74b0fc3a32716bb42299))
* **skip:** option to skip package manager selection ([#20](https://github.com/sern-handler/cli/issues/20)) ([7b1d535](https://github.com/sern-handler/cli/commit/7b1d53520f0aa35e48b72d61d2f1a85ffdfdfec8))
* using degit to clone the templates ([ddb0285](https://github.com/sern-handler/cli/commit/ddb02850f2096d8c9ec36e766ea74e10d2efce3f))
### Bug Fixes
* fix degit erroring when there's no cache ([fc01554](https://github.com/sern-handler/cli/commit/fc01554fae2726f4ebd39a66ef1cb634a421dd9f))
* **install.js:** fix mistyped. cached -> cache ([fa68936](https://github.com/sern-handler/cli/commit/fa689360ce054c63dab77e8b8f0b794b3b8736e4))
* no more crashing cli if yarn isnt present ([#24](https://github.com/sern-handler/cli/issues/24)) ([88893a3](https://github.com/sern-handler/cli/commit/88893a35cd1144867713de32c5bf52c2dc702450))
* no more error when selecting js ([cc410bd](https://github.com/sern-handler/cli/commit/cc410bd370a751833dbc5fc04030bfa53a6c1fd2))
### [0.1.1](https://github.com/sern-handler/cli/compare/v0.1.0...v0.1.1) (2022-05-09)
### Features
* added help command ([ca23d17](https://github.com/sern-handler/cli/commit/ca23d17670663b62e23849e2350deef208bfc100))
* cli is now functional ([5021d28](https://github.com/sern-handler/cli/commit/5021d28bca6ebe1cb4a548f5e595b1220f222c98))
### Bug Fixes
* prettier things ([1265224](https://github.com/sern-handler/cli/commit/1265224bb9f93cb104915be50c1c2ea1e3924955))
* removed useless line ([f268b1c](https://github.com/sern-handler/cli/commit/f268b1c62fd4d5823d483a33cfef2e2d7f7b127c))
## 0.1.0 (2022-04-21)
### Features
* added actions and formatting stuff ([b302a8b](https://github.com/sern-handler/cli/commit/b302a8b362257fb2cea72b7e1fc66bea351c511f))
* bump all files to GitHub 🎉 ([01b39ad](https://github.com/sern-handler/cli/commit/01b39ad9b78f0a67e23ba66c10262082675eeed5))
* more questions, better handling, better ui ([f931802](https://github.com/sern-handler/cli/commit/f9318024bb4c62cee1a7ddfc6af4117c22ca6020))
* refactored code and added custom handling of commands ([0e97b7d](https://github.com/sern-handler/cli/commit/0e97b7db8afed7f625eeb0a43aa992441ab49b39))

View File

@@ -1,18 +1,13 @@
# Sern CLI
<div align="center">
<img src="https://raw.githubusercontent.com/sern-handler/.github/main/cli.png" width="900px">
</div>
[![Go](https://img.shields.io/badge/go-%2300ADD8.svg?style=for-the-badge&logo=go&logoColor=white)](https://github.com/sern-handler/cli)
[![Build](https://img.shields.io/github/workflow/status/sern-handler/cli/goreleaser?style=for-the-badge)](https://github.com/sern-handler/cli)
Our CLI allows you to setup and manage Discord bot projects without writing a single line of code!
😁 **User Friendly** <br>
💦 **Simple** <br>
🌱 **Efficient** <br>
💪 **Powerful** <br>
## License
[![GitHub License](https://img.shields.io/github/license/sern-handler/cli?style=for-the-badge)](https://github.com/sern-handler/cli)
# Features
- Manage discord application commands from the command line.
- Install plugins from the community.
- Really fast startup times (I think).
- Deploy with premade docker configurations.
- Inhouse build tool based on esbuild built for sern applications, nearly **zero** config.
## Installation
@@ -21,7 +16,7 @@ npm install -g @sern/cli@latest
```
```sh
yarn add -g @sern/cli@latest
yarn global add @sern/cli@latest
```
```sh
@@ -32,26 +27,37 @@ pnpm add -g @sern/cli@latest
When you install the CLI, you can use our commands with **sern** prefix.
`sern <command> (opt)<flag>`
```
Usage: sern [options] [command]
___ ___ _ __ _ __
/ __|/ _ \ '__| '_ \
\__ \ __/ | | | | |
|___/\___|_| |_| |_|
Welcome!
If you're new to sern, run npm create @sern/bot for an interactive setup to your new bot project!
If you have any ideas, suggestions, bug reports, kindly join our support server: https://sern.dev/discord
Options:
-v, --version output the version number
-h, --help display help for command
Commands:
init [options] Quickest way to scaffold a new project [DEPRECATED]
plugins [options] Install plugins from https://github.com/sern-handler/awesome-plugins
extra Easy way to add extra things in your sern project
commands Defacto way to manage your slash commands
help [command] display help for command
```
## Setting Up Your Project
To create a new project, you can simply run the following command:
Run `npm create @sern/bot` for an interactive setup on a brand new project using our framework.
```sh
sern init
```
## Installing Plugins
The `init` command will ask you some questions and at the end it will generate a new project.
## Help
If you need help, you can always run the following command:
```sh
sern help
```
## Stats
![Alt](https://repobeats.axiom.co/api/embed/5eb8cf0f79fecee29cc81cd2eca5f6321981304e.svg "Feel free to contribute")
sern runs on your plugins. Contribute to our [repository](https://github.com/sern-handler/awesome-plugins) and then install the plugins via our cli! <br>
Run `sern plugins` to see all installable plugins.

View File

@@ -1,15 +0,0 @@
package cli
import (
"github.com/sern-handler/cli/pkg/initialize"
"github.com/spf13/cobra"
)
var initCmd = &cobra.Command{
Use: "init",
Short: "Initialize a new Sern project.",
Long: `Initialize a new Sern project, either with a JavaScript or a TypeScript template.`,
Run: func(cmd *cobra.Command, args []string) {
initialize.Initialize()
},
}

View File

@@ -1,29 +0,0 @@
package cli
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "sern",
Short: "A powerful CLI tool for Sern.",
Version: "0.1.0",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Sern CLI")
},
}
func Execute() {
rootCmd.Flags().BoolP("help", "h", false, "Help for the Sern CLI.")
rootCmd.Flags().BoolP("version", "v", false, "The version of the Sern CLI.")
rootCmd.SetVersionTemplate("Sern CLI - Version {{.Version}}\n")
rootCmd.AddCommand(initCmd)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

View File

@@ -1,7 +0,0 @@
package main
import "github.com/sern-handler/cli/cmd/cli"
func main() {
cli.Execute()
}

38
go.mod
View File

@@ -1,38 +0,0 @@
module github.com/sern-handler/cli
go 1.18
require (
github.com/AlecAivazis/survey/v2 v2.3.4
github.com/go-git/go-git/v5 v5.4.2
github.com/gookit/color v1.5.0
github.com/spf13/cobra v1.4.0
)
require (
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.3.1 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/net v0.0.0-20210326060303-6b1517762897 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)

136
go.sum
View File

@@ -1,136 +0,0 @@
github.com/AlecAivazis/survey/v2 v2.3.4 h1:pchTU9rsLUSvWEl2Aq9Pv3k0IE2fkqtGxazskAMd9Ng=
github.com/AlecAivazis/survey/v2 v2.3.4/go.mod h1:hrV6Y/kQCLhIZXGcriDCUBtB3wnN7156gMXJ3+b23xM=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

4130
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,63 @@
{
"name": "@sern/cli",
"version": "0.1.1",
"description": "Our CLI allows you to setup and manage Discord bot projects without writing a single line of code!",
"scripts": {
"postinstall": "go-npm install",
"preuninstall": "go-npm uninstall"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sern-handler/cli.git"
},
"dependencies": {
"@gzuidhof/go-npm": "^0.1.13"
},
"keywords": [
"sern",
"cli",
"discord",
"bot",
"discord.js"
],
"contributors": [
"Allyedge",
"EvolutionX-10"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/sern-handler/cli/issues"
},
"homepage": "https://github.com/sern-handler/cli#readme",
"goBinary": {
"name": "sern",
"path": "./bin",
"url": "https://github.com/sern-handler/cli/releases/download/v{{version}}/cli_{{version}}_{{platform}}_{{arch}}.tar.gz"
}
"name": "@sern/cli",
"version": "1.3.2",
"description": "Official CLI for @sern/handler",
"exports": "./dist/index.js",
"bin": {
"sern": "./dist/index.js"
},
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"format": "prettier --check .",
"fix": "prettier --write .",
"build": "tsup",
"watch": "tsup --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sern-handler/cli.git"
},
"keywords": [
"cli",
"discord",
"discord.js",
"sern",
"sern-handler"
],
"author": "EvolutionX",
"license": "MIT",
"bugs": {
"url": "https://github.com/sern-handler/cli/issues"
},
"homepage": "https://sern.dev",
"dependencies": {
"@esbuild-kit/cjs-loader": "^2.4.2",
"@esbuild-kit/esm-loader": "^2.5.5",
"colorette": "2.0.20",
"commander": "11.0.0",
"dotenv": "^16.3.1",
"esbuild": "^0.19.1",
"execa": "7.2.0",
"find-up": "6.3.0",
"glob": "^10.3.3",
"ora": "6.3.1",
"prompts": "2.4.2",
"undici": "5.23.0"
},
"devDependencies": {
"@babel/parser": "^7.22.5",
"@favware/npm-deprecate": "1.0.7",
"@types/prompts": "2.4.4",
"prettier": "2.8.8",
"tsup": "^6.7.0",
"typescript": "5.2.2"
},
"engines": {
"node": ">= 18.16.x"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
}
}

View File

@@ -1,66 +0,0 @@
package initialize
import (
"errors"
"os"
"os/exec"
"github.com/gookit/color"
"github.com/sern-handler/cli/pkg/util"
)
func installDependencies(name string, packageManager string) error {
err := os.Chdir(name)
if err != nil {
color.Error.Prompt("Couldn't change to the project's directory.")
return err
}
packageManagers := util.CheckPackageManagers()
if packageManager == "npm" && packageManagers.NPM {
err := exec.Command("npm", "install").Run()
if err != nil {
color.Error.Prompt("Couldn't install the dependencies.")
return err
}
color.Info.Prompt("Successfully installed the dependencies.")
}
if packageManager == "yarn" && packageManagers.Yarn {
err := exec.Command("yarn", "install").Run()
if err != nil {
color.Error.Prompt("Couldn't install the dependencies.")
return err
}
color.Info.Prompt("Successfully installed the dependencies.")
}
if packageManager == "skip" {
color.Warn.Prompt("Skipping the installation of the dependencies.")
}
if !packageManagers.NPM && !packageManagers.Yarn {
color.Error.Prompt("Couldn't find any package managers.")
return errors.New("couldn't find any package managers")
}
err = os.Chdir("..")
if err != nil {
color.Error.Prompt("Couldn't change to the starting directory.")
return err
}
return nil
}

View File

@@ -1,86 +0,0 @@
package initialize
import (
"fmt"
"os"
"github.com/AlecAivazis/survey/v2"
"github.com/gookit/color"
)
func Initialize() {
answers := struct {
Name string
Language string
Main string
Commands string
Package string
}{}
err := survey.Ask(questions, &answers)
if err != nil {
fmt.Println("Project initialization failed, exiting.")
os.Exit(1)
}
color.Info.Prompt("Initializing the project...")
err = cloneRepository(answers.Name, answers.Language)
if err != nil {
color.Error.Prompt("Couldn't generate the project from the templates, exiting.")
err = os.RemoveAll("templates")
if err != nil {
color.Error.Prompt("Couldn't remove the templates folder.")
}
os.Exit(1)
}
err = os.RemoveAll("templates")
if err != nil {
color.Error.Prompt("Couldn't remove the templates folder.")
}
color.Info.Prompt("Successfully generated the project from the templates.")
color.Info.Prompt("Renaming the project's folders...")
err = renameFolders(answers.Name, answers.Main, answers.Commands)
if err != nil {
color.Error.Prompt("Couldn't rename the folders, exiting.")
color.Warn.Prompt("The project was generated, but the folders weren't renamed.\n\nYou can still use the project, but you will have to rename the folders manually.")
os.Exit(1)
}
color.Info.Prompt("Successfully renamed the project's folders.")
color.Info.Prompt("Installing the dependencies...")
err = installDependencies(answers.Name, answers.Package)
if err != nil {
color.Error.Prompt("Couldn't install the dependencies, exiting.")
color.Warn.Prompt("The project was generated, but the dependencies weren't installed.\n\nYou can still use the project, but you will have to install the dependencies manually.")
os.Exit(1)
}
err = renamePackageJson(answers.Name)
if err != nil {
color.Error.Prompt("Couldn't rename the package.json file, exiting.")
color.Warn.Prompt("The project was generated, but the package.json file wasn't updated.\n\nYou can still use the project, but you will have to update the package.json file manually.")
os.Exit(1)
}
color.Success.Prompt("Project successfully initialized.")
}

View File

@@ -1,14 +0,0 @@
package initialize
type PackageJSON struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Main string `json:"main"`
Scripts map[string]string `json:"scripts"`
Keywords []string `json:"keywords"`
Author string `json:"author"`
License string `json:"license"`
Dependencies map[string]string `json:"dependencies"`
DevDependencies map[string]string `json:"devDependencies"`
}

View File

@@ -1,41 +0,0 @@
package initialize
import "github.com/AlecAivazis/survey/v2"
var questions = []*survey.Question{
{
Name: "name",
Prompt: &survey.Input{
Message: "What is your project's name?",
},
Validate: survey.Required,
},
{
Name: "language",
Prompt: &survey.Select{
Message: "What language do you want to use?",
Options: []string{"JavaScript", "TypeScript"},
},
},
{
Name: "main",
Prompt: &survey.Input{
Message: "What is your project's main directory?",
Default: "src",
},
},
{
Name: "commands",
Prompt: &survey.Input{
Message: "What is your project's command directory?",
Default: "commands",
},
},
{
Name: "package",
Prompt: &survey.Select{
Message: "What package manager do you want to use?",
Options: []string{"npm", "yarn", "skip"},
},
},
}

View File

@@ -1,76 +0,0 @@
package initialize
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/gookit/color"
)
func renameFolders(name string, main string, commands string) error {
if main != "src" {
err := os.Rename(name+"/src", name+"/"+main)
if err != nil {
color.Warn.Prompt("Couldn't rename the main folder.")
return err
}
}
if commands != "commands" {
err := os.Rename(name+"/"+main+"/commands", name+"/"+main+"/"+commands)
if err != nil {
color.Warn.Prompt("Couldn't rename the commands folder.")
return err
}
}
return nil
}
func renamePackageJson(name string) error {
file, err := ioutil.ReadFile(name + "/package.json")
if err != nil {
color.Warn.Prompt("Couldn't read the package.json file.")
return err
}
var packageJSON PackageJSON
err = json.Unmarshal(file, &packageJSON)
if err != nil {
fmt.Println(err)
color.Warn.Prompt("Couldn't unmarshal the package.json file.")
return err
}
packageJSON.Name = name
file, err = json.MarshalIndent(packageJSON, "", " ")
if err != nil {
color.Warn.Prompt("Couldn't marshal the package.json file.")
return err
}
err = ioutil.WriteFile(name+"/package.json", file, 0644)
if err != nil {
color.Warn.Prompt("Couldn't write the package.json file.")
return err
}
return nil
}

View File

@@ -1,41 +0,0 @@
package initialize
import (
"os"
"strings"
"github.com/go-git/go-git/v5"
"github.com/gookit/color"
)
func cloneRepository(name string, language string) error {
_, err := git.PlainClone("templates", false, &git.CloneOptions{
URL: "https://github.com/sern-handler/templates",
Progress: os.Stdout,
})
if err != nil {
color.Error.Prompt("Couldn't install the template.")
return err
}
err = os.Rename("templates/templates/"+strings.ToLower(language), name)
if err != nil {
color.Error.Prompt("Couldn't rename the template to the project's name.")
color.Warn.Prompt("The project was generated, but it wasn't renamed.\n\nYou can still use the project, but you will have to rename it manually.")
return err
}
err = os.RemoveAll("templates")
if err != nil {
color.Error.Prompt("Couldn't remove the templates folder.")
return err
}
return nil
}

View File

@@ -1,29 +0,0 @@
package util
import "os/exec"
type PackageManagers struct {
NPM bool
Yarn bool
}
func CheckPackageManagers() PackageManagers {
packageManagers := PackageManagers{
NPM: false,
Yarn: false,
}
_, err := exec.LookPath("npm")
if err == nil {
packageManagers.NPM = true
}
_, err = exec.LookPath("yarn")
if err == nil {
packageManagers.Yarn = true
}
return packageManagers
}

17
renovate.json Normal file
View File

@@ -0,0 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base", "group:allNonMajor"],
"major": {
"dependencyDashboardApproval": true
},
"schedule": ["every weekend"],
"lockFileMaintenance": {
"enabled": true
},
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"matchCurrentVersion": "!/^0/"
}
]
}

152
src/commands/build.ts Normal file
View File

@@ -0,0 +1,152 @@
import esbuild from 'esbuild';
import { getConfig } from '../utilities/getConfig';
import p from 'node:path';
import { glob } from 'glob';
import { configDotenv } from 'dotenv';
import assert from 'node:assert';
import defaultEsbuild from '../utilities/defaultEsbuildConfig';
import { require } from '../utilities/require';
import { pathExists, pathExistsSync } from 'find-up';
import { mkdir, writeFile, readFile } from 'fs/promises';
import * as Preprocessor from '../utilities/preprocessor';
import { bold, magentaBright } from 'colorette';
import { parseTsConfig } from '../utilities/parseTsconfig';
const VALID_EXTENSIONS = ['.ts', '.js' ];
type BuildOptions = {
/**
* Define __VERSION__
* This option is a quick switch to defining the __VERSION__ constant which will be a string of the version provided in
* cwd's package.json
*/
defineVersion?: boolean;
/**
* default = esm
*/
format?: 'cjs' | 'esm';
/**
* https://esbuild.github.io/api/#drop-labels
**/
dropLabels?: string[];
/**
* https://esbuild.github.io/api/#define
**/
define?: Record<string, string>;
tsconfig?: string;
/**
* default = 'development'
*/
mode: 'production' | 'development';
/**
* will search for env file. If none exists,
* default to .env.
*/
env?: string;
};
const CommandHandlerPlugin = (buildConfig: Partial<BuildOptions>, ambientFilePath: string, sernTsConfigPath: string) => {
return {
name: "commandhandler",
setup(build) {
const options = build.initialOptions
const defVersion = () => JSON.stringify(require(p.resolve('package.json')).version);
options.define = {
...buildConfig.define ?? {},
__DEV__: `${buildConfig.mode === 'development'}`,
__PROD__: `${buildConfig.mode === 'production'}`,
__VERSION__: `${buildConfig.defineVersion ? `${defVersion()}` : 'undefined'}`
} ?? {}
Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile);
Preprocessor.writeAmbientFile(ambientFilePath, options.define!, writeFile);
}
} as esbuild.Plugin
}
const resolveBuildConfig = (path: string|undefined, language: string) => {
if(language === 'javascript') {
return path ?? 'jsconfig.json'
}
return path ?? 'tsconfig.json'
}
export async function build(options: Record<string, any>) {
if (!options.supressWarnings) {
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`);
}
const sernConfig = await getConfig();
let buildConfig: BuildOptions;
const buildConfigPath = p.resolve(options.project ?? 'sern.build.js');
const defaultBuildConfig = {
defineVersion: true,
format: options.format ?? 'esm',
mode: options.mode ?? 'development',
dropLabels: [],
tsconfig: resolveBuildConfig(options.tsconfig, sernConfig.language),
env: options.env ?? '.env',
include: []
};
if (pathExistsSync(buildConfigPath)) {
//throwable, buildConfigPath may not exist
buildConfig = { ...defaultBuildConfig, ...(await import('file:///' + buildConfigPath)).default };
} else {
buildConfig = defaultBuildConfig;
console.log('No build config found, defaulting');
}
configDotenv({ path: buildConfig.env });
if (process.env.NODE_ENV) {
buildConfig.mode = process.env.NODE_ENV as 'production' | 'development';
console.log(magentaBright('NODE_ENV:'), 'Found NODE_ENV variable, setting `mode` to this.');
}
assert(buildConfig.mode === 'development' || buildConfig.mode === 'production', 'Mode is not `production` or `development`');
try {
let config = await parseTsConfig(buildConfig.tsconfig!);
config?.extends && console.warn("Extend the generated tsconfig")
} catch(e) {
console.error("no tsconfig / jsconfig found");
console.error(`Please create a ${sernConfig.language === 'javascript' ? 'jsconfig.json' : 'tsconfig.json' }`);
console.error('It should have at least extend the generated one sern makes.\n \
{ "extends": "./.sern/tsconfig.json" }');
throw e;
}
console.log(bold('Building with:'));
console.log(' ', magentaBright('defineVersion'), buildConfig.defineVersion);
console.log(' ', magentaBright('format'), buildConfig.format);
console.log(' ', magentaBright('mode'), buildConfig.mode);
console.log(' ', magentaBright('tsconfig'), buildConfig.tsconfig);
console.log(' ', magentaBright('env'), buildConfig.env);
const sernDir = p.resolve('.sern'),
[ambientFilePath, sernTsConfigPath, genDir] =
['ambient.d.ts', 'tsconfig.json', 'generated'].map(f => p.resolve(sernDir, f));
if (!(await pathExists(genDir))) {
console.log('Making .sern/generated dir, does not exist');
await mkdir(genDir, { recursive: true });
}
const entryPoints = await glob(`src/**/*{${VALID_EXTENSIONS.join(',')}}`,{
ignore: {
ignored: (p) => p.name.endsWith('.d.ts'),
}
});
//https://esbuild.github.io/content-types/#tsconfig-json
const ctx = await esbuild.context({
entryPoints,
plugins: [CommandHandlerPlugin(buildConfig, ambientFilePath, sernTsConfigPath)],
...defaultEsbuild(buildConfig.format!, buildConfig.tsconfig),
dropLabels: [buildConfig.mode === 'production' ? '__DEV__' : '__PROD__', ...buildConfig.dropLabels!],
});
await ctx.rebuild()
if(options.watch) {
await ctx.watch()
} else {
await ctx.dispose()
}
}

View File

@@ -0,0 +1,60 @@
import * as Rest from '../rest.js'
import assert from 'node:assert'
import dotenv from 'dotenv'
import ora from 'ora';
import type { CommandData, GuildId } from '../utilities/types.js';
import { readFileSync, writeFile } from 'node:fs'
import { resolve } from 'node:path'
import prompts from 'prompts';
const getConfirmation = (args: Record<string,any> ) => {
if(args.yes) {
return args.yes
} else {
return prompts({
type: 'confirm',
name: 'confirmation',
message: 'Are you sure you want to delete ALL your application commands?',
initial: true
}, { onCancel: () => (console.log("Cancelled operation ( ̄┰ ̄*)"), process.exit(1)) })
.then(response => response.confirmation);
}
}
export async function commandClear(args: Record<string,any>) {
dotenv.configDotenv({ path: args.env || resolve('.env') })
const token = process.env.token || process.env.DISCORD_TOKEN;
assert(token, 'Could not find a token for this bot in .env or commandline. Do you have DISCORD_TOKEN in env?');
const confirmation = await getConfirmation(args);
if (confirmation) {
const spin = ora({
text: `Deleting ALL application commands...`,
spinner: 'aesthetic',
}).start();
const rest = await Rest.create(token);
let guildCommands: Record<GuildId, CommandData[]>
try {
guildCommands = JSON.parse(readFileSync('.sern/command-data-remote.json', 'utf-8'))
await rest.updateGlobal([]);
delete guildCommands.global
for (const guildId in guildCommands) {
await rest.putGuildCommands(guildId, []);
}
writeFile('.sern/command-data-remote.json', "{}", (err) => {
if(err) {
spin.fail("Error happened while writing to json:");
console.error(err)
process.exit(1)
}
})
spin.succeed();
} catch(e) {
spin.fail("Something went wrong. ");
throw e;
}
} else {
console.log('Operation canceled. ( ̄┰ ̄*)');
}
}

12
src/commands/extra.ts Normal file
View File

@@ -0,0 +1,12 @@
import prompt from 'prompts';
import { extraPrompt } from '../prompts/extra.js';
import { create } from '../utilities/create.js';
export async function extra() {
const extra = await prompt([extraPrompt]);
if (Object.keys(extra).length < 1) process.exit(1);
const lang = extra.extra.includes('typescript') ? 'TS' : 'JS';
await create(extra.extra.split('-')[0], lang, process.cwd(), true);
}

13
src/commands/help.ts Normal file
View File

@@ -0,0 +1,13 @@
import { cyanBright, green, magentaBright } from 'colorette';
export const help = `
___ ___ _ __ _ __
/ __|/ _ \\ '__| '_ \\
\\__ \\ __/ | | | | |
|___/\\___|_| |_| |_|
Welcome!
If you're new to ${cyanBright('sern')}, run ${magentaBright('npm create @sern/bot')} for an interactive setup to your new bot project!
${green(`If you have any ideas, suggestions, bug reports, kindly join our support server: https://sern.dev/discord`)}`;

123
src/commands/init.ts Normal file
View File

@@ -0,0 +1,123 @@
import { greenBright, redBright, underline, yellowBright } from 'colorette';
import { execa } from 'execa';
import { findUp } from 'find-up';
import ora from 'ora';
import prompt from 'prompts';
import { cmds_dir, gitInit, lang, main_dir, name, skip_install_dep, which_manager } from '../prompts/init.js';
import { writeFile } from 'fs/promises';
import { editDirs, editMain } from '../utilities/edits.js';
import { cloneRepo, installDeps } from '../utilities/install.js';
import { npm } from '../utilities/npm.js';
import type { PackageManagerChoice } from '../utilities/types.js';
/** @deprecated Use npm create instead */
export async function init(flags: Flags) {
console.log(`${yellowBright('[WARN]:')} This command is deprecated, use ${greenBright('npm create @sern/bot')} instead`);
let data: PromptData;
let git_init = true; // the default;
let pm = flags.sync ? undefined : flags.y ? 'npm' : await npm();
if (flags.y) {
const projectName = await prompt([name]);
git_init = true;
data = {
name: projectName.name,
lang: 'typescript',
main_dir: 'src',
cmds_dir: 'commands',
};
} else if (flags.sync) {
data = (await prompt([lang, main_dir, cmds_dir])) as PromptData;
} else {
data = (await prompt([name, lang, main_dir, cmds_dir])) as PromptData;
git_init = (await prompt([gitInit])).gitinit;
}
const language = data.lang === 'javascript-esm' ? 'javascript' : data.lang;
const config = {
language,
paths: {
base: data.main_dir,
commands: data.cmds_dir,
},
};
const file = JSON.stringify(config, null, 2);
const requiredData = flags.sync !== undefined ? 3 : 4;
const receivedData = Object.keys(data).length;
const incompleteDataCondition = receivedData < requiredData;
if (incompleteDataCondition) process.exit(1);
if (!flags.sync) await cloneRepo(data.lang, data.name);
const pkg = await findUp('package.json', {
cwd: process.cwd() + '/' + data.name,
});
if (!pkg) throw new Error('No package.json found!');
await writeFile(pkg.replace('package.json', 'sern.config.json'), file);
if (flags.sync) {
console.log('Project was successfully synced!');
process.exit(0);
}
git_init ? await git(data) : console.log(`Skipping git init...\n`);
let choice: PackageManagerChoice;
if (pm === 'both') {
choice = (await prompt([which_manager])).manager;
} else {
choice = ((await prompt([skip_install_dep])).skip_install_dep ? pm : 'skip') as PackageManagerChoice;
}
await installDeps(choice, data.name);
await editMain(data.name);
await editDirs(data.main_dir, data.cmds_dir, data.name, data.lang);
console.log(`${greenBright('Success, project was initialised!')}`);
process.exit(0);
}
/** It initializes git */
async function git(data: Data) {
const spin = ora({
text: 'Initializing git...',
spinner: 'aesthetic',
}).start();
try {
await execa('git', ['init', data.name]);
await wait(300);
spin.succeed('Git initialized!');
} catch (error) {
spin.fail(`${redBright('Failed')} to initialize git!\nTry to install it at ${underline('https://git-scm.com')}\nSkipping for now.`);
}
}
/** Wait for a specified number of milliseconds, then return a promise that resolves to undefined. */
async function wait(ms: number) {
const wait = (await import('util')).promisify(setTimeout);
return wait(ms);
}
interface Data {
name: string;
}
interface Flags {
y: boolean;
sync: boolean;
}
interface PromptData {
name: string;
lang: 'typescript' | 'javascript' | 'javascript-esm';
main_dir: string;
cmds_dir: string;
}

69
src/commands/list.ts Normal file
View File

@@ -0,0 +1,69 @@
import { blueBright, bold, cyanBright, greenBright, italic, magentaBright, underline } from 'colorette';
import { getSern } from '../utilities/getSern';
import { readFileSync } from 'node:fs';
import type { CommandData, GuildId } from '../utilities/types';
export function list() {
const files = getSern();
if (!files.includes('command-data-remote.json')) {
console.error(`No commands found\nPlease run ${cyanBright('sern commands publish')} to publish your commands`);
process.exit(1);
}
const commands: Record<GuildId, CommandData[]> = JSON.parse(readFileSync('.sern/command-data-remote.json', 'utf-8'));
const globalCommands = commands.global;
delete commands.global;
if(globalCommands) {
console.log(bold('Global Commands'));
for (const command of globalCommands) log(command);
}
console.log('\t');
for (const guildId in commands) {
const guildCommands = commands[guildId];
console.log(`${bold('Guild Commands')} [${underline(cyanBright(guildId))}]`);
for (const command of guildCommands) log(command);
}
}
const AppCommandsType: Record<number, string> = {
1: magentaBright('Slash'),
2: magentaBright('User'),
3: magentaBright('Message'),
};
const AppCommandOptionType: Record<number, string> = {
1: magentaBright('SubCommand'),
2: magentaBright('SubCommand Group'),
3: magentaBright('String'),
4: magentaBright('Integer'),
5: magentaBright('Boolean'),
6: magentaBright('User'),
7: magentaBright('Channel'),
8: magentaBright('Role'),
9: magentaBright('Mentionable'),
10: magentaBright('Number'),
11: magentaBright('Attachment'),
};
function log(command: CommandData) {
console.log(clean(`\t${cyanBright(command.name)} ${italic(command.description)} (${greenBright(command.id)})`));
console.log(`\t Type: ${AppCommandsType[command.type]}`);
if (command.options) {
console.log(`\t Options:`);
for (const option of command.options) {
console.log(`\t ${blueBright(option.name)}: ${AppCommandOptionType[option.type]}`);
if (option.options) {
console.log(`\t Options:`);
for (const subOption of option.options) {
console.log(`\t ${cyanBright(subOption.name)}: ${AppCommandOptionType[subOption.type]}`);
}
}
}
}
}
const clean = (str: string) => str.split(' ').filter(Boolean).join(' ');

104
src/commands/plugins.ts Normal file
View File

@@ -0,0 +1,104 @@
import { greenBright } from 'colorette';
import fs from 'fs';
import prompt from 'prompts';
import { fetch } from 'undici';
import { fromCwd } from '../utilities/fromCwd.js';
import esbuild from 'esbuild';
import { getConfig } from '../utilities/getConfig.js';
import type { PromptObject } from 'prompts';
import { resolve } from 'path';
import { require } from '../utilities/require.js';
interface PluginData {
description: string;
hash: string;
name: string;
author: string[];
link: string;
example: string;
version: string;
}
const link = `https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/pluginlist.json`;
export async function fetchPluginData(): Promise<PluginData[]> {
return fetch(link)
.then(res => res.json())
.then(data => (data as PluginData[]))
.catch(() => [])
}
export function pluginsQ(choices: PluginData[]): PromptObject[] {
return [{
name: 'list',
type: 'autocompleteMultiselect',
message: 'What plugins do you want to install?',
choices: choices.map(e => ({ title: e.name, value: e })),
min: 1,
}];
}
/**
* Installs plugins to project
*/
export async function plugins(args: string[], opts: Record<string, unknown>) {
const plugins = await fetchPluginData();
let selectedPlugins : PluginData[];
if(args.length) {
const normalizedArgs = args.map(str => str.toLowerCase())
console.log("Trying to find plugins to install...");
const results = plugins.reduce((acc, cur) => {
if(normalizedArgs.includes(cur.name.toLowerCase())) {
return [...acc, cur]
}
return acc;
}, [] as PluginData[]);
selectedPlugins = results;
} else {
selectedPlugins = (await prompt(pluginsQ(plugins))).list;
}
if (!selectedPlugins.length) {
process.exit(1);
}
const { language } = await getConfig();
for await (const plgData of selectedPlugins) {
const pluginText = await download(plgData.link);
const dir = fromCwd('/src/plugins');
const linkNoExtension = `${process.cwd()}/src/plugins/${plgData.name}`;
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
if (language === 'typescript') {
fs.writeFileSync(linkNoExtension + '.ts', pluginText);
} else {
const { type = undefined } = require(resolve('package.json'));
const format = type === undefined || type === 'cjs' ? 'cjs' : 'esm';
const transformResult = await esbuild.transform(pluginText, {
target: 'node18',
format,
loader: 'ts',
banner: `/**\n Partial information: ${plgData.description}\n @author ${plgData.author}\n @example${plgData.example}*/`,
});
if (transformResult.warnings.length > 0) {
console.log(transformResult.warnings.map((msg) => msg.text).join('\n'));
}
console.warn('transforming plugins with js strips comments');
console.warn('We provided some minimal information at top of file, or view the documentation for this plugin here:');
console.warn(plgData.link);
fs.writeFileSync(linkNoExtension + '.js', transformResult.code);
}
}
const pluginNames = selectedPlugins.map((data) => {
return 'Installed ' + data.name + ' ' + 'from ' + data.author.join(',');
});
console.log(`Successfully downloaded plugin(s):\n${greenBright(pluginNames.join('\n'))}`);
}
async function download(url: string) {
const data = await fetch(url, { method: 'GET' })
.then((res) => res.text())
.catch(() => null);
if (!data) throw new Error('Download failed! Kindly contact developers');
return data;
}

38
src/commands/publish.ts Normal file
View File

@@ -0,0 +1,38 @@
import { magentaBright } from 'colorette';
import { getConfig } from '../utilities/getConfig';
import { fork } from 'node:child_process';
import { fileURLToPath } from 'url';
export async function publish(commandDir: string | undefined, args: Partial<PublishArgs>) {
if (!args.suppressWarnings) {
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`);
}
const config = await getConfig();
// pass in args into the command.
const rootPath = new URL('../', import.meta.url),
publishScript = new URL('../dist/create-publish.js', rootPath);
// assign args.import to empty array if non existent
args.import ??= [];
commandDir && console.info('Publishing with override path: ', commandDir);
const isBunOrPnpm = rootPath.pathname.includes('.bun') || rootPath.pathname.includes('.pnpm');
const dotenvLocation = new URL(`${isBunOrPnpm ? '../../' : '../'}node_modules/dotenv/config.js`, rootPath),
esmLoader = new URL(`${isBunOrPnpm ? '../../' : '../'}node_modules/@esbuild-kit/esm-loader/dist/index.js`, rootPath);
// We dynamically load the create-publish script in a child process so that we can pass the special
// loader flag to require typescript files
const command = fork(fileURLToPath(publishScript), [], {
execArgv: ['--loader', esmLoader.toString(), '-r', fileURLToPath(dotenvLocation), '--no-warnings'],
});
// send paths object so we dont have to recalculate it in script
command.send({ config, preloads: args.import, commandDir });
}
interface PublishArgs {
suppressWarnings: boolean;
import: string[];
token: string;
applicationId: string;
}

17
src/create-publish.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
export interface PublishableData {
name: string;
type: number;
description: string;
absPath: string;
options: Typeable[];
}
export interface Typeable {
type: number;
}
export interface Config {
guildIds?: string[];
}
export interface PublishableModule {
data: PublishableData;
config: Config;
}

265
src/create-publish.mts Normal file
View File

@@ -0,0 +1,265 @@
/**
* This file is meant to be run with the esm / cjs esbuild-kit loader to properly import typescript modules
*/
import { readdir, mkdir, writeFile } from 'fs/promises';
import { basename, resolve, posix as pathpsx } from 'node:path';
import { pathExistsSync } from 'find-up';
import assert from 'assert';
import { once } from 'node:events';
import * as Rest from './rest';
import type { SernConfig } from './utilities/getConfig';
import type { PublishableData, PublishableModule, Typeable } from './create-publish.d.ts';
import { cyanBright, greenBright, redBright } from 'colorette';
import { inspect } from 'node:util'
import ora from 'ora';
async function* readPaths(dir: string, shouldDebug: boolean): AsyncGenerator<string> {
const files = await readdir(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = pathpsx.join(dir, file.name);
if (file.isDirectory()) {
if (!file.name.startsWith('!')) {
yield* readPaths(fullPath, shouldDebug);
}
} else if (!file.name.startsWith('!')) {
yield "file:///"+resolve(fullPath);
}
}
}
// recieved sern config
const [{ config, preloads, commandDir }] = await once(process, 'message'),
{ paths } = config as SernConfig;
for (const preload of preloads) {
console.log("preloading: ", preload);
await import('file:///' + resolve(preload));
}
const commandsPath = commandDir ? resolve(commandDir) : resolve(paths.base, paths.commands);
const filePaths = readPaths(commandsPath, true);
const modules = [];
const PUBLISHABLE = 0b1110;
for await (const absPath of filePaths) {
let mod = await import(absPath);
let commandModule = mod.default;
let config = mod.config;
if ('default' in commandModule) {
commandModule = commandModule.default;
}
if ((PUBLISHABLE & commandModule.type) != 0) {
// assign defaults
const filename = basename(absPath);
const filenameNoExtension = filename.substring(0, filename.lastIndexOf('.'));
commandModule.name ??= filenameNoExtension;
commandModule.description ??= '';
commandModule.meta = {
absPath
}
commandModule.absPath = absPath;
if (typeof config === 'function') {
config = config(absPath, commandModule);
}
modules.push({ commandModule, config });
}
}
const cacheDir = resolve('./.sern');
if (!pathExistsSync(cacheDir)) {
// TODO: add this in verbose flag
// console.log('Making .sern directory: ', cacheDir);
await mkdir(cacheDir);
}
const optionsTransformer = (ops: Array<Typeable>) => {
return ops.map((el) => {
if ('command' in el) {
const { command, ...rest } = el;
return rest;
}
return el;
});
};
const intoApplicationType = (type: number) => {
if (type === 3) {
return 1;
}
return Math.log2(type);
};
const makeDescription = (type: number, desc: string) => {
if (type !== 1 && desc !== '') {
console.warn('Found context menu that has non empty description field. Implictly publishing with empty description');
return '';
}
return desc;
};
const serialize = (permissions: unknown) => {
if(typeof permissions === 'bigint' || typeof permissions === 'number') {
return permissions.toString();
}
if(Array.isArray(permissions)) {
return permissions
.reduce((acc, cur) => acc | cur, BigInt(0))
.toString()
}
return null;
}
const makePublishData = ({ commandModule, config }: Record<string, Record<string, unknown>>) => {
const applicationType = intoApplicationType(commandModule.type as number);
return {
data: {
name: commandModule.name as string,
type: applicationType,
description: makeDescription(applicationType, commandModule.description as string),
absPath: commandModule.absPath as string,
options: optionsTransformer((commandModule?.options ?? []) as Typeable[]),
dm_permission: config?.dmPermission ?? false,
default_member_permissions: serialize(config?.defaultMemberPermissions),
//@ts-ignore
integration_types: (config?.integrationTypes ?? ['Guild']).map(
(s: string) => {
if(s === "Guild") {
return "0"
} else if (s == "User") {
return "1"
} else {
throw Error("IntegrationType is not one of Guild (0) or User (1)");
}
}),
//@ts-ignore
contexts: config?.contexts ?? undefined,
name_localizations: commandModule.name_localizations,
description_localizations: commandModule.description_localizations
},
config,
};
};
// We can use these objects to publish to DAPI
const publishableData = modules.map(makePublishData),
token = process.env.token || process.env.DISCORD_TOKEN;
assert(token, 'Could not find a token for this bot in .env or commandline. Do you have DISCORD_TOKEN in env?');
// partition globally published and guilded commands
const [globalCommands, guildedCommands] = publishableData.reduce(
([globals, guilded], module) => {
const isPublishableGlobally = !module.config || !Array.isArray(module.config.guildIds);
if (isPublishableGlobally) {
return [[module, ...globals], guilded];
}
return [globals, [module, ...guilded]];
},
[[], []] as [PublishableModule[], PublishableModule[]]
);
const spin = ora(`Publishing ${cyanBright('Global')} commands`);
globalCommands.length && spin.start();
const rest = await Rest.create(token);
const res = await rest.updateGlobal(globalCommands);
let globalCommandsResponse: unknown;
if (res.ok) {
globalCommands.length && spin.succeed(`All ${cyanBright('Global')} commands published`);
globalCommandsResponse = await res.json();
} else {
spin.fail(`Failed to publish global commands [Code: ${redBright(res.status)}]`);
let err: Error
console.error("Status Text ", res.statusText);
switch(res.status) {
case 400 : {
const validation_errors = await res.json()
console.error('errors:', inspect(validation_errors, { depth: Infinity }));
console.error("Modules with validation errors:"
+ inspect(Object.keys(validation_errors.errors).map(idx => globalCommands[idx as any])))
throw Error("400: Ensure your commands have proper fields and data with nothing left out");
}
case 404 : {
console.error('errors:', inspect(await res.json(), { depth: Infinity }));
throw Error("Forbidden 404. Is you application id and/or token correct?")
}
case 429: {
console.error('errors:', inspect(await res.json(), { depth: Infinity }));
err = Error('Chill out homie, too many requests')
} break;
default: {
console.error('errors:', inspect(await res.json(), { depth: Infinity }));
throw Error(res.status.toString() + " error")
}
}
}
function associateGuildIdsWithData(data: PublishableModule[]): Map<string, PublishableData[]> {
const guildIdMap: Map<string, PublishableData[]> = new Map();
data.forEach((entry) => {
const { data, config } = entry;
const { guildIds } = config || {};
if (guildIds) {
guildIds.forEach((guildId) => {
if (guildIdMap.has(guildId)) {
guildIdMap.get(guildId)?.push(data);
} else {
guildIdMap.set(guildId, [data]);
}
});
}
});
return guildIdMap;
}
const guildCommandMap = associateGuildIdsWithData(guildedCommands);
let guildCommandMapResponse = new Map<string, Record<string, unknown>>();
for (const [guildId, array] of guildCommandMap.entries()) {
const spin = ora(`[${cyanBright(guildId)}] Updating commands for guild`);
spin.start();
const response = await rest.putGuildCommands(guildId, array);
const result = await response.json();
if (response.ok) {
guildCommandMapResponse.set(guildId, result);
spin.succeed(`[${greenBright(guildId)}] Successfully updated commands for guild`);
} else {
spin.fail(`[${redBright(guildId)}] Failed to update commands for guild, Reason: ${result.message}`);
switch(response.status) {
case 400 : {
console.error(inspect(result, { depth: Infinity }))
console.error("Modules with validation errors:"
+ inspect(Object.keys(result.errors).map(idx => array[idx as any])))
throw Error("400: Ensure your commands have proper fields and data and nothing left out");
}
case 404 : {
console.error(inspect(result, { depth: Infinity }))
throw Error("Forbidden 404. Is you application id and/or token correct?")
}
case 429: {
console.error(inspect(result, { depth: Infinity }))
throw Error('Chill out homie, too many requests')
}
}
}
}
const remoteData = {
global: globalCommandsResponse,
...Object.fromEntries(guildCommandMapResponse),
};
await writeFile(resolve(cacheDir, 'command-data-remote.json'), JSON.stringify(remoteData, null, 4), 'utf8');
// TODO: add this in a verbose flag
// console.info('View json output in ' + resolve(cacheDir, 'command-data-remote.json'));
process.exit(0);

67
src/index.ts Normal file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env node
import { Command } from 'commander';
import { yellowBright } from 'colorette';
export const program = new Command();
const importDynamic = async <T extends string>(filename: T) => import(`./commands/${filename}` as const);
declare const __VERSION__: string;
program
.name('sern')
.description(await importDynamic('help.js').then((m) => m.help))
.version(`sern CLI v${__VERSION__}`, '-v, --version')
.exitOverride(() => process.exit(0));
program
.command('init')
.description(`Quickest way to scaffold a new project ${yellowBright('[DEPRECATED]')}`)
.option('-y', 'Finishes setup as default')
.option('-s, --sync', 'Syncs the project and generates sern.config.json')
.action(async (...args) => importDynamic('init.js').then((m) => m.init(...args)));
program
.command('plugins')
.description('Install plugins from https://github.com/sern-handler/awesome-plugins')
.argument('[names...]', 'Names of plugins to install')
.action((...args) => importDynamic('plugins.js').then((m) => m.plugins(...args)));
program
.command('extra')
.description('Easy way to add extra things in your sern project')
.action((...args) => importDynamic('extra.js').then((m) => m.extra(...args)));
program //
.command('commands')
.description('Defacto way to manage your slash commands')
.addCommand(
new Command('publish')
.description('New way to manage your slash commands')
.option('-W --suppress-warnings', 'suppress experimental warning')
.option('-i, --import [scriptPath...]', 'Prerequire a script to load into publisher')
.option('-t, --token [token]')
.argument('[path]', 'path with respect to current working directory that will locate all published files')
.action(async (...args) => importDynamic('publish.js').then((m) => m.publish(...args)))
).addCommand(
new Command('list') //
.description('List all slash commands')
.action(async (...args) => importDynamic('list.js').then((m) => m.list(...args))))
.addCommand(
new Command('clear')
.description('Clear and reset commands-data-remote.json and the api')
.option('-y, --yes', "Say yes to all prompts")
.option('-e, --env [path]', "Supply a path to a .env")
.action(async (...args) => importDynamic('command-clear.js').then((m) => m.commandClear(...args))));
program
.command('build')
.description('Build your bot')
.option('-f --format [fmt]', 'The module system of your application. `cjs` or `esm`', 'esm')
.option('-m --mode [mode]', 'the mode for sern to build in. `production` or `development`', 'development')
.option('-w --watch')
.option('-W --suppress-warnings', 'suppress experimental warning')
.option('-p --project [filePath]', 'build with the provided sern.build file')
.option('-e --env', 'path to .env file')
.option('--tsconfig [filePath]', 'Use this tsconfig')
.action(async (...args) => importDynamic('build.js').then((m) => m.build(...args)));
program.parse();

20
src/prompts/extra.ts Normal file
View File

@@ -0,0 +1,20 @@
import type { PromptObject } from 'prompts';
export const extraPrompt: PromptObject = {
message: 'What extra feature do you want to add?',
name: 'extra',
type: 'select',
choices: [
{
title: 'Dockerfile (TypeScript)',
description: 'Dockerfile for TypeScript',
value: 'Dockerfile-typescript',
selected: true,
},
{
title: 'Dockerfile (JavaScript)',
description: 'Dockerfile for JavaScript',
value: 'Dockerfile-javascript',
},
],
};

92
src/prompts/init.ts Normal file
View File

@@ -0,0 +1,92 @@
import { blueBright } from 'colorette';
import type { PromptObject } from 'prompts';
export const lang: PromptObject = {
message: 'What language do you want the project to be in?',
name: 'lang',
type: 'select',
choices: [
{
title: 'JavaScript',
description: 'JS',
value: 'javascript',
},
{
title: 'JavaScript (ESM)',
description: 'JS',
value: 'javascript-esm',
},
{
title: 'TypeScript',
description: 'TS - (Recommended)',
value: 'typescript',
},
],
};
export const main_dir: PromptObject = {
message: 'What is the main directory of your project?',
name: 'main_dir',
type: 'text',
initial: 'src',
};
export const cmds_dir: PromptObject = {
message: 'What is the directory of your commands?',
name: 'cmds_dir',
type: 'text',
initial: 'commands',
validate: (dir: string) => (dir === 'src' ? 'You can not use src as a directory' : true),
};
export const npmInit: PromptObject = {
name: 'npm_init',
type: 'confirm',
message: `Do you want ${blueBright('me')} to initialize npm?`,
initial: true,
};
export const gitInit: PromptObject = {
name: 'gitinit',
type: 'confirm',
message: `Do you want to ${blueBright('me')} to initialize git?`,
initial: true,
};
export const which_manager: PromptObject = {
message: `Which manager do you want to use?`,
name: 'manager',
type: 'select',
choices: [
{
title: 'NPM',
description: 'Default Package Manager',
selected: true,
value: 'npm',
},
{
title: 'Yarn',
description: 'Yarn Package Manager',
value: 'yarn',
},
{
title: 'Skip',
description: 'Skip selection',
value: 'skip',
},
],
};
export const skip_install_dep: PromptObject = {
name: 'skip_install_dep',
type: 'confirm',
message: `Do you want ${blueBright('me')} to install dependencies?`,
initial: false,
};
export const name: PromptObject = {
message: 'What is your project name?',
name: 'name',
type: 'text',
validate: (name: string) => (name.match('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$') ? true : 'Invalid name'),
};

51
src/rest.ts Normal file
View File

@@ -0,0 +1,51 @@
import type { PublishableModule } from './create-publish.d.ts';
const baseURL = new URL('https://discord.com/api/v10/applications/');
const excludedKeys = new Set(['command', 'absPath']);
const publishablesIntoJson = (ps: PublishableModule[]) => {
const s = JSON.stringify(
ps.map((module) => module.data),
(key, value) => (excludedKeys.has(key) ? undefined : value), 4);
return s;
}
export const create = async (token: string) => {
const headers = {
Authorization: 'Bot ' + token,
'Content-Type': 'application/json',
};
let me;
let appid: string;
try {
me = await fetch(new URL('@me', baseURL), { headers }).then(res => res.json());
appid = me.id;
} catch(e) {
console.log("Something went wrong while trying to fetch your application:");
throw e;
}
const globalURL = new URL(`${appid}/commands`, baseURL);
return {
updateGlobal: (commands: PublishableModule[]) =>
fetch(globalURL, {
method: 'PUT',
body: publishablesIntoJson(commands),
headers,
}),
getGuildCommands: (id: string) => {
const guildCommandURL = new URL(`${appid}/guilds/${id}/commands`, baseURL);
return fetch(guildCommandURL, { headers });
},
putGuildCommands: (guildId: string, guildCommand: unknown) => {
const guildCommandURL = new URL(`${appid}/guilds/${guildId}/commands`, baseURL);
return fetch(guildCommandURL, {
method: 'PUT',
body: JSON.stringify(guildCommand),
headers,
});
},
};
};

16
src/types/config.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
export interface sernConfig {
language: 'typescript' | 'javascript';
paths: {
base: string;
commands: string;
};
buildPath: string;
rest?: Record<string, Record<string, unknown>>;
}
export interface TheoreticalEnv {
DISCORD_TOKEN: string;
APPLICATION_ID?: string;
MODE: 'production' | 'environment';
[name: string]: string;
}

51
src/utilities/create.ts Normal file
View File

@@ -0,0 +1,51 @@
import { mkdir, readFile, writeFile } from 'fs/promises';
import { dirname, resolve } from 'node:path';
import { fileURLToPath, URL } from 'url';
const root = new URL('../../', import.meta.url);
const templates = new URL('./templates/', root);
const extraURL = new URL('./extra/', templates);
const extraFolder = fileURLToPath(extraURL);
/**
* It creates a file with the name `name.lang.sern` in the `location` directory
* @param name - The name of the file.
* @param lang - The language you want to use.
* @param location - The location of the file to be created.
* @param no_ext - If true, the file will be created without an extension.
*/
export async function create(name: string, lang: string, location: string, no_ext: boolean) {
const file = `${name}.${lang}.sern`;
const target = no_ext ? `${location}/${name}` : `${location}/${name}.${lang}`;
return createFile(file, target);
}
/**
* It reads a file from a template folder, and writes it to a target folder
* @param template - The name of the file to be created.
* @param target - The location of the file to be created.
*/
async function createFile(template: string, target: string) {
const location = `${extraFolder}${template}`;
const file = await readFile(location, 'utf8');
await writeFileRecursive(target, file);
}
/**
* It creates a directory recursively, then writes a file to it
* @param target - The path to the file you want to write to.
* @param data - The data to write to the file.
* @returns A promise that resolves to the result of the writeFile function.
*/
async function writeFileRecursive(target: string, data: string) {
const resolvedTarget = resolve(target);
const dir = dirname(resolvedTarget);
await mkdir(dir, { recursive: true });
return writeFile(resolvedTarget, data);
}

View File

@@ -0,0 +1,11 @@
import type esbuild from 'esbuild';
import { resolve } from 'path';
export default (format: 'cjs' | 'esm', tsconfig: string|undefined, outdir='dist') => ({
platform: 'node',
format,
tsconfig,
logLevel: 'info',
minify: false,
outdir: resolve(outdir),
} satisfies esbuild.BuildOptions);

83
src/utilities/edits.ts Normal file
View File

@@ -0,0 +1,83 @@
import { findUp } from 'find-up';
import { readFile, rename, writeFile } from 'node:fs/promises';
import { fromCwd } from './fromCwd.js';
import { parseTsConfig } from './parseTsconfig.js';
/**
* It takes a string, finds the package.json file in the directory of the string, and changes the name
* of the package.json file to the string.
* @param name - The name of the project.
*/
export async function editMain(name: string) {
const pjLocation = (await findUp('package.json', {
cwd: fromCwd('/' + name),
})) as string;
const output = JSON.parse(await readFile(pjLocation, 'utf8'));
if (!output) throw new Error("Can't read your package.json.");
output.name = name;
return writeFile(pjLocation, JSON.stringify(output, null, 2));
}
/**
* It renames the `src` and `commands` directories, and edits the `index.ts` file to reflect the
* changes
* @param srcName - The name of the folder that will contain your main files.
* @param cmds_dirName - The name of the directory where your commands will be stored.
* @param name - The name of the folder you want to edit.
* @param lang - The language you want to use.
*/
export async function editDirs(
srcName: string,
cmds_dirName: string,
name: string,
lang: 'javascript' | 'typescript' | 'javascript-esm' = 'typescript'
) {
const path = (await findUp('src', {
cwd: fromCwd(name),
type: 'directory',
})) as string;
const ext = lang === 'typescript' ? 'ts' : 'js';
const newMainDir = path?.replace('src', srcName);
await rename(path, newMainDir);
const cmdsPath = (await findUp('commands', {
cwd: fromCwd(name, srcName),
type: 'directory',
})) as string;
const index = (await findUp(`index.${ext}`, {
cwd: fromCwd(name, srcName),
})) as string;
const newCmdsPath = cmdsPath?.replace('commands', cmds_dirName);
await rename(cmdsPath, newCmdsPath);
const tsconfig = await findUp('tsconfig.json', {
cwd: process.cwd() + '/' + name,
});
if (tsconfig) {
const output = await parseTsConfig(tsconfig);
if (!output) throw new Error("Can't read your tsconfig.json.");
if (!output.compilerOptions) throw new Error("Can't find compilerOptions in your tsconfig.json.");
output.compilerOptions.rootDir = srcName;
// This will strip comments/trailing commas from the tsconfig.json file
await writeFile(tsconfig, JSON.stringify(output, null, 2));
}
const output = await readFile(index, 'utf8');
const oldfold = ext === 'ts' ? 'dist' : 'src';
const newfold = ext === 'ts' ? 'dist' : srcName;
const regex = new RegExp(`commands: '${oldfold}/commands'`);
const edit = output.replace(regex, `commands: '${newfold}/${cmds_dirName}'`);
return writeFile(index, edit);
}

5
src/utilities/fromCwd.ts Normal file
View File

@@ -0,0 +1,5 @@
import path from 'path';
export function fromCwd(...dir: string[]) {
return path.join(...[process.cwd(), ...dir]);
}

View File

@@ -0,0 +1,27 @@
import { findUp } from 'find-up';
import { readFile } from 'node:fs/promises';
import assert from 'node:assert';
export async function getConfig(): Promise<SernConfig> {
const sernLocation = await findUp('sern.config.json');
assert(sernLocation, "Can't find sern.config.json");
const output = JSON.parse(await readFile(sernLocation, 'utf8')) as SernConfig;
assert(output, "Can't read your sern.config.json.");
return output;
}
export interface SernConfig {
language: 'typescript' | 'javascript';
defaultPrefix?: string;
paths: {
base: string;
commands: string;
events?: string;
};
build?: {
}
}

17
src/utilities/getSern.ts Normal file
View File

@@ -0,0 +1,17 @@
import { readdirSync } from 'node:fs';
import { fromCwd } from './fromCwd';
import { redBright, cyanBright } from 'colorette';
export function getSern() {
let files: string[] = [];
try {
const sern = fromCwd('.sern');
files = readdirSync(sern);
} catch (error) {
console.error(`${redBright('Error:')} Could not locate ${cyanBright('.sern')} directory`);
process.exit(1);
} finally {
return files;
}
}

84
src/utilities/install.ts Normal file
View File

@@ -0,0 +1,84 @@
import { redBright } from 'colorette';
import { execa } from 'execa';
import { findUp } from 'find-up';
import fs from 'fs';
import { readFile } from 'fs/promises';
import ora from 'ora';
import path from 'path';
import type { PackageManagerChoice } from './types';
/**
* It installs dependencies from a package.json file
* @param choice - The package manager to use.
* @param name - The name of the project
*/
export async function installDeps(choice: PackageManagerChoice, name: string) {
const pkg = await findUp('package.json', {
cwd: process.cwd() + '/' + name,
});
if (!pkg) throw new Error('No package.json found!');
const output = JSON.parse(await readFile(pkg, 'utf8'));
if (!output) throw new Error("Can't read file.");
const deps = output.dependencies;
if (!deps) throw new Error("Can't find dependencies.");
if (choice === 'skip') {
return console.log('Dependency installation skipped...');
}
const spin = ora({
text: `Installing dependencies...`,
spinner: 'aesthetic',
}).start();
const result = await execa(choice, ['install'], {
cwd: process.cwd() + '/' + name,
}).catch(() => null);
if (!result || result?.failed) {
spin.fail(`${redBright('Failed')} to install dependencies!`);
process.exit(1);
} else spin.succeed(`Dependencies installed!`);
}
/**
* Clone the repo, copy the files from the repo to the new project directory, and delete the repo
* @param lang - The language of the template
* @param name - The name of the project
*/
export async function cloneRepo(lang: string, name: string) {
try {
await execa('git', ['clone', `https://github.com/sern-handler/templates.git`]);
copyRecursiveSync(`templates/templates/${lang}`, name);
fs.rmSync(`templates/`, { recursive: true, force: true });
} catch (error) {
console.log(`${redBright('✖ Failed')} to clone github templates repo. Install git and try again!`);
process.exit(1);
}
}
/**
* If the source is a directory, create the destination directory and then recursively copy the
* contents of the source directory to the destination directory. If the source is not a directory,
* copy the source file to the destination file
* @param src - The source path.
* @param dest - The destination folder where the files will be copied to.
*/
export function copyRecursiveSync(src: string, dest: string) {
const exists = fs.existsSync(src);
const stats = (exists && fs.statSync(src)) as fs.Stats;
const isDirectory = exists && stats.isDirectory();
if (isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function (childItemName) {
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
});
} else {
fs.copyFileSync(src, dest);
}
}

25
src/utilities/npm.ts Normal file
View File

@@ -0,0 +1,25 @@
import { execa } from 'execa';
/**
* It checks if you have npm or yarn installed, and returns a string based on the result
* @returns A promise that resolves to a string.
*/
export async function npm() {
const npm = await execa('npm', ['-v']).catch(() => null);
const npm_version = npm?.stdout;
const yarn = await execa('yarn', ['-v']).catch(() => null);
const yarn_version = yarn?.stdout;
if (npm_version && !yarn_version) {
return 'npm';
}
if (!npm_version && yarn_version) {
return 'yarn';
}
if (npm_version && yarn_version) {
return 'both';
}
}

View File

@@ -0,0 +1,50 @@
import { resolve } from 'node:path';
import { readFile } from 'node:fs/promises';
interface CompilerOptions {
target: string;
module: string;
lib: string[];
allowJs: boolean;
checkJs: boolean;
jsx: string;
declaration: boolean;
sourceMap: boolean;
outDir: string;
rootDir: string;
strict: boolean;
esModuleInterop: boolean;
forceConsistentCasingInFileNames: boolean;
noEmit: boolean;
importHelpers: boolean;
isolatedModules: boolean;
moduleResolution: string;
resolveJsonModule: boolean;
noEmitHelpers: boolean;
}
interface TsConfig {
compilerOptions: CompilerOptions;
files: string[];
include: string[];
exclude: string[];
extends: string;
}
const cleanJson = (json: string) =>
json
.replace(/\/\/.*$/gm, '')
.replace(/\/\*[\s\S]*?\*\//gm, '')
.replace(/,\s*([}\]])/g, '$1');
export const parseTsConfig = async (path: string) => {
const absPath = resolve(path);
const fileContent = await readFile(absPath, 'utf-8');
const cleanContent = cleanJson(fileContent);
try {
return JSON.parse(cleanContent) as Partial<TsConfig>;
} catch (e) {
return null;
}
};

View File

@@ -0,0 +1,92 @@
const declareConstType = (name: string, type: string) => String.raw`declare var ${name}: ${type}`;
const processEnvType = (env: NodeJS.ProcessEnv) => {
const entries = Object.keys(env);
const envBuilder = new StringWriter();
for (const key of entries) {
envBuilder.tab()
.tab()
.envField(key);
}
return envBuilder.build();
};
const determineJSONType = (s: string) => {
return typeof JSON.parse(s);
};
type FileWriter = (path: string, content: string, format: BufferEncoding) => Promise<void>;
const writeAmbientFile = async (path: string, define: Record<string, string>, writeFile: FileWriter) => {
const fileContent = new StringWriter();
for (const [k, v] of Object.entries(define)) {
fileContent.varDecl(k, v);
}
fileContent
.println('declare namespace NodeJS {')
.tab()
.println('interface ProcessEnv {')
.envFields(process.env)
.tab()
.println('}')
.println('}');
await writeFile(path, fileContent.build(), 'utf8');
};
const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: FileWriter) => {
//maybe better way to do this
const sernTsConfig = {
compilerOptions: {
//module determines top level await. CJS doesn't have that abliity afaik
module: format === 'cjs' ? 'node' : 'esnext',
moduleResolution: 'node16',
strict: true,
skipLibCheck: true,
target: 'esnext',
rootDirs: ['./generated', '../src'],
},
include: ['./ambient.d.ts', '../src'],
};
await fw(configPath, JSON.stringify(sernTsConfig, null, 3), 'utf8');
};
class StringWriter {
private fileString = '';
tab() {
this.fileString += ' ';
return this;
}
varDecl(name: string, type: string) {
this.fileString += declareConstType(name, determineJSONType(type)) + '\n';
return this;
}
println(data: string) {
this.fileString += data + '\n';
return this;
}
envField(key: string) {
//if env field has space or parens, wrap key in ""
if (/\s|\(|\)/g.test(key)) {
this.fileString += `"${key}": string`;
} else {
this.fileString += key + ':' + 'string';
}
this.fileString += '\n';
return this;
}
envFields(env: NodeJS.ProcessEnv) {
this.fileString += processEnvType(env);
return this;
}
build() {
return this.fileString;
}
}
export { writeAmbientFile, writeTsConfig };

View File

@@ -0,0 +1,41 @@
import { readdir, stat } from 'fs/promises';
import { basename, join, extname } from 'path';
function isSkippable(filename: string) {
//empty string is for non extension files (directories)
const validExtensions = ['.js', '.cjs', '.mts', '.mjs', '.cts', '.ts', ''];
return filename[0] === '!' || !validExtensions.includes(extname(filename));
}
async function deriveFileInfo(dir: string, file: string) {
const fullPath = join(dir, file);
return {
fullPath,
fileStats: await stat(fullPath),
base: basename(file),
};
}
export async function* readPaths(dir: string, shouldDebug: boolean): AsyncGenerator<string> {
try {
const files = await readdir(dir);
for (const file of files) {
const { fullPath, fileStats, base } = await deriveFileInfo(dir, file);
if (fileStats.isDirectory()) {
//Todo: refactor so that i dont repeat myself for files (line 71)
if (isSkippable(base)) {
if (shouldDebug) console.info(`ignored directory: ${fullPath}`);
} else {
yield* readPaths(fullPath, shouldDebug);
}
} else {
if (isSkippable(base)) {
if (shouldDebug) console.info(`ignored: ${fullPath}`);
} else {
yield 'file:///' + fullPath;
}
}
}
} catch (err) {
throw err;
}
}

3
src/utilities/require.ts Normal file
View File

@@ -0,0 +1,3 @@
import { createRequire } from 'node:module';
export const require = createRequire(import.meta.url);

View File

@@ -0,0 +1,92 @@
import { readdir, stat } from 'fs/promises';
import { basename, join, parse, dirname } from 'path';
import assert from 'assert';
/**
* Import any module based on the absolute path.
* This can accept four types of exported modules
* commonjs, javascript :
* ```js
* exports = commandModule({ })
*
* //or
* exports.default = commandModule({ })
* ```
* esm javascript, typescript, and commonjs typescript
* export default commandModule({})
*/
export async function importModule<T>(absPath: string) {
let fileModule = await import(absPath);
let commandModule = fileModule.default;
assert(commandModule , `Found no export @ ${absPath}. Forgot to ignore with "!"? (!${basename(absPath)})?`);
if ('default' in commandModule ) {
commandModule = commandModule.default;
}
return { module: commandModule } as T;
}
export const fmtFileName = (fileName: string) => parse(fileName).name;
export const getfilename = (path: string) => fmtFileName(basename(path));
async function deriveFileInfo(dir: string, file: string) {
const fullPath = join(dir, file);
return { fullPath,
fileStats: await stat(fullPath),
base: basename(file) };
}
function parseWildcardName(filename: string): string | null {
const wildcardMatch = filename.match(/\[(.*?)\]/);
return wildcardMatch ? wildcardMatch[1] : null;
}
export class RouteEntry {
public import_path: string
public filename: string
public parent: string
public wildcardName: string | null;
constructor(public route: string) {
this.import_path = "file:///"+route
this.filename = getfilename(this.route)
this.parent = dirname(this.route);
this.wildcardName = parseWildcardName(this.filename);
}
}
export interface ReadPathsConfig {
dir: string
onDir?: (dir: string) => Promise<boolean>|boolean
onEntry?: (etry: RouteEntry) => RouteEntry
}
export async function* readPaths(
config: ReadPathsConfig
): AsyncGenerator<RouteEntry> {
const files = await readdir(config.dir);
for (const file of files) {
const { fullPath, fileStats } = await deriveFileInfo(config.dir, file);
if (fileStats.isDirectory()) {
if(config.onDir && await config.onDir(fullPath)) {
yield* readPaths({ ...config, dir: fullPath });
} else {
yield* readPaths({ ...config, dir: fullPath });
}
} else {
const nowindowsPath = fullPath.replace(/\\/g, '/');
if(config.onEntry) {
yield config.onEntry(new RouteEntry(nowindowsPath));
} else {
yield new RouteEntry(nowindowsPath);
}
}
}
}

35
src/utilities/types.ts Normal file
View File

@@ -0,0 +1,35 @@
export type PackageManagerChoice = 'skip' | 'npm' | 'yarn';
export type GuildId = string;
export interface CommandData {
id: string;
application_id: string;
version: string;
default_member_permissions?: string;
type: number;
name: string;
name_localizations?: Record<string, string>;
description: string;
description_localizations?: Record<string, string>;
dm_permission: boolean;
guild_id: string;
nsfw: boolean;
options?: OptionData[];
}
interface OptionData {
type: number;
name: string;
name_localizations?: Record<string, string>;
description: string;
description_localizations?: Record<string, string>;
required?: boolean;
choices?: ChoiceData[];
options?: OptionData[];
}
interface ChoiceData {
name: string;
value: string | number;
}

117
templates/cf.js Normal file
View File

@@ -0,0 +1,117 @@
// i got this idea from chooks22
"use modules";
import {
InteractionResponseFlags,
InteractionType,
verifyKey,
InteractionResponseType
} from 'discord-interactions';
//this will import all the modules statically
class JsonResponse extends Response {
constructor(body, init) {
const jsonBody = JSON.stringify(body);
init = init || {
headers: {
'content-type': 'application/json;charset=UTF-8',
},
};
super(jsonBody, init);
}
}
function createContext(rawcontext) {
return rawcontext
}
async function executeModule(
emitter,
logger,
errHandler,
{ module, task, args },
) {
try {
await module.execute(args);
//emitter.emit('module.activate', /*resultPayload(PayloadType.Success, module)*/);
} catch(e) {
throw e
}
}
async function applyPlugins(module, payload) {
let success = true;
for (const plg of module.onEvent) {
const res = await plg.execute(payload);
if(!res.isOk()) {
success = false;
}
}
return success;
}
const router = Router();
/**
* A simple :wave: hello page to verify the worker is working.
*/
router.get('/', (request, env) => {
return new Response(`👋 ${env.DISCORD_APPLICATION_ID}`);
});
/**
* Main route for all requests sent from Discord. All incoming messages will
* include a JSON payload described here:
* https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object
*/
router.post('/', async (request, env) => {
const { isValid, interaction } = await server.verifyDiscordRequest(
request,
env,
);
if (!isValid || !interaction) {
return new Response('Bad request signature.', { status: 401 });
}
if (interaction.type === InteractionType.PING) {
// The `PING` message is used during the initial webhook handshake, and is
// required to configure the webhook in the developer portal.
return new JsonResponse({
type: InteractionResponseType.PONG,
});
}
if(interaction.type === InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE) {
"use autocomplete";
} else if (interaction.type === InteractionType.APPLICATION_COMMAND) {
"use slash";
}
console.error('Unknown Type');
return new JsonResponse({ error: 'Unknown Type' }, { status: 400 });
});
router.all('*', () => new Response('Not Found.', { status: 404 }));
async function verifyDiscordRequest(request, env) {
const signature = request.headers.get('x-signature-ed25519');
const timestamp = request.headers.get('x-signature-timestamp');
const body = await request.text();
const isValidRequest =
signature &&
timestamp &&
verifyKey(body, signature, timestamp, env.DISCORD_PUBLIC_KEY);
if (!isValidRequest) {
return { isValid: false };
}
return { interaction: JSON.parse(body), isValid: true };
}
const server = {
verifyDiscordRequest: verifyDiscordRequest,
fetch: async function (request, env) {
return router.handle(request, env);
},
};
export default server;

View File

@@ -0,0 +1,11 @@
FROM node:latest
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
CMD node src/index.js

View File

@@ -0,0 +1,15 @@
FROM node:latest
WORKDIR /app
COPY package.json ./
RUN npm install
RUN npm install -D typescript
COPY . .
RUN tsc --build || npx -p typescript tsc --build
CMD node dist/index.js

18
tsconfig.json Normal file
View File

@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"outDir": "dist",
"rootDir": ".",
"declaration": true,
"declarationMap": true,
"strict": true,
"esModuleInterop": true,
"noImplicitAny": true,
"strictNullChecks": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

27
tsup.config.ts Normal file
View File

@@ -0,0 +1,27 @@
import { defineConfig } from 'tsup';
import { createRequire } from 'node:module';
const shared = {
entry: [
'src/index.ts',
'src/create-publish.mts',
'src/commands/**',
],
clean: true,
sourcemap: true,
};
export default defineConfig({
format: 'esm',
target: 'node18',
tsconfig: './tsconfig.json',
outDir: './dist',
treeshake: true,
bundle: true,
esbuildPlugins: [],
platform: 'node',
splitting: true,
define: {
__VERSION__: `"${createRequire(import.meta.url)('./package.json').version}"`,
},
...shared,
});