NetSuite Custom Module entry point error? - deployment

I have a simple custom module which posts messages to a server-side Suitelet.
/**
* test_app_client_module.js
* #NApiVersion 2.x
* #NScriptType ClientScript
* #NModuleScope SameAccount
*/
define(['N/ui/message'], function(message) {
var exports = {};
function showMessage(messageObject) {
message.create(messageObject).show();
};
exports.showMessage = showMessage;
return exports;
});
This module functions properly when used with form.ClientScriptModulePath and invoked from a file cabinet, excluding #NScriptType.
However, if I attempt to create a script record to define this module in a remote function, I get the following error.
SuiteScript 2.0 entry point scripts must implement one script type function.
Any suggestions?

As the error message states, you haven't implemented an entry point function. All Script modules need at least one entry point.
Add an empty pageInit function to your module.
exports.pageInit = function () {}

Related

NetSuite SuiteScript - Constants And Inclusion

I have a NetSuite SuiteScript file (2.0) in which I want to include a small library of utilities I've built. I can do that fine, and access the functions in the included library. But I can't access the constants I've defined in that library - I have to re-declare them in the main file.
Here's the main file:
define(['N/record', 'N/search', './utils.js'],
function (record, search, utils) {
function pageInit(scriptContext) {
isUserAdmin = isCurrentUserAdmin(contextRecord);
if (isUserAdmin) {
alert('Administrator Role ID is ' + ADMINISTRATOR_ROLE);
// Do something for Admin users
}
return;
}
return {
pageInit: pageInit
};
});
You can see I include the file ./utils.js in it. Here's utils.js:
const ADMINISTRATOR_ROLE = 11;
function isCurrentUserAdmin(currentRecord) {
return ADMINISTRATOR_ROLE == nlapiGetRole();
}
That's the entire file - nothing else.
In the main file, the call to the function isCurrentUserAdmin works fine. It correctly tells me whether the current user is an admin. Note that I don't have to preface the call to isCurrentUserAdmin with utils. (utils.isCurrentUserAdmin doesn't work - it gives me the error JS_EXCEPTION TypeError utils is undefined). But when the code gets to the line that uses ADMINSTRATOR_ROLE, I get the error JS_EXCEPTION ReferenceError ADMINISTRATOR_ROLE is not defined. BTW, if I put the constant definition of ADMINISTRATOR_ROLE in the main file instead of utils.js, I get the same error when utils.js tries to use it. The only way I can get it to work is if I have the line defining the constant in both files.
Why does the inclusion work for the function, but not the constant? Am I including the library wrongly? I thought I'd have to use it as utils.isCurrentUserAdmin rather than just isCurrentUserAdmin, but to my surprise that's not the case, as I say above.
If you have utils.js like below, you can use utils.ADMINISTRATOR_ROLE and utils.isCurrentUserAdmin() in your main file.
/**
*#NApiVersion 2.0
*/
define ([],
function() {
const ADMINISTRATOR_ROLE = 11;
function isCurrentUserAdmin() {
// check here
}
return {
ADMINISTRATOR_ROLE: ADMINISTRATOR_ROLE,
isCurrentUserAdmin: isCurrentUserAdmin
};
});
Try
define(['N/record', 'N/search', 'SuiteScripts/utils']
You need to make sure any member you need to access in another module needs to be exported in the source module using the return statement

How to get #borrows tag working in JSDoc

I have been having a hard time getting the #borrows tag working in JSDoc. I have been trying to get the documentation from one function and us it as documentation for a second function. But I don't seem to be able to even get a simple example working!
/**
* This is the description for funcA
*/
var funcA = function() {};
/**
* #borrows funcA as funcB
*/
var funcB = function() {};
I was expecting this to output documentation for both functions with both exactly the same. However only funcA is only has a description.
The #borrows tag doesn't seem to work directly on a symbol, but only indirectly. For example I had:
/** does amazing things */
function origFunc = function() {};
/**
* #borrows origFunc as exportedFunc
*/
exports.exportedFunc = origFunc;
but I, like you, got nothing useful in the generated doc.
That is because, it seems, that the #borrows tag operates on a container. (If you'll notice in the examples the #borrows tag is on the "util" module/namespace, not the renamed symbol.)
So this worked for me:
/** does amazing things */
function origFunc = function() {};
/**
* #borrows origFunc as exportedFunc
*/
exports = {
exportedFunc: origFunc,
}
Seems like a bug in #borrows though. (Or at least a bug in the documentation.)
I recently had a usage of it, what I was trying to do is to create a module and add some functions to it. The problem is that I don't have anything directly related to this module, since the export is just a line. Here's how I ended up with using #borrows.
/**
* A typehead with options filtered by user input.
*
* #module Typehead
* #borrows Typehead
* #borrows TypedOption
* #example
* <Typehead />
*/
export { default } from './Typehead'
In this case, Typehead will be borrowed in either Function or Classes section of module page depending on the kind of Typehead, and it will be displayed under #example render.
Note: However #borrows will add some extra entries to the system, after some experimentation, maybe #see is a better use.

Using Simulink Parameters in generated code

I use m file which initialize parameters in MATLAB workspace.
It is example of file:
Pconstant=Simulink.Parameter;
Pconstant.Value=3;
Pconstant.CoderInfo.StorageClass = 'exportedGlobal';
Pgain=Simulink.Parameter;
Pgain.Value=10;
Pgain.CoderInfo.StorageClass = 'exportedGlobal';
These parameters are used as value in 'Gain' and 'Constant' blocks. I generate c source code for this model and received following structure in model_data.c file:
/* Block parameters (auto storage) */
P_ParameterTest_T ParameterTest_P = {
10.0, /* Expression: Pgain
* Referenced by: '<Root>/Gain'
*/
3.0, /* Expression: Pconstant
* Referenced by: '<Root>/Constant'
*/
};
Model.h file contains following code:
/* Parameters (auto storage) */
struct P_ParameterTest_T_ {
real_T Gain_Gain; /* Expression: Pgain
* Referenced by: '<Root>/Gain'
*/
real_T Constant_Value; /* Expression: Pconstant
* Referenced by: '<Root>/Constant'
*/
};
Model source code compiling into model.a lib file which is used in other programs.
I can change value of constant in external c code:
parameters = (BLOCK_PARAMETERS*)rtmGetDefaultParam(model);
parameters->Constant_Value = 1;
But this solution is not good for me. Because I do not know where are used these parameters and I do not know fields names of structure.
Can I write code which will be set value in all fields of structure where are used Pconstant parameter? Something like this:
Pconstant = 1; //instead of parameters->Constant_Value = 1;
Thanks for help.
You say you have defined the storage class as ExportedGlobal but in the generated code, it appears as "auto storage", so something's not quite right there.
To achieve what you want, I think you need to turn "Inline parameters" on in the optimization pane (see documentation), and then click on the "Configure..." button to define which parameters you do not want inlined, i.e. Pconstant and Pgain (see the bit in the doc about inlining parameters). The structure construction you have in your code is normally used when "inline parameters" is turned off.
I'm guessing you have Simulink Coder, so you should also have a look in the Simulink Coder doc about how it generates code for parameters in different conditions. From memory, it's generally pretty thorough.

How to declare unlimited/variadic parameters in DocBlock?

Lets say I have a function (obviously a trivial example):
public function dot(){
return implode('.', func_get_args());
}
Now I know I could modify this to be
public function dot(array $items){
return implode('.', $array);
}
but with some functions that is not an option. So, how would you document the first version of the function with a docBlock so an IDE can interpret that it can receive unlimited parameters?
I have seen some methods that use:
/**
* Joins one or more strings together with a . (dot)
* #param string $string1
* #param string $string2
* #param string $_ [optional]
* #return string
*/
public function dot($string1, $string2, $_ = null) {
return implode('.', func_get_args());
}
Which in an IDE looks like
But that feels like a hack to me, is there no way to do it just with docBlock?
[UPDATED 2015-01-08]
Old way to do this in PHPDoc was:
http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.param.pkg.html
/**
* #param int $param,...
**/
However, this is no longer supported. As of PHP 5.6 Variadic Method Parameters are a part of the PHP language, and the PHPDoc's have been updated to reflect this as of PHPDoc 2.4 if I recall correctly. This is also in the PhpStorm IDE as of EAP 139.659 (should be in 8.0.2 and up). Not sure about implementation of other IDEs.
https://youtrack.jetbrains.com/issue/WI-20157
In any case, proper syntax for DocBlocks going forward for variadic parameters is:
/**
* #param int ...$param
**/
As Variadics are implemented in PHP 5.6 PHPDocumentor should support the following syntax as of version 2.4.
/**
* #param Type ...$value
* Note: PHP 5.6+ syntax equal to func_get_args()
*/
public function abc(Type ...$value) {}
This should be the correct way to describe such a signature. This will likely be included in PSR-5. Once that is accepted IDE's should follow to support this "official" recommendation.
However, in the mean time some IDE's have an improved understanding of what they consider correct. Hit hard on the IDE vendor to support the offical PHP syntax that is supported as of 5.6 or use whatever works in the meantime.
In php the concept of valist or list of "optional arguments" does not exist.
the $_ variable will just contain, here the third string you give.
The only way to allow an array OR a string is to test the first argument with is_array()
public function dot($arg1){
if(is_array($arg1)){
return implode('.',$arg1);
}
else if $arg1 instanceof \Traversable){
return implode('.',iterator_to_array($arg1));
}
else{
return implode('.',func_get_args());
}
}
Now that you handled the behaviour you want, you have to document it. In php, as overloading is not allowed, a convention is to use "mixed" as a type if you want to provide multiple types.
/**
*#param mixed $arg1 an array, iterator that will be joined OR first string of the list
*#return string a string with all strings of the list joined with a point
*#example dot("1","2","3"); returns 1.2.3 dot(array(1,2,3)); returns 1.2.3
*/
Moreover, according to phpdocumentor documentation you can declare sort of valist with
/**
*#param string ... list of strings
*/

