@reflex-stack/tsp 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,32 @@
1
- # TypeScript Package (TSP)
1
+ # TypeScript Package (tsp)
2
2
 
3
3
  **TypeScript Package** (tsp), scaffolds and build **Typescript** sources to **EcmaScript modules** and publish them as modular packages to **NPM** or **JSR**.
4
4
 
5
- ## Init a new library
5
+ **Features :**
6
+ - It uses `tsc` to compile from ts to js and check errors
7
+ - Generates `.d.ts` to keep types when used
8
+ - Scaffold new packages in 1 minute
9
+ - Testing lib pre-installed, can also use your own or skip tests
10
+ - Generating size report as SVG for **README.md** inclusion ( ex : <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./tests/example-package/reports/main-dark.svg"><img src="./tests/example-package/reports/main-light.svg"></picture> )
11
+ - Compatible with latest **Node** / **Bun** / **Deno** and all bundlers with ecma specification
12
+ - Publishing under `.js` and `.d.ts` helps having better performances in your projects ( typescript is faster ), event if **Bun** or **Deno** support Typescript by default.
6
13
 
7
- First, create the associated **git repository** and clone it.
14
+ Check example on [NPM](https://www.npmjs.com/package/@reflex-stack/tsp-example) and [GitHub](https://github.com/reflex-stack/tsp/tree/main/tests/example-package)
8
15
 
9
- Run this command in git trunk :
16
+ ## Init a new TypeScript Package
17
+
18
+ First, create the associated **git repository** for your package and clone it ( optional ).
19
+
20
+ Then, run this command in the cloned directory. :
10
21
  ```bash
11
22
  npx @reflex-stack/tsp init
12
23
  ```
13
24
 
14
- ## Created files
25
+ > If you create this package in a mono-repo, `cd` in the correct repository before running this command. The subdirectory is important for package.json and size report generation.
26
+
27
+ #### Created files
28
+
29
+ This will ask some questions and create those files. It contains 1 **submodule** example and a simple test implementation.
15
30
 
16
31
  ```
17
32
  ├─ dist/
@@ -21,6 +36,7 @@ npx @reflex-stack/tsp init
21
36
  │ └─ index.ts
22
37
  ├─ tests/
23
38
  │ └─ test.js
39
+ │ └─ tsconfig.json ( to have correct typings in test.js )
24
40
  ├─ .gitignore
25
41
  ├─ .npmignore
26
42
  ├─ LICENCE ( if MIT )
@@ -39,27 +55,67 @@ npm run build
39
55
  - Will clear `./dist`, build sources from `.ts` files to `.js` and `.d.ts` files.
40
56
  - Will generate size report and generate `./reports` directory with JSON and SVG files.
41
57
 
42
- > Run `npm run build --noSizeReport`
58
+ > Run `npm run build --noSizeReport` to skip size report entirely.
43
59
 
44
60
  #### Test
45
- - `npm run test`
61
+ ```bash
62
+ npm run test
63
+ ```
46
64
  > Will clear `./dist`, build sources and run tests. No size report.
47
65
 
48
66
  #### Publish
49
- - `npm run publish`
50
- > Will clear `./dist`, build sources and run tests, and start publish process.
67
+ ```bash
68
+ npm run publish
69
+ ```
70
+ > Will clear `./dist`, build sources, run tests, and start publish process.
51
71
  > This will ask you how to upgrade package.json version, push to git and npm.
52
72
 
53
73
 
54
74
  ## Size report
55
- - TODO SVG doc
56
- - TODO JSON doc
57
75
 
58
- ## tsconfig
59
- - TODO doc, explain forbidden properties
76
+ **TSP** can generate size reports with brotli compression. It generate :
77
+ - 2 svgs for root module
78
+ - 2 svgs by submodule
79
+ - 2 svgs for total if you have submodules
80
+
81
+ There are 2 svgs generated, for dark and light mode, to be included in the README.md, on **GitHub** and **NPM**.
82
+
83
+ > When scaffolded, an example of SVG inclusion is generated in README.md
84
+
85
+ How to include the size report in `README.md` ?
86
+
87
+ ```html
88
+ Main bundle is <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/main-dark.svg"><img src="./reports/main-light.svg"></picture>
89
+ Submodule is <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/submodule-dark.svg"><img src="./reports/submodule-light.svg"></picture>
90
+ Total is <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/total-dark.svg"><img src="./reports/total-light.svg"></picture>
91
+ ```
92
+
93
+ > Those works in GitHub and NPM
94
+
95
+ **TSP** can also generate a json size report if needed ( default is set to false )
60
96
 
61
97
  ## TSP config
62
- - TODO tsp config
98
+ TSP config is in the generated `package.json` under the `"tsp"` node
99
+
100
+ ```json5
101
+ {
102
+ "tsp": {
103
+ // Can set to "bun" or "deno"
104
+ "runtime": "node",
105
+ // If you change them, you should update tsconfig.json file
106
+ "src": './src',
107
+ "dist": './dist',
108
+ "tests": './tests',
109
+ "tmp": './tmp',
110
+ // Add your test files here
111
+ "test-files": ['test.js'],
112
+ // Where size reports are generated
113
+ "reports": './reports',
114
+ "generate-json-report": false,
115
+ "generate-svg-report": true
116
+ },
117
+ }
118
+ ```
63
119
 
64
- ## Next
65
- - TODO config override from package
120
+ ## Next features
121
+ - [ ] docisfy integration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reflex-stack/tsp",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "tsp": "./src/cli.js"
@@ -1,6 +1,6 @@
1
1
  import { nicePrint, askInput, askList, newLine, oraTask, execAsync } from "@zouloux/cli"
2
2
  import { getConfig } from "../config.js";
3
- import { getGitRemoteUrl, getTSPPackageJson } from "../utils.js";
3
+ import { getGitRemoteUrl, getGitSubdirectory, getTSPPackageJson } from "../utils.js";
4
4
  import { existsSync, writeFileSync } from "node:fs";
5
5
  import { Stach } from "stach";
6
6
  import { mkdirSync } from "fs";
@@ -29,16 +29,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
29
  SOFTWARE.`
30
30
 
31
31
  const readmeTemplate = `# {{ packageTextName }}
32
- Main bundle is
33
- <picture style="display: inline-block">
34
- <source media="(prefers-color-scheme: dark)" srcset="./reports/main-dark.svg">
35
- <img src="./reports/main-light.svg">
36
- </picture>
37
- Optional submodule is only
38
- <picture style="display: inline-block">
39
- <source media="(prefers-color-scheme: dark)" srcset="./reports/submodule-dark.svg">
40
- <img src="./reports/submodule-light.svg">
41
- </picture>
32
+ Main bundle is <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/main-dark.svg"><img src="./reports/main-light.svg"></picture>
33
+ and optional submodule is only <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/submodule-dark.svg"><img src="./reports/submodule-light.svg"></picture>
42
34
 
43
35
  ## Install
44
36
 
@@ -52,7 +44,7 @@ Optional submodule is only
52
44
  ##### Sub module
53
45
  - \`import { ... } from "{{ packageNPMName }}/submodule"\`
54
46
 
55
- ## tsp commands
47
+ ## Build commands
56
48
 
57
49
  ##### Build
58
50
  - \`npm run build\`
@@ -60,6 +52,10 @@ Optional submodule is only
60
52
  - \`npm run test\`
61
53
  ##### Publish
62
54
  - \`npm run publish\`
55
+
56
+ ---
57
+ ## TSP
58
+ This package has been created with [tsp](https://github.com/reflex-stack/tsp)
63
59
  `
64
60
 
65
61
  const tsconfigTemplate = `{
@@ -159,8 +155,8 @@ describe("Main module", () => {
159
155
 
160
156
  describe("Sub module", () => {
161
157
  it("Should call sub random", () => {
162
- const rootResult = subRandomFunction()
163
- expect(rootResult).toBe(60)
158
+ const subResult = subRandomFunction()
159
+ expect(subResult).toBe(60)
164
160
  })
165
161
  // Test error example
166
162
  // it("Should fail", () => {
@@ -181,13 +177,19 @@ export async function init () {
181
177
  }
182
178
  // Get git remote
183
179
  const config = getConfig()
184
- let remoteURL = getGitRemoteUrl( config.cwd )
185
- if ( !remoteURL )
186
- nicePrint(`{o}Before scaffolding your TypeScript package, you should create the associated git repository.`)
187
- else
180
+ const remoteURL = getGitRemoteUrl( config.cwd )
181
+ const relativeGitSubDirectory = getGitSubdirectory()
182
+ if ( !remoteURL ) {
183
+ nicePrint(`{o}Before scaffolding your TypeScript package, you should create the associated git repository, and cd in the correct sub-directory.`)
184
+ }
185
+ else {
188
186
  nicePrint(`{d}Git origin is {/}${remoteURL}`)
187
+ if ( relativeGitSubDirectory ) {
188
+ nicePrint(`{d}Git sub directory is {/}${relativeGitSubDirectory}. This will be saved to package.json.`)
189
+ }
190
+ }
189
191
  newLine()
190
- const options = { remoteURL }
192
+ const options = { remoteURL, relativeGitSubDirectory }
191
193
  options.packageTextName = await askInput(`Package name, in plain text {d}ex : My Package`, { notEmpty: true })
192
194
  options.packageNPMName = await askInput(`Package name, for NPM, with namespace {d}ex : @mynamespace/mypackage`, { notEmpty: true })
193
195
  options.authorName = await askInput(`Author name`, { notEmpty: true })
@@ -250,6 +252,10 @@ export async function init () {
250
252
  type: "git",
251
253
  url: options.remoteURL
252
254
  }
255
+ // Add subdirectory for package.json and SVG targeting in README.md on NPMJs
256
+ if ( options.relativeGitSubDirectory ) {
257
+ packageJson.repository.directory = options.relativeGitSubDirectory
258
+ }
253
259
  }
254
260
  // Create directories
255
261
  mkdirSync(config.tests, { recursive: true })
@@ -112,21 +112,37 @@ export function generateJSON ( sizeReport, config ) {
112
112
  )
113
113
  }
114
114
 
115
+ async function generateTextSVG ( filePath, scheme, text ) {
116
+ const svgBitFile = new File( filePath );
117
+ const fontSize = 14
118
+ const height = fontSize + 1
119
+ const width = text.length * fontSize * 0.6 + 1
120
+ svgBitFile.content( () => [
121
+ `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">`,
122
+ `<style> text { fill: ${scheme === "dark" ? "white" : "black" }; font-family: Consolas, Monaco, "Lucida Console", monospace; font-size: ${fontSize}px; }</style>`,
123
+ `<text y="${height - 1}">${text}</text>`,
124
+ `</svg>`,
125
+ ].join(""))
126
+ await svgBitFile.ensureParents()
127
+ await svgBitFile.save();
128
+ }
129
+
115
130
  export async function generateSVGs ( sizeReport, config ) {
131
+ let total = 0
116
132
  for ( const bundle of sizeReport ) {
117
133
  const size = bundle.sizes[2]
134
+ total += size
118
135
  const sizeContent = naiveHumanFileSize( size )
119
136
  for ( const scheme of ["light", "dark"] ) {
120
- const bitPath = join( config.cwd, config.reports, `${bundle.name}-${scheme}.svg` )
121
- const svgBitFile = new File( bitPath );
122
- svgBitFile.content( () => [
123
- `<svg width="${sizeContent.length * 10}" height="22" xmlns="http://www.w3.org/2000/svg">`,
124
- `<style> text { fill: ${scheme === "dark" ? "white" : "black" }; font-family: 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; }</style>`,
125
- `<text y="21">${sizeContent}</text>`,
126
- `</svg>`,
127
- ].join(""))
128
- await svgBitFile.ensureParents()
129
- await svgBitFile.save();
137
+ const filePath = join( config.cwd, config.reports, `${bundle.name}-${scheme}.svg` )
138
+ await generateTextSVG( filePath, scheme, sizeContent )
139
+ }
140
+ }
141
+ if ( sizeReport.length > 1 ) {
142
+ const sizeContent = naiveHumanFileSize( total )
143
+ for ( const scheme of ["light", "dark"] ) {
144
+ const filePath = join( config.cwd, config.reports, `total-${scheme}.svg` )
145
+ await generateTextSVG( filePath, scheme, sizeContent )
130
146
  }
131
147
  }
132
148
  }
