diff --git a/git_modules/abapgit-examples b/git_modules/abapgit-examples index d6cee132..74cd5bc8 160000 --- a/git_modules/abapgit-examples +++ b/git_modules/abapgit-examples @@ -1 +1 @@ -Subproject commit d6cee1321197ce77e195c5d047b9bb391adef4c7 +Subproject commit 74cd5bc854a8b4c83397881fd0ae66813b099b56 diff --git a/packages/adk/src/base/adt.ts b/packages/adk/src/base/adt.ts index c65e618d..3b572f47 100644 --- a/packages/adk/src/base/adt.ts +++ b/packages/adk/src/base/adt.ts @@ -37,6 +37,11 @@ export type { TransportGetResponse, ProgramResponse as ProgramResponseUnion, FunctionGroupResponse as FunctionGroupResponseUnion, + DomainResponse, + DataElementResponse, + TableResponse, + StructureResponse, + TableTypeResponse, } from '@abapify/adt-client'; // CRUD contract types for typed ADK base model @@ -128,6 +133,8 @@ export interface AdkContract { readonly programs: AdtContracts['programs']; /** Functions contracts (function groups) */ readonly functions: AdtContracts['functions']; + /** DDIC contracts (domains, data elements, structures, tables, table types) */ + readonly ddic: AdtContracts['ddic']; } /** @@ -145,5 +152,6 @@ export function createAdkContract(client: AdtClient): AdkContract { repository: client.adt.repository, programs: client.adt.programs, functions: client.adt.functions, + ddic: client.adt.ddic, }; } diff --git a/packages/adk/src/base/kinds.ts b/packages/adk/src/base/kinds.ts index fe5e54d5..b54761d2 100644 --- a/packages/adk/src/base/kinds.ts +++ b/packages/adk/src/base/kinds.ts @@ -67,6 +67,10 @@ import type { AdkTransportTask, } from '../objects/cts/transport/transport'; import type { AdkObject } from './model'; +import type { AdkDomain } from '../objects/ddic/doma/doma.model'; +import type { AdkDataElement } from '../objects/ddic/dtel/dtel.model'; +import type { AdkTable, AdkStructure } from '../objects/ddic/tabl/tabl.model'; +import type { AdkTableType } from '../objects/ddic/ttyp/ttyp.model'; /** * Maps ADK kind to concrete object type @@ -91,5 +95,14 @@ export type AdkObjectForKind = K extends typeof Class ? AdkTransportRequest : K extends typeof TransportTask ? AdkTransportTask - : // Add more mappings as types are implemented - AdkObject; // fallback + : K extends typeof Domain + ? AdkDomain + : K extends typeof DataElement + ? AdkDataElement + : K extends typeof Table + ? AdkTable + : K extends typeof Structure + ? AdkStructure + : K extends typeof TableType + ? AdkTableType + : AdkObject; // fallback diff --git a/packages/adk/src/base/model.ts b/packages/adk/src/base/model.ts index 45fedb1f..18fcf40c 100644 --- a/packages/adk/src/base/model.ts +++ b/packages/adk/src/base/model.ts @@ -456,6 +456,9 @@ export abstract class AdkObject { async save(options: SaveOptions = {}): Promise { const { transport, mode = 'update' } = options; + // Reset per-save-attempt state + this._unchanged = false; + // Check if object has pending sources (from abapGit deserialization) const hasPendingSources = this.hasPendingSources(); @@ -475,9 +478,10 @@ export abstract class AdkObject { try { await this.lock(transport); } catch (e) { - // For upsert, only fallback to create if it's a 404 Not Found error - if (mode === 'upsert' && this.isNotFoundError(e)) { - return this.save({ ...options, mode: 'create' }); + // For upsert, fallback to create if object doesn't exist (404) + // or endpoint doesn't support the operation (405 - common for DDIC types) + if (mode === 'upsert' && this.shouldFallbackToCreate(e)) { + return this.fallbackToCreate(options); } throw e; } @@ -510,9 +514,14 @@ export abstract class AdkObject { return this; } catch (e: unknown) { - // For upsert with PUT failure (404), try POST - if (mode === 'upsert' && this.isNotFoundError(e)) { - return this.save({ ...options, mode: 'create' }); + // For upsert with PUT failure (404/405), try POST (create) + if (mode === 'upsert' && this.shouldFallbackToCreate(e)) { + return this.fallbackToCreate(options); + } + // If PUT returns 422 "already exists" directly in upsert mode + if (mode === 'upsert' && this.isAlreadyExistsError(e)) { + this._unchanged = true; + return this; } throw e; } finally { @@ -586,6 +595,49 @@ export abstract class AdkObject { return false; } + /** + * Upsert fallback: try POST (create), treat 422 "already exists" as unchanged. + * Extracted to avoid duplication in lock-catch and saveViaContract-catch paths. + */ + private async fallbackToCreate(options: SaveOptions): Promise { + try { + return await this.save({ ...options, mode: 'create' }); + } catch (createErr) { + if (this.isAlreadyExistsError(createErr)) { + this._unchanged = true; + return this; + } + throw createErr; + } + } + + /** + * Check if error suggests the object doesn't exist or the operation + * is not supported for the current state. + * + * Some SAP DDIC endpoints (TABL, TTYP) return 405 Method Not Allowed + * instead of 404 when attempting to lock or PUT a non-existent object. + * In upsert mode, both should trigger a fallback to POST (create). + */ + protected shouldFallbackToCreate(e: unknown): boolean { + return ( + this.isNotFoundError(e) || + (e instanceof Error && + (e.message.includes('405') || e.message.includes('Method Not Allowed'))) + ); + } + + /** + * Check if error is a 422 "already exists" from a POST create attempt + */ + protected isAlreadyExistsError(e: unknown): boolean { + const msg = e instanceof Error ? e.message.toLowerCase() : ''; + return ( + (msg.includes('422') || msg.includes('unprocessable')) && + msg.includes('already exists') + ); + } + /** * Check if object has pending sources to save * Subclasses with source code (classes, interfaces) override this diff --git a/packages/adk/src/base/object-set.ts b/packages/adk/src/base/object-set.ts index 8acf7373..4d8ad8bc 100644 --- a/packages/adk/src/base/object-set.ts +++ b/packages/adk/src/base/object-set.ts @@ -345,7 +345,11 @@ export class AdkObjectSet { */ async unlockAll(): Promise { for (const obj of this.objects) { - await obj.unlock(); + try { + await obj.unlock(); + } catch { + // Ignore unlock failures - object may not have been locked + } } } diff --git a/packages/adk/src/index.ts b/packages/adk/src/index.ts index a93f8236..5d63927c 100644 --- a/packages/adk/src/index.ts +++ b/packages/adk/src/index.ts @@ -45,6 +45,9 @@ export type { ProgramResponse, FunctionGroupResponse, TransportGetResponse, + DomainResponse, + DataElementResponse, + TableTypeResponse, } from './base/adt'; export { createAdkContract } from './base/adt'; @@ -103,6 +106,19 @@ export type { } from './objects/repository/fugr'; export { AdkFunctionGroup } from './objects/repository/fugr'; +// DDIC types and classes +export { + AdkDomain, + AdkDataElement, + AdkTable, + AdkStructure, + AdkTableType, + type DomainXml, + type DataElementXml, + type TableXml, + type TableTypeXml, +} from './objects/ddic'; + // CTS types (legacy complex transport) export type { TransportData, diff --git a/packages/adk/src/objects/ddic/doma/doma.model.ts b/packages/adk/src/objects/ddic/doma/doma.model.ts new file mode 100644 index 00000000..c9d1507e --- /dev/null +++ b/packages/adk/src/objects/ddic/doma/doma.model.ts @@ -0,0 +1,55 @@ +/** + * DOMA - Domain + * + * ADK object for ABAP Domains (DOMA). + * DDIC objects are metadata-only (no source code). + */ + +import { AdkMainObject } from '../../../base/model'; +import { Domain as DomainKind } from '../../../base/kinds'; +import { getGlobalContext } from '../../../base/global-context'; +import type { AdkContext } from '../../../base/context'; + +import type { DomainResponse } from '../../../base/adt'; + +/** + * Domain data type - unwrap from schema root element + */ +export type DomainXml = DomainResponse['domain']; + +/** + * ADK Domain object + * + * Inherits from AdkMainObject which provides: + * - name, type, description, version, language, changedBy/At, createdBy/At, links + * - package, packageRef, responsible, masterLanguage, masterSystem, abapLanguageVersion + * + * Domain-specific properties via `data`: + * - data.typeInformation (dataType, length, decimals, outputLength) + * - data.outputInformation (conversionExit, signPresentation, lowerCase) + * - data.fixedValues + */ +export class AdkDomain extends AdkMainObject { + static readonly kind = DomainKind; + readonly kind = AdkDomain.kind; + + get objectUri(): string { + return `/sap/bc/adt/ddic/domains/${encodeURIComponent(this.name.toLowerCase())}`; + } + + protected override get wrapperKey() { + return 'domain'; + } + protected override get crudContract(): any { + return this.ctx.client.adt.ddic.domains; + } + + static async get(name: string, ctx?: AdkContext): Promise { + const context = ctx ?? getGlobalContext(); + return new AdkDomain(context, name).load(); + } +} + +// Self-register with ADK registry +import { registerObjectType } from '../../../base/registry'; +registerObjectType('DOMA', DomainKind, AdkDomain); diff --git a/packages/adk/src/objects/ddic/doma/index.ts b/packages/adk/src/objects/ddic/doma/index.ts new file mode 100644 index 00000000..3b7a8702 --- /dev/null +++ b/packages/adk/src/objects/ddic/doma/index.ts @@ -0,0 +1,6 @@ +/** + * DOMA - Domain + */ + +export { AdkDomain } from './doma.model'; +export type { DomainXml } from './doma.model'; diff --git a/packages/adk/src/objects/ddic/dtel/dtel.model.ts b/packages/adk/src/objects/ddic/dtel/dtel.model.ts new file mode 100644 index 00000000..b108d756 --- /dev/null +++ b/packages/adk/src/objects/ddic/dtel/dtel.model.ts @@ -0,0 +1,59 @@ +/** + * DTEL - Data Element + * + * ADK object for ABAP Data Elements (DTEL). + * DDIC objects are metadata-only (no source code). + */ + +import { AdkMainObject } from '../../../base/model'; +import { DataElement as DataElementKind } from '../../../base/kinds'; +import { getGlobalContext } from '../../../base/global-context'; +import type { AdkContext } from '../../../base/context'; + +import type { DataElementResponse } from '../../../base/adt'; + +/** + * Data Element data type - unwrap from wrapper root element + * SAP wraps DTEL content in a blue:wbobj element extending AdtMainObject + */ +export type DataElementXml = DataElementResponse['wbobj']; + +/** + * ADK Data Element object + * + * Inherits from AdkMainObject which provides: + * - name, type, description, version, language, changedBy/At, createdBy/At, links + * - package, packageRef, responsible, masterLanguage, masterSystem, abapLanguageVersion + * + * Data element-specific properties via `data`: + * - data.typeKind, data.typeName, data.dataType + * - data.shortDescription, data.mediumDescription, data.longDescription, data.headingDescription + * - data.searchHelp + */ +export class AdkDataElement extends AdkMainObject< + typeof DataElementKind, + DataElementXml +> { + static readonly kind = DataElementKind; + readonly kind = AdkDataElement.kind; + + get objectUri(): string { + return `/sap/bc/adt/ddic/dataelements/${encodeURIComponent(this.name.toLowerCase())}`; + } + + protected override get wrapperKey() { + return 'wbobj'; + } + protected override get crudContract(): any { + return this.ctx.client.adt.ddic.dataelements; + } + + static async get(name: string, ctx?: AdkContext): Promise { + const context = ctx ?? getGlobalContext(); + return new AdkDataElement(context, name).load(); + } +} + +// Self-register with ADK registry +import { registerObjectType } from '../../../base/registry'; +registerObjectType('DTEL', DataElementKind, AdkDataElement); diff --git a/packages/adk/src/objects/ddic/dtel/index.ts b/packages/adk/src/objects/ddic/dtel/index.ts new file mode 100644 index 00000000..c6ea337d --- /dev/null +++ b/packages/adk/src/objects/ddic/dtel/index.ts @@ -0,0 +1,6 @@ +/** + * DTEL - Data Element + */ + +export { AdkDataElement } from './dtel.model'; +export type { DataElementXml } from './dtel.model'; diff --git a/packages/adk/src/objects/ddic/index.ts b/packages/adk/src/objects/ddic/index.ts new file mode 100644 index 00000000..06446f06 --- /dev/null +++ b/packages/adk/src/objects/ddic/index.ts @@ -0,0 +1,8 @@ +/** + * DDIC - Data Dictionary Objects + */ + +export { AdkDomain, type DomainXml } from './doma'; +export { AdkDataElement, type DataElementXml } from './dtel'; +export { AdkTable, AdkStructure, type TableXml } from './tabl'; +export { AdkTableType, type TableTypeXml } from './ttyp'; diff --git a/packages/adk/src/objects/ddic/tabl/index.ts b/packages/adk/src/objects/ddic/tabl/index.ts new file mode 100644 index 00000000..a216af00 --- /dev/null +++ b/packages/adk/src/objects/ddic/tabl/index.ts @@ -0,0 +1,6 @@ +/** + * TABL - Database Table / Structure + */ + +export { AdkTable, AdkStructure } from './tabl.model'; +export type { TableXml } from './tabl.model'; diff --git a/packages/adk/src/objects/ddic/tabl/tabl.model.ts b/packages/adk/src/objects/ddic/tabl/tabl.model.ts new file mode 100644 index 00000000..b9599fbd --- /dev/null +++ b/packages/adk/src/objects/ddic/tabl/tabl.model.ts @@ -0,0 +1,87 @@ +/** + * TABL - Database Table / Structure + * + * ADK object for ABAP Database Tables (TABL/DT) and Structures (TABL/DS). + * Tables and structures are source-based DDIC objects whose definition + * lives in ABAP source code (retrieved via sourceUri). + * + * Note: Tables and structures share the same ADT main type (TABL) + * but use different endpoints and subtypes. + * - Tables: /sap/bc/adt/ddic/tables (TABL/DT) + * - Structures: /sap/bc/adt/ddic/structures (TABL/DS) + * + * SAP wraps both in a blue:blueSource root element + * (namespace http://www.sap.com/wbobj/blue) extending AbapSourceMainObject. + */ + +import { AdkMainObject } from '../../../base/model'; +import { + Table as TableKind, + Structure as StructureKind, +} from '../../../base/kinds'; +import { getGlobalContext } from '../../../base/global-context'; +import type { AdkContext } from '../../../base/context'; + +import type { TableResponse } from '../../../base/adt'; + +/** + * Table/Structure data type - unwrap from blueSource wrapper root element + */ +export type TableXml = TableResponse['blueSource']; + +/** + * ADK Table object (database table - TABL/DT) + */ +export class AdkTable extends AdkMainObject { + static readonly kind = TableKind; + readonly kind = AdkTable.kind; + + get objectUri(): string { + return `/sap/bc/adt/ddic/tables/${encodeURIComponent(this.name.toLowerCase())}`; + } + + protected override get wrapperKey() { + return 'blueSource'; + } + protected override get crudContract(): any { + return this.ctx.client.adt.ddic.tables; + } + + static async get(name: string, ctx?: AdkContext): Promise { + const context = ctx ?? getGlobalContext(); + return new AdkTable(context, name).load(); + } +} + +/** + * ADK Structure object (TABL/DS) + */ +export class AdkStructure extends AdkMainObject< + typeof StructureKind, + TableXml +> { + static readonly kind = StructureKind; + readonly kind = AdkStructure.kind; + + get objectUri(): string { + return `/sap/bc/adt/ddic/structures/${encodeURIComponent(this.name.toLowerCase())}`; + } + + protected override get wrapperKey() { + return 'blueSource'; + } + protected override get crudContract(): any { + return this.ctx.client.adt.ddic.structures; + } + + static async get(name: string, ctx?: AdkContext): Promise { + const context = ctx ?? getGlobalContext(); + return new AdkStructure(context, name).load(); + } +} + +// Self-register with ADK registry +import { registerObjectType } from '../../../base/registry'; +registerObjectType('TABL', TableKind, AdkTable); +// Note: Structure uses same main type TABL but different ADK kind +// Registration uses TABL main type - structures will be resolved via subtype logic diff --git a/packages/adk/src/objects/ddic/ttyp/index.ts b/packages/adk/src/objects/ddic/ttyp/index.ts new file mode 100644 index 00000000..65acd0c5 --- /dev/null +++ b/packages/adk/src/objects/ddic/ttyp/index.ts @@ -0,0 +1,6 @@ +/** + * TTYP - Table Type + */ + +export { AdkTableType } from './ttyp.model'; +export type { TableTypeXml } from './ttyp.model'; diff --git a/packages/adk/src/objects/ddic/ttyp/ttyp.model.ts b/packages/adk/src/objects/ddic/ttyp/ttyp.model.ts new file mode 100644 index 00000000..d94ba1f8 --- /dev/null +++ b/packages/adk/src/objects/ddic/ttyp/ttyp.model.ts @@ -0,0 +1,58 @@ +/** + * TTYP - Table Type + * + * ADK object for ABAP Table Types (TTYP). + * DDIC objects are metadata-only (no source code). + */ + +import { AdkMainObject } from '../../../base/model'; +import { TableType as TableTypeKind } from '../../../base/kinds'; +import { getGlobalContext } from '../../../base/global-context'; +import type { AdkContext } from '../../../base/context'; + +import type { TableTypeResponse } from '../../../base/adt'; + +/** + * Table Type data type - unwrap from schema root element + */ +export type TableTypeXml = TableTypeResponse['tableType']; + +/** + * ADK Table Type object + * + * Inherits from AdkMainObject which provides: + * - name, type, description, version, language, changedBy/At, createdBy/At, links + * - package, packageRef, responsible, masterLanguage, masterSystem, abapLanguageVersion + * + * Table type-specific properties via `data`: + * - data.rowType (typeName, typeCategory, tableTypeSchemaReference) + * - data.primaryKey + * - data.secondaryKeys + */ +export class AdkTableType extends AdkMainObject< + typeof TableTypeKind, + TableTypeXml +> { + static readonly kind = TableTypeKind; + readonly kind = AdkTableType.kind; + + get objectUri(): string { + return `/sap/bc/adt/ddic/tabletypes/${encodeURIComponent(this.name.toLowerCase())}`; + } + + protected override get wrapperKey() { + return 'tableType'; + } + protected override get crudContract(): any { + return this.ctx.client.adt.ddic.tabletypes; + } + + static async get(name: string, ctx?: AdkContext): Promise { + const context = ctx ?? getGlobalContext(); + return new AdkTableType(context, name).load(); + } +} + +// Self-register with ADK registry +import { registerObjectType } from '../../../base/registry'; +registerObjectType('TTYP', TableTypeKind, AdkTableType); diff --git a/packages/adt-client/src/index.ts b/packages/adt-client/src/index.ts index 9bb17fd3..863a438a 100644 --- a/packages/adt-client/src/index.ts +++ b/packages/adt-client/src/index.ts @@ -69,6 +69,13 @@ export type { ClassResponse, InterfaceResponse } from '@abapify/adt-contracts'; export type { Package as PackageResponse } from '@abapify/adt-contracts'; export type { ProgramResponse } from '@abapify/adt-contracts'; export type { FunctionGroupResponse } from '@abapify/adt-contracts'; +export type { + DomainResponse, + DataElementResponse, + TableResponse, + StructureResponse, + TableTypeResponse, +} from '@abapify/adt-contracts'; // Transport response type - exported directly from contracts // Note: Transport business logic has moved to @abapify/adk (AdkTransportRequest) diff --git a/packages/adt-contracts/src/adt/ddic/dataelements.ts b/packages/adt-contracts/src/adt/ddic/dataelements.ts new file mode 100644 index 00000000..dca06e08 --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/dataelements.ts @@ -0,0 +1,34 @@ +/** + * DDIC Data Element Contract + * + * ADT endpoint: /sap/bc/adt/ddic/dataelements + * Content-Type: application/vnd.sap.adt.dataelements.v2+xml + * Object type: DTEL/DE (dtelde) + */ + +import { crud } from '../../helpers/crud'; +import { + dataelementWrapper as dataelementWrapperSchema, + type InferTypedSchema, +} from '../../schemas'; + +/** + * Data Element response type - exported for consumers (ADK, etc.) + * + * Uses the custom wrapper schema because SAP wraps the inner + * dtel:dataElement content in a blue:wbobj root element + * (namespace http://www.sap.com/wbobj/dictionary/dtel). + */ +export type DataElementResponse = InferTypedSchema< + typeof dataelementWrapperSchema +>; + +export type DataelementsContract = typeof dataelementsContract; + +export const dataelementsContract = crud({ + basePath: '/sap/bc/adt/ddic/dataelements', + schema: dataelementWrapperSchema, + contentType: 'application/vnd.sap.adt.dataelements.v2+xml', + accept: + 'application/vnd.sap.adt.dataelements.v2+xml, application/vnd.sap.adt.dataelements.v1+xml', +}); diff --git a/packages/adt-contracts/src/adt/ddic/domains.ts b/packages/adt-contracts/src/adt/ddic/domains.ts new file mode 100644 index 00000000..3a22ea0b --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/domains.ts @@ -0,0 +1,25 @@ +/** + * DDIC Domain Contract + * + * ADT endpoint: /sap/bc/adt/ddic/domains + * Content-Type: application/vnd.sap.adt.domains.v2+xml + * Object type: DOMA/DD (domadd) + */ + +import { crud } from '../../helpers/crud'; +import { domain as domainSchema, type InferTypedSchema } from '../../schemas'; + +/** + * Domain response type - exported for consumers (ADK, etc.) + */ +export type DomainResponse = InferTypedSchema; + +export type DomainsContract = typeof domainsContract; + +export const domainsContract = crud({ + basePath: '/sap/bc/adt/ddic/domains', + schema: domainSchema, + contentType: 'application/vnd.sap.adt.domains.v2+xml', + accept: + 'application/vnd.sap.adt.domains.v2+xml, application/vnd.sap.adt.domains.v1+xml', +}); diff --git a/packages/adt-contracts/src/adt/ddic/index.ts b/packages/adt-contracts/src/adt/ddic/index.ts new file mode 100644 index 00000000..18ac70d4 --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/index.ts @@ -0,0 +1,58 @@ +/** + * DDIC (Data Dictionary) Contracts + * + * Covers all DDIC object types: + * - Domains (DOMA) + * - Data Elements (DTEL) + * - Structures (TABL/DS) + * - Database Tables (TABL/DT) + * - Table Types (TTYP) + */ + +export { + domainsContract, + type DomainsContract, + type DomainResponse, +} from './domains'; +export { + dataelementsContract, + type DataelementsContract, + type DataElementResponse, +} from './dataelements'; +export { + structuresContract, + type StructuresContract, + type StructureResponse, +} from './structures'; +export { + tablesContract, + type TablesContract, + type TableResponse, +} from './tables'; +export { + tabletypesContract, + type TabletypesContract, + type TableTypeResponse, +} from './tabletypes'; + +import { domainsContract } from './domains'; +import { dataelementsContract } from './dataelements'; +import { structuresContract } from './structures'; +import { tablesContract } from './tables'; +import { tabletypesContract } from './tabletypes'; + +export interface DdicContract { + domains: typeof domainsContract; + dataelements: typeof dataelementsContract; + structures: typeof structuresContract; + tables: typeof tablesContract; + tabletypes: typeof tabletypesContract; +} + +export const ddicContract: DdicContract = { + domains: domainsContract, + dataelements: dataelementsContract, + structures: structuresContract, + tables: tablesContract, + tabletypes: tabletypesContract, +}; diff --git a/packages/adt-contracts/src/adt/ddic/structures.ts b/packages/adt-contracts/src/adt/ddic/structures.ts new file mode 100644 index 00000000..e2f42f7e --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/structures.ts @@ -0,0 +1,45 @@ +/** + * DDIC Structure Contract + * + * ADT endpoint: /sap/bc/adt/ddic/structures + * Content-Type: application/vnd.sap.adt.structures.v2+xml + * Object type: TABL/DS (tablds) + * + * Uses the custom blueSource wrapper schema because SAP wraps + * structure responses in a blue:blueSource root element + * (namespace http://www.sap.com/wbobj/blue) extending AbapSourceMainObject. + */ + +import { crud } from '../../helpers/crud'; +import { http } from '@abapify/speci/rest'; +import { + blueSource as blueSourceSchema, + type InferTypedSchema, +} from '../../schemas'; + +/** + * Structure response type - exported for consumers (ADK, etc.) + */ +export type StructureResponse = InferTypedSchema; + +export type StructuresContract = typeof structuresContract; + +const basePath = '/sap/bc/adt/ddic/structures'; +const contentType = 'application/vnd.sap.adt.structures.v2+xml'; +const accept = + 'application/vnd.sap.adt.structures.v2+xml, application/vnd.sap.adt.structures.v1+xml'; + +export const structuresContract = { + ...crud({ + basePath, + schema: blueSourceSchema, + contentType, + accept, + }), + + objectstructure: (name: string, options?: { version?: string }) => + http.get(`${basePath}/${name.toLowerCase()}/objectstructure`, { + responses: { 200: undefined }, + query: options?.version ? { version: options.version } : undefined, + }), +}; diff --git a/packages/adt-contracts/src/adt/ddic/tables.ts b/packages/adt-contracts/src/adt/ddic/tables.ts new file mode 100644 index 00000000..64dabd5f --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/tables.ts @@ -0,0 +1,45 @@ +/** + * DDIC Database Table Contract + * + * ADT endpoint: /sap/bc/adt/ddic/tables + * Content-Type: application/vnd.sap.adt.tables.v2+xml + * Object type: TABL/DT (tabldt) + * + * Uses the custom blueSource wrapper schema because SAP wraps + * TABL responses in a blue:blueSource root element + * (namespace http://www.sap.com/wbobj/blue) extending AbapSourceMainObject. + */ + +import { crud } from '../../helpers/crud'; +import { http } from '@abapify/speci/rest'; +import { + blueSource as blueSourceSchema, + type InferTypedSchema, +} from '../../schemas'; + +/** + * Table response type - exported for consumers (ADK, etc.) + */ +export type TableResponse = InferTypedSchema; + +export type TablesContract = typeof tablesContract; + +const basePath = '/sap/bc/adt/ddic/tables'; +const contentType = 'application/vnd.sap.adt.tables.v2+xml'; +const accept = + 'application/vnd.sap.adt.blues.v1+xml, application/vnd.sap.adt.tables.v2+xml'; + +export const tablesContract = { + ...crud({ + basePath, + schema: blueSourceSchema, + contentType, + accept, + }), + + objectstructure: (name: string, options?: { version?: string }) => + http.get(`${basePath}/${name.toLowerCase()}/objectstructure`, { + responses: { 200: undefined }, + query: options?.version ? { version: options.version } : undefined, + }), +}; diff --git a/packages/adt-contracts/src/adt/ddic/tabletypes.ts b/packages/adt-contracts/src/adt/ddic/tabletypes.ts new file mode 100644 index 00000000..e7a5be9c --- /dev/null +++ b/packages/adt-contracts/src/adt/ddic/tabletypes.ts @@ -0,0 +1,28 @@ +/** + * DDIC Table Type Contract + * + * ADT endpoint: /sap/bc/adt/ddic/tabletypes + * Content-Type: application/vnd.sap.adt.tabletype.v1+xml + * Object type: TTYP/TT + */ + +import { crud } from '../../helpers/crud'; +import { + tabletype as tabletypeSchema, + type InferTypedSchema, +} from '../../schemas'; + +/** + * Table Type response type - exported for consumers (ADK, etc.) + */ +export type TableTypeResponse = InferTypedSchema; + +export type TabletypesContract = typeof tabletypesContract; + +export const tabletypesContract = crud({ + basePath: '/sap/bc/adt/ddic/tabletypes', + schema: tabletypeSchema, + contentType: 'application/vnd.sap.adt.tabletype.v1+xml', + accept: + 'application/vnd.sap.adt.tabletypes.v2+xml, application/vnd.sap.adt.tabletypes.v1+xml, application/vnd.sap.adt.blues.v1+xml', +}); diff --git a/packages/adt-contracts/src/adt/functions/groups.ts b/packages/adt-contracts/src/adt/functions/groups.ts index 0d0e1be2..47ab1c77 100644 --- a/packages/adt-contracts/src/adt/functions/groups.ts +++ b/packages/adt-contracts/src/adt/functions/groups.ts @@ -30,6 +30,8 @@ export const functionGroupsContract = crud({ basePath: '/sap/bc/adt/functions/groups', schema: groups, contentType: 'application/vnd.sap.adt.functions.groups.v3+xml', + accept: + 'application/vnd.sap.adt.functions.groups.v2+xml, application/vnd.sap.adt.functions.groups.v1+xml', sources: ['main'] as const, }); diff --git a/packages/adt-contracts/src/adt/index.ts b/packages/adt-contracts/src/adt/index.ts index 275a1ff4..8fc29919 100644 --- a/packages/adt-contracts/src/adt/index.ts +++ b/packages/adt-contracts/src/adt/index.ts @@ -12,6 +12,7 @@ export * from './core'; export * from './repository'; export * from './programs'; export * from './functions'; +export * from './ddic'; /** * Complete ADT Contract @@ -29,6 +30,7 @@ import { type ProgramsModuleContract, } from './programs'; import { functionsContract, type FunctionsContract } from './functions'; +import { ddicContract, type DdicContract } from './ddic'; /** * Explicit type to avoid TS7056 "inferred type exceeds maximum length" @@ -44,6 +46,7 @@ export interface AdtContract { repository: RepositoryContract; programs: ProgramsModuleContract; functions: FunctionsContract; + ddic: DdicContract; } export const adtContract: AdtContract = { @@ -57,6 +60,7 @@ export const adtContract: AdtContract = { repository: repositoryContract, programs: programsModuleContract, functions: functionsContract, + ddic: ddicContract, }; // Import RestClient from base for client type definition diff --git a/packages/adt-contracts/src/adt/oo/classes.ts b/packages/adt-contracts/src/adt/oo/classes.ts index 1d17ab7e..a01a1fad 100644 --- a/packages/adt-contracts/src/adt/oo/classes.ts +++ b/packages/adt-contracts/src/adt/oo/classes.ts @@ -46,6 +46,8 @@ export const classesContract = crud({ basePath: '/sap/bc/adt/oo/classes', schema: classesSchema, contentType: 'application/vnd.sap.adt.oo.classes.v4+xml', + accept: + 'application/vnd.sap.adt.oo.classes.v4+xml, application/vnd.sap.adt.oo.classes.v3+xml, application/vnd.sap.adt.oo.classes.v2+xml, application/vnd.sap.adt.oo.classes.v1+xml', sources: ['main'] as const, includes: [ 'definitions', diff --git a/packages/adt-contracts/src/adt/oo/interfaces.ts b/packages/adt-contracts/src/adt/oo/interfaces.ts index 954a9c45..e10a7d32 100644 --- a/packages/adt-contracts/src/adt/oo/interfaces.ts +++ b/packages/adt-contracts/src/adt/oo/interfaces.ts @@ -36,6 +36,8 @@ export const interfacesContract = crud({ basePath: '/sap/bc/adt/oo/interfaces', schema: interfacesSchema, contentType: 'application/vnd.sap.adt.oo.interfaces.v5+xml', + accept: + 'application/vnd.sap.adt.oo.interfaces.v5+xml, application/vnd.sap.adt.oo.interfaces.v4+xml, application/vnd.sap.adt.oo.interfaces.v3+xml, application/vnd.sap.adt.oo.interfaces.v2+xml, application/vnd.sap.adt.oo.interfaces+xml', sources: ['main'] as const, }); diff --git a/packages/adt-contracts/src/adt/packages/index.ts b/packages/adt-contracts/src/adt/packages/index.ts index 53be607d..14faaa73 100644 --- a/packages/adt-contracts/src/adt/packages/index.ts +++ b/packages/adt-contracts/src/adt/packages/index.ts @@ -30,6 +30,8 @@ export const packagesContract = crud({ basePath: '/sap/bc/adt/packages', schema: packagesV1, contentType: 'application/vnd.sap.adt.packages.v2+xml', + accept: + 'application/vnd.sap.adt.packages.v2+xml, application/vnd.sap.adt.packages.v1+xml', nameTransform: (n) => encodeURIComponent(n), // preserve case (packages are uppercase) }); diff --git a/packages/adt-contracts/src/adt/programs/programs.ts b/packages/adt-contracts/src/adt/programs/programs.ts index b9831f7a..213bdefc 100644 --- a/packages/adt-contracts/src/adt/programs/programs.ts +++ b/packages/adt-contracts/src/adt/programs/programs.ts @@ -30,6 +30,8 @@ export const programsContract = crud({ basePath: '/sap/bc/adt/programs/programs', schema: programs, contentType: 'application/vnd.sap.adt.programs.programs.v2+xml', + accept: + 'application/vnd.sap.adt.programs.programs.v2+xml, application/vnd.sap.adt.programs.programs.v1+xml', sources: ['main'] as const, }); diff --git a/packages/adt-contracts/src/generated/schemas.ts b/packages/adt-contracts/src/generated/schemas.ts index afd8f50e..a3e3acaa 100644 --- a/packages/adt-contracts/src/generated/schemas.ts +++ b/packages/adt-contracts/src/generated/schemas.ts @@ -55,6 +55,12 @@ export const aunitRun = toSpeciSchema(adtSchemas.aunitRun); export const aunitResult = toSpeciSchema(adtSchemas.aunitResult); export const programs = toSpeciSchema(adtSchemas.programs); export const groups = toSpeciSchema(adtSchemas.groups); +export const domain = toSpeciSchema(adtSchemas.domain); +export const dataelements = toSpeciSchema(adtSchemas.dataelements); +export const dataelementWrapper = toSpeciSchema(adtSchemas.dataelementWrapper); +export const tabletype = toSpeciSchema(adtSchemas.tabletype); +export const tablesettings = toSpeciSchema(adtSchemas.tablesettings); +export const blueSource = toSpeciSchema(adtSchemas.blueSource); // ============================================================================ // JSON Schemas (re-exported directly - they use zod, not ts-xsd) diff --git a/packages/adt-contracts/src/helpers/crud.ts b/packages/adt-contracts/src/helpers/crud.ts index 797837bb..5b44c17d 100644 --- a/packages/adt-contracts/src/helpers/crud.ts +++ b/packages/adt-contracts/src/helpers/crud.ts @@ -77,8 +77,10 @@ export interface CrudOptions> { basePath: string; /** Schema for parsing/building XML */ schema: S; - /** Content-Type header value (e.g., 'application/vnd.sap.adt.oo.classes.v4+xml') */ + /** Content-Type header for POST/PUT (single specific version, e.g., 'application/vnd.sap.adt.oo.classes.v4+xml') */ contentType: string; + /** Accept header for GET (multi-version, newest first). Falls back to contentType if not provided. */ + accept?: string; /** Optional: Transform object name for URL (default: lowercase) */ nameTransform?: (name: string) => string; /** Optional: Source endpoints to generate (e.g., ['main']) */ @@ -317,6 +319,7 @@ export function crud< basePath, schema, contentType, + accept = contentType, nameTransform = (n) => n.toLowerCase(), sources, includes, @@ -330,7 +333,7 @@ export function crud< get: (name: string, queryOptions?: Pick) => http.get(`${basePath}/${nameTransform(name)}`, { responses: { 200: schema }, - headers: { Accept: contentType }, + headers: { Accept: accept }, query: queryOptions?.version ? { version: queryOptions.version } : undefined, @@ -345,8 +348,8 @@ export function crud< body: schema, responses: { 200: schema }, headers: { - Accept: contentType, - 'Content-Type': 'application/*', + Accept: accept, + 'Content-Type': contentType, }, query: queryOptions?.corrNr ? { corrNr: queryOptions.corrNr } @@ -365,7 +368,7 @@ export function crud< body: schema, responses: { 200: schema }, headers: { - Accept: contentType, + Accept: accept, 'Content-Type': contentType, }, query: { @@ -406,6 +409,8 @@ export function crud< responses: { 200: undefined }, headers: { 'X-sap-adt-sessiontype': 'stateful', + Accept: + 'application/*,application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.lock.result', }, query: { _action: 'LOCK', @@ -524,6 +529,7 @@ export function repo>( schema: S, contentType: string, nameTransform?: (name: string) => string, + accept?: string, ): CrudContract { - return crud({ basePath, schema, contentType, nameTransform }); + return crud({ basePath, schema, contentType, accept, nameTransform }); } diff --git a/packages/adt-contracts/tests/contracts/oo.test.ts b/packages/adt-contracts/tests/contracts/oo.test.ts index dc9a59f4..91187e63 100644 --- a/packages/adt-contracts/tests/contracts/oo.test.ts +++ b/packages/adt-contracts/tests/contracts/oo.test.ts @@ -21,7 +21,10 @@ class ClassesScenario extends ContractScenario { contract: () => ooContract.classes.get('ZCL_TEST'), method: 'GET', path: '/sap/bc/adt/oo/classes/zcl_test', - headers: { Accept: 'application/vnd.sap.adt.oo.classes.v4+xml' }, + headers: { + Accept: + 'application/vnd.sap.adt.oo.classes.v4+xml, application/vnd.sap.adt.oo.classes.v3+xml, application/vnd.sap.adt.oo.classes.v2+xml, application/vnd.sap.adt.oo.classes.v1+xml', + }, response: { status: 200, schema: classesSchema, @@ -34,8 +37,9 @@ class ClassesScenario extends ContractScenario { method: 'POST', path: '/sap/bc/adt/oo/classes', headers: { - Accept: 'application/vnd.sap.adt.oo.classes.v4+xml', - 'Content-Type': 'application/*', + Accept: + 'application/vnd.sap.adt.oo.classes.v4+xml, application/vnd.sap.adt.oo.classes.v3+xml, application/vnd.sap.adt.oo.classes.v2+xml, application/vnd.sap.adt.oo.classes.v1+xml', + 'Content-Type': 'application/vnd.sap.adt.oo.classes.v4+xml', }, body: { schema: classesSchema }, response: { status: 200, schema: classesSchema }, @@ -46,7 +50,8 @@ class ClassesScenario extends ContractScenario { method: 'PUT', path: '/sap/bc/adt/oo/classes/zcl_test', headers: { - Accept: 'application/vnd.sap.adt.oo.classes.v4+xml', + Accept: + 'application/vnd.sap.adt.oo.classes.v4+xml, application/vnd.sap.adt.oo.classes.v3+xml, application/vnd.sap.adt.oo.classes.v2+xml, application/vnd.sap.adt.oo.classes.v1+xml', 'Content-Type': 'application/vnd.sap.adt.oo.classes.v4+xml', }, body: { schema: classesSchema }, @@ -123,7 +128,10 @@ class InterfacesScenario extends ContractScenario { contract: () => ooContract.interfaces.get('ZIF_TEST'), method: 'GET', path: '/sap/bc/adt/oo/interfaces/zif_test', - headers: { Accept: 'application/vnd.sap.adt.oo.interfaces.v5+xml' }, + headers: { + Accept: + 'application/vnd.sap.adt.oo.interfaces.v5+xml, application/vnd.sap.adt.oo.interfaces.v4+xml, application/vnd.sap.adt.oo.interfaces.v3+xml, application/vnd.sap.adt.oo.interfaces.v2+xml, application/vnd.sap.adt.oo.interfaces+xml', + }, response: { status: 200, schema: interfacesSchema, @@ -135,8 +143,9 @@ class InterfacesScenario extends ContractScenario { method: 'POST', path: '/sap/bc/adt/oo/interfaces', headers: { - Accept: 'application/vnd.sap.adt.oo.interfaces.v5+xml', - 'Content-Type': 'application/*', + Accept: + 'application/vnd.sap.adt.oo.interfaces.v5+xml, application/vnd.sap.adt.oo.interfaces.v4+xml, application/vnd.sap.adt.oo.interfaces.v3+xml, application/vnd.sap.adt.oo.interfaces.v2+xml, application/vnd.sap.adt.oo.interfaces+xml', + 'Content-Type': 'application/vnd.sap.adt.oo.interfaces.v5+xml', }, body: { schema: interfacesSchema }, response: { status: 200, schema: interfacesSchema }, @@ -147,7 +156,8 @@ class InterfacesScenario extends ContractScenario { method: 'PUT', path: '/sap/bc/adt/oo/interfaces/zif_test', headers: { - Accept: 'application/vnd.sap.adt.oo.interfaces.v5+xml', + Accept: + 'application/vnd.sap.adt.oo.interfaces.v5+xml, application/vnd.sap.adt.oo.interfaces.v4+xml, application/vnd.sap.adt.oo.interfaces.v3+xml, application/vnd.sap.adt.oo.interfaces.v2+xml, application/vnd.sap.adt.oo.interfaces+xml', 'Content-Type': 'application/vnd.sap.adt.oo.interfaces.v5+xml', }, body: { schema: interfacesSchema }, diff --git a/packages/adt-contracts/tests/contracts/packages.test.ts b/packages/adt-contracts/tests/contracts/packages.test.ts index 2b9cfaf0..e1d5b32f 100644 --- a/packages/adt-contracts/tests/contracts/packages.test.ts +++ b/packages/adt-contracts/tests/contracts/packages.test.ts @@ -18,7 +18,10 @@ class PackagesScenario extends ContractScenario { contract: () => packagesContract.get('$TMP'), method: 'GET', path: '/sap/bc/adt/packages/%24TMP', // $ is URL-encoded - headers: { Accept: 'application/vnd.sap.adt.packages.v2+xml' }, + headers: { + Accept: + 'application/vnd.sap.adt.packages.v2+xml, application/vnd.sap.adt.packages.v1+xml', + }, response: { status: 200, schema: packagesV1, @@ -30,7 +33,10 @@ class PackagesScenario extends ContractScenario { contract: () => packagesContract.get('Z_MY_PACKAGE'), method: 'GET', path: '/sap/bc/adt/packages/Z_MY_PACKAGE', - headers: { Accept: 'application/vnd.sap.adt.packages.v2+xml' }, + headers: { + Accept: + 'application/vnd.sap.adt.packages.v2+xml, application/vnd.sap.adt.packages.v1+xml', + }, response: { status: 200, schema: packagesV1 }, }, { @@ -39,8 +45,9 @@ class PackagesScenario extends ContractScenario { method: 'POST', path: '/sap/bc/adt/packages', headers: { - Accept: 'application/vnd.sap.adt.packages.v2+xml', - 'Content-Type': 'application/*', + Accept: + 'application/vnd.sap.adt.packages.v2+xml, application/vnd.sap.adt.packages.v1+xml', + 'Content-Type': 'application/vnd.sap.adt.packages.v2+xml', }, query: { corrNr: 'DEVK900001' }, body: { schema: packagesV1 }, diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/adk.ts b/packages/adt-plugin-abapgit/src/lib/handlers/adk.ts index ee2d13d4..877607f2 100644 --- a/packages/adt-plugin-abapgit/src/lib/handlers/adk.ts +++ b/packages/adt-plugin-abapgit/src/lib/handlers/adk.ts @@ -11,6 +11,11 @@ export { AdkPackage, AdkProgram, AdkFunctionGroup, + AdkDomain, + AdkDataElement, + AdkTable, + AdkStructure, + AdkTableType, } from '@abapify/adk'; // Types diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/objects/doma.ts b/packages/adt-plugin-abapgit/src/lib/handlers/objects/doma.ts new file mode 100644 index 00000000..11aaa0a7 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/lib/handlers/objects/doma.ts @@ -0,0 +1,44 @@ +/** + * Domain (DOMA) object handler for abapGit format + */ + +import { AdkDomain } from '../adk'; +import { doma } from '../../../schemas/generated'; +import { createHandler } from '../base'; +import { isoToSapLang, sapLangToIso } from '../lang'; + +export const domainHandler = createHandler(AdkDomain, { + schema: doma, + version: 'v1.0.0', + serializer: 'LCL_OBJECT_DOMA', + serializer_version: 'v1.0.0', + + toAbapGit: (obj) => { + const data = obj.dataSync; + const typeInfo = data?.content?.typeInformation; + const outInfo = data?.content?.outputInformation; + return { + DD01V: { + DOMNAME: obj.name ?? '', + DDLANGUAGE: isoToSapLang(data?.language), + DATATYPE: typeInfo?.datatype ?? '', + LENG: String(typeInfo?.length ?? ''), + OUTPUTLEN: String(outInfo?.length ?? ''), + DECIMALS: String(typeInfo?.decimals ?? ''), + LOWERCASE: outInfo?.lowercase ? 'X' : '', + SIGNFLAG: outInfo?.signExists ? 'X' : '', + CONVEXIT: outInfo?.conversionExit ?? '', + DDTEXT: obj.description ?? '', + }, + }; + }, + + fromAbapGit: ({ DD01V }) => + ({ + name: (DD01V?.DOMNAME ?? '').toUpperCase(), + type: 'DOMA/DD', + description: DD01V?.DDTEXT, + language: sapLangToIso(DD01V?.DDLANGUAGE), + masterLanguage: sapLangToIso(DD01V?.DDLANGUAGE), + }) as { name: string } & Record, +}); diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/objects/dtel.ts b/packages/adt-plugin-abapgit/src/lib/handlers/objects/dtel.ts new file mode 100644 index 00000000..e47d2267 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/lib/handlers/objects/dtel.ts @@ -0,0 +1,49 @@ +/** + * Data Element (DTEL) object handler for abapGit format + */ + +import { AdkDataElement } from '../adk'; +import { dtel } from '../../../schemas/generated'; +import { createHandler } from '../base'; +import { isoToSapLang, sapLangToIso } from '../lang'; + +export const dataElementHandler = createHandler(AdkDataElement, { + schema: dtel, + version: 'v1.0.0', + serializer: 'LCL_OBJECT_DTEL', + serializer_version: 'v1.0.0', + + toAbapGit: (obj) => { + const data = obj.dataSync; + return { + DD04V: { + ROLLNAME: obj.name ?? '', + DDLANGUAGE: isoToSapLang(obj.language || undefined), + DDTEXT: obj.description ?? '', + DOMNAME: data?.typeName ?? '', + DATATYPE: data?.dataType ?? '', + LENG: String(data?.dataTypeLength ?? ''), + DECIMALS: String(data?.dataTypeDecimals ?? ''), + REPTEXT: data?.headingFieldLabel ?? '', + SCRTEXT_S: data?.shortFieldLabel ?? '', + SCRTEXT_M: data?.mediumFieldLabel ?? '', + SCRTEXT_L: data?.longFieldLabel ?? '', + HEADLEN: String(data?.headingFieldLength ?? ''), + SCRLEN1: String(data?.shortFieldLength ?? ''), + SCRLEN2: String(data?.mediumFieldLength ?? ''), + SCRLEN3: String(data?.longFieldLength ?? ''), + REFKIND: data?.typeKind === 'domain' ? 'D' : '', + }, + }; + }, + + fromAbapGit: ({ DD04V }) => + ({ + name: (DD04V?.ROLLNAME ?? '').toUpperCase(), + type: 'DTEL/DE', + description: DD04V?.DDTEXT, + language: sapLangToIso(DD04V?.DDLANGUAGE), + masterLanguage: sapLangToIso(DD04V?.DDLANGUAGE), + abapLanguageVersion: DD04V?.ABAP_LANGUAGE_VERSION, + }) as { name: string } & Record, +}); diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/objects/index.ts b/packages/adt-plugin-abapgit/src/lib/handlers/objects/index.ts index 77757277..60969b1f 100644 --- a/packages/adt-plugin-abapgit/src/lib/handlers/objects/index.ts +++ b/packages/adt-plugin-abapgit/src/lib/handlers/objects/index.ts @@ -9,3 +9,7 @@ export { interfaceHandler } from './intf'; export { packageHandler } from './devc'; export { programHandler } from './prog'; export { functionGroupHandler } from './fugr'; +export { domainHandler } from './doma'; +export { dataElementHandler } from './dtel'; +export { tableHandler } from './tabl'; +export { tableTypeHandler } from './ttyp'; diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/objects/tabl.ts b/packages/adt-plugin-abapgit/src/lib/handlers/objects/tabl.ts new file mode 100644 index 00000000..0f264619 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/lib/handlers/objects/tabl.ts @@ -0,0 +1,34 @@ +/** + * Table/Structure (TABL) object handler for abapGit format + */ + +import { AdkTable } from '../adk'; +import { tabl } from '../../../schemas/generated'; +import { createHandler } from '../base'; +import { isoToSapLang, sapLangToIso } from '../lang'; + +export const tableHandler = createHandler(AdkTable, { + schema: tabl, + version: 'v1.0.0', + serializer: 'LCL_OBJECT_TABL', + serializer_version: 'v1.0.0', + + toAbapGit: (obj) => ({ + DD02V: { + TABNAME: obj.name ?? '', + DDLANGUAGE: isoToSapLang(obj.language || undefined), + TABCLASS: (obj.dataSync as any)?.tabClass ?? '', + DDTEXT: obj.description ?? '', + EXCLASS: (obj.dataSync as any)?.exclass ?? '', + }, + }), + + fromAbapGit: ({ DD02V }) => + ({ + name: (DD02V?.TABNAME ?? '').toUpperCase(), + type: DD02V?.TABCLASS === 'INTTAB' ? 'TABL/DS' : 'TABL/DT', + description: DD02V?.DDTEXT, + language: sapLangToIso(DD02V?.DDLANGUAGE), + masterLanguage: sapLangToIso(DD02V?.DDLANGUAGE), + }) as { name: string } & Record, +}); diff --git a/packages/adt-plugin-abapgit/src/lib/handlers/objects/ttyp.ts b/packages/adt-plugin-abapgit/src/lib/handlers/objects/ttyp.ts new file mode 100644 index 00000000..ee7bf514 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/lib/handlers/objects/ttyp.ts @@ -0,0 +1,41 @@ +/** + * Table Type (TTYP) object handler for abapGit format + */ + +import { AdkTableType } from '../adk'; +import { ttyp } from '../../../schemas/generated'; +import { createHandler } from '../base'; +import { isoToSapLang, sapLangToIso } from '../lang'; + +export const tableTypeHandler = createHandler(AdkTableType, { + schema: ttyp, + version: 'v1.0.0', + serializer: 'LCL_OBJECT_TTYP', + serializer_version: 'v1.0.0', + + toAbapGit: (obj) => { + const data = obj.dataSync; + return { + DD40V: { + TYPENAME: obj.name ?? '', + DDLANGUAGE: isoToSapLang(data?.language || undefined), + ROWTYPE: data?.rowType?.typeName ?? '', + ROWKIND: data?.rowType?.typeKind ?? '', + DATATYPE: data?.rowType?.builtInType?.dataType ?? '', + ACCESSMODE: data?.accessType ?? '', + KEYDEF: data?.primaryKey?.definition ?? '', + KEYKIND: data?.primaryKey?.kind ?? '', + DDTEXT: obj.description ?? '', + }, + }; + }, + + fromAbapGit: ({ DD40V }) => + ({ + name: (DD40V?.TYPENAME ?? '').toUpperCase(), + type: 'TTYP/TT', + description: DD40V?.DDTEXT, + language: sapLangToIso(DD40V?.DDLANGUAGE), + masterLanguage: sapLangToIso(DD40V?.DDLANGUAGE), + }) as { name: string } & Record, +}); diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/index.ts b/packages/adt-plugin-abapgit/src/schemas/generated/index.ts index e5cee40f..bc52f1c4 100644 --- a/packages/adt-plugin-abapgit/src/schemas/generated/index.ts +++ b/packages/adt-plugin-abapgit/src/schemas/generated/index.ts @@ -21,6 +21,8 @@ import _dtel from './schemas/dtel'; import _intf from './schemas/intf'; import _prog from './schemas/prog'; import _fugr from './schemas/fugr'; +import _tabl from './schemas/tabl'; +import _ttyp from './schemas/ttyp'; // Full AbapGit types - using flattened root types // Note: Generated types may be unions, we import the raw schema type @@ -31,6 +33,8 @@ import type { DtelSchema as _DtelSchema } from './types/dtel'; import type { IntfSchema as _IntfSchema } from './types/intf'; import type { ProgSchema as _ProgSchema } from './types/prog'; import type { FugrSchema as _FugrSchema } from './types/fugr'; +import type { TablSchema as _TablSchema } from './types/tabl'; +import type { TtypSchema as _TtypSchema } from './types/ttyp'; // Extract the abapGit variant from union types (generated types may be unions) type ClasAbapGitType = Extract<_ClasSchema, { abapGit: unknown }>; @@ -40,6 +44,8 @@ type DtelAbapGitType = Extract<_DtelSchema, { abapGit: unknown }>; type IntfAbapGitType = Extract<_IntfSchema, { abapGit: unknown }>; type ProgAbapGitType = Extract<_ProgSchema, { abapGit: unknown }>; type FugrAbapGitType = Extract<_FugrSchema, { abapGit: unknown }>; +type TablAbapGitType = Extract<_TablSchema, { abapGit: unknown }>; +type TtypAbapGitType = Extract<_TtypSchema, { abapGit: unknown }>; // AbapGit schema instances - using flattened types with values extracted from abapGit.abap.values export const clas = abapGitSchema< @@ -70,6 +76,14 @@ export const fugr = abapGitSchema< FugrAbapGitType, FugrAbapGitType['abapGit']['abap']['values'] >(_fugr); +export const tabl = abapGitSchema< + TablAbapGitType, + TablAbapGitType['abapGit']['abap']['values'] +>(_tabl); +export const ttyp = abapGitSchema< + TtypAbapGitType, + TtypAbapGitType['abapGit']['abap']['values'] +>(_ttyp); // Re-export types and utilities export { diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/schemas/index.ts b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/index.ts index 5d484860..8eb4c998 100644 --- a/packages/adt-plugin-abapgit/src/schemas/generated/schemas/index.ts +++ b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/index.ts @@ -11,3 +11,5 @@ export { default as dtel } from './dtel'; export { default as fugr } from './fugr'; export { default as intf } from './intf'; export { default as prog } from './prog'; +export { default as tabl } from './tabl'; +export { default as ttyp } from './ttyp'; diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/schemas/tabl.ts b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/tabl.ts new file mode 100644 index 00000000..cd187c61 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/tabl.ts @@ -0,0 +1,292 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: abapgit/tabl.xsd + */ + +export default { + $xmlns: { + xs: 'http://www.w3.org/2001/XMLSchema', + asx: 'http://www.sap.com/abapxml', + }, + targetNamespace: 'http://www.sap.com/abapxml', + elementFormDefault: 'unqualified', + element: [ + { + name: 'abapGit', + complexType: { + sequence: { + element: [ + { + ref: 'asx:abap', + }, + ], + }, + attribute: [ + { + name: 'version', + type: 'xs:string', + use: 'required', + }, + { + name: 'serializer', + type: 'xs:string', + use: 'required', + }, + { + name: 'serializer_version', + type: 'xs:string', + use: 'required', + }, + ], + }, + }, + { + name: 'Schema', + abstract: true, + }, + { + name: 'abap', + type: 'asx:AbapType', + }, + ], + complexType: [ + { + name: 'AbapValuesType', + all: { + element: [ + { + name: 'DD02V', + type: 'asx:Dd02vType', + minOccurs: '0', + }, + { + name: 'DD03P_TABLE', + type: 'asx:Dd03pTableType', + minOccurs: '0', + }, + ], + }, + }, + { + name: 'Dd02vType', + all: { + element: [ + { + name: 'TABNAME', + type: 'xs:string', + }, + { + name: 'DDLANGUAGE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'TABCLASS', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'SQLTAB', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DATCLASS', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'BUFFERED', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'MASTERLANG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'MATEFLAG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'CONTFLAG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'SHLPEXI', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'EXCLASS', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DDTEXT', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'AUTHCLASS', + type: 'xs:string', + minOccurs: '0', + }, + ], + }, + }, + { + name: 'Dd03pType', + all: { + element: [ + { + name: 'TABNAME', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'FIELDNAME', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DDLANGUAGE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'POSITION', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'KEYFLAG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'ROLLNAME', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'ADMINFIELD', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'INTTYPE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'INTLEN', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DATATYPE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'LENG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DECIMALS', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'NOTNULL', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DOMNAME', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'SHLPORIGIN', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'COMPTYPE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'MASK', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'REFTABLE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'REFFIELD', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'CONRFLAG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'PRECFIELD', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DDTEXT', + type: 'xs:string', + minOccurs: '0', + }, + ], + }, + }, + { + name: 'Dd03pTableType', + sequence: { + element: [ + { + name: 'DD03P', + type: 'Dd03pType', + minOccurs: '0', + maxOccurs: 'unbounded', + }, + ], + }, + }, + { + name: 'AbapType', + sequence: { + element: [ + { + name: 'values', + type: 'asx:AbapValuesType', + }, + ], + }, + attribute: [ + { + name: 'version', + type: 'xs:string', + default: '1.0', + }, + ], + }, + ], +} as const; diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/schemas/ttyp.ts b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/ttyp.ts new file mode 100644 index 00000000..60a0ce3d --- /dev/null +++ b/packages/adt-plugin-abapgit/src/schemas/generated/schemas/ttyp.ts @@ -0,0 +1,162 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: abapgit/ttyp.xsd + */ + +export default { + $xmlns: { + xs: 'http://www.w3.org/2001/XMLSchema', + asx: 'http://www.sap.com/abapxml', + }, + targetNamespace: 'http://www.sap.com/abapxml', + elementFormDefault: 'unqualified', + element: [ + { + name: 'abapGit', + complexType: { + sequence: { + element: [ + { + ref: 'asx:abap', + }, + ], + }, + attribute: [ + { + name: 'version', + type: 'xs:string', + use: 'required', + }, + { + name: 'serializer', + type: 'xs:string', + use: 'required', + }, + { + name: 'serializer_version', + type: 'xs:string', + use: 'required', + }, + ], + }, + }, + { + name: 'Schema', + abstract: true, + }, + { + name: 'abap', + type: 'asx:AbapType', + }, + ], + complexType: [ + { + name: 'AbapValuesType', + all: { + element: [ + { + name: 'DD40V', + type: 'asx:Dd40vType', + minOccurs: '0', + }, + ], + }, + }, + { + name: 'Dd40vType', + all: { + element: [ + { + name: 'TYPENAME', + type: 'xs:string', + }, + { + name: 'DDLANGUAGE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'ROWTYPE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'ROWKIND', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DATATYPE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'ACCESSMODE', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'KEYDEF', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'KEYKIND', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'GENERIC', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'LENG', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DECIMALS', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DDTEXT', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'TYPELEN', + type: 'xs:string', + minOccurs: '0', + }, + { + name: 'DEFFDNAME', + type: 'xs:string', + minOccurs: '0', + }, + ], + }, + }, + { + name: 'AbapType', + sequence: { + element: [ + { + name: 'values', + type: 'asx:AbapValuesType', + }, + ], + }, + attribute: [ + { + name: 'version', + type: 'xs:string', + default: '1.0', + }, + ], + }, + ], +} as const; diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/types/index.ts b/packages/adt-plugin-abapgit/src/schemas/generated/types/index.ts index c56412f3..b4c005e6 100644 --- a/packages/adt-plugin-abapgit/src/schemas/generated/types/index.ts +++ b/packages/adt-plugin-abapgit/src/schemas/generated/types/index.ts @@ -12,3 +12,5 @@ export type { DtelSchema as DtelAbapGitType } from './dtel'; export type { IntfSchema as IntfAbapGitType } from './intf'; export type { ProgSchema as ProgAbapGitType } from './prog'; export type { FugrSchema as FugrAbapGitType } from './fugr'; +export type { TablSchema as TablAbapGitType } from './tabl'; +export type { TtypSchema as TtypAbapGitType } from './ttyp'; diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/types/tabl.ts b/packages/adt-plugin-abapgit/src/schemas/generated/types/tabl.ts new file mode 100644 index 00000000..58c48cf4 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/schemas/generated/types/tabl.ts @@ -0,0 +1,109 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: abapgit/tabl.xsd + * Mode: Flattened + */ + +export type TablSchema = + | { + abapGit: { + abap: { + values: { + DD02V?: { + TABNAME: string; + DDLANGUAGE?: string; + TABCLASS?: string; + SQLTAB?: string; + DATCLASS?: string; + BUFFERED?: string; + MASTERLANG?: string; + MATEFLAG?: string; + CONTFLAG?: string; + SHLPEXI?: string; + EXCLASS?: string; + DDTEXT?: string; + AUTHCLASS?: string; + }; + DD03P_TABLE?: { + DD03P?: { + TABNAME?: string; + FIELDNAME?: string; + DDLANGUAGE?: string; + POSITION?: string; + KEYFLAG?: string; + ROLLNAME?: string; + ADMINFIELD?: string; + INTTYPE?: string; + INTLEN?: string; + DATATYPE?: string; + LENG?: string; + DECIMALS?: string; + NOTNULL?: string; + DOMNAME?: string; + SHLPORIGIN?: string; + COMPTYPE?: string; + MASK?: string; + REFTABLE?: string; + REFFIELD?: string; + CONRFLAG?: string; + PRECFIELD?: string; + DDTEXT?: string; + }[]; + }; + }; + version?: string; + }; + version: string; + serializer: string; + serializer_version: string; + }; + } + | { + abap: { + values: { + DD02V?: { + TABNAME: string; + DDLANGUAGE?: string; + TABCLASS?: string; + SQLTAB?: string; + DATCLASS?: string; + BUFFERED?: string; + MASTERLANG?: string; + MATEFLAG?: string; + CONTFLAG?: string; + SHLPEXI?: string; + EXCLASS?: string; + DDTEXT?: string; + AUTHCLASS?: string; + }; + DD03P_TABLE?: { + DD03P?: { + TABNAME?: string; + FIELDNAME?: string; + DDLANGUAGE?: string; + POSITION?: string; + KEYFLAG?: string; + ROLLNAME?: string; + ADMINFIELD?: string; + INTTYPE?: string; + INTLEN?: string; + DATATYPE?: string; + LENG?: string; + DECIMALS?: string; + NOTNULL?: string; + DOMNAME?: string; + SHLPORIGIN?: string; + COMPTYPE?: string; + MASK?: string; + REFTABLE?: string; + REFFIELD?: string; + CONRFLAG?: string; + PRECFIELD?: string; + DDTEXT?: string; + }[]; + }; + }; + version?: string; + }; + }; diff --git a/packages/adt-plugin-abapgit/src/schemas/generated/types/ttyp.ts b/packages/adt-plugin-abapgit/src/schemas/generated/types/ttyp.ts new file mode 100644 index 00000000..f73d6c33 --- /dev/null +++ b/packages/adt-plugin-abapgit/src/schemas/generated/types/ttyp.ts @@ -0,0 +1,59 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: abapgit/ttyp.xsd + * Mode: Flattened + */ + +export type TtypSchema = + | { + abapGit: { + abap: { + values: { + DD40V?: { + TYPENAME: string; + DDLANGUAGE?: string; + ROWTYPE?: string; + ROWKIND?: string; + DATATYPE?: string; + ACCESSMODE?: string; + KEYDEF?: string; + KEYKIND?: string; + GENERIC?: string; + LENG?: string; + DECIMALS?: string; + DDTEXT?: string; + TYPELEN?: string; + DEFFDNAME?: string; + }; + }; + version?: string; + }; + version: string; + serializer: string; + serializer_version: string; + }; + } + | { + abap: { + values: { + DD40V?: { + TYPENAME: string; + DDLANGUAGE?: string; + ROWTYPE?: string; + ROWKIND?: string; + DATATYPE?: string; + ACCESSMODE?: string; + KEYDEF?: string; + KEYKIND?: string; + GENERIC?: string; + LENG?: string; + DECIMALS?: string; + DDTEXT?: string; + TYPELEN?: string; + DEFFDNAME?: string; + }; + }; + version?: string; + }; + }; diff --git a/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_structure.tabl.xml b/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_structure.tabl.xml new file mode 100644 index 00000000..33b36ce7 --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_structure.tabl.xml @@ -0,0 +1,44 @@ + + + + + + ZAGE_STRUCTURE + E + INTTAB + AGE Test Structure + 1 + + + + PARTNER_ID + 0001 + CHAR10 + 0 + CHAR + 000010 + CHAR + + + DESCRIPTION + 0002 + CHAR40 + 0 + CHAR + 000040 + CHAR + + + AMOUNT + 0003 + 0 + P + 000008 + CURR + 000015 + 000002 + + + + + diff --git a/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_transparent_table.tabl.xml b/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_transparent_table.tabl.xml new file mode 100644 index 00000000..779eb6a7 --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/fixtures/tabl/zage_transparent_table.tabl.xml @@ -0,0 +1,46 @@ + + + + + + ZAGE_TRANSPARENT_TABLE + E + TRANSP + AGE Test Transparent Table + A + 1 + + + + MANDT + 0001 + X + MANDT + 0 + X + E + + + KEY_FIELD + 0002 + X + 0 + C + 000020 + CHAR + 000010 + X + + + VALUE_FIELD + 0003 + CHAR40 + 0 + CHAR + 000040 + CHAR + + + + + diff --git a/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_string_table.ttyp.xml b/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_string_table.ttyp.xml new file mode 100644 index 00000000..d2ba668b --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_string_table.ttyp.xml @@ -0,0 +1,18 @@ + + + + + + ZAGE_STRING_TABLE + E + STRING + S + STRG + T + D + N + AGE Test String Table Type + + + + diff --git a/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_struct_table_type.ttyp.xml b/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_struct_table_type.ttyp.xml new file mode 100644 index 00000000..e574ba44 --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/fixtures/ttyp/zage_struct_table_type.ttyp.xml @@ -0,0 +1,18 @@ + + + + + + ZAGE_STRUCT_TABLE_TYPE + E + ZAGE_STRUCTURE + S + STRU + T + D + N + AGE Test Structure Table Type + + + + diff --git a/packages/adt-plugin-abapgit/tests/schemas/tabl.test.ts b/packages/adt-plugin-abapgit/tests/schemas/tabl.test.ts new file mode 100644 index 00000000..c9e0cabc --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/schemas/tabl.test.ts @@ -0,0 +1,85 @@ +/** + * Test for TABL (Table/Structure) schema + * + * Fixture-driven: parses XML, validates content, round-trips + */ + +import assert from 'node:assert'; +import { + runSchemaTests, + createTypedSchema, + type SchemaScenario, +} from './base/scenario.ts'; +import { tabl as tablSchema } from '../../src/schemas/generated/schemas/index.ts'; +import type { TablSchema } from '../../src/schemas/generated/types/tabl.ts'; + +const schema = createTypedSchema(tablSchema); + +const scenario: SchemaScenario = { + name: 'TABL', + xsdName: 'tabl', + schema, + fixtures: [ + { + path: 'tabl/zage_structure.tabl.xml', + validate: (data) => { + const root = (data as any).abapGit; + + // Envelope + assert.strictEqual(root.version, 'v1.0.0'); + assert.strictEqual(root.serializer, 'LCL_OBJECT_TABL'); + assert.strictEqual(root.serializer_version, 'v1.0.0'); + + // DD02V content (table header) + const dd02v = root.abap.values.DD02V!; + assert.strictEqual(dd02v.TABNAME, 'ZAGE_STRUCTURE'); + assert.strictEqual(dd02v.DDLANGUAGE, 'E'); + assert.strictEqual(dd02v.TABCLASS, 'INTTAB'); + assert.strictEqual(dd02v.DDTEXT, 'AGE Test Structure'); + + // DD03P_TABLE content (fields) + const dd03pTable = root.abap.values.DD03P_TABLE; + assert.ok(dd03pTable, 'DD03P_TABLE should exist'); + assert.strictEqual(dd03pTable!.DD03P?.length, 3); + + // First field + const field1 = dd03pTable!.DD03P![0]; + assert.strictEqual(field1.FIELDNAME, 'PARTNER_ID'); + assert.strictEqual(field1.POSITION, '0001'); + assert.strictEqual(field1.DATATYPE, 'CHAR'); + assert.strictEqual(field1.LENG, '000010'); + + // Third field (CURR type) + const field3 = dd03pTable!.DD03P![2]; + assert.strictEqual(field3.FIELDNAME, 'AMOUNT'); + assert.strictEqual(field3.DATATYPE, 'CURR'); + assert.strictEqual(field3.DECIMALS, '000002'); + }, + }, + { + path: 'tabl/zage_transparent_table.tabl.xml', + validate: (data) => { + const root = (data as any).abapGit; + + // DD02V + const dd02v = root.abap.values.DD02V!; + assert.strictEqual(dd02v.TABNAME, 'ZAGE_TRANSPARENT_TABLE'); + assert.strictEqual(dd02v.TABCLASS, 'TRANSP'); + assert.strictEqual(dd02v.CONTFLAG, 'A'); + + // Fields + const dd03pTable = root.abap.values.DD03P_TABLE; + assert.ok(dd03pTable); + assert.strictEqual(dd03pTable!.DD03P?.length, 3); + + // Key field + const mandt = dd03pTable!.DD03P![0]; + assert.strictEqual(mandt.FIELDNAME, 'MANDT'); + assert.strictEqual(mandt.KEYFLAG, 'X'); + assert.strictEqual(mandt.NOTNULL, 'X'); + }, + }, + ], +}; + +runSchemaTests(scenario); diff --git a/packages/adt-plugin-abapgit/tests/schemas/ttyp.test.ts b/packages/adt-plugin-abapgit/tests/schemas/ttyp.test.ts new file mode 100644 index 00000000..d66659f2 --- /dev/null +++ b/packages/adt-plugin-abapgit/tests/schemas/ttyp.test.ts @@ -0,0 +1,61 @@ +/** + * Test for TTYP (Table Type) schema + * + * Fixture-driven: parses XML, validates content, round-trips + */ + +import assert from 'node:assert'; +import { + runSchemaTests, + createTypedSchema, + type SchemaScenario, +} from './base/scenario.ts'; +import { ttyp as ttypSchema } from '../../src/schemas/generated/schemas/index.ts'; +import type { TtypSchema } from '../../src/schemas/generated/types/ttyp.ts'; + +const schema = createTypedSchema(ttypSchema); + +const scenario: SchemaScenario = { + name: 'TTYP', + xsdName: 'ttyp', + schema, + fixtures: [ + { + path: 'ttyp/zage_string_table.ttyp.xml', + validate: (data) => { + const root = (data as any).abapGit; + + // Envelope + assert.strictEqual(root.version, 'v1.0.0'); + assert.strictEqual(root.serializer, 'LCL_OBJECT_TTYP'); + assert.strictEqual(root.serializer_version, 'v1.0.0'); + + // DD40V content + const dd40v = root.abap.values.DD40V!; + assert.strictEqual(dd40v.TYPENAME, 'ZAGE_STRING_TABLE'); + assert.strictEqual(dd40v.DDLANGUAGE, 'E'); + assert.strictEqual(dd40v.ROWTYPE, 'STRING'); + assert.strictEqual(dd40v.ROWKIND, 'S'); + assert.strictEqual(dd40v.ACCESSMODE, 'T'); + assert.strictEqual(dd40v.KEYDEF, 'D'); + assert.strictEqual(dd40v.KEYKIND, 'N'); + assert.strictEqual(dd40v.DDTEXT, 'AGE Test String Table Type'); + }, + }, + { + path: 'ttyp/zage_struct_table_type.ttyp.xml', + validate: (data) => { + const root = (data as any).abapGit; + + // DD40V content + const dd40v = root.abap.values.DD40V!; + assert.strictEqual(dd40v.TYPENAME, 'ZAGE_STRUCT_TABLE_TYPE'); + assert.strictEqual(dd40v.ROWTYPE, 'ZAGE_STRUCTURE'); + assert.strictEqual(dd40v.DATATYPE, 'STRU'); + assert.strictEqual(dd40v.DDTEXT, 'AGE Test Structure Table Type'); + }, + }, + ], +}; + +runSchemaTests(scenario); diff --git a/packages/adt-plugin-abapgit/ts-xsd.config.ts b/packages/adt-plugin-abapgit/ts-xsd.config.ts index 0011b45b..9479ff67 100644 --- a/packages/adt-plugin-abapgit/ts-xsd.config.ts +++ b/packages/adt-plugin-abapgit/ts-xsd.config.ts @@ -28,7 +28,17 @@ export default defineConfig({ outputDir: 'src/schemas/generated/schemas', // Only object schemas - base schemas (asx, abapgit) are included via xs:import/xs:include // and their types get merged into each object schema during resolution - schemas: ['clas', 'devc', 'doma', 'dtel', 'intf', 'prog', 'fugr'], + schemas: [ + 'clas', + 'devc', + 'doma', + 'dtel', + 'intf', + 'prog', + 'fugr', + 'tabl', + 'ttyp', + ], }, }, generators: [ diff --git a/packages/adt-plugin-abapgit/xsd/tabl.xsd b/packages/adt-plugin-abapgit/xsd/tabl.xsd new file mode 100644 index 00000000..bc95f385 --- /dev/null +++ b/packages/adt-plugin-abapgit/xsd/tabl.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-plugin-abapgit/xsd/ttyp.xsd b/packages/adt-plugin-abapgit/xsd/ttyp.xsd new file mode 100644 index 00000000..025dbcd3 --- /dev/null +++ b/packages/adt-plugin-abapgit/xsd/ttyp.xsd @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-plugin-abapgit/xsd/types/dd02v.xsd b/packages/adt-plugin-abapgit/xsd/types/dd02v.xsd new file mode 100644 index 00000000..fd33ba42 --- /dev/null +++ b/packages/adt-plugin-abapgit/xsd/types/dd02v.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-plugin-abapgit/xsd/types/dd03p.xsd b/packages/adt-plugin-abapgit/xsd/types/dd03p.xsd new file mode 100644 index 00000000..74dd5b3d --- /dev/null +++ b/packages/adt-plugin-abapgit/xsd/types/dd03p.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-plugin-abapgit/xsd/types/dd40v.xsd b/packages/adt-plugin-abapgit/xsd/types/dd40v.xsd new file mode 100644 index 00000000..7a8ded3e --- /dev/null +++ b/packages/adt-plugin-abapgit/xsd/types/dd40v.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-schemas/.xsd/custom/blueSource.xsd b/packages/adt-schemas/.xsd/custom/blueSource.xsd new file mode 100644 index 00000000..16637b11 --- /dev/null +++ b/packages/adt-schemas/.xsd/custom/blueSource.xsd @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-schemas/.xsd/custom/dataelementWrapper.xsd b/packages/adt-schemas/.xsd/custom/dataelementWrapper.xsd new file mode 100644 index 00000000..4cbe80b3 --- /dev/null +++ b/packages/adt-schemas/.xsd/custom/dataelementWrapper.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/adt-schemas/src/schemas/generated/schemas/custom/blueSource.ts b/packages/adt-schemas/src/schemas/generated/schemas/custom/blueSource.ts new file mode 100644 index 00000000..f5729b16 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/custom/blueSource.ts @@ -0,0 +1,39 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/custom/blueSource.xsd + */ + +import adtcore from '../sap/adtcore'; +import abapsource from '../sap/abapsource'; + +export default { + $xmlns: { + adtcore: 'http://www.sap.com/adt/core', + abapsource: 'http://www.sap.com/adt/abapsource', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + blue: 'http://www.sap.com/wbobj/blue', + }, + $imports: [adtcore, abapsource], + targetNamespace: 'http://www.sap.com/wbobj/blue', + attributeFormDefault: 'qualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'blueSource', + type: 'blue:BlueSource', + }, + ], + complexType: [ + { + name: 'BlueSource', + complexContent: { + extension: { + base: 'abapsource:AbapSourceMainObject', + }, + }, + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/custom/dataelementWrapper.ts b/packages/adt-schemas/src/schemas/generated/schemas/custom/dataelementWrapper.ts new file mode 100644 index 00000000..1a1b954e --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/custom/dataelementWrapper.ts @@ -0,0 +1,48 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/custom/dataelementWrapper.xsd + */ + +import adtcore from '../sap/adtcore'; +import dataelements from '../sap/dataelements'; + +export default { + $xmlns: { + adtcore: 'http://www.sap.com/adt/core', + dtel: 'http://www.sap.com/adt/dictionary/dataelements', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + blue: 'http://www.sap.com/wbobj/dictionary/dtel', + }, + $imports: [adtcore, dataelements], + targetNamespace: 'http://www.sap.com/wbobj/dictionary/dtel', + attributeFormDefault: 'qualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'wbobj', + type: 'blue:DataElementWrapper', + }, + ], + complexType: [ + { + name: 'DataElementWrapper', + complexContent: { + extension: { + base: 'adtcore:AdtMainObject', + sequence: { + element: [ + { + ref: 'dtel:dataElement', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + }, + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/custom/index.ts b/packages/adt-schemas/src/schemas/generated/schemas/custom/index.ts index a1069f19..9e4e30ca 100644 --- a/packages/adt-schemas/src/schemas/generated/schemas/custom/index.ts +++ b/packages/adt-schemas/src/schemas/generated/schemas/custom/index.ts @@ -3,6 +3,8 @@ * DO NOT EDIT - Generated by ts-xsd codegen */ +export { default as dataelementWrapper } from './dataelementWrapper'; +export { default as blueSource } from './blueSource'; export { default as atomExtended } from './atomExtended'; export { default as discovery } from './discovery'; export { default as http } from './http'; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/sap/dataelements.ts b/packages/adt-schemas/src/schemas/generated/schemas/sap/dataelements.ts new file mode 100644 index 00000000..f3cdc881 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/sap/dataelements.ts @@ -0,0 +1,246 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/dataelements.xsd + */ + +export default { + $xmlns: { + dtel: 'http://www.sap.com/adt/dictionary/dataelements', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + package: 'http://www.sap.com/adt/dictionary/dataelements', + }, + targetNamespace: 'http://www.sap.com/adt/dictionary/dataelements', + attributeFormDefault: 'unqualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'dataElement', + type: 'dtel:DataElement', + }, + ], + complexType: [ + { + name: 'DataElement', + sequence: { + element: [ + { + name: 'typeKind', + type: 'dtel:TypeKind', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'typeName', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'dataType', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'dataTypeLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'dataTypeLengthEnabled', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'dataTypeDecimals', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'dataTypeDecimalsEnabled', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'shortFieldLabel', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'shortFieldLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'shortFieldMaxLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'mediumFieldLabel', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'mediumFieldLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'mediumFieldMaxLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'longFieldLabel', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'longFieldLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'longFieldMaxLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'headingFieldLabel', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'headingFieldLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'headingFieldMaxLength', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'searchHelp', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'searchHelpParameter', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'setGetParameter', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'defaultComponentName', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'deactivateInputHistory', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'changeDocument', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'leftToRightDirection', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'deactivateBIDIFiltering', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'documentationStatus', + type: 'dtel:DocumentationStatus', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + ], + simpleType: [ + { + name: 'TypeKind', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'domain', + }, + { + value: 'predefinedAbapType', + }, + { + value: 'refToPredefinedAbapType', + }, + { + value: 'refToDictionaryType', + }, + { + value: 'refToClifType', + }, + ], + }, + }, + { + name: 'DocumentationStatus', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'required', + }, + { + value: 'notUsedInScreens', + }, + { + value: 'explainedByShortText', + }, + { + value: 'postponed', + }, + ], + }, + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/sap/domain.ts b/packages/adt-schemas/src/schemas/generated/schemas/sap/domain.ts new file mode 100644 index 00000000..da011bd7 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/sap/domain.ts @@ -0,0 +1,220 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/domain.xsd + */ + +import adtcore from './adtcore'; + +export default { + $xmlns: { + adtcore: 'http://www.sap.com/adt/core', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + doma: 'http://www.sap.com/dictionary/domain', + }, + $imports: [adtcore], + targetNamespace: 'http://www.sap.com/dictionary/domain', + attributeFormDefault: 'qualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'domain', + type: 'doma:Domain', + }, + ], + complexType: [ + { + name: 'Domain', + complexContent: { + extension: { + base: 'adtcore:AdtMainObject', + sequence: { + element: [ + { + name: 'content', + type: 'doma:Content', + }, + ], + }, + }, + }, + }, + { + name: 'Content', + sequence: { + element: [ + { + name: 'typeInformation', + type: 'doma:TypeInformation', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'outputInformation', + type: 'doma:OutputInformation', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'valueInformation', + type: 'doma:ValueInformation', + }, + { + name: 'appendInformation', + type: 'doma:AppendInformation', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'TypeInformation', + sequence: { + element: [ + { + name: 'datatype', + type: 'xsd:string', + }, + { + name: 'length', + type: 'xsd:int', + }, + { + name: 'decimals', + type: 'xsd:int', + }, + ], + }, + }, + { + name: 'OutputInformation', + sequence: { + element: [ + { + name: 'length', + type: 'xsd:int', + }, + { + name: 'style', + type: 'xsd:string', + }, + { + name: 'conversionExit', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'signExists', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'lowercase', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'ampmFormat', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'ValueInformation', + sequence: { + element: [ + { + name: 'valueTableRef', + type: 'adtcore:AdtObjectReference', + }, + { + name: 'appendExists', + type: 'xsd:boolean', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'fixValues', + type: 'doma:FixValues', + }, + ], + }, + }, + { + name: 'FixValues', + sequence: { + element: [ + { + name: 'fixValue', + type: 'doma:FixValue', + minOccurs: '0', + maxOccurs: 'unbounded', + }, + ], + }, + }, + { + name: 'FixValue', + sequence: { + element: [ + { + name: 'position', + type: 'xsd:int', + }, + { + name: 'low', + type: 'xsd:string', + }, + { + name: 'high', + type: 'xsd:string', + }, + { + name: 'text', + type: 'xsd:string', + }, + { + name: 'contributingAppendRef', + type: 'adtcore:AdtObjectReference', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'switchRef', + type: 'adtcore:AdtSwitchReference', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'AppendInformation', + sequence: { + element: [ + { + name: 'appendedDomainRef', + type: 'adtcore:AdtObjectReference', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'switchRef', + type: 'adtcore:AdtSwitchReference', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/sap/index.ts b/packages/adt-schemas/src/schemas/generated/schemas/sap/index.ts index 9af4c68d..a899e4be 100644 --- a/packages/adt-schemas/src/schemas/generated/schemas/sap/index.ts +++ b/packages/adt-schemas/src/schemas/generated/schemas/sap/index.ts @@ -32,6 +32,10 @@ export { default as traces } from './traces'; export { default as quickfixes } from './quickfixes'; export { default as log } from './log'; export { default as templatelink } from './templatelink'; +export { default as domain } from './domain'; +export { default as dataelements } from './dataelements'; +export { default as tabletype } from './tabletype'; +export { default as tablesettings } from './tablesettings'; export { default as xml } from './xml'; export { default as abapoo } from './abapoo'; export { default as abapsource } from './abapsource'; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/sap/tablesettings.ts b/packages/adt-schemas/src/schemas/generated/schemas/sap/tablesettings.ts new file mode 100644 index 00000000..a97fa144 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/sap/tablesettings.ts @@ -0,0 +1,323 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/tablesettings.xsd + */ + +import adtcore from './adtcore'; + +export default { + $xmlns: { + adtcore: 'http://www.sap.com/adt/core', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + ts: 'http://www.sap.com/dictionary/table/settings', + }, + $imports: [adtcore], + targetNamespace: 'http://www.sap.com/dictionary/table/settings', + attributeFormDefault: 'qualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'tableSettings', + type: 'ts:TableSettings', + }, + { + name: 'loggingAssessment', + type: 'ts:LoggingAssessment', + }, + ], + complexType: [ + { + name: 'TableSettings', + complexContent: { + extension: { + base: 'adtcore:AdtObject', + sequence: { + element: [ + { + name: 'dataClassCategory', + type: 'xsd:string', + }, + { + name: 'sizeCategory', + type: 'xsd:string', + }, + { + name: 'buffering', + type: 'ts:Buffering', + }, + { + name: 'storageType', + type: 'ts:StorageType', + }, + { + name: 'sharingType', + type: 'ts:SharingType', + }, + { + name: 'loadUnit', + type: 'ts:LoadUnit', + }, + { + name: 'translation', + type: 'ts:TranslationSetting', + }, + { + name: 'loggingEnabled', + type: 'xsd:boolean', + }, + { + name: 'supportsLoggingAssessment', + type: 'xsd:boolean', + }, + { + name: 'isWritableByAMDP', + type: 'xsd:boolean', + }, + ], + }, + }, + }, + }, + { + name: 'Buffering', + sequence: { + element: [ + { + name: 'allowed', + type: 'ts:BufferingAllowed', + }, + { + name: 'type', + type: 'ts:BufferingType', + }, + { + name: 'areaKeyFields', + type: 'xsd:string', + }, + ], + }, + }, + { + name: 'LoggingAssessment', + sequence: { + element: [ + { + name: 'allowed', + type: 'xsd:boolean', + }, + { + name: 'rating', + type: 'ts:Rating', + }, + { + name: 'reason', + type: 'xsd:string', + }, + ], + }, + attribute: [ + { + name: 'isVisible', + type: 'xsd:boolean', + }, + { + name: 'isEditable', + type: 'xsd:boolean', + }, + { + name: 'name', + type: 'xsd:string', + }, + ], + }, + { + name: 'TranslationSetting', + attribute: [ + { + name: 'value', + type: 'ts:Translation', + }, + { + name: 'granularity', + type: 'ts:TranslationGranularity', + }, + { + name: 'isVisible', + type: 'xsd:boolean', + }, + { + name: 'isEditable', + type: 'xsd:boolean', + }, + ], + }, + ], + simpleType: [ + { + name: 'BufferingAllowed', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'N', + }, + { + value: 'X', + }, + { + value: 'A', + }, + ], + }, + }, + { + name: 'BufferingType', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'P', + }, + { + value: 'G', + }, + { + value: 'X', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'StorageType', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'R', + }, + { + value: 'C', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'SharingType', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'L', + }, + { + value: 'R', + }, + { + value: 'W', + }, + { + value: 'T', + }, + { + value: 'S', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'Translation', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'X', + }, + { + value: 'L', + }, + { + value: 'T', + }, + { + value: 'N', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'TranslationGranularity', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: '1', + }, + { + value: '2', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'Rating', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: 'REQUIRED', + }, + { + value: 'NOT_REQUIRED', + }, + { + value: 'MAY_BE_REQUIRED', + }, + { + value: 'UNDEFINED', + }, + { + value: '', + }, + ], + }, + }, + { + name: 'LoadUnit', + restriction: { + base: 'xsd:string', + enumeration: [ + { + value: '', + }, + { + value: 'P', + }, + { + value: 'A', + }, + { + value: 'Q', + }, + ], + }, + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/schemas/sap/tabletype.ts b/packages/adt-schemas/src/schemas/generated/schemas/sap/tabletype.ts new file mode 100644 index 00000000..2a5e7f73 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/schemas/sap/tabletype.ts @@ -0,0 +1,341 @@ +/** + * Auto-generated schema from XSD + * + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/tabletype.xsd + */ + +import adtcore from './adtcore'; + +export default { + $xmlns: { + adtcore: 'http://www.sap.com/adt/core', + ecore: 'http://www.eclipse.org/emf/2002/Ecore', + xsd: 'http://www.w3.org/2001/XMLSchema', + ttyp: 'http://www.sap.com/dictionary/tabletype', + }, + $imports: [adtcore], + targetNamespace: 'http://www.sap.com/dictionary/tabletype', + attributeFormDefault: 'qualified', + elementFormDefault: 'qualified', + element: [ + { + name: 'tableType', + type: 'ttyp:TableType', + }, + ], + complexType: [ + { + name: 'TableType', + complexContent: { + extension: { + base: 'adtcore:AdtMainObject', + sequence: { + element: [ + { + name: 'rowType', + type: 'ttyp:RowType', + }, + { + name: 'initialRowCount', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'accessType', + type: 'xsd:string', + }, + { + name: 'primaryKey', + type: 'ttyp:PrimaryKey', + }, + { + name: 'secondaryKeys', + type: 'ttyp:SecondaryKeys', + }, + { + name: 'valueHelps', + type: 'ttyp:ValueHelps', + }, + ], + }, + }, + }, + }, + { + name: 'RowType', + sequence: { + element: [ + { + name: 'typeKind', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'typeName', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'builtInType', + type: 'ttyp:BuiltInType', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'rangeType', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'BuiltInType', + sequence: { + element: [ + { + name: 'dataType', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'length', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'decimals', + type: 'xsd:int', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'PrimaryKey', + sequence: { + element: [ + { + name: 'definition', + type: 'xsd:string', + }, + { + name: 'kind', + type: 'xsd:string', + }, + { + name: 'components', + type: 'ttyp:KeyComponents', + minOccurs: '0', + maxOccurs: '1', + }, + { + name: 'alias', + type: 'xsd:string', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + attribute: [ + { + name: 'isVisible', + type: 'xsd:boolean', + use: 'optional', + }, + { + name: 'isEditable', + type: 'xsd:boolean', + use: 'optional', + }, + ], + }, + { + name: 'SecondaryKeys', + sequence: { + element: [ + { + name: 'allowed', + type: 'xsd:string', + }, + { + name: 'secondaryKey', + type: 'ttyp:SecondaryKey', + minOccurs: '0', + maxOccurs: 'unbounded', + }, + ], + }, + attribute: [ + { + name: 'isVisible', + type: 'xsd:boolean', + use: 'optional', + }, + { + name: 'isEditable', + type: 'xsd:boolean', + use: 'optional', + }, + ], + }, + { + name: 'SecondaryKey', + sequence: { + element: [ + { + name: 'components', + type: 'ttyp:KeyComponents', + minOccurs: '0', + maxOccurs: '1', + }, + ], + }, + attribute: [ + { + name: 'identifier', + type: 'xsd:string', + use: 'optional', + }, + { + name: 'description', + type: 'xsd:string', + use: 'optional', + }, + { + name: 'language', + type: 'xsd:string', + use: 'optional', + }, + { + name: 'access', + type: 'xsd:string', + use: 'optional', + }, + { + name: 'definition', + type: 'xsd:string', + use: 'optional', + }, + ], + }, + { + name: 'KeyComponents', + sequence: { + element: [ + { + name: 'component', + type: 'ttyp:KeyComponent', + minOccurs: '0', + maxOccurs: 'unbounded', + }, + ], + }, + attribute: [ + { + name: 'isVisible', + type: 'xsd:boolean', + }, + ], + }, + { + name: 'KeyComponent', + attribute: [ + { + name: 'name', + type: 'xsd:string', + }, + ], + }, + { + name: 'ValueHelps', + sequence: { + element: [ + { + name: 'typeKindValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'keyDefinitionValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'keyKindValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'accessTypeValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'secKeyAccessValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'secKeyDefinitionValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + { + name: 'secKeyAllowedValues', + type: 'ttyp:ValueHelpList', + minOccurs: '1', + maxOccurs: '1', + }, + ], + }, + }, + { + name: 'ValueHelpList', + sequence: { + element: [ + { + name: 'valueHelp', + type: 'ttyp:ValueHelp', + minOccurs: '1', + maxOccurs: 'unbounded', + }, + ], + }, + }, + { + name: 'ValueHelp', + attribute: [ + { + name: 'key', + type: 'xsd:string', + use: 'required', + }, + { + name: 'value', + type: 'xsd:string', + use: 'required', + }, + { + name: 'description', + type: 'xsd:string', + use: 'optional', + }, + ], + }, + ], +} as const; diff --git a/packages/adt-schemas/src/schemas/generated/typed.ts b/packages/adt-schemas/src/schemas/generated/typed.ts index 78335824..560945b5 100644 --- a/packages/adt-schemas/src/schemas/generated/typed.ts +++ b/packages/adt-schemas/src/schemas/generated/typed.ts @@ -43,6 +43,12 @@ import type { TracesSchema } from './types/sap/traces.types'; import type { QuickfixesSchema } from './types/sap/quickfixes.types'; import type { LogSchema } from './types/sap/log.types'; import type { TemplatelinkSchema } from './types/sap/templatelink.types'; +import type { DomainSchema } from './types/sap/domain.types'; +import type { DataelementsSchema } from './types/sap/dataelements.types'; +import type { TabletypeSchema } from './types/sap/tabletype.types'; +import type { TablesettingsSchema } from './types/sap/tablesettings.types'; +import type { DataelementWrapperSchema } from './types/custom/dataelementWrapper.types'; +import type { BlueSourceSchema } from './types/custom/blueSource.types'; import type { AtomExtendedSchema } from './types/custom/atomExtended.types'; import type { DiscoverySchema } from './types/custom/discovery.types'; import type { HttpSchema } from './types/custom/http.types'; @@ -139,8 +145,26 @@ export const log: TypedSchema = typedSchema(_log); import _templatelink from './schemas/sap/templatelink'; export const templatelink: TypedSchema = typedSchema(_templatelink); +import _domain from './schemas/sap/domain'; +export const domain: TypedSchema = + typedSchema(_domain); +import _dataelements from './schemas/sap/dataelements'; +export const dataelements: TypedSchema = + typedSchema(_dataelements); +import _tabletype from './schemas/sap/tabletype'; +export const tabletype: TypedSchema = + typedSchema(_tabletype); +import _tablesettings from './schemas/sap/tablesettings'; +export const tablesettings: TypedSchema = + typedSchema(_tablesettings); // Custom schemas +import _dataelementWrapper from './schemas/custom/dataelementWrapper'; +export const dataelementWrapper: TypedSchema = + typedSchema(_dataelementWrapper); +import _blueSource from './schemas/custom/blueSource'; +export const blueSource: TypedSchema = + typedSchema(_blueSource); import _atomExtended from './schemas/custom/atomExtended'; export const atomExtended: TypedSchema = typedSchema(_atomExtended); diff --git a/packages/adt-schemas/src/schemas/generated/types/custom/blueSource.types.ts b/packages/adt-schemas/src/schemas/generated/types/custom/blueSource.types.ts new file mode 100644 index 00000000..23939fcc --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/custom/blueSource.types.ts @@ -0,0 +1,81 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/custom/blueSource.xsd + * Mode: Flattened + */ + +export type BlueSourceSchema = { + blueSource: { + containerRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + adtTemplate?: { + adtProperty?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + packageRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + template?: { + property?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + syntaxConfiguration?: { + language?: { + version?: string; + description?: string; + }; + objectUsage?: { + restricted?: boolean; + }; + }; + name: string; + type: string; + changedBy?: string; + changedAt?: string; + createdAt?: string; + createdBy?: string; + version?: + | '' + | 'active' + | 'inactive' + | 'workingArea' + | 'new' + | 'partlyActive' + | 'activeWithInactiveVersion'; + description?: string; + descriptionTextLimit?: number; + language?: string; + masterSystem?: string; + masterLanguage?: string; + responsible?: string; + abapLanguageVersion?: string; + sourceUri?: string; + sourceObjectStatus?: + | 'SAPStandardProduction' + | 'customerProduction' + | 'system' + | 'test'; + fixPointArithmetic?: boolean; + activeUnicodeCheck?: boolean; + }; +}; diff --git a/packages/adt-schemas/src/schemas/generated/types/custom/dataelementWrapper.types.ts b/packages/adt-schemas/src/schemas/generated/types/custom/dataelementWrapper.types.ts new file mode 100644 index 00000000..edaae6a5 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/custom/dataelementWrapper.types.ts @@ -0,0 +1,96 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/custom/dataelementWrapper.xsd + * Mode: Flattened + */ + +export type DataelementWrapperSchema = { + wbobj: { + containerRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + adtTemplate?: { + adtProperty?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + packageRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + dataElement?: { + typeKind: + | 'domain' + | 'predefinedAbapType' + | 'refToPredefinedAbapType' + | 'refToDictionaryType' + | 'refToClifType'; + typeName?: string; + dataType?: string; + dataTypeLength?: number; + dataTypeLengthEnabled?: boolean; + dataTypeDecimals?: number; + dataTypeDecimalsEnabled?: boolean; + shortFieldLabel?: string; + shortFieldLength?: number; + shortFieldMaxLength?: number; + mediumFieldLabel?: string; + mediumFieldLength?: number; + mediumFieldMaxLength?: number; + longFieldLabel?: string; + longFieldLength?: number; + longFieldMaxLength?: number; + headingFieldLabel?: string; + headingFieldLength?: number; + headingFieldMaxLength?: number; + searchHelp?: string; + searchHelpParameter?: string; + setGetParameter?: string; + defaultComponentName?: string; + deactivateInputHistory?: boolean; + changeDocument?: boolean; + leftToRightDirection?: boolean; + deactivateBIDIFiltering?: boolean; + documentationStatus?: + | 'required' + | 'notUsedInScreens' + | 'explainedByShortText' + | 'postponed'; + }; + name: string; + type: string; + changedBy?: string; + changedAt?: string; + createdAt?: string; + createdBy?: string; + version?: + | '' + | 'active' + | 'inactive' + | 'workingArea' + | 'new' + | 'partlyActive' + | 'activeWithInactiveVersion'; + description?: string; + descriptionTextLimit?: number; + language?: string; + masterSystem?: string; + masterLanguage?: string; + responsible?: string; + abapLanguageVersion?: string; + }; +}; diff --git a/packages/adt-schemas/src/schemas/generated/types/sap/dataelements.types.ts b/packages/adt-schemas/src/schemas/generated/types/sap/dataelements.types.ts new file mode 100644 index 00000000..1612be7e --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/sap/dataelements.types.ts @@ -0,0 +1,48 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/dataelements.xsd + * Mode: Flattened + */ + +export type DataelementsSchema = { + dataElement: { + typeKind: + | 'domain' + | 'predefinedAbapType' + | 'refToPredefinedAbapType' + | 'refToDictionaryType' + | 'refToClifType'; + typeName?: string; + dataType?: string; + dataTypeLength?: number; + dataTypeLengthEnabled?: boolean; + dataTypeDecimals?: number; + dataTypeDecimalsEnabled?: boolean; + shortFieldLabel?: string; + shortFieldLength?: number; + shortFieldMaxLength?: number; + mediumFieldLabel?: string; + mediumFieldLength?: number; + mediumFieldMaxLength?: number; + longFieldLabel?: string; + longFieldLength?: number; + longFieldMaxLength?: number; + headingFieldLabel?: string; + headingFieldLength?: number; + headingFieldMaxLength?: number; + searchHelp?: string; + searchHelpParameter?: string; + setGetParameter?: string; + defaultComponentName?: string; + deactivateInputHistory?: boolean; + changeDocument?: boolean; + leftToRightDirection?: boolean; + deactivateBIDIFiltering?: boolean; + documentationStatus?: + | 'required' + | 'notUsedInScreens' + | 'explainedByShortText' + | 'postponed'; + }; +}; diff --git a/packages/adt-schemas/src/schemas/generated/types/sap/domain.types.ts b/packages/adt-schemas/src/schemas/generated/types/sap/domain.types.ts new file mode 100644 index 00000000..b0e6b822 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/sap/domain.types.ts @@ -0,0 +1,132 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/domain.xsd + * Mode: Flattened + */ + +export type DomainSchema = { + domain: { + containerRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + adtTemplate?: { + adtProperty?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + packageRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + content: { + typeInformation?: { + datatype: string; + length: number; + decimals: number; + }; + outputInformation?: { + length: number; + style: string; + conversionExit?: string; + signExists?: boolean; + lowercase?: boolean; + ampmFormat?: boolean; + }; + valueInformation: { + valueTableRef: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + appendExists?: boolean; + fixValues: { + fixValue?: { + position: number; + low: string; + high: string; + text: string; + contributingAppendRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + switchRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + state?: '' | 'undefined' | 'on' | 'off' | 'stand-by'; + }; + }[]; + }; + }; + appendInformation?: { + appendedDomainRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + switchRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + state?: '' | 'undefined' | 'on' | 'off' | 'stand-by'; + }; + }; + }; + name: string; + type: string; + changedBy?: string; + changedAt?: string; + createdAt?: string; + createdBy?: string; + version?: + | '' + | 'active' + | 'inactive' + | 'workingArea' + | 'new' + | 'partlyActive' + | 'activeWithInactiveVersion'; + description?: string; + descriptionTextLimit?: number; + language?: string; + masterSystem?: string; + masterLanguage?: string; + responsible?: string; + abapLanguageVersion?: string; + }; +}; diff --git a/packages/adt-schemas/src/schemas/generated/types/sap/tablesettings.types.ts b/packages/adt-schemas/src/schemas/generated/types/sap/tablesettings.types.ts new file mode 100644 index 00000000..05c065e8 --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/sap/tablesettings.types.ts @@ -0,0 +1,79 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/tablesettings.xsd + * Mode: Flattened + */ + +export type TablesettingsSchema = + | { + tableSettings: { + containerRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + adtTemplate?: { + adtProperty?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + dataClassCategory: string; + sizeCategory: string; + buffering: { + allowed: 'N' | 'X' | 'A'; + type: unknown; + areaKeyFields: string; + }; + storageType: '' | 'R' | 'C'; + sharingType: '' | 'R' | 'L' | 'W' | 'T' | 'S'; + loadUnit: '' | 'A' | 'P' | 'Q'; + translation: { + value?: '' | 'N' | 'X' | 'L' | 'T'; + granularity?: '' | '1' | '2'; + isVisible?: boolean; + isEditable?: boolean; + }; + loggingEnabled: boolean; + supportsLoggingAssessment: boolean; + isWritableByAMDP: boolean; + name: string; + type: string; + changedBy?: string; + changedAt?: string; + createdAt?: string; + createdBy?: string; + version?: + | '' + | 'active' + | 'inactive' + | 'workingArea' + | 'new' + | 'partlyActive' + | 'activeWithInactiveVersion'; + description?: string; + descriptionTextLimit?: number; + language?: string; + }; + } + | { + loggingAssessment: { + allowed: boolean; + rating: + | '' + | 'REQUIRED' + | 'NOT_REQUIRED' + | 'MAY_BE_REQUIRED' + | 'UNDEFINED'; + reason: string; + isVisible?: boolean; + isEditable?: boolean; + name?: string; + }; + }; diff --git a/packages/adt-schemas/src/schemas/generated/types/sap/tabletype.types.ts b/packages/adt-schemas/src/schemas/generated/types/sap/tabletype.types.ts new file mode 100644 index 00000000..72a2e21e --- /dev/null +++ b/packages/adt-schemas/src/schemas/generated/types/sap/tabletype.types.ts @@ -0,0 +1,151 @@ +/** + * Auto-generated TypeScript interfaces from XSD + * DO NOT EDIT - Generated by ts-xsd codegen + * Source: xsd/sap/tabletype.xsd + * Mode: Flattened + */ + +export type TabletypeSchema = { + tableType: { + containerRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + adtTemplate?: { + adtProperty?: { + $value?: string; + key?: string; + }[]; + name?: string; + }; + packageRef?: { + extension?: unknown; + uri?: string; + parentUri?: string; + type?: string; + name?: string; + packageName?: string; + description?: string; + }; + rowType: { + typeKind?: string; + typeName?: string; + builtInType?: { + dataType?: string; + length?: number; + decimals?: number; + }; + rangeType?: string; + }; + initialRowCount?: number; + accessType: string; + primaryKey: { + definition: string; + kind: string; + components?: { + component?: { + name?: string; + }[]; + isVisible?: boolean; + }; + alias?: string; + isVisible?: boolean; + isEditable?: boolean; + }; + secondaryKeys: { + allowed: string; + secondaryKey?: { + components?: { + component?: { + name?: string; + }[]; + isVisible?: boolean; + }; + identifier?: string; + description?: string; + language?: string; + access?: string; + definition?: string; + }[]; + isVisible?: boolean; + isEditable?: boolean; + }; + valueHelps: { + typeKindValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + keyDefinitionValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + keyKindValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + accessTypeValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + secKeyAccessValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + secKeyDefinitionValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + secKeyAllowedValues: { + valueHelp: { + key: string; + value: string; + description?: string; + }[]; + }; + }; + name: string; + type: string; + changedBy?: string; + changedAt?: string; + createdAt?: string; + createdBy?: string; + version?: + | '' + | 'active' + | 'inactive' + | 'workingArea' + | 'new' + | 'partlyActive' + | 'activeWithInactiveVersion'; + description?: string; + descriptionTextLimit?: number; + language?: string; + masterSystem?: string; + masterLanguage?: string; + responsible?: string; + abapLanguageVersion?: string; + }; +}; diff --git a/packages/adt-schemas/ts-xsd.config.ts b/packages/adt-schemas/ts-xsd.config.ts index 8f7bd74f..9de4f9ed 100644 --- a/packages/adt-schemas/ts-xsd.config.ts +++ b/packages/adt-schemas/ts-xsd.config.ts @@ -60,7 +60,14 @@ const targetSchemas = [ 'sap/quickfixes', 'sap/log', 'sap/templatelink', + // Data Dictionary + 'sap/domain', + 'sap/dataelements', + 'sap/tabletype', + 'sap/tablesettings', // Custom schemas + 'custom/dataelementWrapper', // DTEL wrapper (SAP wraps inner dtel:dataElement in blue:wbobj) + 'custom/blueSource', // TABL/Structure wrapper (SAP uses blue:blueSource extending AbapSourceMainObject) 'custom/atomExtended', 'custom/discovery', 'custom/http',