### Complete Router Setup with Hash Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Example of a complete router setup using `Router.Hash` for URL fragments, including dashboard and countries routes. ```javascript // Setup router //... // dashboard route - '/dashboard' // countries route - '/countries' ``` -------------------------------- ### Install Dependencies and Build UI Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/app/helloworld_app/README.md Install project dependencies and build the UI artifact. Run from the project root. ```bash npm install npm run helloworld_app ``` -------------------------------- ### Install Dependencies Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Installs the required dependencies for the project. ```bash npm i ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/third-party-tools/README.md Run this command in the root folder to install all necessary project dependencies. ```bash npm install ``` -------------------------------- ### Install SuiteCloud CLI Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/README.md Installs the SuiteCloud CLI globally using npm. This tool is required for SuiteCloud development. ```bash npm i -g @oracle/suitecloud-cli ``` -------------------------------- ### Build UI from App Directory Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/app/helloworld_app/README.md Build the UI artifact when running commands from the app's directory. This command assumes dependencies are already installed. ```bash npm run build ``` -------------------------------- ### Redirect Call from Wizard Suitelet Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.defaulting/README.md Example of a redirect call from a wizard Suitelet, setting parameters for entity and indicating it's from a wizard. ```javascript const domain = url.resolveDomain({hostType: url.HostType.APPLICATION}); const path = url.resolveRecord({recordType: "salesorder"}); const soUrl = url.format({domain: `https://${domain}${path}`, params: { fromWizard: "T", entity: 107 }}); redirect.redirect({url: soUrl}); ``` -------------------------------- ### Define Initial State Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-state-management/README.md Defines the initial state for the application. This object holds the starting values for all state properties. ```javascript export default { counter: 0, }; ``` -------------------------------- ### Define Nested Routes with Router Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Configure nested routes to manage different views within a specific URL path. This example shows how to define routes for '/lists/population', '/lists/area', and the index route '/lists'. ```javascript // definition of nested routes under the '/lists' url // list population route - '/lists/population' // list area route - '/lists/area' // lists index route - '/lists' //... ``` -------------------------------- ### Get Optional Keys Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Identifies keys in a schema definition that are marked as optional. Useful for dynamic form generation or validation. ```javascript function gx(e){return Object.keys(e).filter(n=>e[n]._zod.optin==="optional"&&e[n]._zod.optout==="optional")} ``` -------------------------------- ### SuiteQL Query for Auto-Purchasing Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/enhancing-business-flows/automatic-purchasing/README.md This SuiteQL query identifies items that are below their reorder quantity and are not already covered by an open purchase order for the same vendor. It selects vendor, item, and quantity from a custom auto-purchase setup record. ```sql SELECT setup.custrecord_autopurch_vendor AS vendor, setup.custrecord_autopurch_item AS item, setup.custrecord_autopurch_quantity quantity FROM customrecord_autopurchase setup INNER JOIN item item ON setup.custrecord_autopurch_item = item.id WHERE nvl(item.totalQuantityOnHand, 0.0) <= setup.custrecord_autopurch_quantity AND NOT EXISTS( SELECT 1 FROM TransactionLine tl, Transaction t WHERE t.id = tl.transaction AND t.type = 'PurchOrd' AND t.status IN ('PurchOrd:A', 'PurchOrd:B', 'PurchOrd:D', 'PurchOrd:E', 'PurchOrd:F', 'PurchOrd:G') AND tl.item = setup.custrecord_autopurch_item AND t.entity = setup.custrecord_autopurch_vendor ) ``` -------------------------------- ### Initialize App and Handle Host Capabilities Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html This JavaScript function initializes the application, sets up host capabilities, and handles notifications. It throws an error if the server sends an invalid initialize result. Ensure the host runtime is available before calling. ```javascript function HD({appInfo:e,capabilities:n,onAppCreated:r}){let[l,i]=Ei.useState(null),[o,c]=Ei.useState(!1),[m,h]=Ei.useState(null);return Ei.useEffect(()=>{let v=!0;async function y(){try{let b=new Gb(window.parent,window.parent),z=new LD(e,n);r?.(z),await z.connect(b),v&&(i(z),c(!0),h(null))}catch(b){v&&(i(null),c(!1),h(b instanceof Error?b:Error("Failed to connect")))}}return y(),()=>{v=!1}},[]),{app:l,isConnected:o,error:m}} ``` -------------------------------- ### Retrieve Item Sublist Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.dynamicOptions/README.md Gets the 'item' sublist from the form. This is a prerequisite for manipulating item sublist fields. ```javascript const itemSublist = scriptContext.form.getSublist({"id": "item"}); ``` -------------------------------- ### Deploy Application Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Bundles the built application and deploys it to the configured NetSuite account. ```bash npm run deploy ``` -------------------------------- ### Get Current Vendor Field Object Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.dynamicOptions/README.md Retrieves the current vendor field object from the sublist to manipulate its options. ```javascript const currentVendorField = scriptContext.currentRecord.getCurrentSublistField({ sublistId: scriptContext.sublistId, fieldId: "custpage_item_vendor", }); ``` -------------------------------- ### Bundle Sources Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Bundles the application sources into the '/src/FileCabinet/SuiteApps' folder. ```bash npm run bundle ``` -------------------------------- ### Retrieve Entity Value from New Record Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.defaulting/README.md Gets the value of the 'entity' field (customer) from the record that is currently being created. ```javascript const customer = scriptContext.newRecord.getValue({fieldId: "entity"}); ``` -------------------------------- ### Define Specific and Catch-all Routes Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Set up specific routes for pages like country details and a catch-all route for handling undefined paths. The catch-all route ('*') should be placed last to ensure it only matches when no other routes are matched. ```javascript // country route - '/countries/:countryCode' // page not found route - '*' - matches all other routes ``` -------------------------------- ### Bootstrap Application Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md The entry point for the frontend application, responsible for bootstrapping by setting the layout and providing content. ```typescript export function run() { // Set application layout and content here } ``` -------------------------------- ### Get Cloudflare Environment Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Determines if the current environment is Cloudflare. Returns false if navigator.userAgent indicates Cloudflare or if Function constructor is unavailable. ```javascript function Ui(e){return V_} ``` -------------------------------- ### Provide Store to Application Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-state-management/README.md Wraps the application with `` to make the store and its dispatch function available to all child components. ```javascript return ( ); ``` -------------------------------- ### Hello World App Component Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html This React component manages the 'Hello World' application's state, including user input and submission status. It renders the UI for message input and displays connection status and errors. Use this component to build interactive SuiteCloud applications. ```javascript function JD(){const[e,n]=Ei.useState("Hello world"),[r,l]=Ei.useState("idle"),[i,o]=Ei.useState("");{app:c,isConnected:m,error:h}=HD({appInfo:{name:"helloworld_app",version:"1.0.0"},capabilities:{}});var v=async()=>{if(!c){l("error"),o("The MCP app runtime is not available.");return}l("submitting"),o("");try{if((await c.sendMessage({role:"user",content:[{type:"text",text:e}]})).isError){l("error"),o("The MCP client rejected the message.");return}l("success"),o("Message sent to chat.")}catch(y){l("error"),o(y instanceof Error?y.message:"Failed to send the message.")}};return Qe.jsx("div",{className:"ns-shell",children:Qe.jsx("section",{className:"ns-report",children:h?Qe.jsxs("div",{className:"ns-loading-state",children:[ Qe.jsx("p",{className:"ns-loading-title",children:"Unable to load app"}), Qe.jsx("p",{className:"ns-loading-copy",children:h.message}) ]}):m?Qe.jsxs(Qe.Fragment,{children:[ Qe.jsxs("div",{className:"ns-filter-bar",children:[ Qe.jsx("div",{className:"ns-hello-intro",children:Qe.jsx("h1",{className:"ns-hello-title",children:"Hello World"}}) }), Qe.jsxs("div",{className:"field-card",children:[ Qe.jsx("label",{htmlFor:"message",children:"Message"}), Qe.jsx("input",{id:"message",type:"text",value:e,onChange:y=>{n(y.target.value),r!=="idle"&&(l("idle"),o(""))}}) ] }) ] }), Qe.jsxs("div",{className:"ns-footer",children:[ Qe.jsx("div",{className:"button-row",children:Qe.jsx("button",{type:"button",onClick:v,disabled:r==="submitting",children:r==="submitting"?"Sending...":"Send to chat"}}) }), Qe.jsx("p",{className: `ns-submit-status${r==="idle"?" is-hidden":""}${r==="error"?" is-error":" is-success"}`, role:"status",children:i }) ] }) ] }):Qe.jsxs("div",{className:"ns-loading-state",children:[ Qe.jsx("div",{className:"ns-spinner","aria-hidden":"true"}), Qe.jsx("p",{className:"ns-loading-title",children:"Loading app"}), Qe.jsx("p",{className:"ns-loading-copy",children:"Connecting to the MCP host runtime..."}) ] }) })})} dx.createRoot(document.getElementById("root")).render(Qe.jsx(Ei.StrictMode,{children:Qe.jsx(JD,{})})); ``` -------------------------------- ### Get Current User and Time in beforeLoad Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.locking/README.md Retrieves the current user's information and the current timestamp. This is used for generating a unique tag for tracking. ```javascript const user = runtime.getCurrentUser(); const timeNow = Date.now(); ``` -------------------------------- ### Initialize Known Options Set Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.dynamicOptions/README.md Initializes a `Set` to keep track of known options, preventing duplicate entries in the vendor select field. ```javascript const knownOptions = new Set(); ``` -------------------------------- ### React Development Tools Integration Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Initializes React DevTools and checks for dead code elimination. This is typically part of the React library's internal setup. ```javascript function sx(){if(i_)return fd.exports;i_=1;function e(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(n){console.error(n)}}return e(),fd.exports=ox(),fd.exports} ``` -------------------------------- ### Run Unit Tests Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Executes unit tests for the application. ```bash npm run test_unit ``` -------------------------------- ### Programmatic Navigation with Router Navigation Context Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Use the ROUTER_NAVIGATION context to navigate programmatically. Access it via useContext and call the push method with a route path and optional parameters. ```javascript const navigator = Hook.useContext(ContextType.ROUTER_NAVIGATION); navigator.push('/myRoute'); // navigates to '/myRoute' navigator.push('/myRoute/:myParam', {myParam: 42}); // navigates to '/myRoute/42' ``` -------------------------------- ### Get Tracking Record ID in beforeSubmit Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.locking/README.md Retrieves the tracking record ID from the 'custbody_lock' field. This ID is used to determine if a lock record already exists. ```javascript const lockId = scriptContext.newRecord.getValue({ fieldId: "custbody_lock" }); ``` -------------------------------- ### Request Handling Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html APIs for setting up handlers for different types of requests. ```APIDOC ## setRequestHandler(requestType, handler) ### Description Registers a handler function for a specific type of request. ### Parameters - **requestType** (string) - Required - The type of request to handle. - **handler** (function) - Required - The asynchronous callback function to execute when a request of the specified type is received. It should return a Promise that resolves with the response data. ### Example ```javascript protocol.setRequestHandler('getTask', async (request, session) => { const task = await taskStore.getTask(request.params.taskId, session.sessionId); return task; }); ``` ``` -------------------------------- ### Define String Format Validation Rules Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Functions to create string format validation rules, including regex patterns, lowercase, uppercase, includes, starts with, and ends with. ```javascript function KT(e,n){return new pw({check:"string_format",format:"regex",...P(n),pattern:e})} function FT(e){return new vw({check:"string_format",format:"lowercase",...P(e)})} function WT(e){return new hw({check:"string_format",format:"uppercase",...P(e)})} function eO(e,n){return new gw({check:"string_format",format:"includes",...P(n),includes:e})} function tO(e,n){return new yw({check:"string_format",format:"starts_with",...P(n),prefix:e})} function nO(e,n){return new _w({check:"string_format",format:"ends_with",...P(n),suffix:e})} ``` -------------------------------- ### Run All Tests Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Executes both unit and end-to-end tests. ```bash npm run test ``` -------------------------------- ### Task Store Request Handlers Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Sets up request handlers for interacting with a task store, including getting, listing, and updating task statuses. This is used for managing asynchronous operations within the application. ```javascript this.setRequestHandler(qd,async(r,l)=>{const i=await this._taskStore.getTask(r.params.taskId,l.sessionId);if(!i)throw new Se(Ue.InvalidParams,"Failed to retrieve task: Task not found");return{...i}}),this.setRequestHandler(Hd,async(r,l)=>{const i=async()=>{const o=r.params.taskId;if(this._taskMessageQueue){let m;for(;m=await this._taskMessageQueue.dequeue(o,l.sessionId);){if(m.type==="response"||m.type==="error"){const h=m.message,v=h.id,y=this._requestResolvers.get(v);if(y)if(this._requestResolvers.delete(v),m.type==="response")y(h);else{const b=h,z=new Se(b.error.code,b.error.message,b.error.data);y(z)}else{const b=m.type==="response"?"Response":"Error";this._onerror(new Error(\`${b} handler missing for request ${v}\`))}continue}await this._transport?.send(m.message,{relatedRequestId:l.requestId})}}const c=await this._taskStore.getTask(o,l.sessionId);if(!c)throw new Se(Ue.InvalidParams,\`Task not found: ${o}\");if(!aa(c.status))return await this._waitForTaskUpdate(o,l.signal),await i();if(aa(c.status)){const m=await this._taskStore.getTaskResult(o,l.sessionId);return this._clearTaskQueue(o),{...m,\_meta:{...m._meta,\[ra\]:{taskId:o}}}}return await i()};return await i()}),this.setRequestHandler(Jd,async(r,l)=>{try{const{tasks:i,nextCursor:o}=await this._taskStore.listTasks(r.params?.cursor,l.sessionId);return{tasks:i,nextCursor:o,\_meta:{}}}catch(i){throw new Se(Ue.InvalidParams,\`Failed to list tasks: ${i instanceof Error?i.message:String(i)}\`)}},this.setRequestHandler(Gd,async(r,l)=>{try{const i=await this._taskStore.getTask(r.params.taskId,l.sessionId);if(!i)throw new Se(Ue.InvalidParams,\`Task not found: ${r.params.taskId}\");if(aa(i.status))throw new Se(Ue.InvalidParams,\`Cannot cancel task in terminal status: ${i.status}\");await this._taskStore.updateTaskStatus(r.params.taskId,"cancelled","Client cancelled task execution.",l.sessionId),this._clearTaskQueue(r.params.taskId);const o=await this._taskStore.getTask(r.params.taskId,l.sessionId);if(!o)throw new Se(Ue.InvalidParams,\`Task not found after cancellation: ${r.params.taskId}\");return{\_meta:{},...o}}catch(i){throw i instanceof Se?i:new Se(Ue.InvalidRequest,\`Failed to cancel task: ${i instanceof Error?i.message:String(i)}\`))}})) ``` -------------------------------- ### Create Store with State Management Hooks Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-state-management/README.md Creates a store instance using the `Store.create` method. It takes a reducer, the initial state, and an `onStateChanged` callback to update the component's state. ```javascript const [state, setState] = Hook.useState(initialState); const store = Hook.useMemo(() => { return Store.create({ reducer, state, onStateChanged: ({currentState}) => setState(currentState), }); }); ``` -------------------------------- ### Accessing URL Information with Router Location Context Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Access the ROUTER_LOCATION context to get URL details like location, search, and hash. This context is available in children of Router.Hash and Router.Path wrappers. ```javascript const location = Hook.useContext(ContextType.ROUTER_LOCATION); ``` -------------------------------- ### Notification Handling Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html APIs for setting up handlers for different types of notifications. ```APIDOC ## setNotificationHandler(notificationType, handler) ### Description Registers a handler function for a specific type of notification. ### Parameters - **notificationType** (string) - Required - The type of notification to handle (e.g., 'cancel', 'progress'). - **handler** (function) - Required - The callback function to execute when a notification of the specified type is received. ### Example ```javascript protocol.setNotificationHandler('progress', (notification) => { console.log('Task progress:', notification.params); }); ``` ``` -------------------------------- ### Trigger Vendor Option Update on Item Change Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.dynamicOptions/README.md When the 'item' field in the item sublist changes, this code triggers an update to the available vendor options in the 'custpage_item_vendor' field. It uses a helper function 'getCurrentItem' to get the selected item. ```javascript if (scriptContext.fieldId === "item") { updateVendorOptions(scriptContext, getCurrentItem(scriptContext)); } ``` -------------------------------- ### Check for Wizard Creation Parameter Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/suiteworld-samples/suiteworld2024-code-samples/record-scripting/com.netsuite.defaulting/README.md Verifies if the record creation is initiated from a specific wizard by checking for the 'fromWizard' parameter in the request. ```javascript if (scriptContext.request && scriptContext.request.parameters.fromWizard == 'T') { ``` -------------------------------- ### Create Zod Instance Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Instantiates a Zod schema with provided data and optional parent context. Handles deferred initialization and parent linking. ```javascript function Ai(e,n,r){const l=new e._zod.constr(n??e._zod.def);return(!n||r?.parent)&&(l._zod.parent=e),l} ``` -------------------------------- ### Preconnect Link Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Adds a preconnect link to the document for resource hints. Use this to establish early connections to critical origins. ```javascript function C6(t,a){Wn.C(t,a),Uy("preconnect",t,a)} ``` -------------------------------- ### Define Root and Nested Routes Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Define route paths as enumerations for easy reference. Supports routes with parameters and a catch-all for 404 pages. ```javascript // Root Application routes const RootRoute = { DASHBOARD: '/', // default route COUNTRIES: '/countries', COUNTRY: '/countries/:countryCode', // route with 'countryCode' parameter - e.g. '/countries/usa' LISTS: '/lists', // index page '/lists' OTHERS: '*', // route that matches everything - used for 404 Page }; // Nested List route const ListRoute = { POPULATION: '/population', // nested route '/lists/population' AREA: '/area', // nested route '/lists/area' } export { RootRoute, ListRoute, } ``` -------------------------------- ### Catch-all 404 Route Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Implement a '404 Not Found' page by using a `Router.Route` with `path={'*'}`. Place it last in `Router.Routes` to capture undefined URLs. ```javascript //... //... //... ``` -------------------------------- ### Preload Link for Stylesheet Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Creates and appends a link element with `rel="preload"` and `as="style"` to the document's head. This is used to preload stylesheets. ```javascript function B6(t,a,u,s){t.querySelector('link[rel="preload"] [as="style"] ['+a+"]")?s.loading=1:(a=t.createElement("link"),s.preload=a,a.addEventListener("load",function(){return s.loading|=1}),a.addEventListener("error",function(){return s.loading|=2}),bt(a,"link",u),pt(a),t.head.appendChild(a))} ``` -------------------------------- ### NavigationDrawer with Context and Routing Logic Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/basics-routing/README.md Implement a NavigationDrawer that dynamically selects the active item based on the current router location. Requires ContextType.ROUTER_LOCATION and a mapping function. ```javascript export default function Navigation() { // Get the router information const location = Hook.useContext(ContextType.ROUTER_LOCATION); // Return NavigationDrawer whose items route to given routes return ( ); } // Function that maps current route to NavigationDrawer.Item const getCurrentNavigationItem = (location) => { for (const [route, navigationItem] of Object.entries(RouteToNavigationItem)) { if (location.matches(route, {exact: route !== RootRoute.OTHERS})) { return navigationItem; } } return null; }; // Mapping of routes to NavigationDrawer.Item values const RouteToNavigationItem = { [RootRoute.DASHBOARD]: NavigationItem.DASHBOARD, [RootRoute.COUNTRIES]: NavigationItem.COUNTRIES, [RootRoute.LISTS]: NavigationItem.LISTS, [`${RootRoute.LISTS}${ListRoute.AREA}`]: NavigationItem.LIST_AREA, [`${RootRoute.LISTS}${ListRoute.POPULATION}`]: NavigationItem.LIST_POPULATION, }; ``` -------------------------------- ### Zod StartsWith Validation Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Validates if a string begins with a specified prefix. Generates a regex pattern for the validation. ```javascript yw=D("$ZodCheckStartsWith",(e,n)=>{Bt.init(e,n);const r=new RegExp(`^${rr(n.prefix)}.*`);n.pattern??(n.pattern=r),e._zod.onattach.push(l=>{const i=l._zod.bag;i.patterns??(i.patterns=new Set),i.patterns.add(r)}),e._zod.check=l=>{l.value.startsWith(n.prefix)||l.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:n.prefix,input:l.value,inst:e,continue:!n.abort})}}) ``` -------------------------------- ### Run End-to-End Tests Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/spa-suiteapp-samples/airport360/README.md Executes end-to-end tests for the application. ```bash npm run test_e2e ``` -------------------------------- ### Pick Object Properties Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Creates a new schema by selecting specific properties from an existing object schema. Cannot be used on schemas with refinements. ```javascript function _x(e,n){const r=e._zod.def,l=r.checks;if(l&&l.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");const o=ji(e._zod.def,{get shape(){const c={};for(const m in n){if(!(m in r.shape))throw new Error(`Unrecognized key: "${m}"`);n[m]&&(c[m]=r.shape[m])}return fa(this,"shape",c),c},checks:[]});return Ai(e,o)} ``` -------------------------------- ### JSON Schema Conversion Configuration Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Initializes configuration for Zod's JSON Schema conversion process. Allows setting the JSON Schema draft target, custom processors, metadata, and options for handling cycles and schema reuse. ```javascript function cr(e){let n=e?.target?? ``` -------------------------------- ### Event Registration Utilities Source: https://github.com/oracle-samples/netsuite-suitecloud-samples/blob/main/MCP-Sample-Tools/Sample-App/src/FileCabinet/SuiteScripts/helloworld_app/mcp-app.html Functions for registering and managing event listeners in React. These utilities handle the complexities of event delegation and capture phases. ```javascript var lv=new Set,ov={};function Li(t,a){ba(t,a),ba(t+"Capture",a)}function ba(t,a){for(ov[t]=a,t=0;t=r.maxTotalTimeout)throw this._timeoutInfo.delete(n),Se.fromError(Ue.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:r.maxTotalTimeout,totalElapsed:l});return clearTimeout(r.timeoutId),r.timeoutId=setTimeout(r.onTimeout,r.timeout),!0} _cleanupTimeout(n){const r=this._timeoutInfo.get(n);r&&(clearTimeout(r.timeoutId),this._timeoutInfo.delete(n))} ```