@lwc-bolts/sf2ts 0.0.4 → 1.0.0

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.
Files changed (98) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +285 -0
  3. package/dist/apex/apexdoc.d.ts +19 -0
  4. package/dist/apex/apexdoc.js +79 -0
  5. package/dist/apex/file.d.ts +37 -0
  6. package/dist/apex/file.js +623 -0
  7. package/dist/apex/library.config.d.ts +23 -0
  8. package/dist/apex/library.config.js +17 -0
  9. package/dist/apex/library.d.ts +54 -0
  10. package/dist/apex/library.generated.d.ts +2 -0
  11. package/dist/apex/library.generated.js +215 -0
  12. package/dist/apex/library.js +47 -0
  13. package/dist/apex/namespace.d.ts +32 -0
  14. package/dist/apex/namespace.js +41 -0
  15. package/dist/apex/resolution.d.ts +77 -0
  16. package/dist/apex/resolution.js +306 -0
  17. package/dist/apex/sobjects.d.ts +45 -0
  18. package/dist/apex/sobjects.js +141 -0
  19. package/dist/context.d.ts +16 -0
  20. package/dist/context.js +28 -0
  21. package/dist/converters/apex-class.d.ts +7 -0
  22. package/dist/converters/apex-class.js +23 -0
  23. package/dist/converters/content-asset.d.ts +3 -0
  24. package/dist/converters/content-asset.js +20 -0
  25. package/dist/converters/custom-field.d.ts +3 -0
  26. package/dist/converters/custom-field.js +107 -0
  27. package/dist/converters/custom-label.d.ts +10 -0
  28. package/dist/converters/custom-label.js +36 -0
  29. package/dist/converters/custom-labels.d.ts +3 -0
  30. package/dist/converters/custom-labels.js +10 -0
  31. package/dist/converters/custom-object.d.ts +3 -0
  32. package/dist/converters/custom-object.js +37 -0
  33. package/dist/converters/custom-permission.d.ts +3 -0
  34. package/dist/converters/custom-permission.js +21 -0
  35. package/dist/converters/lightning-component-bundle.d.ts +7 -0
  36. package/dist/converters/lightning-component-bundle.js +31 -0
  37. package/dist/converters/lightning-message-channel.d.ts +10 -0
  38. package/dist/converters/lightning-message-channel.js +39 -0
  39. package/dist/converters/registry.d.ts +22 -0
  40. package/dist/converters/registry.js +18 -0
  41. package/dist/converters/static-resource.d.ts +3 -0
  42. package/dist/converters/static-resource.js +20 -0
  43. package/dist/diagnostics.d.ts +5 -0
  44. package/dist/diagnostics.js +18 -0
  45. package/dist/identifiers.d.ts +12 -0
  46. package/dist/identifiers.js +19 -0
  47. package/dist/index.d.ts +34 -0
  48. package/dist/index.js +47 -0
  49. package/dist/jsdoc.d.ts +14 -0
  50. package/dist/jsdoc.js +28 -0
  51. package/dist/lightning-component-bundle/component-source.d.ts +6 -0
  52. package/dist/lightning-component-bundle/component-source.js +21 -0
  53. package/dist/lightning-component-bundle/metadata.d.ts +36 -0
  54. package/dist/lightning-component-bundle/metadata.js +93 -0
  55. package/dist/lightning-component-bundle/templates/ast.d.ts +47 -0
  56. package/dist/lightning-component-bundle/templates/ast.js +46 -0
  57. package/dist/lightning-component-bundle/templates/base-components.d.ts +6 -0
  58. package/dist/lightning-component-bundle/templates/base-components.js +17 -0
  59. package/dist/lightning-component-bundle/templates/declarations.d.ts +30 -0
  60. package/dist/lightning-component-bundle/templates/declarations.js +82 -0
  61. package/dist/lightning-component-bundle/templates/expressions.d.ts +16 -0
  62. package/dist/lightning-component-bundle/templates/expressions.js +33 -0
  63. package/dist/lightning-component-bundle/templates/helpers.d.ts +10 -0
  64. package/dist/lightning-component-bundle/templates/helpers.js +47 -0
  65. package/dist/lightning-component-bundle/templates/slots.d.ts +24 -0
  66. package/dist/lightning-component-bundle/templates/slots.js +78 -0
  67. package/dist/lightning-component-bundle/templates/source.d.ts +36 -0
  68. package/dist/lightning-component-bundle/templates/source.js +81 -0
  69. package/dist/lightning-component-bundle/templates/tags.d.ts +41 -0
  70. package/dist/lightning-component-bundle/templates/tags.js +36 -0
  71. package/dist/lightning-component-bundle/templates/template.d.ts +53 -0
  72. package/dist/lightning-component-bundle/templates/template.js +518 -0
  73. package/dist/lightning-component-bundle/templates/writer.d.ts +9 -0
  74. package/dist/lightning-component-bundle/templates/writer.js +32 -0
  75. package/dist/module-declaration.d.ts +27 -0
  76. package/dist/module-declaration.js +28 -0
  77. package/dist/names.d.ts +39 -0
  78. package/dist/names.js +67 -0
  79. package/dist/text-builder.d.ts +34 -0
  80. package/dist/text-builder.js +46 -0
  81. package/dist/types.d.ts +128 -0
  82. package/dist/types.js +3 -0
  83. package/dist/xml.d.ts +32 -0
  84. package/dist/xml.js +80 -0
  85. package/package.json +37 -26
  86. package/README.MD +0 -5
  87. package/lib/converts/_index.mjs +0 -8
  88. package/lib/converts/apex-class.mjs +0 -469
  89. package/lib/converts/content-asset.mjs +0 -48
  90. package/lib/converts/custom-field.mjs +0 -63
  91. package/lib/converts/custom-label.mjs +0 -62
  92. package/lib/converts/custom-labels.mjs +0 -34
  93. package/lib/converts/custom-object.mjs +0 -51
  94. package/lib/converts/custom-permission.mjs +0 -51
  95. package/lib/converts/static-resource.mjs +0 -56
  96. package/lib/index.mjs +0 -51
  97. package/lib/util.mjs +0 -68
  98. package/lib-cjs/bundle.cjs +0 -962
