@jacebenson/jsn 4.3.0 → 4.3.1
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.
- package/package.json +1 -1
- package/src/sdk.js +55 -7
package/package.json
CHANGED
package/src/sdk.js
CHANGED
|
@@ -237,12 +237,30 @@ export class SDKClient {
|
|
|
237
237
|
* @returns {Promise<object>} created attachment row
|
|
238
238
|
*/
|
|
239
239
|
async addAttachment(table, sysID, content, fileName) {
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
240
|
+
const contentBuffer = Buffer.isBuffer(content) ? content : Buffer.from(String(content));
|
|
241
|
+
const script = [
|
|
242
|
+
'(function() {',
|
|
243
|
+
` var record = new GlideRecord(${scriptString(table)});`,
|
|
244
|
+
` if (!record.get(${scriptString(sysID)})) throw new Error('Record not found');`,
|
|
245
|
+
' var attachment = new GlideSysAttachment();',
|
|
246
|
+
` var fileName = ${scriptString(fileName)};`,
|
|
247
|
+
` var content = ${scriptString(contentBuffer.toString('base64'))};`,
|
|
248
|
+
' var sysId;',
|
|
249
|
+
" if (typeof attachment.writeBase64 === 'function') {",
|
|
250
|
+
" sysId = attachment.writeBase64(record, fileName, 'application/octet-stream', content);",
|
|
251
|
+
' } else {',
|
|
252
|
+
" sysId = new Attachment().write(record.getTableName(), record.getUniqueValue(), fileName, 'application/octet-stream', GlideStringUtil.base64DecodeAsBytes(content));",
|
|
253
|
+
' }',
|
|
254
|
+
" if (!sysId) throw new Error('Attachment was not created');",
|
|
255
|
+
" gs.print('JSN_ATTACHMENT_RESULT:' + JSON.stringify({ sys_id: sysId }));",
|
|
256
|
+
'}());',
|
|
257
|
+
].join('\n');
|
|
258
|
+
const output = await this.executeScript(script, '');
|
|
259
|
+
const result = parseAttachmentResult(output);
|
|
260
|
+
if (!result?.sys_id) {
|
|
261
|
+
throw new Error('Attachment upload returned no attachment sys_id');
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
246
264
|
}
|
|
247
265
|
|
|
248
266
|
async getCurrentUser({ touchLastSeen = true } = {}) {
|
|
@@ -676,7 +694,10 @@ export class SDKClient {
|
|
|
676
694
|
body: formBody.toString(),
|
|
677
695
|
});
|
|
678
696
|
|
|
679
|
-
|
|
697
|
+
const output = this._extractScriptOutput(html);
|
|
698
|
+
const scriptError = detectScriptError(output);
|
|
699
|
+
if (scriptError) throw new Error(`Background script failed: ${scriptError}`);
|
|
700
|
+
return output;
|
|
680
701
|
}
|
|
681
702
|
|
|
682
703
|
/**
|
|
@@ -829,6 +850,33 @@ export class SDKClient {
|
|
|
829
850
|
}
|
|
830
851
|
}
|
|
831
852
|
|
|
853
|
+
function scriptString(value) {
|
|
854
|
+
return JSON.stringify(String(value)).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function parseAttachmentResult(output) {
|
|
858
|
+
if (!output) return null;
|
|
859
|
+
const lines = String(output).split(/\r?\n/).reverse();
|
|
860
|
+
for (const line of lines) {
|
|
861
|
+
const candidate = line.replace(/^\*\*\* Script:\s*/, '').trim();
|
|
862
|
+
const markerCandidate = candidate.replace(/^JSN_ATTACHMENT_RESULT:\s*/, '');
|
|
863
|
+
if (!markerCandidate.startsWith('{')) continue;
|
|
864
|
+
try {
|
|
865
|
+
const result = JSON.parse(markerCandidate);
|
|
866
|
+
if (result && typeof result === 'object') return result;
|
|
867
|
+
} catch {
|
|
868
|
+
// Ignore unrelated script output and keep looking for the result marker.
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return null;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
function detectScriptError(output) {
|
|
875
|
+
const lines = String(output || '').split(/\r?\n/).map(line => line.trim()).filter(Boolean);
|
|
876
|
+
const errorLine = lines.find(line => /(?:ReferenceError|TypeError|RhinoEcmaError|Script execution error|undefined is not a function|is not defined)/i.test(line));
|
|
877
|
+
return errorLine || '';
|
|
878
|
+
}
|
|
879
|
+
|
|
832
880
|
function getBoolField(record, field) {
|
|
833
881
|
const val = record?.[field];
|
|
834
882
|
if (val == null) return false;
|