4 Commits

15 changed files with 2492 additions and 1993 deletions
+28
View File
@@ -0,0 +1,28 @@
{
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartdeno",
"description": "A module to run Deno scripts from Node.js, including functionalities for downloading Deno and executing Deno scripts.",
"npmPackagename": "@push.rocks/smartdeno",
"license": "MIT",
"projectDomain": "push.rocks"
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"@git.zone/tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
},
"@ship.zone/szci": {
"npmGlobalTools": [],
"npmRegistryUrl": "registry.npmjs.org"
}
}
+18
View File
@@ -1,5 +1,23 @@
# Changelog # Changelog
## 2026-04-30 - 1.2.1 - fix(smartdeno)
normalize stderr output to an empty string and update build configuration
- Ensure executeScript always returns a string for stderr in both stdin and temp-file execution paths.
- Adjust tests and TypeScript/build settings for stricter typing and updated toolchain compatibility.
- Refresh package metadata and project configuration files, including registry and issue tracker settings.
## 2025-12-02 - 1.2.0 - feat(smartdeno)
Run small scripts in-memory via stdin, fall back to temp files for large scripts; remove internal HTTP script server and simplify plugin dependencies; update API and docs.
- Execute scripts < 2MB via stdin (deno run -) to support fully in-memory execution with no disk I/O.
- Automatically write scripts >= 2MB to a temp file under .nogit and clean up after execution.
- Removed internal HTTP script server implementation and related types; start() no longer starts a script server.
- Dropped plugin dependencies and exports related to @api.global/typedserver and @push.rocks/lik; plugins.ts simplified to only include necessary push.rocks modules and node path.
- Updated package.json to remove unused dependencies and adjust keywords to reflect in-memory execution.
- Updated README to document new start() behavior, in-memory execution, temp-file fallback, and simplified API signatures (start/stop/isRunning/executeScript).
- ts index now only exports SmartDeno (removed direct type export of TDenoPermission from separate file).
## 2025-12-02 - 1.1.0 - feat(core) ## 2025-12-02 - 1.1.0 - feat(core)
Add permission-controlled Deno execution, configurable script server port, improved downloader, dependency bumps and test updates Add permission-controlled Deno execution, configurable script server port, improved downloader, dependency bumps and test updates
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2026 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+13 -6
View File
@@ -1,5 +1,5 @@
{ {
"gitzone": { "@git.zone/cli": {
"projectType": "npm", "projectType": "npm",
"module": { "module": {
"githost": "code.foss.global", "githost": "code.foss.global",
@@ -21,13 +21,20 @@
"Ephemeral Execution", "Ephemeral Execution",
"Cross-platform" "Cross-platform"
] ]
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
} }
}, },
"npmci": { "@git.zone/tsdoc": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
},
"tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n" "legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
},
"@ship.zone/szci": {
"npmGlobalTools": [],
"npmRegistryUrl": "registry.npmjs.org"
} }
} }
+15 -15
View File
@@ -1,6 +1,6 @@
{ {
"name": "@push.rocks/smartdeno", "name": "@push.rocks/smartdeno",
"version": "1.1.0", "version": "1.2.1",
"private": false, "private": false,
"description": "A module to run Deno scripts from Node.js, including functionalities for downloading Deno and executing Deno scripts.", "description": "A module to run Deno scripts from Node.js, including functionalities for downloading Deno and executing Deno scripts.",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@@ -10,22 +10,20 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "(tstest test/ --verbose --timeout 60)", "test": "(tstest test/ --verbose --timeout 60)",
"build": "(tsbuild --web --allowimplicitany)", "build": "tsbuild --web",
"buildDocs": "(tsdoc)" "buildDocs": "(tsdoc)"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^3.1.2", "@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsrun": "^2.0.0", "@git.zone/tsrun": "^2.0.3",
"@git.zone/tstest": "^3.1.3", "@git.zone/tstest": "^3.6.3",
"@types/node": "^24.10.1" "@types/node": "^25.6.0"
}, },
"dependencies": { "dependencies": {
"@api.global/typedserver": "^4.0.0", "@push.rocks/smartarchive": "^5.2.2",
"@push.rocks/lik": "^6.2.2", "@push.rocks/smartfs": "^1.5.1",
"@push.rocks/smartarchive": "^5.0.1",
"@push.rocks/smartfs": "^1.2.0",
"@push.rocks/smartpath": "^6.0.0", "@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartshell": "^3.3.0", "@push.rocks/smartshell": "^3.3.8",
"@push.rocks/smartunique": "^3.0.9" "@push.rocks/smartunique": "^3.0.9"
}, },
"repository": { "repository": {
@@ -33,7 +31,7 @@
"url": "https://code.foss.global/push.rocks/smartdeno.git" "url": "https://code.foss.global/push.rocks/smartdeno.git"
}, },
"bugs": { "bugs": {
"url": "https://gitlab.com/push.rocks/smartdeno/issues" "url": "https://code.foss.global/push.rocks/smartdeno/issues"
}, },
"homepage": "https://code.foss.global/push.rocks/smartdeno", "homepage": "https://code.foss.global/push.rocks/smartdeno",
"browserslist": [ "browserslist": [
@@ -48,6 +46,8 @@
"dist_ts_web/**/*", "dist_ts_web/**/*",
"assets/**/*", "assets/**/*",
"cli.js", "cli.js",
".smartconfig.json",
"license",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"
], ],
@@ -59,9 +59,9 @@
"Development Tools", "Development Tools",
"Deno Download", "Deno Download",
"Code Execution", "Code Execution",
"Scripting Server",
"Ephemeral Execution", "Ephemeral Execution",
"Cross-platform" "Cross-platform",
"In-memory"
], ],
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34" "packageManager": "pnpm@10.28.2"
} }
+2281 -1793
View File
File diff suppressed because it is too large Load Diff
+5 -9
View File
@@ -43,9 +43,6 @@ await smartDeno.stop();
await smartDeno.start({ await smartDeno.start({
// Force download a local copy of Deno even if it's in PATH // Force download a local copy of Deno even if it's in PATH
forceLocalDeno: true, forceLocalDeno: true,
// Custom port for the internal script server (default: 3210)
port: 4000,
}); });
``` ```
@@ -153,7 +150,7 @@ const smartDeno = new SmartDeno();
app.use(express.json()); app.use(express.json());
// Initialize on startup // Initialize on startup
await smartDeno.start({ port: 3211 }); await smartDeno.start();
app.post('/execute', async (req, res) => { app.post('/execute', async (req, res) => {
const { script, permissions } = req.body; const { script, permissions } = req.body;
@@ -180,8 +177,8 @@ app.listen(3000);
SmartDeno works by: SmartDeno works by:
1. **🦕 Deno Management** — Automatically downloads the latest Deno binary for your platform if not available or if `forceLocalDeno` is set 1. **🦕 Deno Management** — Automatically downloads the latest Deno binary for your platform if not available or if `forceLocalDeno` is set
2. **🖥️ Script Server** — Runs an internal HTTP server that serves scripts to Deno 2. **💾 In-Memory Execution** — Scripts < 2MB are executed via stdin (`deno run -`), staying fully in-memory with no disk I/O
3. **⚡ Ephemeral Execution** — Each script execution is isolated and cleaned up after completion 3. **📁 Large Script Support** — Scripts >= 2MB automatically use a temp file (cleaned up after execution)
4. **🔒 Permission Control** — Translates permission options to Deno's security flags 4. **🔒 Permission Control** — Translates permission options to Deno's security flags
## 📚 API Reference ## 📚 API Reference
@@ -198,8 +195,8 @@ const smartDeno = new SmartDeno();
| Method | Description | | Method | Description |
|--------|-------------| |--------|-------------|
| `start(options?)` | Initialize and start SmartDeno | | `start(options?)` | Initialize SmartDeno (downloads Deno if needed) |
| `stop()` | Stop SmartDeno and clean up resources | | `stop()` | Stop SmartDeno instance |
| `isRunning()` | Check if SmartDeno is currently running | | `isRunning()` | Check if SmartDeno is currently running |
| `executeScript(script, options?)` | Execute a Deno script | | `executeScript(script, options?)` | Execute a Deno script |
@@ -208,7 +205,6 @@ const smartDeno = new SmartDeno();
```typescript ```typescript
interface ISmartDenoOptions { interface ISmartDenoOptions {
forceLocalDeno?: boolean; forceLocalDeno?: boolean;
port?: number;
} }
interface IExecuteScriptOptions { interface IExecuteScriptOptions {
+3
View File
@@ -15,6 +15,9 @@ tap.test('should throw when executing before start', async () => {
await testSmartdeno.executeScript('console.log("test")'); await testSmartdeno.executeScript('console.log("test")');
} catch (e) { } catch (e) {
threw = true; threw = true;
if (!(e instanceof Error)) {
throw e;
}
expect(e.message).toInclude('not started'); expect(e.message).toInclude('not started');
} }
expect(threw).toBeTrue(); expect(threw).toBeTrue();
+1 -1
View File
@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartdeno', name: '@push.rocks/smartdeno',
version: '1.1.0', version: '1.2.1',
description: 'A module to run Deno scripts from Node.js, including functionalities for downloading Deno and executing Deno scripts.' description: 'A module to run Deno scripts from Node.js, including functionalities for downloading Deno and executing Deno scripts.'
} }
-69
View File
@@ -1,69 +0,0 @@
import type { ScriptServer } from './classes.scriptserver.js';
import * as plugins from './plugins.js';
export type TDenoPermission =
| 'all'
| 'env'
| 'ffi'
| 'hrtime'
| 'net'
| 'read'
| 'run'
| 'sys'
| 'write';
export interface IDenoExecutionOptions {
permissions?: TDenoPermission[];
denoBinaryPath?: string;
}
/**
* This class contains logic to execute deno commands in an ephemeral way
*/
export class DenoExecution {
public id: string;
public scriptserverRef: ScriptServer;
public script: string;
public options: IDenoExecutionOptions;
constructor(scriptserverRef: ScriptServer, scriptArg: string, options: IDenoExecutionOptions = {}) {
this.scriptserverRef = scriptserverRef;
this.script = scriptArg;
this.options = options;
this.id = plugins.smartunique.shortId();
}
private buildPermissionFlags(): string {
const permissions = this.options.permissions || [];
if (permissions.length === 0) {
return '';
}
if (permissions.includes('all')) {
return '-A';
}
return permissions.map(p => `--allow-${p}`).join(' ');
}
public async execute(): Promise<{ exitCode: number; stdout: string; stderr: string }> {
this.scriptserverRef.executionMap.add(this);
try {
const denoBinary = this.options.denoBinaryPath || 'deno';
const permissionFlags = this.buildPermissionFlags();
const port = this.scriptserverRef.getPort();
const scriptUrl = `http://localhost:${port}/getscript/${this.id}`;
const command = `${denoBinary} run ${permissionFlags} ${scriptUrl}`.replace(/\s+/g, ' ').trim();
const result = await this.scriptserverRef.smartshellInstance.exec(command);
return {
exitCode: result.exitCode,
stdout: result.stdout,
stderr: result.stderr,
};
} finally {
// Clean up: remove from execution map after execution completes
this.scriptserverRef.executionMap.remove(this);
}
}
}
-56
View File
@@ -1,56 +0,0 @@
import type { DenoExecution } from './classes.denoexecution.js';
import * as plugins from './plugins.js';
export interface IScriptServerOptions {
port?: number;
}
export class ScriptServer {
private server: plugins.typedserver.servertools.Server;
private port: number;
public smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash'
});
public executionMap = new plugins.lik.ObjectMap<DenoExecution>();
constructor(options: IScriptServerOptions = {}) {
this.port = options.port ?? 3210;
}
public getPort(): number {
return this.port;
}
public async start() {
this.server = new plugins.typedserver.servertools.Server({
port: this.port,
cors: true,
});
this.server.addRoute(
'/getscript/:executionId',
new plugins.typedserver.servertools.Handler('GET', async (req, res) => {
const executionId = req.params.executionId;
const denoExecution = await this.executionMap.find(async denoExecutionArg => {
return denoExecutionArg.id === executionId;
});
if (!denoExecution) {
res.statusCode = 404;
res.write('Execution not found');
res.end();
return;
}
res.write(denoExecution.script);
res.end();
})
);
await this.server.start();
}
public async stop() {
if (this.server) {
await this.server.stop();
}
this.executionMap.wipe();
}
}
+101 -28
View File
@@ -1,18 +1,25 @@
import { DenoDownloader } from './classes.denodownloader.js'; import { DenoDownloader } from './classes.denodownloader.js';
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
import * as paths from './paths.js'; import * as paths from './paths.js';
import { ScriptServer } from './classes.scriptserver.js';
import { DenoExecution, type TDenoPermission } from './classes.denoexecution.js'; const MAX_STDIN_SIZE = 2 * 1024 * 1024; // 2MB threshold for stdin execution
export type TDenoPermission =
| 'all'
| 'env'
| 'ffi'
| 'hrtime'
| 'net'
| 'read'
| 'run'
| 'sys'
| 'write';
export interface ISmartDenoOptions { export interface ISmartDenoOptions {
/** /**
* Force downloading a local copy of Deno even if it's available in PATH * Force downloading a local copy of Deno even if it's available in PATH
*/ */
forceLocalDeno?: boolean; forceLocalDeno?: boolean;
/**
* Port for the internal script server (default: 3210)
*/
port?: number;
} }
export interface IExecuteScriptOptions { export interface IExecuteScriptOptions {
@@ -24,16 +31,14 @@ export interface IExecuteScriptOptions {
export class SmartDeno { export class SmartDeno {
private denoDownloader = new DenoDownloader(); private denoDownloader = new DenoDownloader();
private scriptServer: ScriptServer;
private denoBinaryPath: string | null = null; private denoBinaryPath: string | null = null;
private isStarted = false; private isStarted = false;
private smartshellInstance = new plugins.smartshell.Smartshell({
constructor() { executor: 'bash',
this.scriptServer = new ScriptServer(); });
}
/** /**
* Starts the SmartDeno instance * Starts the SmartDeno instance (downloads Deno if needed)
* @param optionsArg Configuration options * @param optionsArg Configuration options
*/ */
public async start(optionsArg: ISmartDenoOptions = {}): Promise<void> { public async start(optionsArg: ISmartDenoOptions = {}): Promise<void> {
@@ -41,11 +46,8 @@ export class SmartDeno {
return; return;
} }
// Create script server with configured port
this.scriptServer = new ScriptServer({ port: optionsArg.port });
const denoAlreadyInPath = await plugins.smartshell.which('deno', { const denoAlreadyInPath = await plugins.smartshell.which('deno', {
nothrow: true nothrow: true,
}); });
if (!denoAlreadyInPath || optionsArg.forceLocalDeno) { if (!denoAlreadyInPath || optionsArg.forceLocalDeno) {
@@ -56,19 +58,13 @@ export class SmartDeno {
this.denoBinaryPath = 'deno'; this.denoBinaryPath = 'deno';
} }
await this.scriptServer.start();
this.isStarted = true; this.isStarted = true;
} }
/** /**
* Stops the SmartDeno instance and cleans up resources * Stops the SmartDeno instance
*/ */
public async stop(): Promise<void> { public async stop(): Promise<void> {
if (!this.isStarted) {
return;
}
await this.scriptServer.stop();
this.isStarted = false; this.isStarted = false;
} }
@@ -79,6 +75,19 @@ export class SmartDeno {
return this.isStarted; return this.isStarted;
} }
/**
* Build permission flags for Deno
*/
private buildPermissionFlags(permissions?: TDenoPermission[]): string {
if (!permissions || permissions.length === 0) {
return '';
}
if (permissions.includes('all')) {
return '-A';
}
return permissions.map((p) => `--allow-${p}`).join(' ');
}
/** /**
* Execute a Deno script * Execute a Deno script
* @param scriptArg The script content to execute * @param scriptArg The script content to execute
@@ -93,11 +102,75 @@ export class SmartDeno {
throw new Error('SmartDeno is not started. Call start() first.'); throw new Error('SmartDeno is not started. Call start() first.');
} }
const denoExecution = new DenoExecution(this.scriptServer, scriptArg, { const denoBinary = this.denoBinaryPath || 'deno';
permissions: options.permissions, const permissionFlags = this.buildPermissionFlags(options.permissions);
denoBinaryPath: this.denoBinaryPath || undefined, const scriptSize = Buffer.byteLength(scriptArg, 'utf8');
});
return denoExecution.execute(); if (scriptSize < MAX_STDIN_SIZE) {
// Use stdin for small scripts (in-memory)
return this.executeViaStdin(denoBinary, permissionFlags, scriptArg);
} else {
// Use temp file for large scripts
return this.executeViaTempFile(denoBinary, permissionFlags, scriptArg);
}
}
/**
* Execute script via stdin (in-memory, for scripts < 2MB)
* Uses `deno run -` which reads from stdin and supports all permission flags
*/
private async executeViaStdin(
denoBinary: string,
permissionFlags: string,
script: string
): Promise<{ exitCode: number; stdout: string; stderr: string }> {
// Use base64 encoding to safely pass script through shell
const base64Script = Buffer.from(script).toString('base64');
const command = `echo '${base64Script}' | base64 -d | ${denoBinary} run ${permissionFlags} -`.trim().replace(/\s+/g, ' ');
const result = await this.smartshellInstance.exec(command);
return {
exitCode: result.exitCode,
stdout: result.stdout,
stderr: result.stderr ?? '',
};
}
/**
* Execute script via temp file (for scripts >= 2MB)
*/
private async executeViaTempFile(
denoBinary: string,
permissionFlags: string,
script: string
): Promise<{ exitCode: number; stdout: string; stderr: string }> {
const tempFileName = `deno_script_${plugins.smartunique.shortId()}.ts`;
const tempFilePath = plugins.path.join(paths.nogitDir, tempFileName);
const fsInstance = new plugins.smartfs.SmartFs(new plugins.smartfs.SmartFsProviderNode());
try {
// Ensure .nogit directory exists
await fsInstance.directory(paths.nogitDir).create();
// Write script to temp file
await fsInstance.file(tempFilePath).write(script);
// Execute the script
const command = `${denoBinary} run ${permissionFlags} "${tempFilePath}"`.trim().replace(/\s+/g, ' ');
const result = await this.smartshellInstance.exec(command);
return {
exitCode: result.exitCode,
stdout: result.stdout,
stderr: result.stderr ?? '',
};
} finally {
// Clean up temp file
try {
await fsInstance.file(tempFilePath).delete();
} catch {
// Ignore cleanup errors
}
}
} }
} }
-1
View File
@@ -1,2 +1 @@
export * from './classes.smartdeno.js'; export * from './classes.smartdeno.js';
export type { TDenoPermission } from './classes.denoexecution.js';
-9
View File
@@ -5,15 +5,7 @@ export {
path, path,
} }
// @api.global scope
import * as typedserver from '@api.global/typedserver';
export {
typedserver,
}
// @push.rocks scope // @push.rocks scope
import * as lik from '@push.rocks/lik';
import * as smartarchive from '@push.rocks/smartarchive'; import * as smartarchive from '@push.rocks/smartarchive';
import * as smartfs from '@push.rocks/smartfs'; import * as smartfs from '@push.rocks/smartfs';
import * as smartpath from '@push.rocks/smartpath'; import * as smartpath from '@push.rocks/smartpath';
@@ -21,7 +13,6 @@ import * as smartshell from '@push.rocks/smartshell';
import * as smartunique from '@push.rocks/smartunique'; import * as smartunique from '@push.rocks/smartunique';
export { export {
lik,
smartarchive, smartarchive,
smartfs, smartfs,
smartpath, smartpath,
+4 -4
View File
@@ -5,10 +5,10 @@
"target": "ES2022", "target": "ES2022",
"module": "NodeNext", "module": "NodeNext",
"moduleResolution": "NodeNext", "moduleResolution": "NodeNext",
"noImplicitAny": true,
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true "verbatimModuleSyntax": true,
"types": ["node"]
}, },
"exclude": [ "exclude": ["dist_*/**/*.d.ts"]
"dist_*/**/*.d.ts"
]
} }