snow-flow-test 10.0.1-test.108 → 10.0.1-test.109

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "10.0.1-test.108",
3
+ "version": "10.0.1-test.109",
4
4
  "name": "snow-flow-test",
5
5
  "description": "Snow-Flow Test - ServiceNow Multi-Agent Development Framework",
6
6
  "license": "Elastic-2.0",
@@ -247,23 +247,23 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
247
247
 
248
248
  _bootstrapPromise = (async () => {
249
249
  try {
250
- // 3. Check if API already exists on instance
250
+ // 3. Check if API already exists on instance (query by api_id, more reliable than name)
251
251
  var checkResp = await client.get('/api/now/table/sys_ws_definition', {
252
252
  params: {
253
- sysparm_query: 'name=' + FLOW_FACTORY_API_NAME,
254
- sysparm_fields: 'sys_id,namespace.name',
253
+ sysparm_query: 'api_id=' + FLOW_FACTORY_API_ID,
254
+ sysparm_fields: 'sys_id,api_id,namespace',
255
255
  sysparm_limit: 1
256
256
  }
257
257
  });
258
258
 
259
259
  if (checkResp.data.result && checkResp.data.result.length > 0) {
260
260
  var existing = checkResp.data.result[0];
261
- var ns = (existing['namespace.name'] || existing.namespace?.display_value || FLOW_FACTORY_NAMESPACE);
261
+ var ns = resolveNamespaceFromRecord(existing);
262
262
  _flowFactoryCache = { apiSysId: existing.sys_id, namespace: ns, timestamp: Date.now() };
263
263
  return { namespace: ns, apiSysId: existing.sys_id };
264
264
  }
265
265
 
266
- // 4. Deploy the Scripted REST API
266
+ // 4. Deploy the Scripted REST API (do NOT set namespace — let ServiceNow assign it)
267
267
  var apiResp = await client.post('/api/now/table/sys_ws_definition', {
268
268
  name: FLOW_FACTORY_API_NAME,
269
269
  api_id: FLOW_FACTORY_API_ID,
@@ -271,8 +271,7 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
271
271
  short_description: 'Bootstrapped by Snow-Flow MCP for reliable Flow Designer creation via GlideRecord',
272
272
  is_versioned: false,
273
273
  enforce_acl: 'no',
274
- requires_authentication: true,
275
- namespace: FLOW_FACTORY_NAMESPACE
274
+ requires_authentication: true
276
275
  });
277
276
 
278
277
  var apiSysId = apiResp.data.result?.sys_id;
@@ -299,19 +298,11 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
299
298
  throw new Error('Failed to create Scripted REST operation: ' + (opError.message || opError));
300
299
  }
301
300
 
302
- // Resolve actual namespace may differ from requested
301
+ // 6. Read back the actual namespace ServiceNow assigned
303
302
  var nsResp = await client.get('/api/now/table/sys_ws_definition/' + apiSysId, {
304
- params: { sysparm_fields: 'sys_id,namespace' }
303
+ params: { sysparm_fields: 'sys_id,api_id,namespace', sysparm_display_value: 'all' }
305
304
  });
306
- var resolvedNs = FLOW_FACTORY_NAMESPACE;
307
- if (nsResp.data.result?.namespace) {
308
- var nsVal = nsResp.data.result.namespace;
309
- if (typeof nsVal === 'object' && nsVal.display_value) {
310
- resolvedNs = nsVal.display_value;
311
- } else if (typeof nsVal === 'string' && nsVal.length > 0) {
312
- resolvedNs = nsVal;
313
- }
314
- }
305
+ var resolvedNs = resolveNamespaceFromRecord(nsResp.data.result || {});
315
306
 
316
307
  _flowFactoryCache = { apiSysId: apiSysId, namespace: resolvedNs, timestamp: Date.now() };
317
308
  return { namespace: resolvedNs, apiSysId: apiSysId };
@@ -324,6 +315,29 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
324
315
  return _bootstrapPromise;
325
316
  }
326
317
 
318
+ /**
319
+ * Extract the URL namespace from a sys_ws_definition record.
320
+ * The namespace field can be a string, a reference object, or empty.
321
+ * For global scope APIs the namespace is typically the instance company prefix or 'now'.
322
+ */
323
+ function resolveNamespaceFromRecord(record: any): string {
324
+ var ns = record.namespace;
325
+ if (!ns) return FLOW_FACTORY_NAMESPACE;
326
+
327
+ // display_value / value pair (sysparm_display_value=all)
328
+ if (typeof ns === 'object') {
329
+ // display_value is the scope name like "Global" or "x_snflw" — use value for sys_id, display_value for name
330
+ var dv = ns.display_value || '';
331
+ // If display_value looks like a scope namespace (x_something, sn_something, now, global), use it
332
+ if (dv && dv !== 'Global' && dv !== 'global') return dv;
333
+ // For Global scope, fall through to default
334
+ }
335
+ if (typeof ns === 'string' && ns.length > 0 && ns.length < 100) {
336
+ return ns;
337
+ }
338
+ return FLOW_FACTORY_NAMESPACE;
339
+ }
340
+
327
341
  /**
328
342
  * Invalidate the Flow Factory cache (e.g. on 404 when API was deleted externally).
329
343
  */
@@ -669,6 +683,34 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
669
683
  var createdFlow = flowResponse.data.result;
670
684
  flowSysId = createdFlow.sys_id;
671
685
 
686
+ // Create sys_hub_flow_version via Table API (critical for Flow Designer UI)
687
+ try {
688
+ var versionData: any = {
689
+ flow: flowSysId,
690
+ name: '1.0',
691
+ version: '1.0',
692
+ state: shouldActivate ? 'published' : 'draft',
693
+ active: true,
694
+ flow_definition: JSON.stringify(flowDefinition)
695
+ };
696
+ var versionResp = await client.post('/api/now/table/sys_hub_flow_version', versionData);
697
+ var versionSysId = versionResp.data.result?.sys_id;
698
+ if (versionSysId) {
699
+ versionCreated = true;
700
+ // Link flow to its version
701
+ try {
702
+ await client.patch('/api/now/table/sys_hub_flow/' + flowSysId, {
703
+ latest_version: versionSysId
704
+ });
705
+ } catch (linkError) {
706
+ // Version exists but link failed — still better than no version
707
+ factoryWarnings.push('Version created but latest_version link failed');
708
+ }
709
+ }
710
+ } catch (verError: any) {
711
+ factoryWarnings.push('sys_hub_flow_version creation failed: ' + (verError.message || verError));
712
+ }
713
+
672
714
  // Create trigger instance (non-manual flows only)
673
715
  if (!isSubflow && triggerType !== 'manual') {
674
716
  try {