dtunnel-sdk 1.1.4 → 1.2.0
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 +48 -42
- package/bin/dtunnel-sdk.mjs +70 -6
- package/docs/getting-started.md +12 -12
- package/package.json +7 -8
- package/sdk/README.md +56 -58
- package/sdk/dtunnel-sdk.js +1 -1
- package/templates/cdn/README.md +2 -2
- package/templates/cdn/package.json +2 -2
- package/templates/cdn/scripts/{copy-webview.mjs → build-android-html.mjs} +2 -2
- package/templates/react-typescript/README.md +4 -4
- package/templates/react-typescript/package.json +1 -1
- package/templates/react-typescript/scripts/{build-webview-html.mjs → build-android-html.mjs} +22 -4
- package/templates/typescript/README.md +4 -4
- package/templates/typescript/package.json +1 -1
- package/templates/typescript/scripts/{build-webview-html.mjs → build-android-html.mjs} +22 -4
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ npm install dtunnel-sdk
|
|
|
10
10
|
|
|
11
11
|
## Inicializar projeto pronto
|
|
12
12
|
|
|
13
|
-
Crie um projeto novo com template e `build:
|
|
13
|
+
Crie um projeto novo com template e `build:android` ja configurado:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npx dtunnel-sdk init
|
|
@@ -30,49 +30,55 @@ Tambem funciona com `npm exec`:
|
|
|
30
30
|
npm exec dtunnel-sdk init meu-app --template react-typescript
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
## Uso rapido
|
|
33
|
+
## Uso rapido
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
import DTunnelSDK from 'dtunnel-sdk';
|
|
37
37
|
|
|
38
|
-
const sdk = new DTunnelSDK({
|
|
39
|
-
strict: false,
|
|
40
|
-
autoRegisterNativeEvents: true,
|
|
41
|
-
});
|
|
38
|
+
const sdk = new DTunnelSDK({
|
|
39
|
+
strict: false,
|
|
40
|
+
autoRegisterNativeEvents: true,
|
|
41
|
+
});
|
|
42
42
|
|
|
43
43
|
sdk.on('vpnState', (event) => {
|
|
44
44
|
console.log('VPN:', event.payload);
|
|
45
|
-
});
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Simulador rapido (sem Android)
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import DTunnelSDK from 'dtunnel-sdk';
|
|
52
|
-
import { installDTunnelSDKSimulator } from 'dtunnel-sdk/simulator';
|
|
53
|
-
|
|
54
|
-
const simulator = installDTunnelSDKSimulator();
|
|
55
|
-
const sdk = new DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
56
|
-
|
|
57
|
-
simulator.emit('vpnState', 'CONNECTED');
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Browser puro (sem bundler):
|
|
61
|
-
|
|
62
|
-
```html
|
|
63
|
-
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.js"></script>
|
|
64
|
-
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.simulator.js"></script>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Nota:
|
|
68
|
-
- No WebView real, o simulador nao instala por padrao se detectar bridge nativa.
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Simulador rapido (sem Android)
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import DTunnelSDK from 'dtunnel-sdk';
|
|
52
|
+
import { installDTunnelSDKSimulator } from 'dtunnel-sdk/simulator';
|
|
69
53
|
|
|
70
|
-
|
|
54
|
+
const simulator = installDTunnelSDKSimulator();
|
|
55
|
+
const sdk = new DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
56
|
+
|
|
57
|
+
sdk.on('vpnState', (event) => {
|
|
58
|
+
console.log('VPN:', event.payload);
|
|
59
|
+
});
|
|
60
|
+
simulator.emit('vpnState', 'CONNECTED');
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Browser puro (sem bundler):
|
|
71
64
|
|
|
72
65
|
```html
|
|
73
66
|
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.js"></script>
|
|
67
|
+
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.simulator.js"></script>
|
|
68
|
+
<script>
|
|
69
|
+
const sdk = new window.DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
70
|
+
const simulator = window.DTunnelSDKSimulator.installDTunnelSDKSimulator();
|
|
71
|
+
|
|
72
|
+
sdk.on('vpnState', (event) => {
|
|
73
|
+
console.log('VPN:', event.payload);
|
|
74
|
+
});
|
|
75
|
+
simulator.emit('vpnState', 'CONNECTED');
|
|
76
|
+
</script>
|
|
74
77
|
```
|
|
75
78
|
|
|
79
|
+
Nota:
|
|
80
|
+
- No WebView real, o simulador nao instala por padrao se detectar bridge nativa.
|
|
81
|
+
|
|
76
82
|
## Documentacao completa
|
|
77
83
|
|
|
78
84
|
Toda a documentacao foi movida para `docs/`:
|
|
@@ -87,14 +93,14 @@ Toda a documentacao foi movida para `docs/`:
|
|
|
87
93
|
|
|
88
94
|
Use apenas `init` para gerar projeto pronto:
|
|
89
95
|
|
|
90
|
-
```bash
|
|
91
|
-
npx dtunnel-sdk init meu-app --template react-typescript
|
|
92
|
-
cd meu-app
|
|
93
|
-
npm run build:
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
O resultado final para
|
|
97
|
-
- `
|
|
96
|
+
```bash
|
|
97
|
+
npx dtunnel-sdk init meu-app --template react-typescript
|
|
98
|
+
cd meu-app
|
|
99
|
+
npm run build:android
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
O resultado final para Android e um arquivo unico:
|
|
103
|
+
- `dist/build.html`
|
|
98
104
|
|
|
99
105
|
## Demos prontas
|
|
100
106
|
|
|
@@ -116,6 +122,6 @@ npm run test:typecheck
|
|
|
116
122
|
## Release e publicacao
|
|
117
123
|
|
|
118
124
|
```bash
|
|
119
|
-
npm run release:sdk -- --version X.Y.Z
|
|
120
|
-
npm run
|
|
121
|
-
```
|
|
125
|
+
npm run release:sdk -- --version X.Y.Z
|
|
126
|
+
npm run release:npm
|
|
127
|
+
```
|
package/bin/dtunnel-sdk.mjs
CHANGED
|
@@ -11,6 +11,7 @@ const __dirname = path.dirname(__filename);
|
|
|
11
11
|
const ROOT_DIR = path.resolve(__dirname, '..');
|
|
12
12
|
const TEMPLATES_DIR = path.join(ROOT_DIR, 'templates');
|
|
13
13
|
const PKG_JSON_PATH = path.join(ROOT_DIR, 'package.json');
|
|
14
|
+
const REQUIRED_GITIGNORE_ENTRIES = ['node_modules', 'dist'];
|
|
14
15
|
|
|
15
16
|
const TEMPLATE_CHOICES = [
|
|
16
17
|
{ id: 'react-typescript', label: 'React + TypeScript (Vite)' },
|
|
@@ -258,6 +259,67 @@ async function copyDirRecursive(sourceDir, targetDir) {
|
|
|
258
259
|
}
|
|
259
260
|
}
|
|
260
261
|
|
|
262
|
+
async function normalizeIgnoreFiles(targetDir) {
|
|
263
|
+
const entries = await fs.readdir(targetDir, { withFileTypes: true });
|
|
264
|
+
|
|
265
|
+
for (const entry of entries) {
|
|
266
|
+
if (!entry.isDirectory()) continue;
|
|
267
|
+
await normalizeIgnoreFiles(path.join(targetDir, entry.name));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
271
|
+
const npmignorePath = path.join(targetDir, '.npmignore');
|
|
272
|
+
const plainIgnorePath = path.join(targetDir, 'gitignore');
|
|
273
|
+
const hasGitignore = await pathExists(gitignorePath);
|
|
274
|
+
|
|
275
|
+
if (!hasGitignore && (await pathExists(npmignorePath))) {
|
|
276
|
+
await fs.rename(npmignorePath, gitignorePath);
|
|
277
|
+
} else if (!hasGitignore && (await pathExists(plainIgnorePath))) {
|
|
278
|
+
await fs.rename(plainIgnorePath, gitignorePath);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if ((await pathExists(gitignorePath)) && (await pathExists(npmignorePath))) {
|
|
282
|
+
await fs.rm(npmignorePath, { force: true });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if ((await pathExists(gitignorePath)) && (await pathExists(plainIgnorePath))) {
|
|
286
|
+
await fs.rm(plainIgnorePath, { force: true });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async function ensureRootGitignoreDefaults(targetDir) {
|
|
291
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
292
|
+
const hasGitignore = await pathExists(gitignorePath);
|
|
293
|
+
|
|
294
|
+
if (!hasGitignore) {
|
|
295
|
+
await fs.writeFile(
|
|
296
|
+
gitignorePath,
|
|
297
|
+
`${REQUIRED_GITIGNORE_ENTRIES.join('\n')}\n`,
|
|
298
|
+
'utf8',
|
|
299
|
+
);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const raw = await fs.readFile(gitignorePath, 'utf8');
|
|
304
|
+
const normalized = raw.replace(/\r\n/g, '\n');
|
|
305
|
+
const existing = new Set(
|
|
306
|
+
normalized
|
|
307
|
+
.split('\n')
|
|
308
|
+
.map((line) => line.trim())
|
|
309
|
+
.filter((line) => line.length > 0),
|
|
310
|
+
);
|
|
311
|
+
const missing = REQUIRED_GITIGNORE_ENTRIES.filter((line) => !existing.has(line));
|
|
312
|
+
|
|
313
|
+
if (missing.length === 0) return;
|
|
314
|
+
|
|
315
|
+
let next = normalized;
|
|
316
|
+
if (next.length > 0 && !next.endsWith('\n')) {
|
|
317
|
+
next += '\n';
|
|
318
|
+
}
|
|
319
|
+
next += `${missing.join('\n')}\n`;
|
|
320
|
+
await fs.writeFile(gitignorePath, next, 'utf8');
|
|
321
|
+
}
|
|
322
|
+
|
|
261
323
|
function isTextLikeFile(fileName) {
|
|
262
324
|
if (fileName === '.gitignore') return true;
|
|
263
325
|
const ext = path.extname(fileName);
|
|
@@ -338,16 +400,16 @@ function printNextSteps({
|
|
|
338
400
|
}
|
|
339
401
|
|
|
340
402
|
if (template === 'cdn') {
|
|
341
|
-
console.log(` ${runScriptCommand(packageManager, 'build:
|
|
342
|
-
console.log('\nArquivo final para
|
|
343
|
-
console.log(` ${path.join(projectName, '
|
|
403
|
+
console.log(` ${runScriptCommand(packageManager, 'build:android')}`);
|
|
404
|
+
console.log('\nArquivo final para Android (unico):');
|
|
405
|
+
console.log(` ${path.join(projectName, 'dist', 'build.html')}`);
|
|
344
406
|
return;
|
|
345
407
|
}
|
|
346
408
|
|
|
347
409
|
console.log(` ${runScriptCommand(packageManager, 'dev')}`);
|
|
348
|
-
console.log(` ${runScriptCommand(packageManager, 'build:
|
|
349
|
-
console.log('\nArquivo final para
|
|
350
|
-
console.log(` ${path.join(projectName, '
|
|
410
|
+
console.log(` ${runScriptCommand(packageManager, 'build:android')}`);
|
|
411
|
+
console.log('\nArquivo final para Android (unico):');
|
|
412
|
+
console.log(` ${path.join(projectName, 'dist', 'build.html')}`);
|
|
351
413
|
}
|
|
352
414
|
|
|
353
415
|
async function runInit(parsed) {
|
|
@@ -402,6 +464,8 @@ async function runInit(parsed) {
|
|
|
402
464
|
const targetDir = path.resolve(process.cwd(), projectName);
|
|
403
465
|
await ensureTargetDirectory(targetDir, parsed.force);
|
|
404
466
|
await copyDirRecursive(templateDir, targetDir);
|
|
467
|
+
await normalizeIgnoreFiles(targetDir);
|
|
468
|
+
await ensureRootGitignoreDefaults(targetDir);
|
|
405
469
|
|
|
406
470
|
const sdkVersion = await readSdkVersion();
|
|
407
471
|
await applyReplacements(targetDir, {
|
package/docs/getting-started.md
CHANGED
|
@@ -8,7 +8,7 @@ npm install dtunnel-sdk
|
|
|
8
8
|
|
|
9
9
|
## Bootstrap de projeto (CLI)
|
|
10
10
|
|
|
11
|
-
Crie um projeto novo com template e script de
|
|
11
|
+
Crie um projeto novo com template e script de build para Android pronto:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npx dtunnel-sdk init
|
|
@@ -82,21 +82,21 @@ export function App() {
|
|
|
82
82
|
</script>
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
##
|
|
86
|
-
|
|
87
|
-
Para publicar no
|
|
88
|
-
|
|
89
|
-
- Todo projeto criado pelo CLI
|
|
90
|
-
|
|
91
|
-
Fluxo recomendado:
|
|
85
|
+
## Build para Android em arquivo unico
|
|
86
|
+
|
|
87
|
+
Para publicar no Android, o artefato final e um unico `dist/build.html`.
|
|
88
|
+
|
|
89
|
+
- Todo projeto criado pelo CLI inclui `npm run build:android`.
|
|
90
|
+
|
|
91
|
+
Fluxo recomendado:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
94
|
npx dtunnel-sdk init meu-app --template react-typescript
|
|
95
95
|
cd meu-app
|
|
96
|
-
npm run build:
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Comportamento de erro (`strict`)
|
|
96
|
+
npm run build:android
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Comportamento de erro (`strict`)
|
|
100
100
|
|
|
101
101
|
- `strict: false` (padrao recomendado para WebView): erros de bridge retornam `null` e disparam evento `error`.
|
|
102
102
|
- `strict: true`: a chamada lanca `DTunnelBridgeError`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dtunnel-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "JavaScript/TypeScript SDK for the DTunnel Android WebView bridge.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -10,13 +10,12 @@
|
|
|
10
10
|
"bin": {
|
|
11
11
|
"dtunnel-sdk": "bin/dtunnel-sdk.mjs"
|
|
12
12
|
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"test": "node --import tsx --test ./tests/*.test.mts",
|
|
15
|
-
"test:typecheck": "tsc -p ./tests/tsconfig.json --noEmit",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "node --import tsx --test ./tests/*.test.mts",
|
|
15
|
+
"test:typecheck": "tsc -p ./tests/tsconfig.json --noEmit",
|
|
16
|
+
"release:npm": "node ./scripts/release-npm.mjs",
|
|
17
|
+
"release:sdk": "node ./scripts/release-sdk.mjs"
|
|
18
|
+
},
|
|
20
19
|
"exports": {
|
|
21
20
|
".": {
|
|
22
21
|
"types": "./sdk/dtunnel-sdk.d.ts",
|
package/sdk/README.md
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
# DTunnel SDK (Runtime)
|
|
2
2
|
|
|
3
|
-
Arquivos do runtime e tipagem:
|
|
4
|
-
|
|
5
|
-
- `dtunnel-sdk.js`: build principal (script tag + CommonJS)
|
|
6
|
-
- `dtunnel-sdk.mjs`: entrada ESM para bundlers
|
|
7
|
-
- `dtunnel-sdk.d.ts`: tipagem TypeScript
|
|
8
|
-
- `dtunnel-sdk.simulator.js`: simulador da bridge (`window.Dt...`)
|
|
9
|
-
- `dtunnel-sdk.simulator.d.ts`: tipagem TypeScript do simulador
|
|
10
|
-
- `dtunnel-sdk.simulator.mjs`: entrada ESM do simulador
|
|
3
|
+
Arquivos do runtime e tipagem:
|
|
4
|
+
|
|
5
|
+
- `dtunnel-sdk.js`: build principal (script tag + CommonJS)
|
|
6
|
+
- `dtunnel-sdk.mjs`: entrada ESM para bundlers
|
|
7
|
+
- `dtunnel-sdk.d.ts`: tipagem TypeScript
|
|
8
|
+
- `dtunnel-sdk.simulator.js`: simulador da bridge (`window.Dt...`)
|
|
9
|
+
- `dtunnel-sdk.simulator.d.ts`: tipagem TypeScript do simulador
|
|
10
|
+
- `dtunnel-sdk.simulator.mjs`: entrada ESM do simulador
|
|
11
11
|
|
|
12
12
|
## Inicializacao
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
|
-
import DTunnelSDK from 'dtunnel-sdk';
|
|
16
|
-
|
|
17
|
-
const sdk = new DTunnelSDK({
|
|
18
|
-
strict: false,
|
|
19
|
-
autoRegisterNativeEvents: true,
|
|
20
|
-
});
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Simulador da bridge no navegador
|
|
24
|
-
|
|
25
|
-
### Uso
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
import DTunnelSDK from 'dtunnel-sdk';
|
|
29
|
-
import { installDTunnelSDKSimulator } from 'dtunnel-sdk/simulator';
|
|
30
|
-
|
|
31
|
-
const simulator = installDTunnelSDKSimulator();
|
|
32
|
-
const sdk = new DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
33
|
-
|
|
34
|
-
sdk.main.startVpn(); // usa simulador
|
|
35
|
-
simulator.emit('vpnState', 'CONNECTED'); // dispara callback nativo
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Regra de WebView real
|
|
39
|
-
|
|
40
|
-
Por padrao, `installDTunnelSDKSimulator()` nao instala se detectar bridge nativa no `window` (nao sobrescreve `window.Dt...` no app real).
|
|
41
|
-
|
|
42
|
-
### Script tag (CDN/browser puro)
|
|
43
|
-
|
|
44
|
-
```html
|
|
45
|
-
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.js"></script>
|
|
46
|
-
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.simulator.js"></script>
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Depois disso:
|
|
50
|
-
|
|
51
|
-
```html
|
|
52
|
-
<script>
|
|
53
|
-
const sdk = new window.DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
54
|
-
const simulator = window.DTunnelSDKSimulator.installDTunnelSDKSimulator();
|
|
55
|
-
simulator.emit('vpnState', 'CONNECTED');
|
|
56
|
-
</script>
|
|
57
|
-
```
|
|
15
|
+
import DTunnelSDK from 'dtunnel-sdk';
|
|
16
|
+
|
|
17
|
+
const sdk = new DTunnelSDK({
|
|
18
|
+
strict: false,
|
|
19
|
+
autoRegisterNativeEvents: true,
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Simulador da bridge no navegador
|
|
24
|
+
|
|
25
|
+
### Uso
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import DTunnelSDK from 'dtunnel-sdk';
|
|
29
|
+
import { installDTunnelSDKSimulator } from 'dtunnel-sdk/simulator';
|
|
30
|
+
|
|
31
|
+
const simulator = installDTunnelSDKSimulator();
|
|
32
|
+
const sdk = new DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
33
|
+
|
|
34
|
+
sdk.main.startVpn(); // usa simulador
|
|
35
|
+
simulator.emit('vpnState', 'CONNECTED'); // dispara callback nativo
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Regra de WebView real
|
|
39
|
+
|
|
40
|
+
Por padrao, `installDTunnelSDKSimulator()` nao instala se detectar bridge nativa no `window` (nao sobrescreve `window.Dt...` no app real).
|
|
41
|
+
|
|
42
|
+
### Script tag (CDN/browser puro)
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.js"></script>
|
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/dtunnel-sdk@latest/sdk/dtunnel-sdk.simulator.js"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Depois disso:
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<script>
|
|
53
|
+
const sdk = new window.DTunnelSDK({ strict: false, autoRegisterNativeEvents: true });
|
|
54
|
+
const simulator = window.DTunnelSDKSimulator.installDTunnelSDKSimulator();
|
|
55
|
+
simulator.emit('vpnState', 'CONNECTED');
|
|
56
|
+
</script>
|
|
57
|
+
```
|
|
58
58
|
|
|
59
59
|
## Modulos
|
|
60
60
|
|
|
@@ -93,12 +93,10 @@ Use `sdk.on('<evento>', handler)` com:
|
|
|
93
93
|
- React + TypeScript: `examples/react-typescript`
|
|
94
94
|
- Guia geral: `examples/README.md`
|
|
95
95
|
|
|
96
|
-
Regra para WebView:
|
|
97
|
-
-
|
|
98
|
-
- nos exemplos TypeScript/React, use `npm run build:webview` para gerar `webview/index.html`.
|
|
99
|
-
- atalho na raiz: `npm run examples:webview`.
|
|
96
|
+
Regra para WebView:
|
|
97
|
+
- use `npm run build:android` para gerar `dist/build.html` (arquivo unico).
|
|
100
98
|
|
|
101
99
|
Publicacao npm (raiz do repo):
|
|
102
|
-
- scripts de publicacao/release sao cross-platform (Linux, macOS e Windows).
|
|
103
|
-
- `npm login`
|
|
104
|
-
- `npm run
|
|
100
|
+
- scripts de publicacao/release sao cross-platform (Linux, macOS e Windows).
|
|
101
|
+
- `npm login`
|
|
102
|
+
- `npm run release:npm`
|
package/sdk/dtunnel-sdk.js
CHANGED
package/templates/cdn/README.md
CHANGED
|
@@ -4,10 +4,10 @@ import path from 'node:path';
|
|
|
4
4
|
|
|
5
5
|
const cwd = process.cwd();
|
|
6
6
|
const inputPath = path.join(cwd, 'index.html');
|
|
7
|
-
const outputPath = path.join(cwd, '
|
|
7
|
+
const outputPath = path.join(cwd, 'dist', 'build.html');
|
|
8
8
|
|
|
9
9
|
const html = await fs.readFile(inputPath, 'utf8');
|
|
10
10
|
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
11
11
|
await fs.writeFile(outputPath, html, 'utf8');
|
|
12
12
|
|
|
13
|
-
console.log(`[build-
|
|
13
|
+
console.log(`[build-android] Gerado: ${outputPath}`);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# DTunnel SDK - Template React + TypeScript
|
|
2
2
|
|
|
3
|
-
Projeto React + TypeScript (Vite) pronto com `build:
|
|
3
|
+
Projeto React + TypeScript (Vite) pronto com `build:android`.
|
|
4
4
|
|
|
5
5
|
## Comandos
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install
|
|
9
9
|
npm run dev
|
|
10
|
-
npm run build:
|
|
10
|
+
npm run build:android
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Saida:
|
|
14
|
-
- `
|
|
13
|
+
Saida:
|
|
14
|
+
- `dist/build.html` (arquivo unico)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "vite build",
|
|
9
|
-
"build:
|
|
9
|
+
"build:android": "npm run build && node ./scripts/build-android-html.mjs --dist dist --out dist/build.html",
|
|
10
10
|
"preview": "vite preview",
|
|
11
11
|
"typecheck": "tsc --noEmit"
|
|
12
12
|
},
|
package/templates/react-typescript/scripts/{build-webview-html.mjs → build-android-html.mjs}
RENAMED
|
@@ -6,7 +6,7 @@ import process from 'node:process';
|
|
|
6
6
|
function parseArgs(argv) {
|
|
7
7
|
const options = {
|
|
8
8
|
dist: 'dist',
|
|
9
|
-
out: '
|
|
9
|
+
out: 'dist/build.html',
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -116,6 +116,23 @@ function removeLocalModulePreloads(html) {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
async function keepOnlyOutputFile(outputPath) {
|
|
120
|
+
const outputDir = path.dirname(outputPath);
|
|
121
|
+
const entries = await fs.readdir(outputDir, { withFileTypes: true });
|
|
122
|
+
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
const entryPath = path.join(outputDir, entry.name);
|
|
125
|
+
if (path.resolve(entryPath) === outputPath) continue;
|
|
126
|
+
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
await fs.rm(entryPath, { recursive: true, force: true });
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await fs.rm(entryPath, { force: true });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
119
136
|
async function main() {
|
|
120
137
|
const args = parseArgs(process.argv.slice(2));
|
|
121
138
|
const cwd = process.cwd();
|
|
@@ -126,7 +143,7 @@ async function main() {
|
|
|
126
143
|
const outputDir = path.dirname(outputPath);
|
|
127
144
|
|
|
128
145
|
if (!(await fileExists(inputPath))) {
|
|
129
|
-
console.error(`[build-
|
|
146
|
+
console.error(`[build-android] index nao encontrado: ${inputPath}`);
|
|
130
147
|
process.exit(1);
|
|
131
148
|
}
|
|
132
149
|
|
|
@@ -137,11 +154,12 @@ async function main() {
|
|
|
137
154
|
|
|
138
155
|
await fs.mkdir(outputDir, { recursive: true });
|
|
139
156
|
await fs.writeFile(outputPath, html, 'utf8');
|
|
157
|
+
await keepOnlyOutputFile(outputPath);
|
|
140
158
|
|
|
141
|
-
console.log(`[build-
|
|
159
|
+
console.log(`[build-android] Gerado: ${outputPath}`);
|
|
142
160
|
}
|
|
143
161
|
|
|
144
162
|
main().catch((error) => {
|
|
145
|
-
console.error('[build-
|
|
163
|
+
console.error('[build-android] Falha:', error);
|
|
146
164
|
process.exit(1);
|
|
147
165
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# DTunnel SDK - Template TypeScript
|
|
2
2
|
|
|
3
|
-
Projeto TypeScript (Vite) pronto com `build:
|
|
3
|
+
Projeto TypeScript (Vite) pronto com `build:android`.
|
|
4
4
|
|
|
5
5
|
## Comandos
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install
|
|
9
9
|
npm run dev
|
|
10
|
-
npm run build:
|
|
10
|
+
npm run build:android
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Saida:
|
|
14
|
-
- `
|
|
13
|
+
Saida:
|
|
14
|
+
- `dist/build.html` (arquivo unico)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "vite build",
|
|
9
|
-
"build:
|
|
9
|
+
"build:android": "npm run build && node ./scripts/build-android-html.mjs --dist dist --out dist/build.html",
|
|
10
10
|
"preview": "vite preview",
|
|
11
11
|
"typecheck": "tsc --noEmit"
|
|
12
12
|
},
|
|
@@ -6,7 +6,7 @@ import process from 'node:process';
|
|
|
6
6
|
function parseArgs(argv) {
|
|
7
7
|
const options = {
|
|
8
8
|
dist: 'dist',
|
|
9
|
-
out: '
|
|
9
|
+
out: 'dist/build.html',
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -116,6 +116,23 @@ function removeLocalModulePreloads(html) {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
async function keepOnlyOutputFile(outputPath) {
|
|
120
|
+
const outputDir = path.dirname(outputPath);
|
|
121
|
+
const entries = await fs.readdir(outputDir, { withFileTypes: true });
|
|
122
|
+
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
const entryPath = path.join(outputDir, entry.name);
|
|
125
|
+
if (path.resolve(entryPath) === outputPath) continue;
|
|
126
|
+
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
await fs.rm(entryPath, { recursive: true, force: true });
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await fs.rm(entryPath, { force: true });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
119
136
|
async function main() {
|
|
120
137
|
const args = parseArgs(process.argv.slice(2));
|
|
121
138
|
const cwd = process.cwd();
|
|
@@ -126,7 +143,7 @@ async function main() {
|
|
|
126
143
|
const outputDir = path.dirname(outputPath);
|
|
127
144
|
|
|
128
145
|
if (!(await fileExists(inputPath))) {
|
|
129
|
-
console.error(`[build-
|
|
146
|
+
console.error(`[build-android] index nao encontrado: ${inputPath}`);
|
|
130
147
|
process.exit(1);
|
|
131
148
|
}
|
|
132
149
|
|
|
@@ -137,11 +154,12 @@ async function main() {
|
|
|
137
154
|
|
|
138
155
|
await fs.mkdir(outputDir, { recursive: true });
|
|
139
156
|
await fs.writeFile(outputPath, html, 'utf8');
|
|
157
|
+
await keepOnlyOutputFile(outputPath);
|
|
140
158
|
|
|
141
|
-
console.log(`[build-
|
|
159
|
+
console.log(`[build-android] Gerado: ${outputPath}`);
|
|
142
160
|
}
|
|
143
161
|
|
|
144
162
|
main().catch((error) => {
|
|
145
|
-
console.error('[build-
|
|
163
|
+
console.error('[build-android] Falha:', error);
|
|
146
164
|
process.exit(1);
|
|
147
165
|
});
|