create-near-app 4.0.0-beta.3.0 → 4.1.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 (54) hide show
  1. package/README.md +2 -0
  2. package/dist/app.js +5 -14
  3. package/dist/make.js +19 -18
  4. package/dist/messages.js +33 -20
  5. package/dist/package-json.js +26 -18
  6. package/dist/tracking.js +2 -2
  7. package/dist/types.js +4 -0
  8. package/dist/user-input.js +34 -50
  9. package/package.json +2 -5
  10. package/templates/contracts/js/README.md +71 -15
  11. package/templates/contracts/js/build.sh +5 -0
  12. package/templates/contracts/js/deploy.sh +13 -0
  13. package/templates/contracts/js/package.json +3 -3
  14. package/templates/contracts/js/src/contract.ts +10 -23
  15. package/templates/contracts/rust/Cargo.toml +1 -1
  16. package/templates/contracts/rust/README.md +83 -16
  17. package/templates/contracts/rust/build.sh +6 -0
  18. package/templates/contracts/rust/deploy.sh +13 -0
  19. package/templates/frontend/react/{frontend/App.js → App.js} +12 -11
  20. package/templates/frontend/react/{frontend/assets → assets}/favicon.ico +0 -0
  21. package/templates/frontend/{vanilla/frontend → react}/assets/global.css +62 -4
  22. package/templates/frontend/react/{frontend/assets → assets}/logo-black.svg +0 -0
  23. package/templates/frontend/react/{frontend/assets → assets}/logo-white.svg +0 -0
  24. package/templates/frontend/react/{frontend/index.html → index.html} +0 -0
  25. package/templates/frontend/react/index.js +21 -0
  26. package/templates/frontend/react/{frontend/package.json → package.json} +13 -2
  27. package/templates/frontend/react/{frontend/ui-components.js → ui-components.js} +4 -5
  28. package/templates/frontend/shared/near-interface.js +15 -0
  29. package/templates/frontend/shared/near-wallet.js +109 -0
  30. package/templates/frontend/shared/start.sh +26 -0
  31. package/templates/frontend/vanilla/{frontend/assets → assets}/favicon.ico +0 -0
  32. package/templates/frontend/{react/frontend → vanilla}/assets/global.css +64 -4
  33. package/templates/frontend/vanilla/{frontend/assets → assets}/logo-black.svg +0 -0
  34. package/templates/frontend/vanilla/{frontend/assets → assets}/logo-white.svg +0 -0
  35. package/templates/frontend/vanilla/index.html +91 -0
  36. package/templates/frontend/vanilla/{frontend/index.js → index.js} +30 -42
  37. package/templates/frontend/vanilla/package.json +29 -0
  38. package/templates/integration-tests/{shared/js-tests → js-tests}/ava.config.cjs +0 -0
  39. package/templates/integration-tests/{shared/js-tests → js-tests}/package.json +1 -1
  40. package/templates/integration-tests/{shared/js-tests → js-tests}/src/main.ava.ts +1 -1
  41. package/templates/integration-tests/{shared/rust-tests → rust-tests}/Cargo.toml +0 -0
  42. package/templates/integration-tests/{shared/rust-tests → rust-tests}/src/tests.rs +0 -0
  43. package/templates/shared/README.md +3 -3
  44. package/templates/shared/{near.gitignore → template.gitignore} +0 -0
  45. package/dist/checks.js +0 -34
  46. package/templates/frontend/react/frontend/index.js +0 -15
  47. package/templates/frontend/react/frontend/near-api.js +0 -51
  48. package/templates/frontend/react/frontend/near-config.js +0 -61
  49. package/templates/frontend/vanilla/frontend/index.html +0 -86
  50. package/templates/frontend/vanilla/frontend/near-api.js +0 -51
  51. package/templates/frontend/vanilla/frontend/near-config.js +0 -62
  52. package/templates/frontend/vanilla/frontend/package.json +0 -18
  53. package/templates/integration-tests/overrides/js-contract/js-tests/src/main.ava.ts +0 -46
  54. package/templates/integration-tests/overrides/js-contract/rust-tests/src/tests.rs +0 -74
package/README.md CHANGED
@@ -17,6 +17,8 @@ To create a new NEAR project run this and follow interactive prompts:
17
17
 
18
18
  npx create-near-app
19
19
 
20
+ > If you've previously installed `create-near-app` globally via `npm install -g create-near-app`, please uninstall the package using `npm uninstall -g create-near-app` to ensure that `npx` always uses the latest version.
21
+
20
22
  Follow the instructions in the README.md in the project you just created! 🚀
21
23
 
22
24
  You can create contracts written in:
package/dist/app.js CHANGED
@@ -35,11 +35,8 @@ const show = __importStar(require("./messages"));
35
35
  if (promptResult === null) {
36
36
  return;
37
37
  }
