@reflex-stack/tsp 0.1.2 → 0.1.3

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,30 @@
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** and clone it ( optional ).
19
+
20
+ Then, run this command the cloned directory :
10
21
  ```bash
11
22
  npx @reflex-stack/tsp init
12
23
  ```
13
24
 
14
- ## Created files
25
+ #### Created files
26
+
27
+ This will ask some questions and create those files. It contains 1 **submodule** example and a simple test implementation.
15
28
 
16
29
  ```
17
30
  ├─ dist/
@@ -21,6 +34,7 @@ npx @reflex-stack/tsp init
21
34
  │ └─ index.ts
22
35
  ├─ tests/
23
36
  │ └─ test.js
37
+ │ └─ tsconfig.json ( to have correct typings in test.js )
24
38
  ├─ .gitignore
25
39
  ├─ .npmignore
26
40
  ├─ LICENCE ( if MIT )
@@ -52,14 +66,40 @@ npm run build
52
66
 
53
67
 
54
68
  ## Size report
55
- - TODO SVG doc
56
- - TODO JSON doc
57
69
 
58
- ## tsconfig
59
- - TODO doc, explain forbidden properties
70
+ **TSP** can generate size reports with brotli compression. It generate :
71
+ - 2 svgs for root module
72
+ - 2 svgs by submodule
73
+ - 2 svgs for total if you have submodules
74
+
75
+ There are 2 svgs generated, for dark and light mode, to be included in the README.md, on **GitHub** and **NPM**.
76
+
77
+ > When scaffolded, an example of SVG inclusion is generated in README.md
78
+
79
+ **TSP** can also generate a json size report if needed ( default is set to false )
60
80
 
61
81
  ## TSP config
62
- - TODO tsp config
82
+ TSP config is in the generated `package.json` under the `"tsp"` node
83
+
84
+ ```json5
85
+ {
86
+ "tsp": {
87
+ // Can set to "bun" or "deno"
88
+ "runtime": "node",
89
+ // If you change them, you should update tsconfig.json file
90
+ "src": './src',
91
+ "dist": './dist',
92
+ "tests": './tests',
93
+ "tmp": './tmp',
94
+ // Add your test files here
95
+ "test-files": ['test.js'],
96
+ // Where size reports are generated
97
+ "reports": './reports',
98
+ "generate-json-report": false,
99
+ "generate-svg-report": true
100
+ },
101
+ }
102
+ ```
63
103
 
64
- ## Next
65
- - TODO config override from package
104
+ ## Next features
105
+ - [ ] 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.3",
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
  }