typenative 0.0.10 → 0.0.12

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
@@ -4,7 +4,8 @@ Build native applications using Typescript.
4
4
 
5
5
  ## PreRequisites
6
6
 
7
- - Go 1.21 or newer.
7
+ - [Nodejs v20](https://nodejs.org/en) or newer.
8
+ - [Go 1.21](https://go.dev/doc/install) or newer.
8
9
 
9
10
  ## Get Started
10
11
 
@@ -12,6 +13,12 @@ Build native applications using Typescript.
12
13
  - Run `npx typenative --source test.ts --script`
13
14
  - See your message in the terminal
14
15
 
16
+ ## Create a TypeNative Project
17
+
18
+ - Run `npx typenative --new`
19
+ - Give your project a name
20
+ - Start writing code
21
+
15
22
  ## Typescript Syntax Support
16
23
 
17
24
  TypeNative currently supports a subset of TypeScript syntax elements that are transpiled to Go code:
@@ -33,18 +40,24 @@ TypeNative currently supports a subset of TypeScript syntax elements that are tr
33
40
  | Increment/Decrement | ✅ | `++`, `--` |
34
41
  | **Control Flow** | | |
35
42
  | For loops | ✅ | Standard `for` loops |
43
+ | For...of loops | ✅ | Iteration over arrays |
44
+ | While loops | ✅ | Transpiled to Go's `for` loops |
45
+ | Do...while loops | ✅ | Implemented with conditional break |
46
+ | If/Else statements | ✅ | Fully supported |
47
+ | Switch statements | ✅ | Case and default statements |
36
48
  | **Data Structures** | | |
37
49
  | Arrays | ✅ | Basic array operations |
50
+ | Array methods | ✅ | `push` supported |
38
51
  | **Functions** | | |
52
+ | Function declarations | ✅ | Transpiled to Go functions |
53
+ | Arrow Functions | ✅ | Transpiled to anonymous functions |
39
54
  | console.log | ✅ | Mapped to `fmt.Println` |
55
+ | console.time/timeEnd | ✅ | Performance measurement |
56
+ | Math.random | ✅ | Mapped to Go's `rand.Float64()` |
57
+ | Math.floor | ✅ | Mapped to Go's `math.Floor()` |
40
58
  | **Unsupported Features** | | |
41
59
  | Classes | ❌ | Not implemented |
42
60
  | Interfaces | ❌ | Not implemented |
43
- | Functions | ❌ | Custom function definitions not supported |
44
- | Arrow Functions | ❌ | Not implemented |
45
- | If/Else statements | ❌ | Not implemented |
46
- | While/Do loops | ❌ | Not implemented |
47
- | Switch statements | ❌ | Not implemented |
48
61
  | Async/Await | ❌ | Not implemented |
49
62
  | Modules/Imports | ❌ | Not implemented |
50
63
  | Generics | ❌ | Not implemented |
package/bin/index.js CHANGED
@@ -1,53 +1,150 @@
1
1
  #!/usr/bin/env node
2
2
  import inquirer from 'inquirer';
3
- import shell from 'shelljs';
4
3
  import fs from 'fs-extra';
5
4
  import path from 'path';
5
+ import { execa } from 'execa';
6
6
  import { transpileToNative } from './transpiler.js';
7
7
  import { fileURLToPath } from 'url';
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
10
  (async function main() {
11
11
  const scriptMode = process.argv.findIndex((a) => a === '--script') > -1;
12
- const targetIndex = process.argv.findIndex((a) => a === '--source');
13
- const target = targetIndex > -1 ? process.argv[targetIndex + 1] : null;
12
+ const newCommand = process.argv.findIndex((a) => a === '--new') > -1;
13
+ const sourceIndex = process.argv.findIndex((a) => a === '--source');
14
+ const source = sourceIndex > -1 ? process.argv[sourceIndex + 1] : null;
15
+ const outputIndex = process.argv.findIndex((a) => a === '--output');
16
+ const output = outputIndex > -1 ? process.argv[outputIndex + 1] : null;
14
17
  const answers = await inquirer.prompt([
18
+ {
19
+ type: 'input',
20
+ name: 'projectName',
21
+ message: 'Enter Project Name:',
22
+ when: newCommand,
23
+ validate: (input) => input.trim() !== ''
24
+ },
25
+ {
26
+ type: 'confirm',
27
+ name: 'installDependencies',
28
+ message: 'Do you want to install dependencies?',
29
+ when: newCommand
30
+ },
15
31
  {
16
32
  type: 'input',
17
33
  name: 'path',
18
34
  message: 'Enter Path to typescript main file:',
19
- when: !scriptMode && !target
35
+ when: !newCommand && !scriptMode && !source,
36
+ validate: (input) => input.trim() !== ''
20
37
  },
21
38
  {
22
39
  type: 'input',
23
40
  name: 'output',
24
41
  message: 'Enter Output Path:',
25
- when: !scriptMode && !target
42
+ when: !newCommand && !scriptMode && !output,
43
+ validate: (input) => input.trim() !== ''
26
44
  },
27
45
  {
28
46
  type: 'editor',
29
47
  name: 'tsCode',
30
- message: 'Write your typescript code and save',
31
- when: scriptMode && !target
48
+ message: 'Write your typescript code here:',
49
+ when: !newCommand && scriptMode && !source,
50
+ default: `console.log('Hello, World!');`
32
51
  }
33
52
  ]);
53
+ if (newCommand) {
54
+ const projectName = answers.projectName.trim();
55
+ await fs.ensureDir(projectName);
56
+ await fs.writeFile(path.join(projectName, 'main.ts'), `// Write your TypeScript code here\nconsole.log('Hello, World!');\n`, { encoding: 'utf-8' });
57
+ await fs.writeFile(path.join(projectName, 'tsconfig.json'), getTsConfig(), {
58
+ encoding: 'utf-8'
59
+ });
60
+ await fs.writeFile(path.join(projectName, 'package.json'), getPackageJson(projectName), {
61
+ encoding: 'utf-8'
62
+ });
63
+ await fs.writeFile(path.join(projectName, '.gitignore'), getGitIgnore(), {
64
+ encoding: 'utf-8'
65
+ });
66
+ await fs.writeFile(path.join(projectName, 'README.md'), getReadMe(projectName), {
67
+ encoding: 'utf-8'
68
+ });
69
+ console.log(`Project "${projectName}" created successfully!`);
70
+ if (answers.installDependencies) {
71
+ console.log('Installing dependencies...');
72
+ await execa('npm install', { cwd: projectName, stdio: 'inherit' });
73
+ console.log('Dependencies installed successfully!');
74
+ }
75
+ return;
76
+ }
34
77
  const tsCode = answers.tsCode
35
78
  ? answers.tsCode
36
- : await fs.readFile(target ?? answers.path, { encoding: 'utf-8' });
79
+ : await fs.readFile(source ?? answers.path, { encoding: 'utf-8' });
37
80
  const nativeCode = transpileToNative(tsCode);
38
81
  await fs.ensureDir('dist');
39
82
  await fs.writeFile('dist/code.go', nativeCode, { encoding: 'utf-8' });
40
- shell.exec('go build -o dist/native.exe dist/code.go');
83
+ await execa('go build -o dist/native.exe dist/code.go', {
84
+ stdio: 'inherit'
85
+ });
41
86
  // await fs.remove('dist/code.go');
42
- if (answers.output) {
43
- await fs.copy('dist/native.exe', answers.output, { overwrite: true });
44
- await fs.remove('dist/native.exe');
45
- }
46
87
  if (scriptMode) {
47
- shell.exec(path.join('dist', 'native.exe'));
48
- await fs.remove('dist/native.exe');
88
+ await execa('dist/native.exe', {
89
+ stdio: 'inherit'
90
+ });
91
+ //await fs.remove('dist/native.exe');
49
92
  }
50
- else {
51
- console.log('DONE');
93
+ else if (output || answers.output) {
94
+ await fs.copy('dist/native.exe', output ?? answers.output, { overwrite: true });
95
+ //await fs.remove('dist/native.exe');
96
+ console.log(`Created native executable at: ${output ?? answers.output}`);
52
97
  }
53
98
  })();
99
+ function getPackageJson(projectName) {
100
+ const pckg = {
101
+ name: projectName,
102
+ version: '1.0.0',
103
+ scripts: {
104
+ execute: 'npx typenative --source main.ts --script',
105
+ build: `npx typenative --source main.ts --output bin/${projectName}.exe`
106
+ },
107
+ devDependencies: {
108
+ typenative: '^0.12.0'
109
+ }
110
+ };
111
+ return JSON.stringify(pckg, null, 2);
112
+ }
113
+ function getTsConfig() {
114
+ const tsConfig = {
115
+ include: ['*.ts'],
116
+ compilerOptions: {
117
+ target: 'es2020',
118
+ lib: [],
119
+ types: ['./node_modules/types/typenative.d.ts'],
120
+ rootDir: '.',
121
+ strict: true,
122
+ noImplicitAny: true
123
+ }
124
+ };
125
+ return JSON.stringify(tsConfig, null, 2);
126
+ }
127
+ function getGitIgnore() {
128
+ return `# TypeNative generated files
129
+ node_modules/
130
+ dist/
131
+ bin/
132
+ `;
133
+ }
134
+ function getReadMe(projectName) {
135
+ return `# ${projectName}
136
+
137
+ This project was created using TypeNative, a tool to transpile TypeScript code to native Go code.
138
+
139
+ ## How to Run
140
+
141
+ 1. Install dependencies: \`npm install\`
142
+ 2. Build the project: \`npm run build\`
143
+ 3. Run the executable: \`./dist/native.exe\`
144
+
145
+ ## How to Use
146
+
147
+ You can write your TypeScript code in the \`main.ts\` file. The code will be transpiled to Go and compiled into a native executable.
148
+ You can also run the code directly in script mode using \`npm run execute\`.
149
+ `;
150
+ }
package/bin/transpiler.js CHANGED
@@ -1,111 +1,253 @@
1
- import ts from 'typescript';
2
- let TypeCheker;
3
- export function transpileToNative(code) {
4
- const sourceFile = ts.createSourceFile('main.ts', code, ts.ScriptTarget.ES2020, true, ts.ScriptKind.TS);
5
- TypeCheker = ts.createProgram(['main.ts'], {}).getTypeChecker();
1
+ import ts from 'typescript';
2
+ let TypeCheker;
3
+ const importedPackages = new Set();
4
+ let outsideNodes = [];
5
+ export function transpileToNative(code) {
6
+ const sourceFile = ts.createSourceFile('main.ts', code, ts.ScriptTarget.ES2020, true, ts.ScriptKind.TS);
7
+ TypeCheker = ts.createProgram(['main.ts'], {}).getTypeChecker();
8
+ importedPackages.clear();
9
+ outsideNodes = [];
10
+ const transpiledCode = visit(sourceFile, { addFunctionOutside: true });
11
+ const transpiledCodeOutside = outsideNodes.map((n) => visit(n, { isOutside: true })).join('\n');
6
12
  return `package main
7
13
 
8
- import "fmt"
14
+ ${[...importedPackages].map((pkg) => `import "${pkg}"`).join('\n')}
9
15
 
10
16
  func main() {
11
- ${visit(sourceFile)}
12
- }`;
13
- }
14
- export function visit(node, inline = false) {
15
- let code = '';
16
- if (ts.isIdentifier(node)) {
17
- return node.text;
18
- }
19
- else if (ts.isStringLiteral(node)) {
20
- return `"${node.text}"`;
21
- }
22
- else if (ts.isNumericLiteral(node)) {
23
- return `float64(${node.text})`;
24
- }
25
- else if (ts.isToken(node) && node.kind === ts.SyntaxKind.TrueKeyword) {
26
- return `true`;
27
- }
28
- else if (ts.isToken(node) && node.kind === ts.SyntaxKind.FalseKeyword) {
29
- return `false`;
30
- }
31
- else if (ts.isBlock(node)) {
32
- return `{\n\t\t${node.statements.map((n) => visit(n)).join('\t')}}\n\t`;
33
- }
34
- else if (ts.isPropertyAccessExpression(node)) {
35
- return `${visit(node.expression)}.${visit(node.name)}`;
36
- }
37
- else if (ts.isVariableDeclaration(node)) {
38
- const type = getType(node.type);
39
- const initializer = node.initializer ? `= ${visit(node.initializer)}` : '';
40
- return `${type === ':' ? '' : 'var'} ${visit(node.name)} ${type}${type === ':' ? '' : ' '}${initializer}`;
41
- }
42
- else if (ts.isCallExpression(node)) {
43
- const expr = visit(node.expression);
44
- return `${getFunction(expr)}(${node.arguments.map((a) => visit(a)).join(',')})`;
45
- }
46
- else if (ts.isPrefixUnaryExpression(node)) {
47
- return `${getOperatorText(node.operator)}${visit(node.operand)}`;
48
- }
49
- else if (ts.isPostfixUnaryExpression(node)) {
50
- return `${visit(node.operand, true)}${getOperatorText(node.operator)}`;
51
- }
52
- else if (ts.isBinaryExpression(node)) {
53
- return `${visit(node.left)} ${node.operatorToken.getText()} ${visit(node.right)}`;
54
- }
55
- else if (ts.isParenthesizedExpression(node)) {
56
- return `(${visit(node.expression)})`;
57
- }
58
- else if (ts.isVariableDeclarationList(node)) {
59
- return (node.declarations.map((n) => visit(n)).join(inline ? ';' : ';\n\t') + (inline ? ';' : ';\n\t'));
60
- }
61
- else if (ts.isExpressionStatement(node)) {
62
- return visit(node.expression) + (inline ? ';' : ';\n\t');
63
- }
64
- else if (ts.isForStatement(node)) {
65
- return `for${visit(node.initializer, true)} ${visit(node.condition, true)}; ${visit(node.incrementor, true)}${visit(node.statement)}`;
66
- }
67
- console.log(ts.SyntaxKind[node.kind], node.getText());
68
- ts.forEachChild(node, (subNode) => {
69
- code += visit(subNode);
70
- return null;
71
- });
72
- return code;
73
- }
74
- function getType(typeNode) {
75
- const type = TypeCheker.getTypeFromTypeNode(typeNode);
76
- const typeName = TypeCheker.typeToString(type);
77
- switch (typeName) {
78
- case 'number':
79
- return 'float64';
80
- case 'boolean':
81
- return 'bool';
82
- case 'any':
83
- return ':';
84
- default:
85
- return typeName;
86
- }
87
- }
88
- function getFunction(expr) {
89
- switch (expr) {
90
- case 'console.log':
91
- return 'fmt.Println';
92
- default:
93
- return expr;
94
- }
95
- }
96
- function getOperatorText(operator) {
97
- switch (operator) {
98
- case ts.SyntaxKind.PlusToken:
99
- return '+';
100
- case ts.SyntaxKind.MinusToken:
101
- return '-';
102
- case ts.SyntaxKind.TildeToken:
103
- return '~';
104
- case ts.SyntaxKind.ExclamationToken:
105
- return '!';
106
- case ts.SyntaxKind.PlusPlusToken:
107
- return '++';
108
- case ts.SyntaxKind.MinusMinusToken:
109
- return '--';
110
- }
111
- }
17
+ ${transpiledCode.trim()}
18
+ }
19
+
20
+ ${transpiledCodeOutside.trim()}`;
21
+ }
22
+ export function visit(node, options = {}) {
23
+ let code = '';
24
+ if (ts.isSourceFile(node)) {
25
+ return node.statements
26
+ .map((n) => visit(n, { addFunctionOutside: true }))
27
+ .filter((n) => !!n)
28
+ .join(options.inline ? '' : '\n\t');
29
+ }
30
+ else if (ts.isIdentifier(node)) {
31
+ return node.text;
32
+ }
33
+ else if (ts.isStringLiteral(node)) {
34
+ return `"${node.text}"`;
35
+ }
36
+ else if (ts.isNumericLiteral(node)) {
37
+ return `float64(${node.text})`;
38
+ }
39
+ else if (ts.isToken(node) && node.kind === ts.SyntaxKind.TrueKeyword) {
40
+ return `true`;
41
+ }
42
+ else if (ts.isToken(node) && node.kind === ts.SyntaxKind.FalseKeyword) {
43
+ return `false`;
44
+ }
45
+ else if (ts.isArrayLiteralExpression(node)) {
46
+ const type = ts.isVariableDeclaration(node.parent) ? getType(node.parent.type, true) : '';
47
+ return `[]${type} {${node.elements.map((e) => visit(e)).join(', ')}}`;
48
+ }
49
+ else if (ts.isBlock(node)) {
50
+ return `{\n\t\t${node.statements.map((n) => visit(n)).join('\t')}${options.extraBlockContent ?? ''}}${options.inline ? '' : '\n\t'}`;
51
+ }
52
+ else if (ts.isElementAccessExpression(node)) {
53
+ return `${visit(node.expression)}[int(${visit(node.argumentExpression)})]`;
54
+ }
55
+ else if (ts.isPropertyAccessExpression(node)) {
56
+ const leftSide = visit(node.expression);
57
+ const rightSide = visit(node.name);
58
+ return getAcessString(leftSide, rightSide);
59
+ }
60
+ else if (ts.isVariableDeclaration(node)) {
61
+ const type = getType(node.type);
62
+ const initializer = node.initializer ? `= ${visit(node.initializer)}` : '';
63
+ return `${type === ':' ? '' : 'var '}${visit(node.name)} ${type}${type === ':' ? '' : ' '}${initializer}`;
64
+ }
65
+ else if (ts.isCallExpression(node)) {
66
+ const caller = visit(node.expression);
67
+ const args = node.arguments.map((a) => visit(a));
68
+ return getCallString(caller, args);
69
+ }
70
+ else if (ts.isPrefixUnaryExpression(node)) {
71
+ return `${getOperatorText(node.operator)}${visit(node.operand)}`;
72
+ }
73
+ else if (ts.isPostfixUnaryExpression(node)) {
74
+ return `${visit(node.operand, { inline: true })}${getOperatorText(node.operator)}`;
75
+ }
76
+ else if (ts.isBinaryExpression(node)) {
77
+ return `${visit(node.left)} ${node.operatorToken.getText()} ${visit(node.right)}`;
78
+ }
79
+ else if (ts.isParenthesizedExpression(node)) {
80
+ return `(${visit(node.expression)})`;
81
+ }
82
+ else if (ts.isVariableDeclarationList(node)) {
83
+ return (node.declarations.map((n) => visit(n)).join(options.inline ? ';' : ';\n\t') +
84
+ (options.inline ? '' : ';\n\t'));
85
+ }
86
+ else if (ts.isExpressionStatement(node)) {
87
+ return visit(node.expression) + (options.inline ? '' : ';\n\t');
88
+ }
89
+ else if (ts.isForStatement(node)) {
90
+ return `for ${visit(node.initializer, { inline: true })}; ${visit(node.condition, {
91
+ inline: true
92
+ })}; ${visit(node.incrementor, { inline: true })}${visit(node.statement)}`;
93
+ }
94
+ else if (ts.isForOfStatement(node)) {
95
+ return `for _,${visit(node.initializer, { inline: true })}= range ${visit(node.expression, {
96
+ inline: true
97
+ })}${visit(node.statement)}`;
98
+ }
99
+ else if (ts.isWhileStatement(node)) {
100
+ return `for ${visit(node.expression, { inline: true })}${visit(node.statement)}`;
101
+ }
102
+ else if (ts.isDoStatement(node)) {
103
+ const condition = `\tif !(${visit(node.expression, {
104
+ inline: true
105
+ })}) {\n\t\t\tbreak \n\t\t}\n\t`;
106
+ return `for ${visit(node.statement, { inline: true, extraBlockContent: condition })}`;
107
+ }
108
+ else if (ts.isIfStatement(node)) {
109
+ const condition = `if ${visit(node.expression, { inline: true })} ${visit(node.thenStatement, {
110
+ inline: !!node.elseStatement
111
+ })}`;
112
+ if (node.elseStatement) {
113
+ return `${condition} else ${visit(node.elseStatement)}`;
114
+ }
115
+ return condition;
116
+ }
117
+ else if (ts.isSwitchStatement(node)) {
118
+ return `switch ${visit(node.expression)} ${visit(node.caseBlock)}`;
119
+ }
120
+ else if (ts.isCaseBlock(node)) {
121
+ return `{\n\t\t${node.clauses.map((c) => visit(c)).join('\n\t\t')}\n\t}`;
122
+ }
123
+ else if (ts.isCaseClause(node)) {
124
+ const isFallThrough = !node.statements.some((c) => ts.isBreakStatement(c));
125
+ return `case ${visit(node.expression, { inline: true })}: \n\t\t\t${node.statements
126
+ .filter((n) => !ts.isBreakStatement(n))
127
+ .map((s) => visit(s))
128
+ .join('')}${isFallThrough ? 'fallthrough\n\t' : ''}`;
129
+ }
130
+ else if (ts.isDefaultClause(node)) {
131
+ return `default: \n\t\t\t${node.statements
132
+ .filter((n) => !ts.isBreakStatement(n))
133
+ .map((s) => visit(s))
134
+ .join('')}`;
135
+ }
136
+ else if (ts.isBreakStatement(node)) {
137
+ return 'break';
138
+ }
139
+ else if (ts.isReturnStatement(node)) {
140
+ return (`return ${node.expression ? visit(node.expression) : ''}` + (options.inline ? '' : ';\n\t'));
141
+ }
142
+ else if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
143
+ if (options.addFunctionOutside) {
144
+ outsideNodes.push(node);
145
+ return '';
146
+ }
147
+ const name = visit(node.name, { inline: true });
148
+ const parameters = node.parameters
149
+ .map((p) => `${visit(p.name)} ${getType(p.type)}`)
150
+ .join(', ');
151
+ const returnType = node.type ? ` ${getType(node.type)}` : '';
152
+ if (options.isOutside) {
153
+ return `func ${name}(${parameters})${returnType} ${visit(node.body)}`;
154
+ }
155
+ return `${name} := func(${parameters})${returnType} ${visit(node.body)}`;
156
+ }
157
+ else if (ts.isArrowFunction(node)) {
158
+ const parameters = node.parameters
159
+ .map((p) => `${visit(p.name)} ${getType(p.type)}`)
160
+ .join(', ');
161
+ const returnType = node.type ? ` ${getType(node.type)}` : '';
162
+ return `func(${parameters})${returnType} ${visit(node.body)}`;
163
+ }
164
+ const syntaxKind = ts.SyntaxKind[node.kind];
165
+ if (!['FirstStatement', 'EndOfFileToken'].includes(syntaxKind)) {
166
+ console.log(ts.SyntaxKind[node.kind], node.getText());
167
+ }
168
+ ts.forEachChild(node, (subNode) => {
169
+ code += visit(subNode);
170
+ });
171
+ return code;
172
+ }
173
+ function getType(typeNode, getArrayType = false) {
174
+ const type = TypeCheker.getTypeFromTypeNode(typeNode);
175
+ let typeName = TypeCheker.typeToString(type);
176
+ const isArray = typeName.includes('[]');
177
+ if (isArray) {
178
+ if (getArrayType) {
179
+ typeName = typeName.replace('[]', '');
180
+ }
181
+ else {
182
+ return ':';
183
+ }
184
+ }
185
+ switch (typeName) {
186
+ case 'number':
187
+ return 'float64';
188
+ case 'boolean':
189
+ return 'bool';
190
+ case 'any':
191
+ return ':';
192
+ case 'void':
193
+ return '';
194
+ default:
195
+ return typeName;
196
+ }
197
+ }
198
+ function getAcessString(leftSide, rightSide) {
199
+ if (rightSide === 'length') {
200
+ return 'float64(len(arr))';
201
+ }
202
+ return `${leftSide}.${rightSide}`;
203
+ }
204
+ function getCallString(caller, args) {
205
+ if (caller === 'console.log') {
206
+ importedPackages.add('fmt');
207
+ return `fmt.Println(${args.join(', ')})`;
208
+ }
209
+ else if (caller === 'console.time') {
210
+ importedPackages.add('time');
211
+ return `${getTimerName(args[0])} := time.Now()`;
212
+ }
213
+ else if (caller === 'console.timeEnd') {
214
+ importedPackages.add('time');
215
+ importedPackages.add('fmt');
216
+ return `fmt.Println("Elapsed time:", time.Since(${getTimerName(args[0])}))`;
217
+ }
218
+ else if (caller === 'Math.random') {
219
+ importedPackages.add('math/rand');
220
+ return 'rand.Float64()';
221
+ }
222
+ else if (caller === 'Math.floor') {
223
+ importedPackages.add('math');
224
+ return `math.Floor(${args.join(', ')})`;
225
+ }
226
+ else if (caller.endsWith('.push')) {
227
+ const arrayName = caller.substring(0, caller.length - '.push'.length);
228
+ return `${arrayName} = append(${arrayName},${args.join(', ')})`;
229
+ }
230
+ return `${caller}(${args.join(', ')})`;
231
+ }
232
+ function getOperatorText(operator) {
233
+ switch (operator) {
234
+ case ts.SyntaxKind.PlusToken:
235
+ return '+';
236
+ case ts.SyntaxKind.MinusToken:
237
+ return '-';
238
+ case ts.SyntaxKind.TildeToken:
239
+ return '~';
240
+ case ts.SyntaxKind.ExclamationToken:
241
+ return '!';
242
+ case ts.SyntaxKind.PlusPlusToken:
243
+ return '++';
244
+ case ts.SyntaxKind.MinusMinusToken:
245
+ return '--';
246
+ default:
247
+ console.error('Did not find operator', operator);
248
+ return '';
249
+ }
250
+ }
251
+ function getTimerName(name) {
252
+ return `__timer_${name.replaceAll(' ', '_').replaceAll('"', '')}__`;
253
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typenative",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Build native applications using Typescript.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,14 @@
14
14
  "test": "node ./bin/index --source test/test.ts --script",
15
15
  "test2": "node ./bin/index --source test/test2.ts --script",
16
16
  "test3": "node ./bin/index --source test/test3.ts --script",
17
+ "test3_node": "tsc test/test3.ts && node test/test3.js && rimraf test/test3.js",
17
18
  "test4": "node ./bin/index --source test/test4.ts --script",
19
+ "test5": "node ./bin/index --source test/test5.ts --script",
20
+ "test6": "node ./bin/index --source test/test6.ts --script",
21
+ "test7": "node ./bin/index --source test/test7.ts --script",
22
+ "test8": "node ./bin/index --source test/test8.ts --script",
23
+ "test9": "node ./bin/index --source test/test9.ts --script",
24
+ "test10": "node ./bin/index --source test/test10.ts --script",
18
25
  "release": "npm publish"
19
26
  },
20
27
  "repository": {
@@ -31,12 +38,12 @@
31
38
  "@types/fs-extra": "^11.0.4",
32
39
  "@types/inquirer": "^9.0.8",
33
40
  "@types/node": "^22.15.21",
34
- "@types/shelljs": "^0.8.16"
41
+ "rimraf": "^6.0.1"
35
42
  },
36
43
  "dependencies": {
44
+ "execa": "^9.5.3",
37
45
  "fs-extra": "^11.3.0",
38
46
  "inquirer": "^12.6.1",
39
- "shelljs": "^0.10.0",
40
47
  "typescript": "^5.8.3"
41
48
  }
42
49
  }
@@ -1,4 +1,33 @@
1
- interface Array<T> {
1
+ interface SymbolConstructor {
2
+ readonly iterator: unique symbol;
3
+ }
4
+
5
+ declare var Symbol: SymbolConstructor;
6
+
7
+ interface IteratorYieldResult<TYield> {
8
+ done?: false;
9
+ value: TYield;
10
+ }
11
+
12
+ interface IteratorReturnResult<TReturn> {
13
+ done: true;
14
+ value: TReturn;
15
+ }
16
+
17
+ type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
18
+
19
+ interface Iterator<T, TReturn = any, TNext = any> {
20
+ // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
21
+ next(...[value]: [] | [TNext]): IteratorResult<T, TReturn>;
22
+ return?(value?: TReturn): IteratorResult<T, TReturn>;
23
+ throw?(e?: any): IteratorResult<T, TReturn>;
24
+ }
25
+
26
+ interface IterableIterator<T, TReturn = any, TNext = any> extends Iterator<T, TReturn, TNext> {
27
+ [Symbol.iterator](): IterableIterator<T, TReturn, TNext>;
28
+ }
29
+
30
+ interface Array<T> extends IterableIterator<T> {
2
31
  /**
3
32
  * Gets or sets the length of the array. This is a number one higher than the highest index in the array.
4
33
  */
@@ -13,5 +42,13 @@ interface Array<T> {
13
42
 
14
43
  interface Console {
15
44
  log(...data: any[]): void;
45
+ time(label?: string): void;
46
+ timeEnd(label?: string): void;
16
47
  }
17
48
  declare var console: Console;
49
+
50
+ interface Math {
51
+ random(): number;
52
+ floor(x: number): number;
53
+ }
54
+ declare var Math: Math;