create-near-app 1.3.6 → 3.0.0-pre.7.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.
Files changed (146) hide show
  1. package/README.md +3 -3
  2. package/{common/contracts → contracts}/assemblyscript/README.md +2 -3
  3. package/{common/contracts → contracts}/assemblyscript/as-pect.config.js +0 -0
  4. package/{common/contracts → contracts}/assemblyscript/asconfig.json +0 -0
  5. package/{common/contracts → contracts}/assemblyscript/assembly/__tests__/as-pect.d.ts +0 -0
  6. package/contracts/assemblyscript/assembly/__tests__/main.spec.ts +11 -0
  7. package/{common/contracts → contracts}/assemblyscript/assembly/as_types.d.ts +0 -0
  8. package/contracts/assemblyscript/assembly/index.ts +23 -0
  9. package/{common/contracts → contracts}/assemblyscript/assembly/tsconfig.json +0 -0
  10. package/{common/contracts → contracts}/assemblyscript/package.json +2 -6
  11. package/{common/contracts → contracts}/rust/.cargo/config +0 -0
  12. package/{common/contracts → contracts}/rust/Cargo.toml +4 -5
  13. package/{common/contracts → contracts}/rust/README.md +2 -3
  14. package/contracts/rust/src/lib.rs +72 -0
  15. package/index.js +74 -77
  16. package/integration-tests/rs/Cargo.toml +22 -0
  17. package/integration-tests/rs/src/tests.rs +66 -0
  18. package/integration-tests/ts/ava.config.cjs +9 -0
  19. package/integration-tests/ts/package.json +16 -0
  20. package/integration-tests/ts/src/main.ava.ts +44 -0
  21. package/package.json +24 -23
  22. package/templates/react/README.md +2 -2
  23. package/templates/react/ava.config.cjs +9 -0
  24. package/templates/react/{src → frontend}/App.js +35 -30
  25. package/templates/react/{src → frontend}/__mocks__/fileMock.js +0 -0
  26. package/{common/frontend → templates/react/frontend/assets/css}/global.css +4 -3
  27. package/{common/frontend/assets → templates/react/frontend/assets/img}/favicon.ico +0 -0
  28. package/{common/frontend/assets → templates/react/frontend/assets/img}/logo-black.svg +0 -0
  29. package/{common/frontend/assets → templates/react/frontend/assets/img}/logo-white.svg +0 -0
  30. package/templates/react/{src → frontend/assets/js/near}/config.js +1 -1
  31. package/templates/{vue/src → react/frontend/assets/js/near}/utils.js +14 -4
  32. package/templates/react/{src → frontend}/index.html +3 -3
  33. package/templates/react/frontend/index.js +14 -0
  34. package/templates/react/near.gitignore +6 -3
  35. package/templates/react/package.json +29 -43
  36. package/templates/vanilla/README.md +2 -2
  37. package/templates/vanilla/frontend/assets/css/global.css +189 -0
  38. package/templates/vanilla/frontend/assets/img/favicon.ico +0 -0
  39. package/templates/vanilla/frontend/assets/img/logo-black.svg +1 -0
  40. package/templates/vanilla/frontend/assets/img/logo-white.svg +1 -0
  41. package/templates/vanilla/frontend/assets/js/index.js +74 -0
  42. package/templates/vanilla/{src → frontend/assets/js/near}/config.js +1 -1
  43. package/templates/{angular/src → vanilla/frontend/assets/js/near}/utils.js +14 -4
  44. package/templates/vanilla/{src → frontend}/index.html +25 -30
  45. package/templates/vanilla/near.gitignore +1 -1
  46. package/templates/vanilla/package.json +25 -31
  47. package/utils/rust-setup.js +102 -0
  48. package/utils/tracking.js +29 -0
  49. package/LICENSE-APACHE +0 -176
  50. package/common/.npmignore +0 -2
  51. package/common/contracts/.gitignore +0 -1
  52. package/common/contracts/assemblyscript/.gitignore +0 -4
  53. package/common/contracts/assemblyscript/assembly/__tests__/main.spec.ts +0 -9
  54. package/common/contracts/assemblyscript/assembly/index.ts +0 -40
  55. package/common/contracts/assemblyscript/compile.js +0 -51
  56. package/common/contracts/rust/.gitignore +0 -1
  57. package/common/contracts/rust/Cargo.lock +0 -472
  58. package/common/contracts/rust/compile.js +0 -55
  59. package/common/contracts/rust/res/.gitkeep +0 -0
  60. package/common/contracts/rust/src/lib.rs +0 -115
  61. package/common/contracts/rust/target/.gitkeep +0 -0
  62. package/templates/.npmignore +0 -3
  63. package/templates/angular/.gitignore +0 -26
  64. package/templates/angular/.gitpod.yml +0 -6
  65. package/templates/angular/README.md +0 -102
  66. package/templates/angular/angular.json +0 -126
  67. package/templates/angular/contract +0 -1
  68. package/templates/angular/extra-webpack.config.ts +0 -7
  69. package/templates/angular/karma.conf.js +0 -40
  70. package/templates/angular/near.gitignore +0 -46
  71. package/templates/angular/neardev/.gitignore +0 -2
  72. package/templates/angular/neardev/shared-test/test.near.json +0 -1
  73. package/templates/angular/neardev/shared-test-staging/test.near.json +0 -1
  74. package/templates/angular/package.json +0 -63
  75. package/templates/angular/set-contract-name.js +0 -16
  76. package/templates/angular/src/app/app.component.html +0 -87
  77. package/templates/angular/src/app/app.component.spec.ts +0 -107
  78. package/templates/angular/src/app/app.component.ts +0 -88
  79. package/templates/angular/src/app/app.module.ts +0 -21
  80. package/templates/angular/src/app/components/notification/notification.component.html +0 -12
  81. package/templates/angular/src/app/components/notification/notification.component.spec.ts +0 -25
  82. package/templates/angular/src/app/components/notification/notification.component.ts +0 -23
  83. package/templates/angular/src/app/services/window.service.ts +0 -47
  84. package/templates/angular/src/assets +0 -1
  85. package/templates/angular/src/config.d.ts +0 -13
  86. package/templates/angular/src/config.js +0 -62
  87. package/templates/angular/src/contract-name.js +0 -1
  88. package/templates/angular/src/environments/environment.prod.ts +0 -3
  89. package/templates/angular/src/environments/environment.ts +0 -16
  90. package/templates/angular/src/global.css +0 -1
  91. package/templates/angular/src/index.html +0 -15
  92. package/templates/angular/src/main.ts +0 -15
  93. package/templates/angular/src/polyfills.ts +0 -64
  94. package/templates/angular/src/styles.scss +0 -1
  95. package/templates/angular/src/test.ts +0 -25
  96. package/templates/angular/src/utils.d.ts +0 -3
  97. package/templates/angular/src/window.d.ts +0 -15
  98. package/templates/angular/tsconfig.app.json +0 -15
  99. package/templates/angular/tsconfig.json +0 -21
  100. package/templates/angular/tsconfig.spec.json +0 -18
  101. package/templates/angular/tslint.json +0 -149
  102. package/templates/react/.gitignore +0 -28
  103. package/templates/react/babel.config.js +0 -3
  104. package/templates/react/contract +0 -1
  105. package/templates/react/neardev/.gitignore +0 -2
  106. package/templates/react/neardev/shared-test-staging/test.near.json +0 -1
  107. package/templates/react/src/assets +0 -1
  108. package/templates/react/src/global.css +0 -1
  109. package/templates/react/src/index.js +0 -13
  110. package/templates/react/src/jest.init.js +0 -1
  111. package/templates/react/src/main.test.js +0 -28
  112. package/templates/react/src/utils.js +0 -39
  113. package/templates/react/src/wallet/login/index.html +0 -28
  114. package/templates/vanilla/.gitignore +0 -26
  115. package/templates/vanilla/contract +0 -1
  116. package/templates/vanilla/neardev/.gitignore +0 -2
  117. package/templates/vanilla/neardev/shared-test-staging/test.near.json +0 -1
  118. package/templates/vanilla/src/assets +0 -1
  119. package/templates/vanilla/src/global.css +0 -1
  120. package/templates/vanilla/src/index.js +0 -113
  121. package/templates/vanilla/src/main.test.js +0 -15
  122. package/templates/vanilla/src/utils.js +0 -39
  123. package/templates/vanilla/src/wallet/login/index.html +0 -28
  124. package/templates/vue/.gitignore +0 -26
  125. package/templates/vue/.gitpod.yml +0 -6
  126. package/templates/vue/README.md +0 -101
  127. package/templates/vue/babel.config.js +0 -5
  128. package/templates/vue/contract +0 -1
  129. package/templates/vue/copy-dev-account.js +0 -7
  130. package/templates/vue/jest.config.js +0 -7
  131. package/templates/vue/near.gitignore +0 -46
  132. package/templates/vue/neardev/shared-test/test.near.json +0 -1
  133. package/templates/vue/neardev/shared-test-staging/test.near.json +0 -1
  134. package/templates/vue/package.json +0 -86
  135. package/templates/vue/src/App.vue +0 -37
  136. package/templates/vue/src/assets +0 -1
  137. package/templates/vue/src/components/Notification.vue +0 -38
  138. package/templates/vue/src/components/SignedIn.vue +0 -179
  139. package/templates/vue/src/components/SignedOut.vue +0 -34
  140. package/templates/vue/src/config.js +0 -63
  141. package/templates/vue/src/favicon.ico +0 -1
  142. package/templates/vue/src/global.css +0 -1
  143. package/templates/vue/src/main.js +0 -16
  144. package/templates/vue/tests/unit/Notification.spec.js +0 -26
  145. package/templates/vue/tests/unit/SignedIn.spec.js +0 -24
  146. package/templates/vue/tests/unit/SignedOut.spec.js +0 -17