package/src/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { dirname, join } from "node:path";
1
+ import { dirname, join, relative } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { newLine, nicePrint } from "@zouloux/cli";
@@ -59,3 +59,19 @@ export function getGitRemoteUrl ( cwd ) {
59
59
  return '';
60
60
  }
61
61
  }
62
+
63
+
64
+ export function getGitSubdirectory () {
65
+ let currentDir = process.cwd()
66
+ let rootDir = null
67
+ while ( currentDir !== '/' ) {
68
+ if ( existsSync(join(currentDir, '.git')) ) {
69
+ rootDir = currentDir
70
+ break
71
+ }
72
+ currentDir = dirname(currentDir)
73
+ }
74
+ if ( !rootDir )
75
+ return null
76
+ return relative(rootDir, process.cwd())
77
+ }
@@ -1,13 +1,31 @@
1
- # ecma-build test package
2
-
3
- Main bundle is only
4
- <picture style="display: inline-block">
5
- <source media="(prefers-color-scheme: dark)" srcset="./reports/main-dark.svg">
6
- <img src="./reports/main-light.svg">
7
- </picture>
8
-
9
- Optional sub-module is only
10
- <picture style="display: inline-block">
11
- <source media="(prefers-color-scheme: dark)" srcset="./reports/submodule-dark.svg">
12
- <img src="./reports/submodule-light.svg">
13
- </picture>
1
+ # TSP Example
2
+
3
+ ## This is a test package for @reflex-stack/tsp, do not use it
4
+
5
+ Main bundle is <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/main-dark.svg"><img src="./reports/main-light.svg"></picture>
6
+ and optional submodule is only <picture style="display: inline-block"><source media="(prefers-color-scheme: dark)" srcset="./reports/submodule-dark.svg"><img src="./reports/submodule-light.svg"></picture>
7
+
8
+ ## Install
9
+
10
+ `npm i @reflex-stack/tsp-example`
11
+
12
+ ## Usage
13
+
14
+ ##### Main module
15
+ - `import { ... } from "{{ packageNPMName }}"`
16
+
17
+ ##### Sub module
18
+ - `import { ... } from "{{ packageNPMName }}/submodule"`
19
+
20
+ ## Build commands
21
+
22
+ ##### Build
23
+ - `npm run build`
24
+ ##### Test
25
+ - `npm run test`
26
+ ##### Publish
27
+ - `npm run publish`
28
+
29
+ ---
30
+ ## TSP
31
+ This package has been created with [tsp](https://github.com/reflex-stack/tsp)
@@ -1 +1 @@
1
- export declare function doStuff(): void;
1
+ export declare function doStuff(): string;
@@ -1,4 +1,5 @@
1
1
  import { commonDep } from "./common-dep.js";
2
2
  export function doStuff() {
3
- console.log("Do stuff", commonDep);
3
+ console.log("DO STUFFF");
4
+ return `Do stuff ${commonDep}`;
4
5
  }
@@ -1 +1 @@
1
- export declare function doSubmoduleStuff(): void;
1
+ export declare function doSubmoduleStuff(): string;
@@ -1,5 +1,5 @@
1
1
  import { submoduleDep } from "./submodule-dep.js";
2
2
  import { commonDep } from "../common-dep.js";
3
3
  export function doSubmoduleStuff() {
4
- console.log("Do submodule stuff", submoduleDep, commonDep);
4
+ return `Do submodule stuff ${submoduleDep} ${commonDep}`;
5
5
  }