38
- const { config: { projectName, contract, frontend, tests, install }, projectPath, isFromPrompts, } = promptResult;
38
+ const { config: { projectName, contract, frontend, tests, install, }, projectPath, } = promptResult;
39
39
  show.creatingApp();
40
- if (contract === 'assemblyscript') {
41
- show.assemblyscriptWarning();
42
- }
43
40
  let createSuccess;
44
41
  try {
45
42
  createSuccess = await (0, make_1.createProject)({
@@ -56,21 +53,15 @@ const show = __importStar(require("./messages"));
56
53
  console.error(e);
57
54
  createSuccess = false;
58
55
  }
56
+ if (install) {
57
+ await (0, make_1.runDepsInstall)(projectPath);
58
+ }
59
59
  if (createSuccess) {
60
- show.setupSuccess(projectPath, contract, frontend);
60
+ show.setupSuccess(projectName, contract, frontend, install);
61
61
  }
62
62
  else {
63
63
  show.setupFailed();
64
64
  return;
65
65
  }
66
- if (install) {
67
- await (0, make_1.runDepsInstall)(projectPath);
68
- }
69
- else if (isFromPrompts) {
70
- const { depsInstall } = await (0, user_input_1.showDepsInstallPrompt)();
71
- if (depsInstall) {
72
- await (0, make_1.runDepsInstall)(projectPath);
73
- }
74
- }
75
66
  })();
76
67
  //# sourceMappingURL=app.js.map
