@abapify/adt-plugin-abapgit 0.4.0 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,30 @@
4
4
 
5
5
  abapGit format plugin for ADT — serializes ABAP objects to Git-compatible XML/ABAP files.
6
6
 
7
+ ## Pure materialization
8
+
9
+ The registered `abapgitFormatPlugin` can produce a desired object tree without
10
+ filesystem, ADT, or Git side effects. Explicit source components override
11
+ mutable ADK source getters, while existing XSD-backed handlers continue to
12
+ produce metadata:
13
+
14
+ ```typescript
15
+ const { files } = await abapgitFormatPlugin.materialize({
16
+ object: adkClass,
17
+ objectType: 'CLAS',
18
+ packagePath: ['ZROOT', 'ZROOT_FEATURE'],
19
+ sources: {
20
+ main: selectedMainSource,
21
+ definitions: selectedLocalDefinitions,
22
+ },
23
+ formatOptions: { folderLogic: 'prefix' },
24
+ });
25
+ ```
26
+
27
+ Paths are rooted below `src/`, ordered deterministically, and annotated with
28
+ their semantic role and source-component identity. Existing filesystem import
29
+ and Git-to-SAP export APIs remain unchanged.
30
+
7
31
  ## Architecture Overview
8
32
 
9
33
  ```
@@ -0,0 +1,224 @@
1
+ import { AbapObjectType, AdtPlugin, AdtPlugin as AdtPlugin$1, ExportContext, ExportResult, FormatMaterializationInput, FormatMaterializationResult, FormatPlugin, FormatSerializeOptions, ImportContext, ImportResult, MaterializedFormatFile } from "@abapify/adt-plugin";
2
+ import { AdkObject } from "@abapify/adk";
3
+ import { SchemaLike, TypedSchema } from "@abapify/ts-xsd";
4
+ import { adtUriToAbapGitPath, createAbapGitResolver as createFindingResolver } from "@abapify/adt-atc";
5
+ //#region src/lib/format-plugin.d.ts
6
+ declare const abapgitFormatPlugin: FormatPlugin;
7
+ //#endregion
8
+ //#region src/lib/folder-logic.d.ts
9
+ /**
10
+ * abapGit Folder Logic
11
+ *
12
+ * Shared functions for resolving SAP package names from directory paths
13
+ * using abapGit's folder logic (PREFIX/FULL).
14
+ *
15
+ * Used by both the serializer (import: SAP → Git) and deserializer (export: Git → SAP).
16
+ */
17
+ type FolderLogic = 'prefix' | 'full' | 'full-with-root';
18
+ /**
19
+ * Parse abapGit repository metadata from .abapgit.xml content
20
+ */
21
+ declare function parseAbapGitMetadata(xmlContent: string): {
22
+ folderLogic: FolderLogic;
23
+ startingFolder: string;
24
+ };
25
+ /**
26
+ * Reverse of calculatePackageDir — compute SAP package name from directory path
27
+ *
28
+ * Given a directory path relative to the starting folder, the folder logic,
29
+ * and the root package name, compute the SAP package name.
30
+ *
31
+ * PREFIX mode: root 'ZABAPGIT_EXAMPLES' + dir 'clas' → 'ZABAPGIT_EXAMPLES_CLAS'
32
+ * FULL mode: dir 'zabapgit_examples_clas' → 'ZABAPGIT_EXAMPLES_CLAS'
33
+ *
34
+ * @param dirPath - Directory path relative to starting folder
35
+ * @param folderLogic - Folder logic mode (prefix or full)
36
+ * @param rootPackage - Root SAP package name
37
+ * @returns SAP package name
38
+ */
39
+ declare function resolvePackageFromDir(dirPath: string, folderLogic: FolderLogic, rootPackage: string): string;
40
+ /**
41
+ * Reverse of resolvePackageFromDir — given a SAP package name and the
42
+ * relative directory of an object, back-derive the root package.
43
+ *
44
+ * PREFIX mode: sapPackage 'ZABAPGIT_EXAMPLES_FUGR' + dir 'fugr' → 'ZABAPGIT_EXAMPLES'
45
+ * FULL mode: cannot derive root (returns undefined)
46
+ *
47
+ * @param sapPackage - Actual SAP package name (from GET response)
48
+ * @param relDir - Directory path relative to starting folder
49
+ * @param folderLogic - Folder logic mode
50
+ * @returns Root package name, or undefined if it cannot be derived
51
+ */
52
+ declare function reverseResolveRootPackage(sapPackage: string, relDir: string, folderLogic: FolderLogic): string | undefined;
53
+ //#endregion
54
+ //#region src/lib/abapgit.d.ts
55
+ /**
56
+ * abapGit Plugin
57
+ *
58
+ * Provides import/export of ADK objects to abapGit repository format.
59
+ */
60
+ declare const abapGitPlugin: AdtPlugin$1;
61
+ //#endregion
62
+ //#region src/lib/handlers/abapgit-schema.d.ts
63
+ /**
64
+ * AbapGit schema instance with both full type and values type
65
+ *
66
+ * @typeParam TFull - Full AbapGitType (root XML structure)
67
+ * @typeParam TValues - Inner values type (e.g., DevcType)
68
+ * @typeParam S - Raw schema literal type
69
+ */
70
+ interface AbapGitSchema<TFull, TValues, S extends SchemaLike = SchemaLike> extends TypedSchema<TFull, S> {
71
+ /** The inner values type - use with typeof for type extraction */
72
+ readonly _values: TValues;
73
+ }
74
+ /** Extract the values type from an AbapGitSchema */
75
+ type InferValuesType<S> = S extends AbapGitSchema<unknown, infer V> ? V : unknown;
76
+ //#endregion
77
+ //#region src/lib/handlers/base.d.ts
78
+ /**
79
+ * Extract the data type (D) from an AdkObject<K, D>
80
+ * This allows us to infer the payload type from the ADK class itself
81
+ */
82
+ type InferAdkData<T> = T extends AdkObject<infer _K, infer D> ? D : never;
83
+ /**
84
+ * ABAP object type code (e.g., 'CLAS', 'INTF', 'DOMA')
85
+ */
86
+ type AbapObjectType$1 = string;
87
+ /**
88
+ * Result of serializing a single file
89
+ */
90
+ interface SerializedFile {
91
+ /** Relative path from object directory */
92
+ path: string;
93
+ /** File content */
94
+ content: string;
95
+ /** Optional encoding (default: utf-8) */
96
+ encoding?: BufferEncoding;
97
+ }
98
+ /**
99
+ * Handler interface for object serialization/deserialization
100
+ *
101
+ * @typeParam T - ADK object type
102
+ * @typeParam TSchema - AbapGit schema type (provides type-safe values)
103
+ */
104
+ interface ObjectHandler<T extends AdkObject = AdkObject, TSchema extends AbapGitSchema<unknown, unknown> = AbapGitSchema<unknown, unknown>> {
105
+ /** ABAP object type (e.g., 'CLAS', 'INTF') */
106
+ readonly type: AbapObjectType$1;
107
+ /** File extension for this type (e.g., 'clas', 'intf') */
108
+ readonly fileExtension: string;
109
+ /** Schema for parsing/building XML */
110
+ readonly schema: TSchema;
111
+ /** Map abapGit file suffix to source key */
112
+ readonly suffixToSourceKey?: Record<string, string>;
113
+ /** Whether this handler treats an explicit `sources` map as authoritative. */
114
+ readonly supportsExplicitSources?: boolean;
115
+ /** Serialize object to files (SAP → Git) */
116
+ serialize(object: T, options?: FormatSerializeOptions): Promise<SerializedFile[]>;
117
+ /**
118
+ * Map abapGit values to ADK data (Git → SAP)
119
+ * Return type includes name (required) plus any ADK data fields
120
+ */
121
+ fromAbapGit?(values: InferValuesType<TSchema>): Partial<InferAdkData<T>> & {
122
+ name: string;
123
+ };
124
+ /**
125
+ * Map AFF JSON metadata to ADK data (Git → SAP)
126
+ * Used when the metadata file is `.json` (ABAP File Format) instead of legacy `.xml`.
127
+ * Receives the parsed JSON object and returns the full payload including name.
128
+ */
129
+ fromAffJson?(json: Record<string, unknown>): Partial<InferAdkData<T>> & {
130
+ name: string;
131
+ };
132
+ /**
133
+ * Set source files on ADK object during deserialization (Git → SAP)
134
+ * Symmetric counterpart to getSources
135
+ */
136
+ setSources?(object: T, sources: Record<string, string>): void;
137
+ }
138
+ /**
139
+ * Get handler for object type
140
+ *
141
+ * Tries the full type first (e.g., 'TABL/DS'), then falls back to the
142
+ * main type (e.g., 'CLAS/OC' → 'CLAS'). This matches ADK's resolveType()
143
+ * behaviour and handles quickSearch results that return subtypes.
144
+ */
145
+ declare function getHandler(type: AbapObjectType$1): ObjectHandler | undefined;
146
+ /**
147
+ * Check if object type is supported
148
+ *
149
+ * Tries the full type first, then falls back to the main type.
150
+ */
151
+ declare function isSupported(type: AbapObjectType$1): boolean;
152
+ /**
153
+ * Get all supported object types
154
+ */
155
+ declare function getSupportedTypes(): AbapObjectType$1[];
156
+ //#endregion
157
+ //#region src/lib/filename-parser.d.ts
158
+ /**
159
+ * abapGit filename parsing utilities.
160
+ *
161
+ * Extracted into a standalone module so it can be unit-tested without
162
+ * pulling in the full handler/schema dependency chain.
163
+ */
164
+ /**
165
+ * abapGit file naming convention:
166
+ * - XML metadata: {name}.{type}.xml (e.g., zcl_myclass.clas.xml)
167
+ * - AFF JSON metadata: {name}.{type}.json (e.g., zfoo.bdef.json)
168
+ * - Source code: {name}.{type}.abap (e.g., zcl_myclass.clas.abap)
169
+ * - Source includes: {name}.{type}.{suffix}.abap (e.g., zcl_myclass.clas.testclasses.abap)
170
+ * - AFF source files: {name}.{type}.abdl, {name}.{type}.acds, {name}.{type}.asrvd
171
+ */
172
+ /**
173
+ * Parse abapGit filename to extract object info
174
+ *
175
+ * Supports both legacy XML metadata (.xml) and AFF JSON metadata (.json),
176
+ * plus source file extensions (.abap, .abdl, .acds, .asrvd).
177
+ */
178
+ declare function parseAbapGitFilename(filename: string): {
179
+ name: string;
180
+ type: string;
181
+ suffix?: string;
182
+ extension: string;
183
+ } | null;
184
+ //#endregion
185
+ //#region src/lib/handlers/xml-format.d.ts
186
+ /**
187
+ * XML formatting utilities for abapGit serialization.
188
+ *
189
+ * Centralizes XML post-processing that was previously duplicated
190
+ * across base.ts, fugr.ts, tabl.ts, and roundtrip.ts.
191
+ *
192
+ * Uses indexOf-based parsing instead of regex to avoid
193
+ * super-linear backtracking (SonarQube S5852).
194
+ */
195
+ /**
196
+ * Format XML attributes on separate lines for better diff readability.
197
+ *
198
+ * Turns `<tag a="1" b="2">` into:
199
+ * ```
200
+ * <tag
201
+ * a="1"
202
+ * b="2"
203
+ * >
204
+ * ```
205
+ *
206
+ * Uses indexOf-based scanning to avoid regex backtracking (S5852).
207
+ */
208
+ declare function formatXmlAttributes(xml: string): string;
209
+ /**
210
+ * Move `xmlns:asx` declaration from root `<abapGit>` to nested `<asx:abap>`.
211
+ *
212
+ * Uses indexOf-based approach instead of regex to avoid backtracking on
213
+ * the `[\s\S]*?` pattern that SonarQube flags.
214
+ */
215
+ declare function moveNamespaceToAbap(xml: string): string;
216
+ /**
217
+ * Apply standard abapGit XML formatting:
218
+ * 1. Format attributes on separate lines
219
+ * 2. Move xmlns:asx to asx:abap element
220
+ */
221
+ declare function formatAbapGitXml(xml: string): string;
222
+ //#endregion
223
+ export { abapGitPlugin as AbapGitPlugin, abapGitPlugin, abapGitPlugin as default, type AbapObjectType, type AdtPlugin, type ExportContext, type ExportResult, type FolderLogic, type FormatMaterializationInput, type FormatMaterializationResult, type ImportContext, type ImportResult, type MaterializedFormatFile, type ObjectHandler, type SerializedFile, abapgitFormatPlugin, adtUriToAbapGitPath, createFindingResolver, formatAbapGitXml, formatXmlAttributes, getHandler, getSupportedTypes, isSupported, moveNamespaceToAbap, parseAbapGitFilename, parseAbapGitMetadata, resolvePackageFromDir, reverseResolveRootPackage };
224
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/format-plugin.ts","../src/lib/folder-logic.ts","../src/lib/abapgit.ts","../src/lib/handlers/abapgit-schema.ts","../src/lib/handlers/base.ts","../src/lib/filename-parser.ts","../src/lib/handlers/xml-format.ts"],"mappings":";;;;;cAgGa,qBAAqB;;;;;;;;;;;KCvFtB;;;;iBA6CI,qBAAqB;EACnC,aAAa;EACb;;;;;;;;;;;;;;;;iBAsBc,sBACd,iBACA,aAAa,aACb;;;;;;;;;;;;;iBA2Cc,0BACd,oBACA,gBACA,aAAa;;;;;;;;cCwBF,eAAe;;;;;;;;;;UClIX,cACf,OACA,SACA,UAAU,aAAa,oBACf,YAAY,OAAO;;WAElB,SAAS;;;KA2CR,gBAAgB,KAC1B,UAAU,6BAA6B,KAAK;;;;;;;KC/ClC,aAAa,KACvB,UAAU,gBAAgB,UAAU,KAAK;;;;KAsB/B;;;;UAKK;;EAEf;;EAEA;;EAEA,WAAW;;;;;;;;UASI,cACf,UAAU,YAAY,WACtB,gBAAgB,kCAAkC;;WAMzC,MAAM;;WAEN;;WAEA,QAAQ;;WAER,oBAAoB;;WAEpB;;EAET,UACE,QAAQ,GACR,UAAU,yBACT,QAAQ;;;;;EAKX,aACE,QAAQ,gBAAgB,WACvB,QAAQ,aAAa;IAAQ;;;;;;;EAOhC,aAAa,MAAM,0BAA0B,QAAQ,aAAa;IAChE;;;;;;EAOF,YAAY,QAAQ,GAAG,SAAS;;;;;;;;;iBAyBlB,WAAW,MAAM,mBAAiB;;;;;;iBASlC,YAAY,MAAM;;;;iBAOlB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;iBCjIrB,qBAAqB;EACnC;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;;;;;iBC+Bc,oBAAoB;;;;;;;iBA8DpB,oBAAoB;;;;;;iBA8BpB,iBAAiB"}