package/README.md CHANGED
@@ -25,12 +25,12 @@ Using [npm's npx](https://blog.npmjs.org/post/162869356040/introducing-npx-an-np
25
25
 
26
26
  yarn create near-app [options] new-awesome-project
27
27
 
28
- Without any options, this will create a project with a **vanilla JavaScript** frontend and an [AssemblyScript](https://docs.near.org/docs/roles/developer/contracts/assemblyscript) smart contract
28
+ Without any options, this will create a project with a **vanilla JavaScript** frontend and an [AssemblyScript](https://docs.near.org/docs/develop/contracts/as/intro) smart contract
29
29
 
30
30
  Other options:
31
31
 
32
32
  * `--frontend=react` – use [React](https://reactjs.org/) for your frontend template
33
- * `--contract=rust` – use [Rust](https://docs.near.org/docs/roles/developer/contracts/near-sdk-rs) for your smart contract
33
+ * `--contract=rust` – use [Rust](https://docs.near.org/docs/develop/contracts/rust/near-sdk-rs) for your smart contract
34
34
 
35
35
 
36
36
  Develop your own Dapp
@@ -64,7 +64,7 @@ about commit messages
64
64
 
65
65
  Real world examples can look like this:
66
66
 
67
- chore: run tests on travis ci
67
+ chore: run tests with GitHub Actions
68
68
 
69
69
  fix(server): send cors headers
70
70
 
@@ -13,13 +13,12 @@ Before you compile this code, you will need to install [Node.js] ≥ 12
13
13
  Exploring The Code
14
14
  ==================
15
15
 
16
- 1. The main smart contract code lives in `assembly/index.ts`. You can compile
17
- it with the `./compile` script.
16
+ 1. The main smart contract code lives in `assembly/index.ts`.
18
17
  2. Tests: You can run smart contract tests with the `./test` script. This runs
19
18
  standard AssemblyScript tests using [as-pect].
20
19
 
21
20
 
22
- [smart contract]: https://docs.near.org/docs/roles/developer/contracts/intro
21
+ [smart contract]: https://docs.near.org/docs/develop/contracts/overview
23
22
  [AssemblyScript]: https://www.assemblyscript.org/
24
23
  [create-near-app]: https://github.com/near/create-near-app
25
24
  [Node.js]: https://nodejs.org/en/download/package-manager/
@@ -0,0 +1,11 @@
1
+ import { set_greeting, get_greeting } from '..'
2
+
3
+ describe('Greeting ', () => {
4
+ it('should get the default greeting', () => {
5
+ expect(get_greeting()).toBe('Hello')
6
+ })
7
+ it('should change the greeting', () => {
8
+ set_greeting('howdy')
9
+ expect(get_greeting()).toBe('howdy')
10
+ })
11
+ })
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Example smart contract written in AssemblyScript
3
+ *
4
+ * Learn more about writing NEAR smart contracts with AssemblyScript:
5
+ * https://near-docs.io/develop/welcome
6
+ *
7
+ */
8
+
9
+ import { logging, storage } from 'near-sdk-as'
10
+
11
+ const DEFAULT_MESSAGE = 'Hello'
12
+
13
+ // Public method - returns the greeting saved, defaulting to DEFAULT_MESSAGE
14
+ export function get_greeting(): string {
15
+ return storage.getPrimitive<string>('message', DEFAULT_MESSAGE)
16
+ }
17
+
18
+ // Public method - accepts a greeting, such as 'howdy', and records it
19
+ export function set_greeting(message: string): void {
20
+ // Use logging.log to record logs permanently to the blockchain!
21
+ logging.log(`Saving greeting '${message}'`)
22
+ storage.set<string>('message', message)
23
+ }
@@ -1,17 +1,13 @@
1
1
  {
2
2
  "name": "greeter",
3
- "version": "0.0.1",
3
+ "version": "1.0.0",
4
4
  "license": "UNLICENSED",
5
5
  "private": true,
6
6
  "scripts": {
7
7
  "build": "asb",
8
- "build:debug": "asb --target debug",
9
8
  "test": "asp --nologo"
10
9
  },
11
10
  "dependencies": {
12
- "near-sdk-as": "2.2.4"
13
- },
14
- "devDependencies": {
15
- "shelljs": "^0.8.4"
11
+ "near-sdk-as": "^3.2.3"
16
12
  }
17
13
  }
@@ -1,23 +1,22 @@
1
1
  [package]
2
2
  name = "greeter"
3
- version = "0.1.0"
3
+ version = "1.0.0"
4
4
  authors = ["Near Inc <hello@near.org>"]
5
- edition = "2018"
5
+ edition = "2021"
6
6
 
7
7
  [lib]
8
8
  crate-type = ["cdylib", "rlib"]
9
9
 
10
10
  [dependencies]
11
- near-sdk = "2.0.1"
11
+ near-sdk = "4.0.0"
12
+ uint = { version = "0.9.3", default-features = false }
12
13
 
13
14
  [profile.release]
14
15
  codegen-units = 1
15
- # Tell `rustc` to optimize for small code size.
16
16
  opt-level = "z"
17
17
  lto = true
18
18
  debug = false
19
19
  panic = "abort"
20
- # Opt into extra safety checks on arithmetic operations https://stackoverflow.com/a/64136471/249801
21
20
  overflow-checks = true
22
21
 
23
22
  [workspace]
@@ -13,14 +13,13 @@ Before you compile this code, you will need to install Rust with [correct target
13
13
  Exploring The Code
14
14
  ==================
15
15
 
16
- 1. The main smart contract code lives in `src/lib.rs`. You can compile it with
17
- the `./compile` script.
16
+ 1. The main smart contract code lives in `src/lib.rs`.
18
17
  2. Tests: You can run smart contract tests with the `./test` script. This runs
19
18
  standard Rust tests using [cargo] with a `--nocapture` flag so that you
20
19
  can see any debug info you print to the console.
21
20
 
22
21
 
23
- [smart contract]: https://docs.near.org/docs/roles/developer/contracts/intro
22
+ [smart contract]: https://docs.near.org/docs/develop/contracts/overview
24
23
  [Rust]: https://www.rust-lang.org/
25
24
  [create-near-app]: https://github.com/near/create-near-app
26
25
  [correct target]: https://github.com/near/near-sdk-rs#pre-requisites
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Example smart contract written in RUST
3
+ *
4
+ * Learn more about writing NEAR smart contracts with Rust:
5
+ * https://near-docs.io/develop/Contract
6
+ *
7
+ */
8
+
9
+ use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
10
+ use near_sdk::{log, near_bindgen};
11
+
12
+ // Define the default message
13
+ const DEFAULT_MESSAGE: &str = "Hello";
14
+
15
+ // Define the contract structure
16
+ #[near_bindgen]
17
+ #[derive(BorshDeserialize, BorshSerialize)]
18
+ pub struct Contract {
19
+ message: String,
20
+ }
21
+
22
+ // Define the default, which automatically initializes the contract
23
+ impl Default for Contract{
24
+ fn default() -> Self{
25
+ Self{message: DEFAULT_MESSAGE.to_string()}
26
+ }
27
+ }
28
+
29
+ // Implement the contract structure
30
+ #[near_bindgen]
31
+ impl Contract {
32
+ // Public method - returns the greeting saved, defaulting to DEFAULT_MESSAGE
33
+ pub fn get_greeting(&self) -> String {
34
+ return self.message.clone();
35
+ }
36
+
37
+ // Public method - accepts a greeting, such as "howdy", and records it
38
+ pub fn set_greeting(&mut self, message: String) {
39
+ // Use env::log to record logs permanently to the blockchain!
40
+ log!("Saving greeting {}", message);
41
+ self.message = message;
42
+ }
43
+ }
44
+
45
+ /*
46
+ * The rest of this file holds the inline tests for the code above
47
+ * Learn more about Rust tests: https://doc.rust-lang.org/book/ch11-01-writing-tests.html
48
+ */
49
+ #[cfg(test)]
50
+ mod tests {
51
+ use super::*;
52
+
53
+ #[test]
54
+ fn get_default_greeting() {
55
+ let contract = Contract::default();
56
+ // this test did not call set_greeting so should return the default "Hello" greeting
57
+ assert_eq!(
58
+ contract.get_greeting(),
59
+ "Hello".to_string()
60
+ );
61
+ }
62
+
63
+ #[test]
64
+ fn set_then_get_greeting() {
65
+ let mut contract = Contract::default();
66
+ contract.set_greeting("howdy".to_string());
67
+ assert_eq!(
68
+ contract.get_greeting(),
69
+ "howdy".to_string()
70
+ );
71
+ }
72
+ }
package/index.js CHANGED
@@ -1,24 +1,26 @@
1
1
  #!/usr/bin/env node
2
+ const fs = require('fs')
3
+ const os = require('os')
4
+ const path = require('path')
2
5
  const yargs = require('yargs')
3
- const { basename, resolve } = require('path')
6
+
4
7
  const replaceInFiles = require('replace-in-files')
5
- const ncp = require('ncp').ncp
6
- ncp.limit = 16
7
- const fs = require('fs')
8
8
  const spawn = require('cross-spawn')
9
9
  const chalk = require('chalk')
10
10
  const which = require('which')
11
- const sh = require('shelljs')
12
- const path = require('path')
11
+ const ncp = require('ncp').ncp
12
+ ncp.limit = 16
13
13
 
14
- const renameFile = async function(oldPath, newPath) {
14
+ const rustSetup = require('./utils/rust-setup')
15
+ const mixpanel = require('./utils/tracking')
16
+
17
+ const renameFile = async function (oldPath, newPath) {
15
18
  return new Promise((resolve, reject) => {
16
19
  fs.rename(oldPath, newPath, (err) => {
17
20
  if (err) {
18
21
  console.error(err)
19
22
  return reject(err)
20
23
  }
21
- console.log(`Renamed ${oldPath} to ${newPath}`)
22
24
  resolve()
23
25
  })
24
26
  })
@@ -26,7 +28,7 @@ const renameFile = async function(oldPath, newPath) {
26
28
 
27
29
  // Wrap `ncp` tool to wait for the copy to finish when using `await`
28
30
  // Allow passing `skip` variable to skip copying an array of filenames
29
- function copyDir (source, dest, { skip, veryVerbose } = {}) {
31
+ function copyDir(source, dest, { skip, veryVerbose } = {}) {
30
32
  return new Promise((resolve, reject) => {
31
33
  const copied = []
32
34
  const skipped = []
@@ -51,65 +53,50 @@ function copyDir (source, dest, { skip, veryVerbose } = {}) {
51
53
  })
52
54
  }
53
55
 
54
- const createProject = async function({ contract, frontend, projectDir, veryVerbose }) {
55
- const templateDir = `/templates/${frontend}`
56
- const sourceTemplateDir = __dirname + templateDir
57
-
58
- console.log(`Copying files to new project directory (${projectDir}) from template source (${sourceTemplateDir}).`)
59
-
60
- await copyDir(sourceTemplateDir, projectDir, { veryVerbose, skip: [
61
- // our frontend templates are set up with symlinks for easy development,
62
- // developing right in these directories also results in build artifacts;
63
- // we don't want to copy these
64
- path.join(sourceTemplateDir, '.cache'),
65
- path.join(sourceTemplateDir, 'dist'),
66
- path.join(sourceTemplateDir, 'out'),
67
- path.join(sourceTemplateDir, 'node_modules'),
68
- path.join(sourceTemplateDir, 'yarn.lock'),
69
- path.join(sourceTemplateDir, 'package-lock.json'),
70
- path.join(sourceTemplateDir, 'contract'),
71
- ...sh.ls(`${__dirname}/common/frontend`).map(f => path.join('src', f))
72
- ]})
73
-
74
-
75
- // copy common files
76
- await copyDir(`${__dirname}/common/frontend`, `${projectDir}/src`)
77
- const contractSourceDir = `${__dirname}/common/contracts/${contract}`
78
- await copyDir(contractSourceDir, `${projectDir}/contract`, { veryVerbose, skip: [
79
- // as above, skip rapid-development build artifacts
80
- path.join(contractSourceDir, 'node_modules'),
81
- path.join(contractSourceDir, 'yarn.lock'),
82
- path.join(contractSourceDir, 'package-lock.json'),
83
- ]})
84
-
85
- // update package name
86
- let projectName = basename(resolve(projectDir))
87
- await replaceInFiles({
88
- files: [
89
- // NOTE: These can use globs if necessary later
90
- `${projectDir}/README.md`,
91
- `${projectDir}/package.json`,
92
- `${projectDir}/contract/README.md`,
93
- `${projectDir}/src/config.js`,
94
- `${projectDir}/src/App.vue`,
95
- `${projectDir}/angular.json`,
96
- `${projectDir}/karma.conf.js`,
97
- `${projectDir}/set-contract-name.js`,
98
- ],
99
- from: /near-blank-project/g,
100
- to: projectName
101
- })
56
+ const createProject = async function ({ contract, frontend, projectDir, veryVerbose }) {
57
+ if (os.platform() === 'win32') {
58
+ console.log('Sorry, create-near-app is not compatible with Windows. Please consider using Windows Subsystem for Linux.\n')
59
+ return
60
+ }
61
+ // track used options
62
+ mixpanel.track(frontend, contract)
63
+
64
+ console.log(chalk`Creating {bold ${projectDir}} with a contract in {bold ${contract}}, and a frontend using {bold ${frontend} js}.`)
65
+ console.log('Remember that you can change these settings using the --frontend and --contract flags. \n')
66
+
67
+ // skip rapid-development build artifacts and symlinks
68
+ const skip = ['.cache', 'dist', 'out', 'node_modules', 'yarn.lock', 'package-lock.json', 'contract', 'integration-tests']
102
69
 
70
+ // copy frontend
71
+ const sourceTemplateDir = __dirname + `/templates/${frontend}`
72
+ await copyDir(sourceTemplateDir, projectDir, { veryVerbose, skip: skip.map(f => path.join(sourceTemplateDir, f)) })
73
+
74
+ // copy tests
75
+ const sourceTestDir = __dirname + '/integration-tests'
76
+ await copyDir(sourceTestDir, `${projectDir}/integration-tests`, { veryVerbose, skip: skip.map(f => path.join(sourceTestDir, f)) })
77
+
78
+ // copy contract files
79
+ const contractSourceDir = `${__dirname}/contracts/${contract}`
80
+ await copyDir(contractSourceDir, `${projectDir}/contract`, { veryVerbose, skip: skip.map(f => path.join(contractSourceDir, f)) })
81
+
82
+ // changes in package.json for rust
103
83
  if (contract === 'rust') {
104
- await replaceInFiles({ files: `${projectDir}/src/**/*`, from: /getGreeting/g, to: 'get_greeting' })
105
- await replaceInFiles({ files: `${projectDir}/src/**/*`, from: /setGreeting/g, to: 'set_greeting' })
106
- await replaceInFiles({ files: `${projectDir}/src/**/*`, from: /{ accountId:/g, to: '{ account_id:' })
107
- await replaceInFiles({ files: `${projectDir}/package.json`, from: 'cd contract && npm run test', to: 'cd contract && cargo test -- --nocapture' })
108
- await replaceInFiles({ files: `${projectDir}/package.json`, from: 'watch contract -e ts', to: 'watch contract/src -e rs' })
84
+ await replaceInFiles({
85
+ files: `${projectDir}/package.json`,
86
+ from: 'cd contract && npm run build && mkdir -p ../out && rm -f ./out/main.wasm && cp ./build/release/greeter.wasm ../out/main.wasm',
87
+ to: 'mkdir -p out && cd contract && rustup target add wasm32-unknown-unknown && cargo build --all --target wasm32-unknown-unknown --release && rm -f ./out/main.wasm && cp ./target/wasm32-unknown-unknown/release/greeter.wasm ../out/main.wasm'
88
+ })
89
+ await replaceInFiles({
90
+ files: `${projectDir}/package.json`,
91
+ from: '"test:unit": "cd contract && npm i && npm run test"',
92
+ to: '"test:unit": "cd contract && cargo test"'
93
+ })
109
94
  }
110
95
 
96
+ // add .gitignore
111
97
  await renameFile(`${projectDir}/near.gitignore`, `${projectDir}/.gitignore`)
112
- console.log('Copying project files complete.\n')
98
+
99
+ console.log('Project created! Lets set it up.\n')
113
100
 
114
101
  const hasNpm = which.sync('npm', { nothrow: true })
115
102
  const hasYarn = which.sync('yarn', { nothrow: true })
@@ -119,6 +106,12 @@ const createProject = async function({ contract, frontend, projectDir, veryVerbo
119
106
  await replaceInFiles({ files: `${projectDir}/README.md`, from: /npm\b( run)?/g, to: 'yarn' })
120
107
  }
121
108
 
109
+ // setup rust
110
+ let wasRustupInstalled = false
111
+ if (contract === 'rust') {
112
+ wasRustupInstalled = await rustSetup.setupRustAndWasm32Target()
113
+ }
114
+
122
115
  if (hasNpm || hasYarn) {
123
116
  console.log('Installing project dependencies...')
124
117
  spawn.sync(hasYarn ? 'yarn' : 'npm', ['install'], { cwd: projectDir, stdio: 'inherit' })
@@ -129,6 +122,7 @@ const createProject = async function({ contract, frontend, projectDir, veryVerbo
129
122
 
130
123
  const runCommand = hasYarn ? 'yarn' : 'npm run'
131
124
 
125
+ // print success message
132
126
  console.log(chalk`
133
127
  Success! Created ${projectDir}
134
128
  Inside that directory, you can run several commands:
@@ -140,34 +134,37 @@ Inside that directory, you can run several commands:
140
134
  {bold ${runCommand} test}
141
135
  Starts the test runner.
142
136
 
143
- {bold ${runCommand} deploy}
144
- Deploys contract in permanent location (as configured in {bold src/config.js}).
145
- Also deploys web frontend using GitHub Pages.
146
- Consult with {bold README.md} for details on how to deploy and {bold package.json} for full list of commands.
147
-
148
- We suggest that you begin by typing:
149
-
150
- {bold cd ${projectDir}}
151
- {bold ${runCommand} dev}
137
+ We suggest that you begin by typing:`)
138
+
139
+ if (wasRustupInstalled) {
140
+ console.log(chalk`
141
+ {bold source $HOME/.cargo/env}
142
+ {bold cd ${projectDir}}
143
+ {bold ${runCommand} dev}`)
144
+ } else {
145
+ console.log(chalk`
146
+ {bold cd ${projectDir}}
147
+ {bold ${runCommand} dev}`)
148
+ }
152
149
 
153
- Happy hacking!
154
- `)
150
+ console.log(chalk`
151
+ Happy hacking!`)
155
152
  }
156
153
 
157
154
  const opts = yargs
158
155
  .strict()
159
156
  .usage('$0 <projectDir>', 'Create a new NEAR project')
160
- // BUG: does not work; https://github.com/yargs/yargs/issues/1331
157
+ // BUG: does not work; https://github.com/yargs/yargs/issues/1331
161
158
  .example('$0 new-app', 'Create a project called "new-app"')
162
159
  .option('frontend', {
163
160
  desc: 'template to use',
164
- choices: ['vanilla', 'react', 'vue', 'angular'],
161
+ choices: ['vanilla', 'react'],
165
162
  default: 'vanilla',
166
163
  })
167
164
  .option('contract', {
168
165
  desc: 'language for smart contract',
169
166
  choices: ['assemblyscript', 'rust'],
170
- default: 'assemblyscript'
167
+ default: 'rust'
171
168
  })
172
169
  .option('very-verbose', {
173
170
  desc: 'turn on very verbose logging',
@@ -0,0 +1,22 @@
1
+ [package]
2
+ name = "integration-tests"
3
+ version = "1.0.0"
4
+ publish = false
5
+ edition = "2018"
6
+
7
+ [dev-dependencies]
8
+ anyhow = "1.0"
9
+ borsh = "0.9"
10
+ maplit = "1.0"
11
+ near-units = "0.2.0"
12
+ # arbitrary_precision enabled for u128 types that workspaces requires for Balance types
13
+ serde_json = { version = "1.0", features = ["arbitrary_precision"] }
14
+ tokio = { version = "1.18.1", features = ["full"] }
15
+ tracing = "0.1"
16
+ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
17
+ workspaces = "0.2.1"
18
+ pkg-config = "0.3.1"
19
+
20
+ [[example]]
21
+ name = "integration-tests"
22
+ path = "src/tests.rs"
@@ -0,0 +1,66 @@
1
+ use near_units::parse_near;
2
+ use serde_json::json;
3
+ use workspaces::prelude::*;
4
+ use workspaces::{network::Sandbox, Account, Contract, Worker};
5
+
6
+ const WASM_FILEPATH: &str = "../../out/main.wasm";
7
+
8
+ #[tokio::main]
9
+ async fn main() -> anyhow::Result<()> {
10
+ let worker = workspaces::sandbox().await?;
11
+ let wasm = std::fs::read(WASM_FILEPATH)?;
12
+ let contract = worker.dev_deploy(&wasm).await?;
13
+
14
+ // create accounts
15
+ let owner = worker.root_account();
16
+ let alice = owner
17
+ .create_subaccount(&worker, "alice")
18
+ .initial_balance(parse_near!("30 N"))
19
+ .transact()
20
+ .await?
21
+ .into_result()?;
22
+
23
+ // begin tests
24
+ test_default_message(&alice, &contract, &worker).await?;
25
+ test_changes_message(&alice, &contract, &worker).await?;
26
+ Ok(())
27
+ }
28
+
29
+ async fn test_default_message(
30
+ user: &Account,
31
+ contract: &Contract,
32
+ worker: &Worker<Sandbox>,
33
+ ) -> anyhow::Result<()> {
34
+ let message: String = user
35
+ .call(&worker, contract.id(), "get_greeting")
36
+ .args_json(json!({}))?
37
+ .transact()
38
+ .await?
39
+ .json()?;
40
+
41
+ assert_eq!(message, "Hello".to_string());
42
+ println!(" Passed ✅ gets default message");
43
+ Ok(())
44
+ }
45
+
46
+ async fn test_changes_message(
47
+ user: &Account,
48
+ contract: &Contract,
49
+ worker: &Worker<Sandbox>,
50
+ ) -> anyhow::Result<()> {
51
+ user.call(&worker, contract.id(), "set_greeting")
52
+ .args_json(json!({"message": "Howdy"}))?
53
+ .transact()
54
+ .await?;
55
+
56
+ let message: String = user
57
+ .call(&worker, contract.id(), "get_greeting")
58
+ .args_json(json!({}))?
59
+ .transact()
60
+ .await?
61
+ .json()?;
62
+
63
+ assert_eq!(message, "Howdy".to_string());
64
+ println!(" Passed ✅ changes message");
65
+ Ok(())
66
+ }
@@ -0,0 +1,9 @@
1
+ require("util").inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
2
+
3
+ module.exports = {
4
+ timeout: "300000",
5
+ files: ["src/*.ava.ts"],
6
+ failWithoutAssertions: false,
7
+ extensions: ["ts"],
8
+ require: ["ts-node/register"],
9
+ };
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "ava-testing",
3
+ "version": "1.0.0",
4
+ "license": "(MIT AND Apache-2.0)",
5
+ "scripts": {
6
+ "test": "ava --verbose"
7
+ },
8
+ "devDependencies": {
9
+ "ava": "^4.2.0",
10
+ "near-workspaces": "^2.0.0",
11
+ "typescript": "^4.7.2",
12
+ "ts-node": "^10.8.0",
13
+ "@types/bn.js": "^5.1.0"
14
+ },
15
+ "dependencies": {}
16
+ }
@@ -0,0 +1,44 @@
1
+ import { Worker, NEAR, NearAccount } from 'near-workspaces'
2
+ import anyTest, { TestFn } from 'ava'
3
+
4
+ const test = anyTest as TestFn<{
5
+ worker: Worker;
6
+ accounts: Record<string, NearAccount>;
7
+ }>
8
+
9
+ test.beforeEach(async (t) => {
10
+ // Init the worker and start a Sandbox server
11
+ const worker = await Worker.init()
12
+
13
+ // deploy contract
14
+ const root = worker.rootAccount
15
+ const contract = await root.createAndDeploy(
16
+ root.getSubAccount('greeter').accountId,
17
+ './out/main.wasm',
18
+ { initialBalance: NEAR.parse('30 N').toJSON() }
19
+ )
20
+
21
+ // Save state for test runs, it is unique for each test
22
+ t.context.worker = worker
23
+ t.context.accounts = { root, contract }
24
+ })
25
+
26
+ test.afterEach(async (t) => {
27
+ // Stop Sandbox server
28
+ await t.context.worker.tearDown().catch((error) => {
29
+ console.log('Failed to stop the Sandbox:', error)
30
+ })
31
+ })
32
+
33
+ test('returns the default greeting', async (t) => {
34
+ const { contract } = t.context.accounts
35
+ const message: string = await contract.view('get_greeting', {})
36
+ t.is(message, 'Hello')
37
+ })
38
+
39
+ test('changes the message', async (t) => {
40
+ const { root, contract } = t.context.accounts
41
+ await root.call(contract, 'set_greeting', { message: 'Howdy' })
42
+ const message: string = await contract.view('get_greeting', {})
43
+ t.is(message, 'Howdy')
44
+ })