{"_id":"@abapify/openai-codegen","_rev":"3-80802abef7019f9e80993ef47b40517a","name":"@abapify/openai-codegen","dist-tags":{"latest":"0.3.6"},"versions":{"0.0.0":{"name":"@abapify/openai-codegen","version":"0.0.0","_id":"@abapify/openai-codegen@0.0.0","maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"dist":{"shasum":"68f3a7614d05e0961921abb41e007ec3d86ea0a3","tarball":"https://registry.npmjs.org/@abapify/openai-codegen/-/openai-codegen-0.0.0.tgz","fileCount":2,"integrity":"sha512-GLCCJk48L9Y0TrZ6ljnAiSmHyIq+TrL2TuzdDLqW1GjtR3yuSyHUDUzgI97uYUu8VuMEKtEf29t6gsPWV/JcNw==","signatures":[{"sig":"MEQCIDeDmZndgvtOMDoTKQdoCldLFBfjeBf86JKbzyKImKhrAiAQvjmZ3a1SC8TOZ26HcEGF4/t5p54tZJaPpBfLNDsDHw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236},"_npmUser":{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"},"_npmVersion":"11.12.1","description":"Placeholder — real package is published via CI/CD (trusted publishing).","directories":{},"_nodeVersion":"24.10.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/openai-codegen_0.0.0_1776719580579_0.07275873277559497","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"@abapify/openai-codegen","version":"0.3.5","keywords":["openapi","swagger","abap","codegen","sap","steampunk"],"author":{"name":"abapify"},"license":"MIT","_id":"@abapify/openai-codegen@0.3.5","maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"homepage":"https://github.com/abapify/adt-cli/tree/main/packages/openai-codegen#readme","bugs":{"url":"https://github.com/abapify/adt-cli/issues"},"bin":{"openai-codegen":"dist/cli.mjs"},"dist":{"shasum":"2ea4507fcdf9b36191d93b01939e568f97f89fb5","tarball":"https://registry.npmjs.org/@abapify/openai-codegen/-/openai-codegen-0.3.5.tgz","fileCount":2,"integrity":"sha512-oq6aTL6qT2GQb/zqSSsVneNqW/ESiFQulpbpSNTAlM/teXeo86n5r9xGPHjbDV8ynytx85xgwDPMs0Tx50vEMw==","signatures":[{"sig":"MEYCIQDGNV6JIkshShNwhMS58FbHFuJgN8MxvWQTinzSDLwKrwIhAJso6QPPHNe+ZdBy9Gy/zbtXWIEGJ0RF8bZ0hlxv/SOo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abapify%2fopenai-codegen@0.3.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":16001},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs","./cli":"./dist/cli.mjs","./package.json":"./package.json"},"gitHead":"185666fe6ccb304e7b08529eb376ec2493131a7a","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a399f142-d1b1-466d-bc25-423dd4f73771"}},"repository":{"url":"git+https://github.com/abapify/adt-cli.git","type":"git","directory":"packages/openai-codegen"},"_npmVersion":"11.12.1","description":"Deterministic OpenAPI → ABAP client code generator. Emits a single zero-dependency ABAP class per OpenAPI spec, targeting SAP Cloud / on-prem profiles, packaged as abapGit or gCTS.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"yaml":"^2.5.0","commander":"^11.1.0","fast-xml-parser":"^5.5.0","@abapify/abap-ast":"0.3.5","@apidevtools/swagger-parser":"^10.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@abaplint/core":"^2.118.12"},"_npmOperationalInternal":{"tmp":"tmp/openai-codegen_0.3.5_1776723654415_0.4861749913729083","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"@abapify/openai-codegen","publishConfig":{"access":"public"},"version":"0.3.6","description":"Deterministic OpenAPI → ABAP client code generator. Emits a single zero-dependency ABAP class per OpenAPI spec, targeting SAP Cloud / on-prem profiles, packaged as abapGit or gCTS.","type":"module","types":"./dist/index.d.mts","bin":{"openai-codegen":"dist/cli.mjs"},"exports":{".":"./dist/index.mjs","./cli":"./dist/cli.mjs","./package.json":"./package.json"},"dependencies":{"@abapify/abap-ast":"0.3.6","@apidevtools/swagger-parser":"^10.1.0","commander":"^11.1.0","fast-xml-parser":"^5.5.0","yaml":"^2.5.0"},"keywords":["openapi","swagger","abap","codegen","sap","steampunk"],"author":{"name":"abapify"},"license":"MIT","devDependencies":{"@abaplint/core":"^2.118.12"},"repository":{"type":"git","url":"git+https://github.com/abapify/adt-cli.git","directory":"packages/openai-codegen"},"homepage":"https://github.com/abapify/adt-cli/tree/main/packages/openai-codegen#readme","bugs":{"url":"https://github.com/abapify/adt-cli/issues"},"gitHead":"489b2b4ad7c2ea972f323d4c356997ac5962ba9e","_id":"@abapify/openai-codegen@0.3.6","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-n6BWmuaNn1rJNcq1w3TD/Ks4LozpoVmEX/1Knb2ll8DkHQJL3BAXw6OLgzaenpmeTwD6nGpbQuQNCtZC9ZHxIA==","shasum":"dfe7dc0b23a6e3fe7bc6b5cd0115a21319e68e9b","tarball":"https://registry.npmjs.org/@abapify/openai-codegen/-/openai-codegen-0.3.6.tgz","fileCount":2,"unpackedSize":16001,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abapify%2fopenai-codegen@0.3.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDI7qBuRak0DdKt+2AxnNICLU3MYV4E3uOcMSrA1htrmAiEAhEu12KPxSQhEdTPucRvtOX4tl2BEEvLemT1aK+Yh9Ts="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a399f142-d1b1-466d-bc25-423dd4f73771"}},"directories":{},"maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openai-codegen_0.3.6_1776744802083_0.23183466515733508"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-20T21:13:00.484Z","modified":"2026-04-21T04:13:22.863Z","0.0.0":"2026-04-20T21:13:00.728Z","0.3.5":"2026-04-20T22:20:54.583Z","0.3.6":"2026-04-21T04:13:22.214Z"},"bugs":{"url":"https://github.com/abapify/adt-cli/issues"},"author":{"name":"abapify"},"license":"MIT","homepage":"https://github.com/abapify/adt-cli/tree/main/packages/openai-codegen#readme","keywords":["openapi","swagger","abap","codegen","sap","steampunk"],"repository":{"type":"git","url":"git+https://github.com/abapify/adt-cli.git","directory":"packages/openai-codegen"},"description":"Deterministic OpenAPI → ABAP client code generator. Emits a single zero-dependency ABAP class per OpenAPI spec, targeting SAP Cloud / on-prem profiles, packaged as abapGit or gCTS.","maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"readme":"# @abapify/openai-codegen\n\n**Deterministic OpenAPI → ABAP client code generator.** Reads an OpenAPI\n3.x spec and emits three global ABAP interfaces, one global exception\nclass, and one thin implementation class bundled with a small set of\nlocal helper classes. The result targets SAP BTP / Steampunk\n(`s4-cloud`) out of the box and has **zero Z-dependencies** — the\nbundled locals wrap kernel APIs (`cl_web_http_client_manager`,\n`cl_http_destination_provider`, `/ui2/cl_json`, `cl_abap_conv_codepage`,\n…) only.\n\nRe-running the generator with the same inputs produces byte-identical\noutput. Generated artifacts are safe to commit and diff.\n\n## Install\n\n```bash\nbun add -D @abapify/openai-codegen\nbunx openai-codegen --help\n```\n\n## Quick start\n\n```bash\nbunx openai-codegen \\\n  --input ./petstore3.json \\\n  --out ./out/abapgit \\\n  --base petstore3 \\\n  --format abapgit \\\n  --target s4-cloud \\\n  --description \"Petstore v3 client\"\n```\n\nWith the default `abapgit` layout this writes **11 files**:\n\n```text\nout/abapgit/\n├── package.devc.xml\n└── src/\n    ├── zif_petstore3_types.intf.abap         # Layer 1 — TYPES interface\n    ├── zif_petstore3_types.intf.xml\n    ├── zif_petstore3.intf.abap               # Layer 2 — operations interface\n    ├── zif_petstore3.intf.xml\n    ├── zcx_petstore3_error.clas.abap         # global exception class\n    ├── zcx_petstore3_error.clas.xml\n    ├── zcl_petstore3.clas.abap               # Layer 3 — thin implementation\n    ├── zcl_petstore3.clas.xml\n    ├── zcl_petstore3.clas.locals_def.abap    # bundled helper locals\n    └── zcl_petstore3.clas.locals_imp.abap\n```\n\n## Architecture\n\n```text\nZIF_<BASE>_TYPES   ── all schemas as ABAP TYPES (+ @openapi-schema markers)\n        ▲\n        │\nZIF_<BASE>         ── all operations as typed METHODS (+ @openapi-operation markers)\n        │                                             ── RAISING ZCX_<BASE>_ERROR\n        │\nZCL_<BASE>         ── implements ZIF_<BASE>\n                      one private attribute: client TYPE REF TO lcl_http\n                      each method body = fetch(...) + CASE response->status( )\n                      ─────────────────────────────────────────────\n                      local classes (same .clas file, locals_def/imp):\n                        lcl_http          (HTTP transport)\n                        lcl_response      (status / body / headers)\n                        json              (stringify / render / parse)\n                        lcl_json_parser   (internal JSON parser)\n\nZCX_<BASE>_ERROR   ── inherits cx_static_check\n                      carries status / description / body / headers\n```\n\nThe implementation class is deliberately minimal:\n\n- exactly one private attribute (`client`),\n- no private helper methods besides `constructor`,\n- each operation method is **one `fetch` call** followed by a `CASE`\n  block that decodes the success branch via `json=>parse( ... )->to( … )`\n  and raises `ZCX_<BASE>_ERROR` for every other status.\n\nSchema `TYPES` intentionally live on their own **interface** — not on\nthe class. ABAP's unified component namespace for types / attributes /\nmethods on a class would otherwise force awkward name mangling; putting\ntypes on `ZIF_<BASE>_TYPES` keeps the main class and the operations\ninterface collision-free.\n\n## Generated API surface\n\n### Layer 1 — types interface (`zif_petstore3_types.intf.abap`)\n\n```abap\n\"! Generated types for ZCL_PETSTORE3.\nINTERFACE ZIF_PETSTORE3_TYPES PUBLIC.\n  \"! @openapi-schema Category\n  TYPES: BEGIN OF category,\n    id   TYPE int8,\n    name TYPE string,\n  END OF category.\n  \"! @openapi-schema Pet\n  TYPES: BEGIN OF pet,\n    id         TYPE int8,\n    name       TYPE string,\n    category   TYPE category,\n    photo_urls TYPE STANDARD TABLE OF string WITH EMPTY KEY,\n    tags       TYPE STANDARD TABLE OF tag WITH EMPTY KEY,\n    status     TYPE string,\n  END OF pet.\nENDINTERFACE.\n```\n\n### Layer 2 — operations interface (`zif_petstore3.intf.abap`)\n\n```abap\nINTERFACE zif_petstore3 PUBLIC.\n  \"! @openapi-operation addPet\n  \"! @openapi-path POST /pet\n  \"! Add a new pet to the store.\n  METHODS add_pet\n    IMPORTING body TYPE zif_petstore3_types=>pet\n    RETURNING VALUE(pet) TYPE zif_petstore3_types=>pet\n    RAISING zcx_petstore3_error.\n  \"! @openapi-operation getPetById\n  \"! @openapi-path GET /pet/{petId}\n  \"! Find pet by ID.\n  METHODS get_pet_by_id\n    IMPORTING pet_id TYPE int8\n    RETURNING VALUE(pet) TYPE zif_petstore3_types=>pet\n    RAISING zcx_petstore3_error.\nENDINTERFACE.\n```\n\n### Layer 3 — implementation class (`zcl_petstore3.clas.abap`)\n\n```abap\nCLASS ZCL_PETSTORE3 DEFINITION PUBLIC CREATE PUBLIC.\n  INTERFACES zif_petstore3.\n  PUBLIC SECTION.\n    METHODS constructor\n      IMPORTING\n        destination TYPE string\n        server TYPE string DEFAULT '/api/v3'.\n  PRIVATE SECTION.\n    DATA client TYPE REF TO lcl_http.\nENDCLASS.\n\nCLASS ZCL_PETSTORE3 IMPLEMENTATION.\n  METHOD constructor.\n    client = NEW lcl_http( destination = destination server = server ).\n  ENDMETHOD.\n\n  METHOD zif_petstore3~add_pet.\n    DATA(response) = client->fetch(\n      method  = 'POST'\n      path    = '/pet'\n      body    = json=>stringify( body )\n      headers = VALUE #( ( name = 'Content-Type' value = 'application/json' ) ) ).\n    CASE response->status( ).\n      WHEN 200.\n        json=>parse( response->body( ) )->to( REF #( pet ) ).\n      WHEN 400.\n        RAISE EXCEPTION NEW zcx_petstore3_error(\n          status      = 400\n          description = 'Invalid input'\n          body        = response->body( ) ).\n      WHEN OTHERS.\n        RAISE EXCEPTION NEW zcx_petstore3_error(\n          status      = response->status( )\n          description = 'Unexpected error'\n          body        = response->body( ) ).\n    ENDCASE.\n  ENDMETHOD.\nENDCLASS.\n```\n\n### Bundled locals (`zcl_petstore3.clas.locals_def.abap` / `locals_imp.abap`)\n\nThe local classes expose a small, stable API that is **transport-only**\nfor HTTP and **typed-by-reference** for JSON:\n\n```abap\n\" Transport (HTTP): lcl_http / lcl_response\nDATA(response) = client->fetch(\n  method  = 'GET'\n  path    = '/pet/123'\n  query   = VALUE #( ( name = 'detail' value = 'full' ) )\n  headers = VALUE #( ( name = 'Accept' value = 'application/json' ) ) ).\nresponse->status( ).     \" -> i\nresponse->body( ).       \" -> xstring\nresponse->text( ).       \" -> string (decoded)\nresponse->header( 'etag' ).\nresponse->headers( ).\n\n\" JSON: json helper (mirrors abapify/json)\nDATA(payload) = json=>stringify( pet ).       \" string\nDATA(raw)     = json=>render( pet ).          \" xstring\njson=>parse( response->body( ) )->to( REF #( pet ) ).\n```\n\n`lcl_http->fetch` is deliberately ignorant of JSON, status codes, and\noperation identities. All policy lives in the per-operation method body\nin `ZCL_<BASE>`. The JSON API surface mirrors\n[`abapify/json`](https://github.com/abapify) and wraps `/ui2/cl_json` +\n`cl_abap_conv_codepage`.\n\n## Configuration\n\nAll four global names and all four local names are configurable. The\nsimplest path is to provide `--base`; every name then derives from it.\nAny individual override wins.\n\n| CLI flag                        | Library field (`NamesConfig`) | Default                                 |\n| ------------------------------- | ----------------------------- | --------------------------------------- |\n| `--base <name>`                 | `base`                        | _required unless all 4 overrides given_ |\n| `--types-interface <name>`      | `typesInterface`              | `ZIF_<BASE>_TYPES`                      |\n| `--operations-interface <name>` | `operationsInterface`         | `ZIF_<BASE>`                            |\n| `--class-name <name>`           | `implementationClass`         | `ZCL_<BASE>`                            |\n| `--exception-class <name>`      | `exceptionClass`              | `ZCX_<BASE>_ERROR`                      |\n| _(library only)_                | `localHttpClass`              | `lcl_http`                              |\n| _(library only)_                | `localResponseClass`          | `lcl_response`                          |\n| _(library only)_                | `localJsonClass`              | `json`                                  |\n| _(library only)_                | `localJsonParserClass`        | `lcl_json_parser`                       |\n\nOther flags:\n\n| Flag                      | Purpose                                                          |\n| ------------------------- | ---------------------------------------------------------------- |\n| `-i, --input <path>`      | Path / URL / file for the OpenAPI spec (JSON or YAML). Required. |\n| `-o, --out <dir>`         | Output directory. Required.                                      |\n| `-f, --format <list>`     | `abapgit` (default), `gcts`, or `abapgit,gcts`.                  |\n| `-t, --target <profile>`  | Target profile (`s4-cloud` only, default).                       |\n| `-d, --description <txt>` | Description stored in the generated `.clas.xml` / `.intf.xml`.   |\n\n## Library usage\n\n```ts\nimport { generate } from '@abapify/openai-codegen';\n\nconst result = await generate({\n  input: './petstore3.json',\n  outDir: './out/abapgit',\n  format: 'abapgit',\n  target: 's4-cloud',\n  names: { base: 'petstore3' },\n  description: 'Petstore v3 client',\n});\n\nconsole.log(result.files); // sorted, deduped relative paths\nconsole.log(result.typeCount, result.operationCount);\nconsole.log(result.resolvedNames);\n```\n\n## Pipeline\n\n```text\nOpenAPI spec\n  → loadSpec           ($ref-deref via @apidevtools/swagger-parser)\n  → planTypes          (topological sort of schemas + cycle detection)\n  → resolveNames       (NamesConfig → ResolvedNames; validates ABAP idents)\n  → emitTypesInterface      (Layer 1 — ZIF_<BASE>_TYPES AST)\n  → emitOperationsInterface (Layer 2 — ZIF_<BASE> AST)\n  → emitExceptionClass      (ZCX_<BASE>_ERROR AST)\n  → emitImplementationClass (Layer 3 — ZCL_<BASE> AST)\n  → emitLocalClasses        (locals_def + locals_imp templates)\n  → print               (four AST → ABAP source, via @abapify/abap-ast)\n  → writeClientBundle   (abapgit or gcts on-disk tree + envelopes)\n```\n\n## Type mapping\n\n| JSON Schema                               | ABAP                                                        |\n| ----------------------------------------- | ----------------------------------------------------------- |\n| `boolean`                                 | `abap_bool`                                                 |\n| `integer` / `integer, format: int64`      | `i` / `int8`                                                |\n| `number` (default / `float` / `double`)   | `decfloat34` / `f`                                          |\n| `string` (default)                        | `string`                                                    |\n| `string, format: date`                    | `d`                                                         |\n| `string, format: date-time`               | `timestampl`                                                |\n| `string, format: uuid`                    | `sysuuid_x16`                                               |\n| `string, format: byte` / `binary`         | `xstring`                                                   |\n| `array of X`                              | `STANDARD TABLE OF <X> WITH EMPTY KEY`                      |\n| `object` (properties)                     | `BEGIN OF <name> … END OF <name>.`                          |\n| `object` with `additionalProperties` only | `_map` table of `BEGIN OF entry, key, value, END OF entry`  |\n| `enum`                                    | Field typed as base scalar; values documented via ABAPDoc.  |\n| `allOf`                                   | Flattened into one structure.                               |\n| `oneOf` / `anyOf`                         | Union merge — fields from every branch, optional semantics. |\n| `$ref` (forward)                          | `NamedTypeRef` into the existing plan entry.                |\n| `$ref` (back-edge — cyclic)               | `REF TO data` with `\"! @openapi-ref <field>:<Target>`.      |\n| `nullable: true`                          | Same ABAP type (nullability preserved at (de)serialise).    |\n\nTypes are emitted in semantic topological order. Back-edges introduced\nby cyclic schemas are broken with a `REF TO data` plus a structured\n`@openapi-ref` marker, so a future reader can reconstruct the original\nreference target.\n\n## Round-trip markers\n\nEvery generated ABAP declaration carries an ABAPDoc block that a\ndownstream tool (for example a future `.aclass` parser) can use to\nrebuild the originating OpenAPI shape:\n\n| Marker                                | Attached to         | Meaning                                              |\n| ------------------------------------- | ------------------- | ---------------------------------------------------- |\n| `\"! @openapi-schema <Name>`           | `TYPES` declaration | Original JSON-Schema component name.                 |\n| `\"! @openapi-operation <operationId>` | `METHODS`           | Original OpenAPI `operationId`.                      |\n| `\"! @openapi-path <VERB> <path>`      | `METHODS`           | HTTP verb + templated path.                          |\n| `\"! @openapi-ref <field>:<Target>`    | `TYPES` field       | Field broken to `REF TO data` references `<Target>`. |\n\nMarkers are plain lines under the printer's ABAPDoc rules; they are\nnever rewritten or wrapped.\n\n## Deploying to BTP Steampunk\n\nShort recipe (see\n[`samples/petstore3-client/e2e/README.md`](../../samples/petstore3-client/e2e/README.md)\nfor the authoritative walk-through):\n\n```bash\nbunx adt auth login\nbunx openai-codegen \\\n  --input ./spec/openapi.json \\\n  --out ./generated/abapgit \\\n  --format abapgit \\\n  --base petstore3\nbunx adt deploy --source ./generated/abapgit --package ZMY_PACKAGE --activate --unlock\n```\n\n`S_ABPLNGVS` is granted per package on BTP. Deploy into a user-owned\n`Z*` package (for example `ZMY_PACKAGE` or `ZPEPL`); targeting `$TMP`\noften returns HTTP 403 on BTP.\n\n## Not yet supported\n\n- OpenAPI webhooks and callbacks.\n- Server-Sent Events / streaming responses.\n- Full OAuth2 `authorization_code` / `client_credentials` flows\n  (`apiKey`, `http bearer`, `http basic` are emitted; `oauth2` exposes\n  an overridable hook only).\n- `.aclass` DSL parser — tracked in `@abapify/abap-ast`.\n- Per-target runtime bundles beyond `s4-cloud` (profile slots exist for\n  `s4-onprem-modern` and `on-prem-classic`; only `s4-cloud` emits in v1).\n\n## License\n\nMIT\n","readmeFilename":"README.md"}