Repository navigation
Releases
Releases · Freight-Art/abapsmith
v0.6.42
Fixed
- Queued calls no longer time out behind a long
abap_uipress, and a remaining timeout is retryable (#242). The pool's wait budget was a fixedABAP_SESSION_WAIT_MS(10 s), so a call queued behind a ~60 s press failed withTimed out waiting for the ABAP session. It is nowABAP_SESSION_WAIT_MSplus the longest request timeout, as the connection-level lock already was. A refusal that still happens is classifiedSESSION_BUSYwithretryable: trueanddetailsholder,heldForMs,expectedRemainingMsandretryAfterMs, instead of a genericADT_ERROR. Press already runs on the write lane, so reads are not blocked behind it. README documents the variable. abap_ui mode=pressrunsCALL TRANSACTION ... OPTIONS FROM CTU_PARAMSwithDEFSIZE = 'X'by default (#240), so table controls expose their standard row count to batch input instead of only rows (01)/(02). New optional inputsdefsize(default true),racommit,nobinpt,nobiend(default false); DISMODE staysN, UPDMODES. The effective options are echoed in the response header asoptions.abap_ui mode=fcodeno longer claims a function code has no handler when it is just not a literalWHENin the screen's PAI (#239). The unresolved reason now reads "not found statically" and says the code may be handled via a variable/constant, table-driven sequence control or by the caller after the screen returns; a note suggests a shortpressprobe. The bridge also emitsmentionframes for every line in the program that holds the code as a quoted literal (capped at 40), and each row lists them as "OTHER MENTIONS" (constants, otherCASEblocks, caller includes). The bridge source changes, so the first call after upgrading rewrites its class once. Not verified live against A4H: the programSAPLV45Cis not present there and the installed MCP build predatesmode=fcode.core.call_fmfills structured IMPORTING/CHANGING parameters from a JSON object keyed by component name, andcore.describe_fmlists the components (#238). Previously the raw input string was assigned to the structure, so a JSON object landed as shifted garbage in the first fields and a structure with packed, integer or raw components could not be filled at all. A parameter value that is a JSON object (an object inparams, or a string holding one) is now parsed with the bridge's ownscan()and each component is converted by its RTTI type: char, numc, dats (YYYYMMDDorYYYY-MM-DD), tims (HHMMSSorHH:MM:SS), packed and decimal floats from a JSON number or numeric string, integers, and raw/xstring from hex. Unknown component names, values that would be truncated or rounded, tables, references and nesting deeper than one sub-structure are refused with the component named. A plain string for a flat character structure keeps working as before.params_schemanow carriescomponents(name,type,length,decimals) for each structured parameter; output is unchanged.TABLESrows are not covered:call_fmdoes not bind TABLES parameters from input yet.core.call_fmbindsTABLESparameters from a JSON array of row objects, andcore.describe_fmlists them inparams_schema(#237). Previouslydescribe_fmshowedTABLESparameters only underparametersandcall_fmrefused them (RFC_READ_TABLE has no input parameter OPTIONS), soRFC_READ_TABLEand every other TABLES-based function module could not be given input. ATABLESvalue that is an array (or a string holding one) is now split into rows and each row filled like a structure parameter (component names, RTTI conversion, errors prefixedrow N:);[]or an empty value passes an empty table. Tables with an elementary line type are refused with a message.params_schemacarriestype: [array, string]anditems.componentsfor eachTABLESparameter, mandatory ones inrequired.abap_ui mode=pressno longer refuses dialog transactions whoseTSTC-CINFOcarries the authorization flag (#236).XD01,MM01and similar (CINFO=04) were refused although the tool itself classified them as dialog transactions, because batch-input applicability was tested against the literal'00'. It is now derived from the decoded kind in one shared helper (describeTstc), used by both the press pre-check and the screen-mode transcript parser: dialog kinds with only non-type bits press; report (80,84,90), OO, parameter and area-menu transactions stay refused, andabap_runis suggested only for reports. A locked transaction (0x20) is refused with its own SM01 message, and an unrecognised CINFO is still refused conservatively, with text that no longer contradicts itself.abap_ui mode=pressno longer leaves enqueue locks held by the bridge session (#241). The driven transaction's enqueues lived on as long as the pooled ADT session did, which blocked the same user in SAP GUI. The generated bridge now ends withROLLBACK WORK.andCALL FUNCTION 'DEQUEUE_ALL'after every result line is written (the update is synchronous underUPDATE 'S', so the rollback only discards leftovers), and the press run drops its ADT session afterwards through the new opt-inRunClassOptions.dropSessionAfter, so a dump, timeout or stall cannot keep the locks alive either. The bridge source changes, so the first press after upgrading rewrites its bridge class once.
v0.6.41
Changed
- Internal refactor:
src/tools/write.ts(6,828 lines) is split into cohesivesrc/tools/write-*.tsmodules (schema, response notes, source resolution, classrun-bridge create/delete/update/index/search-help handlers, package create, batch delete). No behaviour change: theabap_writeschema, description and every response string are unchanged, andtools/listoutput is byte-identical.
v0.6.40
Fixed
abap_read view="footprint"now reports dynamicUPDATE (tab)andDELETE FROM (tab)writes (#232). Both patterns put a word boundary right after the closing)of the dynamic table token, so a statement such asUPDATE (gv_tab) SET ...orDELETE FROM (gv_tab) WHERE ...never matched and the write was silently dropped. They now match and are reported as unresolved writes, like dynamicINSERTandMODIFYalready were. The dynamic token also now accepts a structure component, field symbol or attribute ((ls_cfg-tabname),(<lv_tab>),(me->mv_tab)) in every Open SQL write form; static table names resolve as before.
v0.6.39
v0.6.38
Removed
- The dead
abap-contractCLI and the@abaplint/coredependency (#229).src/bin/contract.tswas the subprocess behindabap_read view:"contract", which #76 removed; nothing has spawned it since. It is deleted together with its test, the unregisteredbin/abap-contractshim and the second bundle outputbundle/bin/contract.js, sosrc/index.tsis now the only bundle entry point.@abaplint/corewas imported only by that file and is no longer a runtime dependency; THIRD-PARTY-NOTICES drops it and the two packages it alone pulled in (json5,vscode-languageserver-types). The server bundle and theabap-journal-reconcileCLI are unchanged.
v0.6.37
Added
- Journal entries carry
undoable(bool) andundoBlocker(reason) fields, computed at write time (#200). - Text pool writes (
abap_write text_pool) record a before-image, andabap_journal mode=undorestores the complete previous pool (#200). - BOPF
abap_bopf_editmodel updates record the previous model XML, andabap_journal mode=undoPUTs it back and re-activates, with node IDs mapped to the live model's first (BOPF re-mints them on every PUT) (#200). abap_enh create_spot/create_impl/create_hookentries are undoable (delete the object) when the before-state was confirmed-absent, guarded by a where-used check (#200).abap_enh set_impl_activeentries record the implementation's previous active state, andabap_journal mode=undosets it back (#200).abap_journal mode=undoon anactivateentry now undoes the latest earlier succeeded write entry for the same object instead of refusing outright (#200).
Changed
v0.6.36
Added
abap_bopf_edit/abap_bopf_deletework on transportable packages (#216).abap_bopf_edit operation=create_bono longer refusesUNSUPPORTED"package X is transportable", and every mutatingabap_bopf_editoperation plusabap_bopf_deleteno longer refuse "pinned to transport X" after already taking the lock. Both tools take a new optionalcorr_nrinput, resolved before the lock the same wayabap_writeresolves one: the caller'scorr_nrif given, otherwise underABAP_ALLOW_TRANSPORTS—autoreuses or creates a session request, a pinned allowlist must already contain the request, and deny-all refusesSAFETY_DENIEDbefore any wire request is made. The resolved request is judged by the safety gate, sent ascorrNron the create POST / model PUT / DELETE, and cross-checked against the lock'sCORRNR: a lock naming a different request refusesTRANSPORT_ERRORwith nothing written. When a request was used, the response header carries atransport: <request>line.create_bo's POST into a transportable package is not atomic — a failed POST can still create the object — so on failure abapsmith now re-reads: object present and complete → success, with awarnings:header line saying the POST failed but the object was found complete and kept (naming the transport request); object present but unusable (root node unnamed or absent) → the partial object and the constants interface BOPF generated with it are deleted again under the same request (one stateful session, like the delete cascade), andBOPF_CREATE_UNUSABLEstates whether that delete worked or what is left; object absent → the original error, unchanged. The same cleanup runs when the POST succeeds but the root node comes back unusable on a transportable package (live-observed on A4H:rootNodeNamewith a space). The journal entry of a BOPF create, edit or delete on a transportable package now records the request ascorrNr, asabap_write's entries do.$TMP/local packages behave exactly as before — no cleanup, notransport:line.abap_bopf_delete'scascade_ddicsends the same request for any DDIC candidate whose lock reports a transport; a candidate pinned to a different transport while the BO delete itself was local is reported as not deleted, with the reason.
Fixed
abap_bopf_testno longer generates bridge source lines over 255 characters (#207). A scenario with many fields or a long string value could produce aDATAline, a transcript line, or a cleanupAPPEND VALUE #( ... )past ABAP's 255-character line limit, and the generated bridge class failed to compile. The generator now wraps at 120 columns: a long string literal is split into pieces of at most 100 chars and rejoined with&&, each node's transcriptDATAline is assembled from several template pieces, and the cleanupAPPEND VALUE #( ... )is written one component per line. Before any wire request, abapsmith asserts that no emitted line exceeds 255 chars; if one still would, the call is refusedBAD_INPUTnaming the scenario node and field instead of shipping source that won't compile. The runtime transcript itself is unchanged.
v0.6.35
Added
- abap_debug
set_valuechanges a simple variable, structure component or table cell at a stop in edit/admin mode, validates the value against the type first, refuses constants and references, and lists every change in the session's final output (#198).
v0.6.34
Added
abap_enhcreate-family operations takepackage,corr_nrandactivate(#215).create_spot,add_badi_def,add_filter_def,create_implandset_filter_valuesnow take an optionalpackage(default$TMP) and, against a transportable package,corr_nr, following the same transport rules asabap_write— the safety gate's verdict is taken before the session resolver gets a chance to create a request.activate(defaulttrue) set tofalseleaves the object saved but inactive, ready forabap_read enhancements:trueand a laterabap_activate(withaffects, as the response's NOTE spells out);add_badi_def's marker interface is still always activated, since the BAdI definition needs it active.exerciseandcreate_hookare unchanged.
Changed
abap_enh affectsis optional where the journal needs no foreign object (#212).create_spot,add_badi_defandadd_filter_defnow defaultaffectsto the spot being created or extended, andcreate_hookderives it from the host named inspecwith one read of the host object, instead of requiring the caller to repeat what the call already states.create_impl,set_filter_values,exercise,write_description,deleteandset_impl_activestill require it, andBAD_INPUTnames all six when it's missing. Every one of these checks runs before any network request.
v0.6.33
Added
abap_write'stext_poolnow applies toCLAS/OCandFUGR/F, not justPROG/P, and gains aheadingsgroup (#199). Each type writes its own textelements resource (PROG/PX/CLAS/OCX/FUGR/PX); aCLAS/OCtext pool has text symbols only — namingselection_textsorheadingsfor a class is refusedBAD_INPUTbefore any request ("applies to PROG/P and FUGR/F only").headings(PROG/PandFUGR/Fonly) is{list_header?, column_headers?}— the report's list header (max 70 chars) and up to four column heading lines (max 132 chars each, SE38 "List Headings"); each group given still replaces that whole group, as before. Namingtext_poolagainst any other type is refusedBAD_INPUTbefore any request, now naming the supported types ("text_poolapplies to PROG/P, CLAS/OC and FUGR/F only, not INTF/OI."). A whole-object source read of aCLAS/OCorFUGR/Fnow appends the sameTEXT POOLsection aPROG/Pread has, including the newheadings:group, when the object has any text symbols, selection texts or headings; that read costs one extra request for a class (three for a function group), as it already did for a program. The textelements resource has no per-call language selector — probed on A4H, asap-language/languagequery parameter, anAccept-Language/sap-languageheader, andABAP_LANGUAGE=ENvsDEat logon all returned the same master-language texts — sotext_poolreads and writes the object's own master language and takes nolanguageparameter. Verified on A4H:$TMPclassZCL_AS_TEXT199(static method returningtext-001), function groupZAS_FG199with a module returningtext-002, and reportZAS_R199calling both — aftertext_poolwrites,abap_readshowed theTEXT POOLsection for all three andabap_runof the report printedclass: Hello,fm: Hello from FM, the list headerIssue 199 headingsand both column heading lines;text_poolonINTF/OIandselection_textson the class were refused as described.
Changed
- The
text_poolresponse's<language>is now the object's master language, not the configured logon language (#199). The textelements resource has no per-call language selector and always writes the master language, so the response header now reads<language>off the textelements descriptor instead of reporting the configured logon language.