Defining Window for Testing in Mocha

I'm trying to integrate some testing into my current Backbone/CoffeeScript application.
I have created a module for my application baked into the window object, but running any mocha tests fail because window is undefined.
module = (name) ->
window[name] = window[name] or {}
module 'Cart'
Any direction as to how I can define window for mocha?
I did try using jsdom and creating a window that way, but it still threw the same error. Thanks in advance.
EDIT:
Using zombie.js is getting me further then using jsdom.
zombie = require 'zombie'
browser = new zombie.Browser
browser.window.location = 'http://local.cart'
I'm trying to figure out a way to access the DOMWindow and set a variable to one of its values.
It would be ideal if browser.window was the same object as returned from accessing window in Chrome console, but it isn't.
I can access what I'm looking for with
zombie.visit 'http://local.cart', (err, browser) ->
throw err if err
browser.window.Cart
Is there a way for me to set what this returns to a global variable I can use throughout all of my specs?
Can't seem to get what I want trying a beforeEach or setting the previous block to a method and setting a variable to that method.
I think you'll definitely want to mock window, as opposed to trying to pass around a real DOM window object in the node side of your app (mocha).
Try this pattern I just whipped up (sort of conforms to mocha tutorials I have read and uses the this context which changes when in browser (window) vs. run on node (exports):
/**
* My namespace is 'AV'
*/
(function(root) {
/**
* #namespace root namespace object
*/
root['AV'] = root['AV'] || {};
var AV = root['AV'];
AV.CoolThing = {
//...
};
// this will give you
// your "window" object
// which is actually
// module.exports
return root;
})(this);
Then, the test might look something like this (mine are in coffeescript too):
chai = require 'chai'
chai.should()
# exports / "window"
{ AV } = require '../src/AV.js'
describe 'Sample test with namespace', ->
it 'should be an object', ->
AV.should.be.an 'object'