@@ -1,962 +0,0 @@
1
- 'use strict';
2
-
3
- var webTreeSitterSfapex = require('web-tree-sitter-sfapex');
4
- var xml2js = require('xml2js');
5
-
6
- /** @import { MapPair } from "./index.mjs" */
7
-
8
- /**
9
- * @typedef MapDelta
10
- * @property {number | null} sourcePos
11
- * @property {number} destDeltaPos
12
- */
13
-
14
- /**
15
- *
16
- * @param {MapDelta[]} mappings
17
- */
18
- function getMappings(mappings) {
19
- // increase destination position as an aggregate
20
- /** @type {MapPair[]} */
21
- let filteredMappings = [];
22
- let lastDestPos = 0;
23
- mappings.forEach((m) => {
24
- m.destDeltaPos += lastDestPos;
25
- lastDestPos = m.destDeltaPos;
26
- if (m.sourcePos !== null) {
27
- filteredMappings.push({
28
- sourcePos: m.sourcePos,
29
- destPos: m.destDeltaPos,
30
- });
31
- }
32
- });
33
- return filteredMappings;
34
- }
35
-
36
- class PositionAwareTextBuilder {
37
- /** @type {MapDelta[]} */
38
- mappings = [];
39
- /** @type {string[]} */
40
- textParts = [];
41
-
42
- lastTextLen = 0;
43
-
44
- /**
45
- *
46
- * @param {string} text
47
- * @param {number?} sourceStartPos
48
- * @param {number?} sourceEndPos
49
- */
50
- addText(text, sourceStartPos = null, sourceEndPos = null) {
51
- this.mappings.push({
52
- sourcePos: sourceStartPos,
53
- destDeltaPos: this.lastTextLen,
54
- });
55
- this.lastTextLen = text.length;
56
- if (sourceEndPos != null) {
57
- this.mappings.push({
58
- sourcePos: sourceEndPos,
59
- destDeltaPos: this.lastTextLen,
60
- });
61
- this.lastTextLen = 0;
62
- }
63
- this.textParts.push(text);
64
- }
65
-
66
- build() {
67
- return this.textParts.join("");
68
- }
69
-
70
- getMappings() {
71
- return getMappings(this.mappings);
72
- }
73
- }
74
-
75
- /** @import Parser from "web-tree-sitter" */
76
- /** @import { Component, ConvertedComponent, MapPair } from "../index.mjs" */
77
-
78
- /** @type { Parser } */
79
- let prsr;
80
-
81
- const getParserPromise = webTreeSitterSfapex.getApexParser().then((newParser) => {
82
- prsr = newParser;
83
- });
84
-
85
- /**
86
- *
87
- * @param {Component} comp
88
- * @returns {ConvertedComponent}
89
- */
90
- function ApexClass(comp) {
91
- // generate d.ts
92
- if (prsr === undefined) {
93
- /** @type { any } */
94
- const err = new Error("Apex parser not ready yet");
95
- err.waitFor = getParserPromise; // smuggle a "ready" signal out to the invoker
96
- throw err;
97
- }
98
-
99
- const [declarationContent, mappingContent] = buildDeclarationForApexFile(
100
- prsr,
101
- comp.content,
102
- false
103
- );
104
- if (declarationContent === undefined) {
105
- throw new Error("Problem building declaration content");
106
- }
107
- if (mappingContent === undefined) {
108
- throw new Error("Problem building declaration content mappings");
109
- }
110
-
111
- return {
112
- ...comp,
113
- declarationContent: declarationContent,
114
- mapData: mappingContent,
115
- };
116
- }
117
-
118
- /** @type { Record<string, string> } */
119
- const typeOverrides = {
120
- string: "string",
121
- datetime: "Date",
122
- decimal: "number",
123
- integer: "number",
124
- boolean: "boolean",
125
- id: "string",
126
- };
127
-
128
- /** @type { string[] } */
129
- let localNestedClasses = [];
130
- /** @type { string? } */
131
- let outerClassName;
132
-
133
- // TODO: probably don't want this to be a global
134
- let builder = new PositionAwareTextBuilder();
135
-
136
- /**
137
- *
138
- * @param {Parser} parser
139
- * @param {string} apexText
140
- * @param {boolean} isSobject
141
- * @returns { [string, MapPair[]] | [] }
142
- */
143
- function buildDeclarationForApexFile(
144
- parser,
145
- apexText,
146
- isSobject = false
147
- ) {
148
- builder = new PositionAwareTextBuilder();
149
- try {
150
- const tree = parser.parse(apexText);
151
- // step into top-level class, if any
152
- // if outer-most thing isn't a class the leave
153
- const classes = tree.rootNode.descendantsOfType("class_declaration");
154
-
155
- if (classes.length === 0 || !classes[0]) {
156
- return []; // this isn't a class
157
- }
158
-
159
- processClass(classes[0], isSobject);
160
- localNestedClasses = [];
161
- outerClassName = null;
162
- return [builder.build(), builder.getMappings()];
163
- } catch (error) {
164
- console.error(error);
165
-
166
- localNestedClasses = [];
167
- outerClassName = null;
168
- return [];
169
- }
170
- }
171
-
172
- /**
173
- *
174
- * @param {Parser.SyntaxNode} classNode
175
- * @param {boolean} isSobject
176
- */
177
- function processClass(classNode, isSobject) {
178
- const classNameNode = classNode.childForFieldName("name");
179
- if (!classNameNode) {
180
- throw new Error("Class Name Node not found");
181
- }
182
- let className = classNameNode?.text ?? "";
183
- if (!outerClassName) {
184
- outerClassName = className;
185
- }
186
- let classBody = classNode.childForFieldName("body");
187
- if (!classBody) {
188
- return;
189
- }
190
-
191
- const methodsToProcess = [];
192
- const fieldsToProcess = [];
193
- const classesToProcess = [];
194
-
195
- for (const cNode of classBody.children) {
196
- switch (cNode.type) {
197
- case "method_declaration":
198
- // gather methods because AuraEnabled methods create their own exports
199
- methodsToProcess.push(cNode);
200
- break;
201
- case "field_declaration":
202
- fieldsToProcess.push(cNode);
203
- break;
204
- case "class_declaration":
205
- classesToProcess.push(cNode);
206
- const innerNameNode = cNode.childForFieldName("name");
207
- if (innerNameNode) {
208
- // queue up nested class names so type resolution can use them
209
- localNestedClasses.push(innerNameNode.text);
210
- }
211
- break;
212
- }
213
- }
214
- if (fieldsToProcess.length > 0) {
215
- builder.addText("declare interface ");
216
- builder.addText(
217
- className,
218
- classNameNode.startIndex,
219
- classNameNode.endIndex
220
- );
221
- builder.addText(" {\n");
222
- for (let fNode of fieldsToProcess) {
223
- transformFieldDeclaration(fNode, isSobject);
224
- }
225
- builder.addText("}\n");
226
- }
227
-
228
- if (classesToProcess.length > 0) {
229
- builder.addText("declare namespace ");
230
- builder.addText(
231
- className,
232
- classNameNode.startIndex,
233
- classNameNode.endIndex
234
- );
235
- builder.addText(" {\n");
236
- for (const cNode of classesToProcess) {
237
- processClass(cNode, isSobject);
238
- // TODO: somehow queue up local classes for type resolution
239
- }
240
-
241
- builder.addText("}\n");
242
- }
243
-
244
- for (const mNode of methodsToProcess) {
245
- transformMethodDeclaration(classNameNode, mNode);
246
- }
247
- }
248
-
249
- /**
250
- *
251
- * @param {Parser.SyntaxNode} classNameNode
252
- * @param {Parser.SyntaxNode} methodNode
253
- */
254
- function transformMethodDeclaration(classNameNode, methodNode) {
255
- const methodNameNode = methodNode.childForFieldName("name");
256
- if (!methodNameNode) {
257
- return;
258
- }
259
- methodNameNode.text;
260
- const returnType = methodNode.childForFieldName("type");
261
- if (!returnType) {
262
- return;
263
- }
264
- const parameters = getMethodParameters(methodNode);
265
-
266
- const auraEnabledNode = getAuraEnabledAnnotation(methodNode);
267
- if (!auraEnabledNode) {
268
- // method doesn't hold the AuraEnabled Annotation
269
- return;
270
- }
271
- const isCacheableEnabled = getAuraEnabledIsCacheable(auraEnabledNode);
272
- const isContinuation = getAuraEnabledIsContinuation(auraEnabledNode);
273
-
274
- // TODO: continuation return type is actually the return type of the `continuationMethod` referenced in the Continuation object
275
- declarationString(
276
- classNameNode,
277
- methodNameNode,
278
- getType(returnType),
279
- parameters,
280
- isCacheableEnabled,
281
- isContinuation
282
- );
283
- }
284
-
285
- /**
286
- *
287
- * @param {Parser.SyntaxNode} node
288
- * @param {boolean} isSobject
289
- */
290
- function transformFieldDeclaration(node, isSobject) {
291
- /** @type {string[]} */
292
- let deprecatedReasons = [];
293
- const modifiers = node.descendantsOfType("modifiers");
294
-
295
- if (modifiers.length === 0 || !modifiers[0]) {
296
- deprecatedReasons.push("public or global");
297
- } else {
298
- // initialize so the generated SObjects don't flag missing AuraEnabled
299
- let isAuraEnabled = isSobject;
300
- for (const aNode of modifiers[0].descendantsOfType("annotation")) {
301
- const aNameNode = aNode.childForFieldName("name");
302
- if (aNameNode && aNameNode.text.toLowerCase() === "auraenabled") {
303
- isAuraEnabled = true;
304
- }
305
- }
306
- if (!isAuraEnabled) {
307
- deprecatedReasons.push("@AuraEnabled");
308
- }
309
-
310
- let isAtLeastPublic = false;
311
- for (const mNode of modifiers[0].descendantsOfType("modifier")) {
312
- switch (mNode.text.toLowerCase()) {
313
- case "public":
314
- case "global":
315
- isAtLeastPublic = true;
316
- break;
317
- case "static":
318
- deprecatedReasons.push("non-static");
319
- break;
320
- }
321
- }
322
- if (!isAtLeastPublic) {
323
- deprecatedReasons.push("public or global");
324
- }
325
- }
326
- /**
327
- * determine if AuraEnabled & public or global & not static
328
- * otherwise mark as deprecated with note (dynamic based on missing access component)
329
- * {property}: {getType({type})}?;
330
- */
331
- if (deprecatedReasons.length > 0) {
332
- builder.addText(
333
- ` /** @deprecated not exposed; property must be ${deprecatedReasons.join(
334
- ", "
335
- )} */\n`
336
- );
337
- }
338
- const nameNode = node
339
- .childForFieldName("declarator")
340
- ?.childForFieldName("name");
341
- builder.addText(" ");
342
- if (!nameNode) {
343
- throw new Error("Field doesn't have a name");
344
- }
345
- builder.addText(
346
- `${nameNode?.text ?? ""}`,
347
- nameNode.startIndex,
348
- nameNode.endIndex
349
- );
350
- builder.addText("?: ");
351
- const typeNode = node.childForFieldName("type");
352
- if (!typeNode) {
353
- throw new Error("Type node not found");
354
- }
355
- const typeText = getType(typeNode);
356
- builder.addText(typeText, typeNode.startIndex, typeNode.endIndex);
357
- builder.addText(";\n");
358
- }
359
-
360
- /**
361
- *
362
- * @param {Parser.SyntaxNode} node
363
- * @returns {boolean}
364
- */
365
- function getAuraEnabledIsCacheable(node) {
366
- const args = node.childForFieldName("arguments");
367
- if (args) {
368
- for (const a of args.descendantsOfType("annotation_key_value")) {
369
- const k = a.childForFieldName("key");
370
- const v = a.childForFieldName("value");
371
- if (
372
- k &&
373
- v &&
374
- k.text.toLowerCase() === "cacheable" &&
375
- v.text.toLowerCase() === "true"
376
- ) {
377
- return true;
378
- }
379
- }
380
- }
381
- return false;
382
- }
383
-
384
- /**
385
- *
386
- * @param {Parser.SyntaxNode} node
387
- * @returns {boolean}
388
- */
389
- function getAuraEnabledIsContinuation(node) {
390
- const args = node.childForFieldName("arguments");
391
- if (args) {
392
- for (const a of args.descendantsOfType("annotation_key_value")) {
393
- const k = a.childForFieldName("key");
394
- const v = a.childForFieldName("value");
395
- if (
396
- k &&
397
- v &&
398
- k.text.toLowerCase() === "continuation" &&
399
- v.text.toLowerCase() === "true"
400
- ) {
401
- return true;
402
- }
403
- }
404
- }
405
- return false;
406
- }
407
-
408
- /**
409
- *
410
- * @param {Parser.SyntaxNode} node
411
- * @returns {Parser.SyntaxNode | null}
412
- */
413
- function getAuraEnabledAnnotation(node) {
414
- for (const m of node.descendantsOfType("modifiers")) {
415
- for (const a of m.descendantsOfType("annotation")) {
416
- if (a.childForFieldName("name")?.text.toLowerCase() === "auraenabled") {
417
- return a;
418
- }
419
- }
420
- }
421
- return null;
422
- }
423
-
424
- /**
425
- *
426
- * @param {Parser.SyntaxNode} node
427
- * @returns {Map<string, string>}
428
- */
429
- function getMethodParameters(node) {
430
- const params = new Map();
431
- const parameters = node.childForFieldName("parameters");
432
- if (!parameters) {
433
- return params;
434
- }
435
- for (const p of parameters.namedChildren) {
436
- params.set(
437
- p.childForFieldName("name")?.text,
438
- getType(p.childForFieldName("type"))
439
- );
440
- }
441
- return params;
442
- }
443
-
444
- /**
445
- *
446
- * @param {Parser.SyntaxNode} classNameNode
447
- * @param {Parser.SyntaxNode} methodNameNode
448
- * @param {string} returnType
449
- * @param {Map<string, string>} params
450
- * @param {boolean} isCacheable
451
- * @param {boolean} isContinuation
452
- */
453
- function declarationString(
454
- classNameNode,
455
- methodNameNode,
456
- returnType,
457
- params,
458
- isCacheable,
459
- isContinuation
460
- ) {
461
- builder.addText("declare module ");
462
- // if method has Containuation
463
- builder.addText(
464
- `"@salesforce/apex${isContinuation ? "Continuation" : ""}/${classNameNode.text}.${methodNameNode.text}"`,
465
- methodNameNode.startIndex,
466
- methodNameNode.endIndex
467
- );
468
- builder.addText(` {
469
- const `);
470
- builder.addText(
471
- methodNameNode.text,
472
- methodNameNode.startIndex,
473
- methodNameNode.endIndex
474
- );
475
- builder.addText(`: {
476
- (${
477
- params.size === 0
478
- ? ""
479
- : `param: { ${Array.from(params.entries())
480
- .map(([name, type]) => `${name}: ${type}`)
481
- .join("; ")} }`
482
- }): Promise<${returnType}>;${
483
- // Apex can only be wired if it is cacheable
484
- // the adapter is the WireAdapterConstructor that the @wire decorator consumes
485
- !isCacheable
486
- ? ""
487
- : `
488
- adapter: import("lwc").WireAdapterConstructor<
489
- ${
490
- params.size === 0
491
- ? "never"
492
- : `{ ${Array.from(params.entries())
493
- .map(([name, type]) => `${name}: ${type}`)
494
- .join("; ")} }`
495
- },
496
- { error?: any; data?: ${returnType}; }
497
- >;`
498
- }
499
- };
500
- export default ${methodNameNode.text};
501
- }
502
- `);
503
- }
504
-
505
- /**
506
- *
507
- * @param {Parser.SyntaxNode | null} node
508
- * @returns {string}
509
- */
510
- function getType(node) {
511
- if (!node) {
512
- return "";
513
- }
514
- // if generic type, see if it is a list or map
515
- switch (node.type) {
516
- case "generic_type":
517
- const genType = getType(node.namedChildren[0]);
518
- let typeNode = node.namedChildren[1];
519
- if (!typeNode) {
520
- return "";
521
- }
522
- switch (genType.toLowerCase()) {
523
- case "list":
524
- return getType(typeNode.namedChildren[0]) + "[]";
525
- case "map":
526
- return `Record<${getType(typeNode.namedChildren[0])}, ${getType(
527
- typeNode.namedChildren[1]
528
- )}>`;
529
- case "set":
530
- return `Set<${getType(typeNode.namedChildren[0])}>`;
531
-
532
- default:
533
- console.error("Unexpected generic type", genType);
534
- }
535
- }
536
- if (localNestedClasses.includes(node.text)) {
537
- return `${outerClassName}.${node.text}`;
538
- }
539
- return typeOverrides[node.text.toLowerCase()] ?? node.text;
540
- }
541
-
542
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
543
-
544
- /**
545
- *
546
- * @param {Component} component
547
- * @returns {ConvertedComponent}
548
- */
549
- function ContentAsset(component) {
550
- // generate d.ts
551
- /** @type {any} */
552
- let asset;
553
- xml2js.parseString(component.content, (error, result) => {
554
- if (error) {
555
- throw error;
556
- }
557
- asset = result;
558
- });
559
- const label = asset.ContentAsset.masterLabel[0];
560
- const namePosStart =
561
- component.content.indexOf("<masterLabel>") + "<masterLabel>".length;
562
- const namePosEnd = namePosStart + label.length;
563
-
564
- const builder = new PositionAwareTextBuilder();
565
-
566
- builder.addText(`declare module `);
567
- builder.addText(
568
- `"@salesforce/contentAssetUrl/${label}"`,
569
- namePosStart,
570
- namePosEnd
571
- );
572
- builder.addText(
573
- ` {
574
- const `
575
- );
576
- builder.addText(label, namePosStart, namePosEnd);
577
- builder.addText(
578
- `: string;
579
- export default ${label};
580
- }`
581
- );
582
- return {
583
- declarationContent: builder.build(),
584
- mapData: builder.getMappings(),
585
- ...component,
586
- };
587
- }
588
-
589
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
590
-
591
- /**
592
- *
593
- * @param {Component} component
594
- * @returns {ConvertedComponent}
595
- */
596
- function CustomPermission(component) {
597
- /** @type {any} */
598
- let perm;
599
- xml2js.parseString(component.content, (error, result) => {
600
- if (error) {
601
- throw error;
602
- }
603
- perm = result;
604
- });
605
- const permName = component.path.split("/").pop()?.split(".")[0];
606
- const namePosStart = component.content.indexOf("<label>") + "<label>".length;
607
- const namePosEnd = component.content.indexOf("</label>");
608
-
609
- const builder = new PositionAwareTextBuilder();
610
- builder.addText("declare module ");
611
- builder.addText(
612
- `"@salesforce/customPermission/${permName}"`,
613
- namePosStart,
614
- namePosEnd
615
- );
616
-
617
- builder.addText(
618
- ` {
619
- /**
620
- * ${perm.CustomPermission.label}
621
- *
622
- * @description ${perm.CustomPermission.description}
623
- */
624
- const `
625
- );
626
- builder.addText(`has${permName}`, namePosStart, namePosEnd);
627
- builder.addText(
628
- `:boolean;
629
- export default has${permName};
630
- }`
631
- );
632
- return {
633
- declarationContent: builder.build(),
634
- mapData: builder.getMappings(),
635
- ...component,
636
- };
637
- }
638
-
639
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
640
-
641
- /**
642
- *
643
- * @param {Component} component
644
- * @returns {ConvertedComponent}
645
- */
646
- function CustomField(component) {
647
- // generate d.ts
648
- /** @type {any} */
649
- let field;
650
- xml2js.parseString(component.content, (error, result) => {
651
- if (error) {
652
- throw error;
653
- }
654
- field = result;
655
- });
656
- const pathParts = component.path.split("/");
657
- const fieldName = pathParts.pop()?.split(".")[0];
658
- if (!fieldName) {
659
- throw new Error("Unable to resolve field name from file path");
660
- }
661
- pathParts?.pop(); // discard `fields`
662
- const objectName = pathParts.pop();
663
-
664
- const namePosStart =
665
- component.content.indexOf("<fullName>") + "<fullName>".length;
666
- const namePosEnd = namePosStart + fieldName.length;
667
-
668
- const builder = new PositionAwareTextBuilder();
669
- builder.addText(`declare module `);
670
- builder.addText(
671
- `"@salesforce/schema/${objectName}.${fieldName}"`,
672
- namePosStart,
673
- namePosEnd
674
- );
675
- builder.addText(
676
- ` {
677
- /**
678
- * @description ${field.CustomField.inlineHelpText}
679
- * @description ${field.CustomField.description}
680
- */
681
- const `
682
- );
683
-
684
- builder.addText(`${fieldName}`, namePosStart, namePosEnd);
685
-
686
- builder.addText(
687
- `: {
688
- fieldApiName: '${fieldName}';
689
- objectApiName: '${objectName}';
690
- }
691
- export default ${fieldName};
692
- }`
693
- );
694
- return {
695
- declarationContent: builder.build(),
696
- mapData: builder.getMappings(),
697
- ...component,
698
- };
699
- }
700
-
701
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
702
-
703
- /**
704
- *
705
- * @param {Component} component
706
- * @returns {ConvertedComponent}
707
- */
708
- function CustomLabel(component) {
709
- // generate d.ts
710
- /** @type {any} */
711
- let labels;
712
- xml2js.parseString(component.content, (error, result) => {
713
- if (error) {
714
- throw error;
715
- }
716
- labels = result;
717
- });
718
- console.log(labels.CustomLabel);
719
- const builder = new PositionAwareTextBuilder();
720
- getDtsFromLabel(builder, component.content, labels.CustomLabel);
721
- return {
722
- declarationContent: builder.build(),
723
- mapData: builder.getMappings(),
724
- ...component,
725
- };
726
- }
727
-
728
- /**
729
- *
730
- * @param {PositionAwareTextBuilder} builder
731
- * @param {string} content
732
- * @param {any} label
733
- */
734
- function getDtsFromLabel(builder, content, label) {
735
- const labelName = label.fullName[0];
736
- const namePosStart =
737
- content.indexOf(`<fullName>${labelName}`) + `<fullName>`.length;
738
- const namePosEnd = namePosStart + labelName.length;
739
-
740
- builder.addText(`declare module `);
741
- builder.addText(
742
- `"@salesforce/label/c.${labelName}"`,
743
- namePosStart,
744
- namePosEnd
745
- );
746
- builder.addText(
747
- ` {
748
- /**
749
- * @description ${label.shortDescription}
750
- */
751
- const `
752
- );
753
- builder.addText(`lbl${label.fullName}`, namePosStart, namePosEnd);
754
- builder.addText(
755
- ` = '${label.value}';
756
- export default lbl${label.fullName};
757
- }
758
- `
759
- );
760
- }
761
-
762
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
763
-
764
- /**
765
- *
766
- * @param {Component} component
767
- * @returns {ConvertedComponent}
768
- */
769
- function CustomLabels(component) {
770
- // generate d.ts
771
- /** @type {any} */
772
- let labels;
773
- xml2js.parseString(component.content, (error, result) => {
774
- if (error) {
775
- throw error;
776
- }
777
- labels = result;
778
- });
779
- if (!Array.isArray(labels.CustomLabels.labels)) {
780
- labels.CustomLabels.labels = [labels.CustomLabels.labels];
781
- }
782
-
783
- const builder = new PositionAwareTextBuilder();
784
- for (let label of labels.CustomLabels.labels) {
785
- getDtsFromLabel(builder, component.content, label);
786
- }
787
- return {
788
- declarationContent: builder.build(),
789
- mapData: builder.getMappings(),
790
- ...component,
791
- };
792
- }
793
-
794
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
795
-
796
- /**
797
- *
798
- * @param {Component} component
799
- * @returns {ConvertedComponent}
800
- */
801
- function CustomObject(component) {
802
- // generate d.ts
803
- /** @type {any} */
804
- let obj;
805
- xml2js.parseString(component.content, (error, result) => {
806
- if (error) {
807
- throw error;
808
- }
809
- obj = result;
810
- });
811
- const objectName = component.path.split("/").pop()?.split(".")[0];
812
- if (!objectName) {
813
- throw new Error("Unable to find Object Name");
814
- }
815
-
816
- const namePos = component.content.indexOf("<label>") + "<label>".length;
817
- const namePosEnd = component.content.indexOf("</label>");
818
-
819
- const builder = new PositionAwareTextBuilder();
820
- builder.addText(`declare module `);
821
- builder.addText(`"@salesforce/schema/${objectName}"`, namePos, namePosEnd);
822
- builder.addText(
823
- ` {
824
- /**
825
- * @description ${obj.CustomObject.description}
826
- */
827
- const `
828
- );
829
- builder.addText(`${objectName}`, namePos, namePosEnd);
830
- builder.addText(
831
- `: {
832
- objectApiName: '${objectName}';
833
- }
834
- export default ${objectName};
835
- }`
836
- );
837
- return {
838
- declarationContent: builder.build(),
839
- mapData: builder.getMappings(),
840
- ...component,
841
- };
842
- }
843
-
844
- /** @import { Component, ConvertedComponent } from "../index.mjs" */
845
-
846
- /**
847
- *
848
- * @param {Component} component
849
- * @returns {ConvertedComponent}
850
- */
851
- function StaticResource(component) {
852
- // generate d.ts
853
- /** @type {any} */
854
- let resource;
855
- xml2js.parseString(component.content, (error, result) => {
856
- if (error) {
857
- throw error;
858
- }
859
- resource = result;
860
- });
861
- const resourceName = component.path.split("/").pop()?.split(".")[0];
862
- const namePosStart =
863
- component.content.indexOf("<description>") + "<description>".length;
864
- const namePosEnd = component.content.indexOf("</description>");
865
-
866
- const builder = new PositionAwareTextBuilder();
867
-
868
- builder.addText("declare module ");
869
-
870
- builder.addText(
871
- `"@salesforce/resourceUrl/${resourceName}"`,
872
- namePosStart,
873
- namePosEnd
874
- );
875
-
876
- builder.addText(
877
- ` {
878
- /**
879
- * @description ${resource.StaticResource.description}
880
- * @access ${resource.StaticResource.cacheControl}
881
- */
882
- const `
883
- );
884
-
885
- builder.addText(`${resourceName}`, namePosStart, namePosEnd);
886
-
887
- builder.addText(
888
- `:string;
889
- export default ${resourceName};
890
- }`
891
- );
892
- return {
893
- declarationContent: builder.build(),
894
- mapData: builder.getMappings(),
895
- ...component,
896
- };
897
- }
898
-
899
- var converters = /*#__PURE__*/Object.freeze({
900
- __proto__: null,
901
- ApexClass: ApexClass,
902
- ContentAsset: ContentAsset,
903
- CustomField: CustomField,
904
- CustomLabel: CustomLabel,
905
- CustomLabels: CustomLabels,
906
- CustomObject: CustomObject,
907
- CustomPermission: CustomPermission,
908
- StaticResource: StaticResource
909
- });
910
-
911
- // maybe there is a smarter way to do this
912
- /** @type {Readonly<{[p in keyof converters]: p}>} */
913
- const MetadataType = Object.freeze(
914
- Object.keys(converters).reduce((/** @type {any} */ t, v) => {
915
- t[v] = v;
916
- return t;
917
- }, {})
918
- );
919
-
920
- /**
921
- * @typedef MapPair
922
- * @property {number} sourcePos
923
- * @property {number} destPos
924
- */
925
-
926
- /**
927
- * @typedef Component
928
- * @property {string} path
929
- * @property {keyof converters} type
930
- * @property {string} content
931
- */
932
-
933
- /**
934
- * @typedef { Component & {
935
- * declarationContent: string;
936
- * mapData: MapPair[]}} ConvertedComponent
937
- */
938
-
939
- /**
940
- *
941
- * @param {Component[]} components
942
- * @returns {ConvertedComponent[]}
943
- */
944
- function convert(components) {
945
- /** @type {ConvertedComponent[]} */
946
- const convertedComponents = [];
947
- for (const c of components) {
948
- if (!converters[c.type]) {
949
- throw new Error(
950
- "Unsupported Metadata Type:" +
951
- c.type +
952
- ", must be one of " +
953
- Object.keys(converters)
954
- );
955
- }
956
- convertedComponents.push(converters[c.type](c));
957
- }
958
- return convertedComponents;
959
- }
960
-
961
- exports.MetadataType = MetadataType;
962
- exports.convert = convert;