├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .prettierrc ├── .vscode ├── settings.json └── tasks.json ├── LICENSE ├── README.md ├── __tests__ └── sample-test.js ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── AccountConfiguration │ └── .gitkeep ├── FileCabinet │ ├── SuiteScripts │ │ └── netsuite-typescript-sdf │ │ │ └── .gitkeep │ ├── Templates │ │ ├── E-mail Templates │ │ │ └── .gitkeep │ │ └── Marketing Templates │ │ │ └── .gitkeep │ └── Web Site Hosting Files │ │ ├── Live Hosting Files │ │ └── .gitkeep │ │ └── Staging Hosting Files │ │ └── .gitkeep ├── Objects │ └── .gitkeep ├── Translations │ └── .gitkeep ├── TypeScripts │ └── netsuite-typescript-sdf │ │ └── .gitkeep ├── deploy.xml └── manifest.xml ├── suitecloud.config.js └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | # skip the node modules 2 | node_modules 3 | 4 | # skip the generated NetSuite JavaScript files 5 | src/FileCabinet/SuiteScripts 6 | 7 | # skip the SuiteCloud SDK config file 8 | suitecloud.config.js 9 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:suitescript/all"], 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "ecmaVersion": 12 10 | }, 11 | "plugins": ["@typescript-eslint", "suitescript"], 12 | "rules": { 13 | "max-len": [ 14 | "error", 15 | { 16 | "code": 120, 17 | "ignoreComments": true, 18 | "ignoreStrings": true, 19 | "ignoreTemplateLiterals": true 20 | } 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDEs and editors 2 | .idea 3 | *.iml 4 | *.iws 5 | .project 6 | .classpath 7 | *.launch 8 | .settings 9 | *.sublime-workspace 10 | # .vscode 11 | 12 | # Dependency directories 13 | node_modules 14 | 15 | # TypeScript cache 16 | *.tsbuildinfo 17 | 18 | # Logs 19 | logs 20 | *.log 21 | npm-debug.log* 22 | 23 | # Packaged SuiteCloud projects 24 | build 25 | 26 | # misc 27 | .sass-cache 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # System Files 33 | .DS_Store 34 | Thumbs.db 35 | 36 | # Output of 'npm pack' 37 | *.tgz 38 | 39 | # Project config 40 | project.json 41 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "task.allowAutomaticTasks": "on", 4 | 5 | // Prettier - ESLint settings 6 | "editor.defaultFormatter": "rvest.vs-code-prettier-eslint", // https://github.com/idahogurl/vs-code-prettier-eslint 7 | "editor.formatOnPaste": false, // required 8 | "editor.formatOnType": false, // required 9 | "editor.formatOnSave": true, // optional 10 | "editor.formatOnSaveMode": "file", // required to format on save 11 | "files.autoSave": "onFocusChange" // optional but recommended 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "typescript", 6 | "tsconfig": "tsconfig.json", 7 | "option": "watch", 8 | "presentation": { 9 | "echo": true, 10 | "reveal": "silent", 11 | "focus": false, 12 | "panel": "shared" 13 | }, 14 | "isBackground": true, 15 | "runOptions": { 16 | "runOn": "folderOpen" 17 | }, 18 | "problemMatcher": ["$tsc-watch"], 19 | "group": { 20 | "kind": "build", 21 | "isDefault": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Matthew Plant 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetSuite TypeScript SDF Project Template 2 | 3 | For an example of this project template being used, see [SuiteTools](https://github.com/mattplant/SuiteTools). 4 | 5 | ## Requirements 6 | 7 | - Node - 8 | - TypeScript - 9 | - Oracle JDK version 17 (64 bit) - required for SuiteCloud SDK 10 | - SuiteCloud SDK - 11 | - "SuiteCloud Development Integration" (245955) bundle installed in NetSuite 12 | 13 | ## Initial Setup 14 | 15 | These initial steps will only need to be done once. 16 | 17 | ### Core Configuration 18 | 19 | - clone the repo 20 | - `git clone https://github.com/mattplant/netsuite-typescript-sdf.git` 21 | - enable linting 22 | - `cd netsuite-typescript-sdf; npm install` 23 | - connect your NetSuite account 24 | - `suitecloud account:setup` 25 | 26 | ### VS Code Configuration (optional) 27 | 28 | - install VS Code extensions 29 | - SuiteCloud Extension for Visual Studio Code - 30 | - VS Code ESLint extension - 31 | - Prettier ESLint - 32 | - allow VS Code to run tasks automatically so that TypeScript can automatically run in the background 33 | - in command palette, select "Tasks: Manage Automatic Tasks in Folder" and then "Allow Automatic Tasks in Folder" 34 | 35 | ## Usage 36 | 37 | Now in VS Code when you create your TypeScript files in the */src/TypeScripts/netsuite-typescript-sdf/ folder they will automatically be linted as you type and automatically formatted and code fixed upon saving. The corresponding JavaScript for NetSuite's API Version 2.1 (aka SuiteScript 2.1) will automatically be generated in the*/src/FileCabinet/SuiteScripts/netsuite-typescript-sdf/ folder ready for deployment to your NetSuite account. 38 | 39 | ## Notes 40 | 41 | NetSuite customization development is now done with modern tools. You now have complete control over your development processes including using VS Code. Your NetSuite customizations (files, scripts and other custom objects) can be imported and exported between your NetSuite environments (production, sandbox, release preview, or development). 42 | 43 | This template was initially built by Oracle's SuiteCloud SDK via `suitecloud project:create -i`. 44 | 45 | For NetSuite TypeScript support I leveraged . 46 | 47 | ## macOS Tools (optional) 48 | 49 | Tools I used to fulfill the above requirements in macOS. 50 | 51 | - Homebrew 52 | - 53 | - Node 54 | - `brew install node` 55 | - TypeScript 56 | - `npm install -g typescript` 57 | - OpenJDK 17 58 | - `brew install openjdk@17` 59 | - SuiteCloud SDK 60 | - `npm install -g @oracle/suitecloud-cli` 61 | - VS Code (optional) 62 | - `brew install --cask visual-studio-code` 63 | - Oracle's SuiteCloud extension for VS Code (optional) 64 | - [SuiteCloud Extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=Oracle.suitecloud-vscode-extension) 65 | - Microsoft's ESLint extension for VS Code (optional) 66 | - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 67 | -------------------------------------------------------------------------------- /__tests__/sample-test.js: -------------------------------------------------------------------------------- 1 | import record from 'N/record'; 2 | import Record from 'N/record/instance'; 3 | 4 | jest.mock('N/record'); 5 | jest.mock('N/record/instance'); 6 | 7 | beforeEach(() => { 8 | jest.clearAllMocks(); 9 | }); 10 | 11 | describe('Basic jest test with simple assert', () => { 12 | it('should assert strings are equal', () => { 13 | const a = 'foobar'; 14 | const b = 'foobar'; 15 | expect(a).toMatch(b); 16 | }); 17 | }); 18 | 19 | describe('Sample test with provided record module stubs', () => { 20 | it('should update Sales Order memo field', () => { 21 | // given 22 | const salesOrderId = 1352; 23 | record.load.mockReturnValue(Record); 24 | Record.save.mockReturnValue(salesOrderId); 25 | 26 | // when 27 | let salesOrderRecord = record.load({ id: salesOrderId }); 28 | salesOrderRecord.setValue({ fieldId: 'memo', value: 'foobar' }); 29 | const updatedSalesOrderId = salesOrderRecord.save({ enableSourcing: false }); 30 | 31 | // then 32 | expect(record.load).toHaveBeenCalledWith({ id: salesOrderId }); 33 | expect(Record.setValue).toHaveBeenCalledWith({ fieldId: 'memo', value: 'foobar' }); 34 | expect(Record.save).toHaveBeenCalledWith({ enableSourcing: false }); 35 | expect(salesOrderId).toBe(updatedSalesOrderId); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const SuiteCloudJestConfiguration = require('@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration'); 2 | const cliConfig = require('./suitecloud.config'); 3 | 4 | module.exports = SuiteCloudJestConfiguration.build({ 5 | projectFolder: cliConfig.defaultProjectFolder, 6 | projectType: SuiteCloudJestConfiguration.ProjectType.ACP, 7 | }); 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "netsuite-typescript-sdf", 3 | "displayName": "NetSuite TypeScript SDF Project Template", 4 | "description": "NetSuite TypeScript SDF Project Template", 5 | "keywords": [ 6 | "netsuite", 7 | "sdf", 8 | "suitescript", 9 | "typescript" 10 | ], 11 | "author": { 12 | "name": "Matthew Plant", 13 | "url": "https://github.com/mattplant" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/mattplant/netsuite-typescript-sdf" 18 | }, 19 | "version": "1.3.0", 20 | "license": "MIT", 21 | "scripts": { 22 | "lint": "npx eslint . --ext .js --ext .ts", 23 | "test": "jest" 24 | }, 25 | "devDependencies": { 26 | "@hitc/netsuite-types": "^2022.2.14", 27 | "@oracle/suitecloud-unit-testing": "^1.2.1", 28 | "@typescript-eslint/eslint-plugin": "^5.35.1", 29 | "@typescript-eslint/parser": "^5.35.1", 30 | "eslint": "^8.22.0", 31 | "eslint-config-airbnb-base": "^15.0.0", 32 | "eslint-plugin-suitescript": "^1.2.1", 33 | "jest": "^29.3.1", 34 | "prettier": "^2.8.1", 35 | "typescript": "^4.8.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/AccountConfiguration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/AccountConfiguration/.gitkeep -------------------------------------------------------------------------------- /src/FileCabinet/SuiteScripts/netsuite-typescript-sdf/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/FileCabinet/SuiteScripts/netsuite-typescript-sdf/.gitkeep -------------------------------------------------------------------------------- /src/FileCabinet/Templates/E-mail Templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/FileCabinet/Templates/E-mail Templates/.gitkeep -------------------------------------------------------------------------------- /src/FileCabinet/Templates/Marketing Templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/FileCabinet/Templates/Marketing Templates/.gitkeep -------------------------------------------------------------------------------- /src/FileCabinet/Web Site Hosting Files/Live Hosting Files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/FileCabinet/Web Site Hosting Files/Live Hosting Files/.gitkeep -------------------------------------------------------------------------------- /src/FileCabinet/Web Site Hosting Files/Staging Hosting Files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/FileCabinet/Web Site Hosting Files/Staging Hosting Files/.gitkeep -------------------------------------------------------------------------------- /src/Objects/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/Objects/.gitkeep -------------------------------------------------------------------------------- /src/Translations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/Translations/.gitkeep -------------------------------------------------------------------------------- /src/TypeScripts/netsuite-typescript-sdf/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattplant/NetSuite-TypeScript-SDF/ab4c923910cf3d75fafae4ca74a53c8f973801b9/src/TypeScripts/netsuite-typescript-sdf/.gitkeep -------------------------------------------------------------------------------- /src/deploy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ~/AccountConfiguration/* 4 | 5 | 6 | ~/FileCabinet/* 7 | 8 | 9 | ~/Objects/* 10 | 11 | 12 | ~/Translations/* 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | NetSuite_TypeScript_SDF 3 | 1.0 4 | 5 | 6 | SERVERSIDESCRIPTING 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /suitecloud.config.js: -------------------------------------------------------------------------------- 1 | const SuiteCloudJestUnitTestRunner = require('@oracle/suitecloud-unit-testing/services/SuiteCloudJestUnitTestRunner'); 2 | 3 | module.exports = { 4 | defaultProjectFolder: 'src', 5 | commands: { 6 | "project:deploy": { 7 | beforeExecuting: async args => { 8 | // await SuiteCloudJestUnitTestRunner.run({ 9 | // // Jest configuration options. 10 | // }); 11 | return args; 12 | }, 13 | }, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "baseUrl": ".", 5 | "esModuleInterop": true, 6 | "experimentalDecorators": true, 7 | "lib": ["es7", "es2015.promise", "dom"], 8 | "module": "amd", 9 | "moduleResolution": "node", 10 | "newLine": "LF", 11 | "noImplicitUseStrict": true, 12 | "noUnusedLocals": true, 13 | "outDir": "./src/FileCabinet/SuiteScripts/netsuite-typescript-sdf", 14 | "paths": { 15 | "N": ["node_modules/@hitc/netsuite-types/N"], 16 | "N/*": ["node_modules/@hitc/netsuite-types/N/*"] 17 | }, 18 | "sourceMap": false, 19 | "target": "es2020" 20 | }, 21 | "include": ["."], 22 | "exclude": ["node_modules"] 23 | } 24 | --------------------------------------------------------------------------------