package/dist/make.js CHANGED
@@ -47,34 +47,35 @@ async function createFiles({ contract, frontend, tests, projectPath, verbose, ro
47
47
  const skip = ['.cache', 'dist', 'out', 'node_modules'];
48
48
  // copy frontend
49
49
  if (frontend !== 'none') {
50
- const sourceTemplateDir = `${rootDir}/frontend/${frontend}`;
51
- await copyDir(sourceTemplateDir, projectPath, { verbose, skip: skip.map(f => path_1.default.join(sourceTemplateDir, f)) });
50
+ const sourceFrontendDir = path_1.default.resolve(`${rootDir}/frontend/${frontend}`);
51
+ const sourceSharedFrontendDir = path_1.default.resolve(`${rootDir}/frontend/shared`);
52
+ const targetFrontendDir = path_1.default.resolve(`${projectPath}/frontend`);
53
+ fs_1.default.mkdirSync(targetFrontendDir, { recursive: true });
54
+ await copyDir(sourceFrontendDir, targetFrontendDir, { verbose, skip: skip.map(f => path_1.default.join(sourceFrontendDir, f)) });
55
+ await copyDir(sourceSharedFrontendDir, targetFrontendDir, { verbose, skip: skip.map(f => path_1.default.join(sourceSharedFrontendDir, f)) });
52
56
  }
53
57
  // shared files
54
- const sourceSharedDir = `${rootDir}/shared`;
58
+ const sourceSharedDir = path_1.default.resolve(rootDir, 'shared');
55
59
  await copyDir(sourceSharedDir, projectPath, { verbose, skip: skip.map(f => path_1.default.join(sourceSharedDir, f)) });
56
60
  // copy contract files
57
- const contractSourceDir = `${rootDir}/contracts/${contract}`;
58
- await copyDir(contractSourceDir, `${projectPath}/contract`, {
61
+ const sourceContractDir = path_1.default.resolve(rootDir, 'contracts', contract);
62
+ const targetContractDir = path_1.default.resolve(projectPath, 'contract');
63
+ fs_1.default.mkdirSync(targetContractDir, { recursive: true });
64
+ await copyDir(sourceContractDir, targetContractDir, {
59
65
  verbose,
60
- skip: skip.map(f => path_1.default.join(contractSourceDir, f))
66
+ skip: skip.map(f => path_1.default.join(sourceContractDir, f))
61
67
  });
68
+ // tests dir
69
+ const targetTestDir = path_1.default.resolve(projectPath, 'integration-tests');
70
+ fs_1.default.mkdirSync(targetTestDir, { recursive: true });
62
71
  // copy tests - shared files
63
- let sourceTestSharedDir = path_1.default.resolve(`${rootDir}/integration-tests/shared/${tests}-tests`);
64
- await copyDir(sourceTestSharedDir, `${projectPath}/integration-tests/`, {
72
+ const sourceTestSharedDir = path_1.default.resolve(`${rootDir}/integration-tests/${tests}-tests`);
73
+ await copyDir(sourceTestSharedDir, targetTestDir, {
65
74
  verbose,
66
75
  skip: skip.map(f => path_1.default.join(sourceTestSharedDir, f))
67
76
  });
68
- // copy tests - overrides files
69
- let sourceTestOverridesDir = path_1.default.resolve(`${rootDir}/integration-tests/overrides/${contract}-contract/${tests}-tests`);
70
- if (fs_1.default.existsSync(sourceTestOverridesDir)) {
71
- await copyDir(sourceTestOverridesDir, `${projectPath}/integration-tests/`, {
72
- verbose,
73
- skip: skip.map(f => path_1.default.join(sourceTestOverridesDir, f))
74
- });
75
- }
76
77
  // add .gitignore
77
- await (0, exports.renameFile)(`${projectPath}/near.gitignore`, `${projectPath}/.gitignore`);
78
+ await (0, exports.renameFile)(`${projectPath}/template.gitignore`, `${projectPath}/.gitignore`);
78
79
  }
79
80
  exports.createFiles = createFiles;
80
81
  const renameFile = async function (oldPath, newPath) {
@@ -119,7 +120,7 @@ function copyDir(source, dest, { skip, verbose }) {
119
120
  exports.copyDir = copyDir;
120
121
  async function runDepsInstall(projectPath) {
121
122
  show.depsInstall();
122
- const npmCommandArgs = ['run', 'deps-install'];
123
+ const npmCommandArgs = ['install'];
123
124
  await new Promise((resolve, reject) => (0, cross_spawn_1.default)('npm', npmCommandArgs, {
124
125
  cwd: projectPath,
125
126
  stdio: 'inherit',
package/dist/messages.js CHANGED
@@ -3,19 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.depsInstallError = exports.depsInstall = exports.creatingApp = exports.directoryExists = exports.assemblyscriptWarning = exports.windowsWarning = exports.unsupportedNodeVersion = exports.argsError = exports.setupSuccess = exports.successFrontendToText = exports.successContractToText = exports.setupFailed = exports.welcome = exports.log = void 0;
6
+ exports.depsInstallError = exports.depsInstall = exports.creatingApp = exports.directoryExists = exports.windowsWarning = exports.unsupportedNodeVersion = exports.argsError = exports.setupSuccess = exports.successFrontendToText = exports.successContractToText = exports.setupFailed = exports.welcome = exports.show = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const tracking_1 = require("./tracking");
9
- const log = (...args) => console.log(...args);
10
- exports.log = log;
11
- const welcome = () => (0, exports.log)((0, chalk_1.default) `{blue ======================================================}
9
+ if (process.env.NEAR_NO_COLOR) {
10
+ chalk_1.default.level = 0;
11
+ }
12
+ const show = (...args) => console.log(...args);
13
+ exports.show = show;
14
+ const welcome = () => (0, exports.show)((0, chalk_1.default) `{blue ======================================================}
12
15
  👋 {bold {green Welcome to NEAR!}} Learn more: https://docs.near.org/
13
16
  🔧 Let's get your dApp ready.
14
17
  {blue ======================================================}
15
18
  (${tracking_1.trackingMessage})
16
19
  `);
17
20
  exports.welcome = welcome;
18
- const setupFailed = () => (0, exports.log)((0, chalk_1.default) `{bold {red ==========================================}}
21
+ const setupFailed = () => (0, exports.show)((0, chalk_1.default) `{bold {red ==========================================}}
19
22
  {red ⛔️ There was a problem during NEAR project setup}.
20
23
  Please refer to https://github.com/near/create-near-app README to troubleshoot.
21
24
  Notice: some platforms aren't supported (yet).
@@ -25,32 +28,42 @@ const successContractToText = (contract) => (0, chalk_1.default) `with a smart c
25
28
  exports.successContractToText = successContractToText;
26
29
  const successFrontendToText = (frontend) => frontend === 'none' ? '' : (0, chalk_1.default) ` and a frontend template${frontend === 'react' ? (0, chalk_1.default) `{bold in React.js}` : ''}`;
27
30
  exports.successFrontendToText = successFrontendToText;
28
- const setupSuccess = (projectName, contract, frontend) => (0, exports.log)((0, chalk_1.default) `
31
+ const setupSuccess = (projectName, contract, frontend, install) => (0, exports.show)((0, chalk_1.default) `
32
+ {green ======================================================}
29
33
  ✅ Success! Created '${projectName}'
30
34
  ${(0, exports.successContractToText)(contract)}${(0, exports.successFrontendToText)(frontend)}.
31
- 🧠 See {bold {green README.md}} to get started.
32
- ${contract === 'rust' ? (0, chalk_1.default) `🦀 If you are new to Rust please visit {bold {green https://www.rust-lang.org }}` : ''}
33
- Happy Hacking! 👍
34
- {blue ======================================================}`);
35
+ ${contract === 'rust' ? (0, chalk_1.default) `🦀 If you are new to Rust please visit {bold {green https://www.rust-lang.org }}\n` : ''}
36
+ {bold {bgYellow {black Your next steps}}}:
37
+ - {inverse Navigate to your project}:
38
+ {blue cd {bold ${projectName}}}
39
+ ${!install ? (0, chalk_1.default) `- {inverse Install all dependencies}
40
+ {blue npm {bold install}}` : 'Then:'}
41
+ - {inverse Test your contract} in NEAR SandBox:
42
+ {blue npm {bold test}}
43
+ - {inverse Deploy your contract} to NEAR TestNet with a temporary dev account:
44
+ {blue npm {bold run deploy}}
45
+ ${frontend !== 'none' ? (0, chalk_1.default) `- {inverse Start your frontend}:
46
+ {blue npm {bold start}}\n` : ''}
47
+ 🧠 Read {bold {greenBright README.md}} to explore further.`);
35
48
  exports.setupSuccess = setupSuccess;
36
- const argsError = () => (0, exports.log)((0, chalk_1.default) `{red Arguments error}
49
+ const argsError = () => (0, exports.show)((0, chalk_1.default) `{red Arguments error}
37
50
  Run {blue npx create-near-app} without arguments, or use:
38
51
  npx create-near-app <projectName> --contract rust|js|assemblyscript --frontend react|vanilla|none --tests js|rust`);
39
52
  exports.argsError = argsError;
40
- const unsupportedNodeVersion = (supported) => (0, exports.log)((0, chalk_1.default) `{red We support node.js version ${supported} or later}`);
53
+ const unsupportedNodeVersion = (supported) => (0, exports.show)((0, chalk_1.default) `{red We support node.js version ${supported} or later}`);
41
54
  exports.unsupportedNodeVersion = unsupportedNodeVersion;
42
- const windowsWarning = () => (0, exports.log)((0, chalk_1.default) `👉 Notice: On Windows we recommend using WSL.`);
55
+ const windowsWarning = () => (0, exports.show)((0, chalk_1.default) `{bgYellow {black Notice: On Win32 please use WSL (Windows Subsystem for Linux).}}
56
+ https://docs.microsoft.com/en-us/windows/wsl/install
57
+ Exiting now.`);
43
58
  exports.windowsWarning = windowsWarning;
44
- const assemblyscriptWarning = () => (0, exports.log)((0, chalk_1.default) `👉 Notice: AssemblyScript is not supported on all platforms.`);
45
- exports.assemblyscriptWarning = assemblyscriptWarning;
46
- const directoryExists = (dirName) => (0, exports.log)((0, chalk_1.default) `{red This directory already exists! ${dirName}}`);
59
+ const directoryExists = (dirName) => (0, exports.show)((0, chalk_1.default) `{red This directory already exists! ${dirName}}`);
47
60
  exports.directoryExists = directoryExists;
48
- const creatingApp = () => (0, exports.log)((0, chalk_1.default) `\n...creating a new NEAR app...`);
61
+ const creatingApp = () => (0, exports.show)((0, chalk_1.default) `\nCreating a new {bold NEAR dApp}`);
49
62
  exports.creatingApp = creatingApp;
50
- const depsInstall = () => (0, exports.log)((0, chalk_1.default) `
51
- {green Installing dependencies in a few folders, this might take a while...}
63
+ const depsInstall = () => (0, exports.show)((0, chalk_1.default) `
64
+ {green Installing dependencies in a few folders, this might take a while.}
52
65
  `);
53
66
  exports.depsInstall = depsInstall;
54
- const depsInstallError = () => (0, exports.log)(chalk_1.default.red('Error installing NEAR project dependencies'));
67
+ const depsInstallError = () => (0, exports.show)(chalk_1.default.red('Error installing NEAR project dependencies'));
55
68
  exports.depsInstallError = depsInstallError;
56
69
  //# sourceMappingURL=messages.js.map
@@ -51,10 +51,8 @@ const buildContractScript = (contract) => {
51
51
  };
52
52
  case 'rust':
53
53
  return {
54
- 'build:contract': 'cd contract && rustup target add wasm32-unknown-unknown && cargo build --all --target wasm32-unknown-unknown --release',
54
+ 'build:contract': 'cd contract && ./build.sh',
55
55
  };
56
- default:
57
- return {};
58
56
  }
59
57
  };
60
58
  const deployScript = (contract) => {
@@ -66,10 +64,8 @@ const deployScript = (contract) => {
66
64
  };
67
65
  case 'rust':
68
66
  return {
69
- 'deploy': 'npm run build:contract && cd contract && near dev-deploy --wasmFile ./target/wasm32-unknown-unknown/release/hello_near.wasm',
67
+ 'deploy': 'cd contract && ./deploy.sh',
70
68
  };
71
- default:
72
- return {};
73
69
  }
74
70
  };
75
71
  const unitTestScripts = (contract) => {
@@ -79,8 +75,6 @@ const unitTestScripts = (contract) => {
79
75
  return { 'test:unit': 'cd contract && npm test' };
80
76
  case 'rust':
81
77
  return { 'test:unit': 'cd contract && cargo test' };
82
- default:
83
- return {};
84
78
  }
85
79
  };
86
80
  const integrationTestScripts = (contract, tests) => {
@@ -118,45 +112,59 @@ const integrationTestScripts = (contract, tests) => {
118
112
  'test:integration': 'npm run build:contract && cd integration-tests && cargo run --example integration-tests "../contract/target/wasm32-unknown-unknown/release/hello_near.wasm"',
119
113
  };
120
114
  }
121
- default:
122
- return {};
123
115
  }
124
116
  };
125
117
  const npmInstallScript = (contract, hasFrontend, tests) => {
126
118
  switch (contract) {
127
119
  case 'assemblyscript':
120
+ if (hasFrontend) {
121
+ if (tests === 'js') {
122
+ return { 'postinstall': 'cd contract && npm install --ignore-scripts && cd ../integration-tests && npm install && cd ../frontend && npm install && cd ..' };
123
+ }
124
+ else {
125
+ return { 'postinstall': 'cd contract && npm install --ignore-scripts && cd ../frontend && npm install && cd ..' };
126
+ }
127
+ }
128
+ else {
129
+ if (tests === 'js') {
130
+ return { 'postinstall': 'cd contract && npm install --ignore-scripts && cd ../integration-tests && npm install && cd ..' };
131
+ }
132
+ else {
133
+ return { 'postinstall': 'cd contract && npm install --ignore-scripts && cd ..' };
134
+ }
135
+ }
128
136
  case 'js':
129
137
  if (hasFrontend) {
130
138
  if (tests === 'js') {
131
- return { 'deps-install': 'npm install && cd contract && npm install && cd ../integration-tests && npm install && cd ../frontend && npm install && cd ..' };
139
+ return { 'postinstall': 'cd contract && npm install && cd ../integration-tests && npm install && cd ../frontend && npm install && cd ..' };
132
140
  }
133
141
  else {
134
- return { 'deps-install': 'npm install && cd contract && npm install && cd ../frontend && npm install && cd ..' };
142
+ return { 'postinstall': 'cd contract && npm install && cd ../frontend && npm install && cd ..' };
135
143
  }
136
144
  }
137
145
  else {
138
146
  if (tests === 'js') {
139
- return { 'deps-install': 'npm install && cd contract && npm install && cd ../integration-tests && npm install && cd ..' };
147
+ return { 'postinstall': 'cd contract && npm install && cd ../integration-tests && npm install && cd ..' };
140
148
  }
141
149
  else {
142
- return { 'deps-install': 'npm install && cd contract && npm install && cd ..' };
150
+ return { 'postinstall': 'cd contract && npm install && cd ..' };
143
151
  }
144
152
  }
145
153
  case 'rust':
146
154
  if (hasFrontend) {
147
155
  if (tests === 'js') {
148
- return { 'deps-install': 'npm install && cd frontend && npm install && cd ../integration-tests && npm install && cd ..' };
156
+ return { 'postinstall': 'cd frontend && npm install && cd ../integration-tests && npm install && cd ..' };
149
157
  }
150
158
  else {
151
- return { 'deps-install': 'npm install && cd frontend && npm install && cd ..' };
159
+ return { 'postinstall': 'cd frontend && npm install && cd ..' };
152
160
  }
153
161
  }
154
162
  else {
155
163
  if (tests === 'js') {
156
- return { 'deps-install': 'npm install && cd ./integration-tests && npm install && cd ..' };
164
+ return { 'postinstall': 'cd ./integration-tests && npm install && cd ..' };
157
165
  }
158
166
  else {
159
- return { 'deps-install': 'npm install' };
167
+ return {};
160
168
  }
161
169
  }
162
170
  }
package/dist/tracking.js CHANGED
@@ -9,10 +9,10 @@ const mixpanel_1 = __importDefault(require("mixpanel"));
9
9
  const MIXPANEL_TOKEN = 'df164f13212cbb0dfdae991da60e87f2';
10
10
  const tracker = mixpanel_1.default.init(MIXPANEL_TOKEN);
11
11
  exports.trackingMessage = (0, chalk_1.default) `NEAR collects anonymous information on the commands used. No personal information that could identify you is shared`;
12
- // TODO: track different failures & deps-install usage
12
+ // TODO: track different failures & install usage
13
13
  const trackUsage = async (frontend, contract) => {
14
14
  // prevents logging from CI
15
- if (process.env.IS_GITHUB_ACTION) {
15
+ if (process.env.NEAR_ENV === 'ci' || process.env.NODE_ENV === 'ci') {
16
16
  console.log('Mixpanel logging is skipped in CI env');
17
17
  return;
18
18
  }
package/dist/types.js CHANGED
@@ -1,3 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TESTING_FRAMEWORKS = exports.FRONTENDS = exports.CONTRACTS = void 0;
4
+ exports.CONTRACTS = ['assemblyscript', 'js', 'rust'];
5
+ exports.FRONTENDS = ['react', 'vanilla', 'none'];
6
+ exports.TESTING_FRAMEWORKS = ['rust', 'js'];
3
7
  //# sourceMappingURL=types.js.map
@@ -26,7 +26,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.projectPath = exports.promptAndGetConfig = exports.userAnswersAreValid = exports.showDepsInstallPrompt = exports.showProjectNamePrompt = exports.getUserAnswers = exports.validateUserArgs = exports.getUserArgs = void 0;
29
+ exports.projectPath = exports.promptAndGetConfig = exports.userAnswersAreValid = exports.showProjectNamePrompt = exports.getUserAnswers = exports.validateUserArgs = exports.getUserArgs = void 0;
30
+ const types_1 = require("./types");
30
31
  const chalk_1 = __importDefault(require("chalk"));
31
32
  const prompts_1 = __importDefault(require("prompts"));
32
33
  const commander_1 = require("commander");
@@ -59,9 +60,9 @@ function validateUserArgs(args) {
59
60
  const hasAllArgs = hasAllOptions && hasProjectName;
60
61
  const hasNoArgs = !hasPartialOptions && !hasProjectName;
61
62
  const optionsAreValid = hasAllOptions
62
- && ['react', 'vanilla', 'none'].includes(frontend)
63
- && ['js', 'rust', 'assemblyscript'].includes(contract)
64
- && ['js', 'rust'].includes(tests);
63
+ && types_1.FRONTENDS.includes(frontend)
64
+ && types_1.CONTRACTS.includes(contract)
65
+ && types_1.TESTING_FRAMEWORKS.includes(tests);
65
66
  if (hasNoArgs) {
66
67
  return 'none';
67
68
  }
@@ -73,35 +74,38 @@ function validateUserArgs(args) {
73
74
  }
74
75
  }
75
76
  exports.validateUserArgs = validateUserArgs;
77
+ const contractChoices = [
78
+ { title: 'TypeScript', value: 'js' },
79
+ { title: 'Rust', value: 'rust' },
80
+ { title: 'AssemblyScript', value: 'assemblyscript' },
81
+ ];
82
+ const testsChoices = [
83
+ { title: 'Rust Sandbox Tests', value: 'rust' },
84
+ { title: 'TypeScript Sandbox Tests', value: 'js' },
85
+ ];
86
+ const frontendChoices = [
87
+ { title: 'React.js', value: 'react' },
88
+ { title: 'Vanilla JavaScript', value: 'vanilla' },
89
+ { title: 'No frontend', value: 'none' },
90
+ ];
76
91
  const userPrompts = [
77
92
  {
78
93
  type: 'select',
79
94
  name: 'contract',
80
95
  message: 'Select your smart-contract language',
81
- choices: [
82
- { title: 'JavaScript', value: 'js' },
83
- { title: 'Rust', value: 'rust' },
84
- { title: 'AssemblyScript', value: 'assemblyscript' },
85
- ]
96
+ choices: contractChoices,
86
97
  },
87
98
  {
88
99
  type: prev => prev === 'rust' ? 'select' : null,
89
100
  name: 'tests',
90
101
  message: 'Select language for Sandbox Test',
91
- choices: [
92
- { title: 'Rust Sandbox Tests', value: 'rust' },
93
- { title: 'JavaScript Sandbox Tests', value: 'js' },
94
- ]
102
+ choices: testsChoices,
95
103
  },
96
104
  {
97
105
  type: 'select',
98
106
  name: 'frontend',
99
107
  message: 'Select a template for your frontend',
100
- choices: [
101
- { title: 'React.js', value: 'react' },
102
- { title: 'Vanilla JavaScript', value: 'vanilla' },
103
- { title: 'No frontend', value: 'none' },
104
- ]
108
+ choices: frontendChoices,
105
109
  },
106
110
  {
107
111
  type: 'text',
@@ -109,10 +113,15 @@ const userPrompts = [
109
113
  message: 'Name your project (this will create a directory with that name)',
110
114
  initial: 'hello-near',
111
115
  },
116
+ {
117
+ type: 'confirm',
118
+ name: 'install',
119
+ message: (0, chalk_1.default) `Run {bold {blue 'npm install'}} now?`,
120
+ initial: true,
121
+ },
112
122
  ];
113
123
  async function getUserAnswers() {
114
- const [contract, frontend, tests, projectName] = userPrompts;
115
- const answers = await (0, prompts_1.default)([contract, frontend, tests, projectName]);
124
+ const answers = await (0, prompts_1.default)(userPrompts);
116
125
  if (!answers.tests) {
117
126
  answers.tests = answers.contract !== 'rust' ? 'js' : 'rust';
118
127
  }
@@ -125,22 +134,6 @@ async function showProjectNamePrompt() {
125
134
  return answers;
126
135
  }
127
136
  exports.showProjectNamePrompt = showProjectNamePrompt;
128
- async function showDepsInstallPrompt() {
129
- const questions = [
130
- {
131
- type: 'toggle',
132
- name: 'depsInstall',
133
- // message: chalk`One last thing:\n There are few package.json files with dependencies. We can run {bold {blue 'yarn install'}} for you.\n Run {bold {blue 'yarn install'}} now? (To do it yourself: {blue 'yarn run deps-install'}).\n \n`,
134
- message: (0, chalk_1.default) `Run {bold {blue 'npm install'}} now in all folders? (To do it yourself: {blue 'npm run deps-install'}).\n`,
135
- initial: true,
136
- active: 'yes',
137
- inactive: 'no'
138
- },
139
- ];
140
- const answers = await (0, prompts_1.default)(questions);
141
- return answers;
142
- }
143
- exports.showDepsInstallPrompt = showDepsInstallPrompt;
144
137
  function userAnswersAreValid(answers) {
145
138
  const { contract, frontend, projectName, tests } = answers;
146
139
  if ([contract, frontend, projectName, tests].includes(undefined)) {
@@ -156,7 +149,6 @@ async function promptAndGetConfig() {
156
149
  let isFromPrompts = false;
157
150
  // process cli args
158
151
  const args = await getUserArgs();
159
- const { install } = args;
160
152
  const argsValid = validateUserArgs(args);
161
153
  if (argsValid === 'error') {
162
154
  show.argsError();
@@ -176,6 +168,7 @@ async function promptAndGetConfig() {
176
168
  if (process.platform === 'win32') {
177
169
  // TODO: track windows
178
170
  show.windowsWarning();
171
+ return null;
179
172
  }
180
173
  // Get user input
181
174
  if (config === null) {
@@ -189,21 +182,12 @@ async function promptAndGetConfig() {
189
182
  const { frontend, contract } = config;
190
183
  (0, tracking_1.trackUsage)(frontend, contract);
191
184
  let path = (0, exports.projectPath)(config.projectName);
192
- // If dir exists keep asking user
185
+ // If dir exists warn and exit
193
186
  if (fs_1.default.existsSync(path)) {
194
- if (!isFromPrompts) {
195
- show.directoryExists(path);
196
- return null;
197
- }
198
- else {
199
- while (fs_1.default.existsSync(path)) {
200
- show.directoryExists(path);
201
- const { projectName: newProjectName } = await showProjectNamePrompt();
202
- config.projectName = newProjectName;
203
- }
204
- }
187
+ show.directoryExists(path);
188
+ return null;
205
189
  }
206
- return { config: { ...config, install }, projectPath: path, isFromPrompts };
190
+ return { config, projectPath: path, isFromPrompts };
207
191
  }
208
192
  exports.promptAndGetConfig = promptAndGetConfig;
209
193
  const projectPath = (projectName) => `${process.cwd()}/${projectName}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-near-app",
3
- "version": "4.0.0-beta.3.0",
3
+ "version": "4.1.0",
4
4
  "description": "Quickly scaffold your dApp on NEAR Blockchain",
5
5
  "main": "index.js",
6
6
  "engines": {
@@ -16,7 +16,7 @@
16
16
  "scripts": {
17
17
  "start": "npm run build && node index.js",
18
18
  "build": "tsc",
19
- "test": "npm run build && jest --runInBand",
19
+ "test": "npm run build && FORCE_COLOR=1 jest --runInBand",
20
20
  "test-e2e": "npm run build && ./test/e2e.sh",
21
21
  "lint": "eslint .",
22
22
  "fix": "eslint . --fix",
@@ -27,7 +27,6 @@
27
27
  "chalk": "^4.1.2",
28
28
  "commander": "^9.4.0",
29
29
  "cross-spawn": "^7.0.3",
30
- "lodash": "^4.17.21",
31
30
  "mixpanel": "^0.16.0",
32
31
  "ncp": "^2.0.0",
33
32
  "prompts": "^2.4.2",
@@ -44,8 +43,6 @@
44
43
  "@types/node": "^18.6.1",
45
44
  "@types/prompts": "^2.0.14",
46
45
  "@types/semver": "^7.3.10",
47
- "@typescript-eslint/eslint-plugin": "^5.26.0",
48
- "@typescript-eslint/parser": "^5.26.0",
49
46
  "eslint": "^8.20.0",
50
47
  "eslint-config-react-app": "^7.0.1",
51
48
  "eslint-plugin-import": "^2.26.0",
@@ -1,23 +1,79 @@
1
- Hello NEAR!
2
- =================================
1
+ # Hello NEAR Contract
3
2
 
4
- A [smart contract] written with [NEAR JavaScript SDK] for an app initialized with [create-near-app]
3
+ The smart contract exposes two methods to enable storing and retrieving a greeting in the NEAR network.
5
4
 
5
+ ```ts
6
+ @NearBindgen({})
7
+ class HelloNear {
8
+ greeting: string = "Hello";
6
9
 
7
- Quick Start
8
- ===========
10
+ @view // This method is read-only and can be called for free
11
+ get_greeting(): string {
12
+ return this.greeting;
13
+ }
9
14
 
10
- 1. Install dependencies: `npm install`
11
- 2. Deploy to NEAR TestNet with a temporary dev account: `npm run deploy`
15
+ @call // This method changes the state, for which it cost gas
16
+ set_greeting({ greeting }: { greeting: string }): void {
17
+ // Record a log permanently to the blockchain!
18
+ near.log(`Saving greeting ${greeting}`);
19
+ this.greeting = greeting;
20
+ }
21
+ }
22
+ ```
12
23
 
13
- Exploring The Code
14
- ==================
24
+ <br />
15
25
 
16
- 1. The smart contract code is in `src/contract.ts`.
17
- 2. There are two functions to the smart contract: `get_greeting` and `set_greeting`.
18
- 3. Tests: Use integration-tests that `create-near-app` created for you.
26
+ # Quickstart
19
27
 
28
+ 1. Make sure you have installed [node.js](https://nodejs.org/en/download/package-manager/) >= 16.
29
+ 2. Install the [`NEAR CLI`](https://github.com/near/near-cli#setup)
20
30
 
21
- [smart contract]: https://docs.near.org/develop/welcome
22
- [NEAR JavaScript SDK]: https://github.com/near/near-sdk-js
23
- [create-near-app]: https://github.com/near/create-near-app
31
+ <br />
32
+
33
+ ## 1. Build and Deploy the Contract
34
+ You can automatically compile and deploy the contract in the NEAR testnet by running:
35
+
36
+ ```bash
37
+ npm run deploy
38
+ ```
39
+
40
+ Once finished, check the `neardev/dev-account` file to find the address in which the contract was deployed:
41
+
42
+ ```bash
43
+ cat ./neardev/dev-account
44
+ # e.g. dev-1659899566943-21539992274727
45
+ ```
46
+
47
+ <br />
48
+
49
+ ## 2. Retrieve the Greeting
50
+
51
+ `get_greeting` is a read-only method (aka `view` method).
52
+
53
+ `View` methods can be called for **free** by anyone, even people **without a NEAR account**!
54
+
55
+ ```bash
56
+ # Use near-cli to get the greeting
57
+ near view <dev-account> get_greeting
58
+ ```
59
+
60
+ <br />
61
+
62
+ ## 3. Store a New Greeting
63
+ `set_greeting` changes the contract's state, for which it is a `call` method.
64
+
65
+ `Call` methods can only be invoked using a NEAR account, since the account needs to pay GAS for the transaction.
66
+
67
+ ```bash
68
+ # Use near-cli to set a new greeting
69
+ near call <dev-account> set_greeting '{"greeting":"howdy"}' --accountId <dev-account>
70
+ ```
71
+
72
+ **Tip:** If you would like to call `set_greeting` using your own account, first login into NEAR using:
73
+
74
+ ```bash
75
+ # Use near-cli to login your NEAR account
76
+ near login
77
+ ```
78
+
79
+ and then use the logged account to sign the transaction: `--accountId <your-account>`.
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ echo ">> Building contract"
4
+
5
+ near-sdk-js build src/contract.ts build/hello_near.wasm
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ ./build.sh
4
+
5
+ if [ $? -ne 0 ]; then
6
+ echo ">> Error building contract"
7
+ exit 1
8
+ fi
9
+
10
+ echo ">> Deploying contract"
11
+
12
+ # https://docs.near.org/tools/near-cli#near-dev-deploy
13
+ near dev-deploy --wasmFile build/hello_near.wasm
@@ -4,13 +4,13 @@
4
4
  "license": "(MIT AND Apache-2.0)",
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "near-sdk-js build src/contract.ts build/hello_near.wasm",
8
- "deploy": "npm run build && rm -rf neardev && near dev-deploy --wasmFile build/hello_near.wasm && export $(cat ./neardev/dev-account.env) && near call $CONTRACT_NAME init --accountId $CONTRACT_NAME --deposit 1 && echo $CONTRACT_NAME",
7
+ "build": "./build.sh",
8
+ "deploy": "./deploy.sh",
9
9
  "test": "echo use integration-tests"
10
10
  },
11
11
  "dependencies": {
12
12
  "near-cli": "^3.4.0",
13
- "near-sdk-js": "0.4.0-4"
13
+ "near-sdk-js": "0.5.0-0"
14
14
  },
15
15
  "devDependencies": {
16
16
  "typescript": "^4.7.4"